[med-svn] [ncbi-blast+] 01/03: New upstream version 2.6.0

Olivier Sallou osallou at debian.org
Sun Jan 15 17:29:26 UTC 2017


This is an automated email from the git hooks/post-receive script.

osallou pushed a commit to branch master
in repository ncbi-blast+.

commit edfc13137ba904f5260790dee3746cf7ab5cc041
Author: Olivier Sallou <osallou at debian.org>
Date:   Sun Jan 15 17:12:04 2017 +0000

    New upstream version 2.6.0
---
 c++/compilers/unix/GCC.sh                          |     2 +-
 c++/compilers/unix/ICC.sh                          |     2 +-
 c++/compilers/vs2013/build_exec.bat                |     3 +-
 c++/compilers/vs2013/configure.bat                 |     2 +-
 .../vs2013/dll/build/gbench/ncbi_gbench.sln        |    32 +-
 .../vs2013/dll/build/gui/ncbi_gui_dll.sln          |    32 +-
 c++/compilers/vs2013/dll/build/ncbi_cpp_dll.sln    |    32 +-
 c++/compilers/vs2013/make.bat                      |    12 +-
 c++/compilers/vs2013/ptb.bat                       |    12 +-
 c++/compilers/vs2013/static/build/gui/ncbi_gui.sln |    32 +-
 c++/compilers/vs2013/static/build/ncbi_cpp.sln     |    20 +-
 c++/compilers/vs2013/user/build/ncbi_user.sln      |    32 +-
 c++/compilers/vs2015/Makefile.WinMain.app.msvc     |    11 +
 c++/compilers/vs2015/Makefile.wxWidgets.app.msvc   |    11 +
 c++/compilers/vs2015/build.sh                      |   264 +
 c++/compilers/vs2015/build_exec.bat                |    51 +
 c++/compilers/vs2015/build_util.sh                 |    67 +
 c++/compilers/vs2015/check.sh                      |   276 +
 c++/compilers/vs2015/configure.bat                 |   384 +
 c++/compilers/vs2015/datatool.bat                  |   188 +
 .../dll/build/UtilityProjects/_CONFIGURE_.vcxproj  |   144 +
 .../UtilityProjects/_CONFIGURE_DIALOG_.vcxproj     |   144 +
 .../vs2015/dll/build/UtilityProjects/configure._   |     4 +
 .../dll/build/UtilityProjects/configure_dialog._   |     4 +
 c++/compilers/vs2015/dll/build/all.bat             |    42 +
 c++/compilers/vs2015/dll/build/all_gbench.bat      |    75 +
 c++/compilers/vs2015/dll/build/all_gui.bat         |    75 +
 c++/compilers/vs2015/dll/build/all_ncbi.bat        |    75 +
 .../gbench/UtilityProjects/_CONFIGURE_.vcxproj     |   148 +
 .../UtilityProjects/_CONFIGURE_DIALOG_.vcxproj     |   148 +
 .../dll/build/gbench/UtilityProjects/configure._   |     5 +
 .../gbench/UtilityProjects/configure_dialog._      |     5 +
 .../vs2015/dll/build/gbench/configure_prebuild.bat |    48 +
 .../gbench/gbench_install/gbench-install.vcxproj   |   218 +
 .../vs2015/dll/build/gbench/ncbi_gbench.sln        |    35 +
 .../build/gui/UtilityProjects/_CONFIGURE_.vcxproj  |   144 +
 .../gui/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj |   144 +
 .../dll/build/gui/UtilityProjects/configure._      |     4 +
 .../build/gui/UtilityProjects/configure_dialog._   |     4 +
 .../vs2015/dll/build/gui/ncbi_gui_dll.sln          |    35 +
 .../gbench-install-internal.vcxproj                |   218 +
 c++/compilers/vs2015/dll/build/ncbi_cpp_dll.sln    |    35 +
 c++/compilers/vs2015/dll/dll_main.cpp              |    18 +
 .../vs2015/dll/third_party_dll_install.mak         |    62 +
 .../vs2015/dll/third_party_dll_install.vcxproj     |   433 +
 .../vs2015/dll/third_party_msvcdll_install.vcxproj |   433 +
 c++/compilers/vs2015/install.sh                    |   186 +
 c++/compilers/vs2015/lock_ptb_config.bat           |    94 +
 c++/compilers/vs2015/make.bat                      |   223 +
 c++/compilers/vs2015/make_ncbi.bat                 |    60 +
 c++/compilers/vs2015/msvcvars.bat                  |    14 +
 c++/compilers/vs2015/ncbi.rc                       |     1 +
 c++/compilers/vs2015/ncbilogo.ico                  |   Bin 0 -> 766 bytes
 c++/compilers/vs2015/ptb.bat                       |   288 +
 .../vs2015/static/build/UtilityProjects/PTB.sln    |    79 +
 .../build/UtilityProjects/_CONFIGURE_.vcxproj      |   144 +
 .../UtilityProjects/_CONFIGURE_DIALOG_.vcxproj     |   144 +
 .../static/build/UtilityProjects/configure._       |     4 +
 .../build/UtilityProjects/configure_dialog._       |     4 +
 c++/compilers/vs2015/static/build/all.bat          |    39 +
 c++/compilers/vs2015/static/build/all_gui.bat      |    79 +
 c++/compilers/vs2015/static/build/all_ncbi.bat     |    79 +
 .../msbuild/msbuild_dataobj.lib.vcxproj            |   149 +
 .../project_tree_builder.exe.vcxproj               |   415 +
 .../vs2015/static/build/corelib/xncbi.lib.vcxproj  |   509 +
 .../build/gui/UtilityProjects/_CONFIGURE_.vcxproj  |   144 +
 .../gui/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj |   144 +
 .../static/build/gui/UtilityProjects/configure._   |     4 +
 .../build/gui/UtilityProjects/configure_dialog._   |     4 +
 c++/compilers/vs2015/static/build/gui/ncbi_gui.sln |    35 +
 c++/compilers/vs2015/static/build/ncbi_cpp.sln     |    35 +
 .../build/serial/datatool/datatool.exe.vcxproj     |   506 +
 .../vs2015/static/build/serial/xser.lib.vcxproj    |   533 +
 .../static/build/util/regexp/regexp.lib.vcxproj    |   363 +
 .../static/build/util/xregexp/xregexp.lib.vcxproj  |   176 +
 .../vs2015/static/build/util/xutil.lib.vcxproj     |   308 +
 .../static/third_party_msvcstatic_install.vcxproj  |   433 +
 .../vs2015/static/third_party_static_install.mak   |    62 +
 .../static/third_party_static_install.vcxproj      |   433 +
 c++/compilers/vs2015/third_party_install.meta.mk   |   330 +
 .../user/build/UtilityProjects/_CONFIGURE_.vcxproj |   144 +
 .../UtilityProjects/_CONFIGURE_DIALOG_.vcxproj     |   144 +
 .../vs2015/user/build/UtilityProjects/configure._  |     4 +
 .../user/build/UtilityProjects/configure_dialog._  |     4 +
 c++/compilers/vs2015/user/build/ncbi_user.sln      |    35 +
 c++/compilers/xcode30_prj/configure                |    34 +-
 c++/compilers/xcode30_prj/ptb.sh                   |    12 +-
 c++/configure                                      |     2 +-
 c++/include/algo/blast/api/blast_aux.hpp           |    26 +-
 c++/include/algo/blast/api/blast_options.hpp       |    22 +-
 .../algo/blast/api/blast_options_handle.hpp        |     3 +-
 c++/include/algo/blast/api/blast_seqinfosrc.hpp    |     2 +-
 .../algo/blast/api/blast_seqinfosrc_aux.hpp        |    21 +-
 c++/include/algo/blast/api/blast_types.hpp         |     3 +-
 c++/include/algo/blast/api/magicblast.hpp          |   115 +
 c++/include/algo/blast/api/magicblast_options.hpp  |   211 +
 .../algo/blast/api/objmgrfree_query_data.hpp       |     5 +-
 c++/include/algo/blast/api/remote_blast.hpp        |     2 +-
 c++/include/algo/blast/api/seqinfosrc_seqdb.hpp    |     2 +-
 c++/include/algo/blast/api/seqinfosrc_seqvec.hpp   |     2 +-
 c++/include/algo/blast/api/setup_factory.hpp       |     4 +-
 c++/include/algo/blast/blastinput/blast_args.hpp   |   162 +-
 .../algo/blast/blastinput/blast_asn1_input.hpp     |   119 +
 .../algo/blast/blastinput/blast_fasta_input.hpp    |    82 +-
 c++/include/algo/blast/blastinput/blast_input.hpp  |    51 +-
 .../algo/blast/blastinput/blast_input_aux.hpp      |    15 +-
 .../algo/blast/blastinput/blast_scope_src.hpp      |     6 +-
 .../algo/blast/blastinput/cmdline_flags.hpp        |    51 +-
 c++/include/algo/blast/blastinput/kblastp_args.hpp |    75 +
 .../algo/blast/blastinput/magicblast_args.hpp      |    63 +
 .../composition_adjustment.h                       |     2 +-
 .../blast/composition_adjustment/redo_alignment.h  |    15 +-
 c++/include/algo/blast/core/blast_engine.h         |    23 +-
 c++/include/algo/blast/core/blast_gapalign.h       |     9 +-
 c++/include/algo/blast/core/blast_hits.h           |   102 +-
 c++/include/algo/blast/core/blast_hspfilter.h      |    12 +-
 c++/include/algo/blast/core/blast_hspstream.h      |    19 +-
 c++/include/algo/blast/core/blast_kappa.h          |     2 +-
 c++/include/algo/blast/core/blast_lookup.h         |    53 +-
 c++/include/algo/blast/core/blast_nalookup.h       |   112 +-
 c++/include/algo/blast/core/blast_options.h        |    30 +-
 c++/include/algo/blast/core/blast_program.h        |    15 +-
 c++/include/algo/blast/core/blast_query_info.h     |    19 +-
 c++/include/algo/blast/core/blast_stat.h           |     2 +-
 c++/include/algo/blast/core/hspfilter_mapper.h     |   101 +
 c++/include/algo/blast/core/lookup_util.h          |     4 +-
 c++/include/algo/blast/core/lookup_wrap.h          |     8 +-
 c++/include/algo/blast/core/na_ungapped.h          |    65 +-
 c++/include/algo/blast/format/blast_format.hpp     |    38 +-
 c++/include/algo/blast/igblast/igblast.hpp         |     7 +-
 c++/include/cgi/cgi_session.hpp                    |     2 +-
 c++/include/cgi/cgiapp.hpp                         |     2 +-
 c++/include/cgi/cgictx.hpp                         |     4 +-
 c++/include/cgi/error_codes.hpp                    |     2 +-
 c++/include/cgi/ncbicgi.hpp                        |     2 +-
 c++/include/cgi/ncbicgir.hpp                       |     6 +-
 c++/include/cgi/user_agent.hpp                     |     6 +-
 c++/include/common/config/ncbiconf_msvc_site.h     |    35 -
 c++/include/common/config/ncbiconf_universal.h     |     5 +-
 c++/include/common/config/ncbiconf_xcode.h         |    28 +-
 c++/include/common/config/ncbiconf_xcode_site.h    |   123 -
 c++/include/common/ncbi_build_ver.h.in             |    37 +
 c++/include/common/ncbi_export.h                   |    19 +-
 c++/include/common/ncbi_package_ver.h              |     2 +-
 c++/include/common/ncbi_source_ver.h               |    12 +-
 c++/include/common/ncbiconf_impl.h                 |     2 +-
 c++/include/connect/impl/server_connection.hpp     |     3 +-
 .../connect/impl/thread_pool_for_server.hpp        |    22 +-
 c++/include/connect/ncbi_base64.h                  |     8 +-
 c++/include/connect/ncbi_buffer.h                  |     5 +-
 c++/include/connect/ncbi_connector.h               |    16 +-
 c++/include/connect/ncbi_connutil.h                |    35 +-
 c++/include/connect/ncbi_core.h                    |     3 +-
 c++/include/connect/ncbi_core_cxx.hpp              |     7 +-
 c++/include/connect/ncbi_gnutls.h                  |     8 +-
 c++/include/connect/ncbi_http_connector.h          |     9 +-
 c++/include/connect/ncbi_http_session.hpp          |    24 +-
 c++/include/connect/ncbi_lbos.hpp                  |   283 +-
 c++/include/connect/ncbi_monkey.hpp                |   405 +
 c++/include/connect/ncbi_server_info.h             |     5 +-
 c++/include/connect/ncbi_service.h                 |    47 +-
 c++/include/connect/ncbi_socket.h                  |    26 +-
 c++/include/connect/ncbi_types.h                   |     6 +-
 c++/include/connect/server.hpp                     |    25 +-
 c++/include/connect/services/grid_client.hpp       |     2 +-
 c++/include/connect/services/grid_worker.hpp       |     2 +-
 c++/include/connect/services/grid_worker_app.hpp   |     2 +-
 .../connect/services/impl/neticache_client_int.hpp |     2 +-
 .../connect/services/impl/netschedule_api_int.hpp  |     2 +-
 .../connect/services/impl/netstorage_impl.hpp      |    15 +-
 .../connect/services/impl/netstorage_int.hpp       |     2 +-
 c++/include/connect/services/json_over_uttp.hpp    |     6 +-
 c++/include/connect/services/netcache_api_expt.hpp |     2 +-
 c++/include/connect/services/netcache_search.hpp   |   169 +
 c++/include/connect/services/netcomponent.hpp      |     9 +-
 c++/include/connect/services/neticache_client.hpp  |    22 +-
 c++/include/connect/services/netschedule_api.hpp   |    68 +-
 c++/include/connect/services/netstorage.hpp        |    28 +-
 c++/include/connect/services/netstorage_ft.hpp     |     2 +-
 c++/include/connect/services/ns_output_parser.hpp  |    38 +-
 c++/include/corelib/ddumpable.hpp                  |     2 +-
 c++/include/corelib/hash_impl/_hash_map.h          |   102 +-
 c++/include/corelib/hash_impl/_hash_set.h          |   105 +-
 c++/include/corelib/impl/ncbi_atomic_defs.h        |     6 +-
 c++/include/corelib/impl/ncbi_dbsvcmapper.hpp      |    54 +-
 c++/include/corelib/ncbi_base64.h                  |     8 +-
 c++/include/corelib/ncbi_config.hpp                |     2 +-
 c++/include/corelib/ncbi_cookies.hpp               |    13 +-
 c++/include/corelib/ncbi_param.hpp                 |    14 +-
 c++/include/corelib/ncbi_stack.hpp                 |    11 +-
 c++/include/corelib/ncbi_xstr.hpp                  |    22 +-
 c++/include/corelib/ncbiapp.hpp                    |    11 +-
 c++/include/corelib/ncbiargs.hpp                   |    99 +-
 c++/include/corelib/ncbiatomic.h                   |     4 +-
 c++/include/corelib/ncbictype.hpp                  |    15 +-
 c++/include/corelib/ncbidbg.hpp                    |     2 +-
 c++/include/corelib/ncbidiag.hpp                   |    51 +-
 c++/include/corelib/ncbidiag.inl                   |     5 +-
 c++/include/corelib/ncbierror.hpp                  |    79 +-
 c++/include/corelib/ncbifile.hpp                   |   122 +-
 c++/include/corelib/ncbimisc.hpp                   |   119 +-
 c++/include/corelib/ncbiobj.hpp                    |    68 +-
 c++/include/corelib/ncbireg.hpp                    |    10 +-
 c++/include/corelib/ncbistl.hpp                    |     3 +-
 c++/include/corelib/ncbistr.hpp                    |   653 +-
 c++/include/corelib/request_ctx.hpp                |    81 +-
 c++/include/corelib/rwstream.hpp                   |    40 +-
 c++/include/corelib/version.hpp                    |     3 +-
 c++/include/dbapi/dbapi.hpp                        |     4 +-
 c++/include/dbapi/driver/dbapi_driver_conn_mgr.hpp |     2 +-
 c++/include/dbapi/driver/dbapi_driver_convert.hpp  |     2 +-
 c++/include/dbapi/driver/dbapi_object_convert.hpp  |     2 +-
 c++/include/dbapi/driver/dbapi_svc_mapper.hpp      |     4 +-
 c++/include/dbapi/driver/exception.hpp             |    12 +-
 .../dbapi/driver/impl/dbapi_driver_utils.hpp       |    15 +-
 c++/include/dbapi/driver/impl/dbapi_impl_cmd.hpp   |     2 +-
 .../dbapi/driver/impl/dbapi_impl_connection.hpp    |    14 +-
 .../dbapi/driver/impl/dbapi_impl_context.hpp       |    11 +-
 .../dbapi/driver/impl/dbapi_impl_result.hpp        |     2 +-
 c++/include/dbapi/driver/interfaces.hpp            |    33 +-
 c++/include/dbapi/driver/odbc/interfaces.hpp       |     2 +-
 c++/include/dbapi/driver/public.hpp                |     2 +-
 c++/include/dbapi/driver/types.hpp                 |     2 +-
 c++/include/dbapi/driver/util/blobstore.hpp        |     2 +-
 c++/include/dbapi/error_codes.hpp                  |     2 +-
 c++/include/dbapi/variant.hpp                      |     2 +-
 c++/include/html/htmlhelper.hpp                    |    12 +-
 c++/include/html/nodemap.hpp                       |     4 +-
 c++/include/misc/error_codes.hpp                   |    52 +
 c++/include/ncbi_pch.hpp                           |     2 +-
 c++/include/ncbi_source_ver.h                      |     2 +-
 c++/include/ncbiconf.h                             |     2 +-
 c++/include/objects/biblio/MedlineUID.hpp          |    76 +
 c++/include/objects/biblio/PmcID.hpp               |    76 +
 c++/include/objects/biblio/PubMedId.hpp            |    76 +
 c++/include/objects/general/Dbtag.hpp              |     6 +-
 c++/include/objects/general/Name_std.hpp           |     5 +-
 c++/include/objects/general/User_object.hpp        |     9 +-
 .../genomecoll/GCClient_GetAssemblyBySequ.hpp      |    89 +
 c++/include/objects/genomecoll/GC_Assembly.hpp     |     8 +-
 c++/include/objects/genomecoll/cached_assembly.hpp |     4 +
 .../objects/genomecoll/genomic_collections_cli.hpp |   106 +-
 c++/include/objects/id2/id2processor.hpp           |     6 +-
 c++/include/objects/macro/String_constraint.hpp    |     2 +-
 c++/include/objects/macro/Suspect_rule.hpp         |    30 +-
 c++/include/objects/seq/Seq_gap.hpp                |     2 +-
 c++/include/objects/seq/Seq_inst.hpp               |     4 +-
 c++/include/objects/seq/Seq_literal.hpp            |     7 +-
 c++/include/objects/seq/seq_loc_mapper_base.hpp    |   249 +-
 c++/include/objects/seq/sofa_map.hpp               |     2 +-
 c++/include/objects/seqfeat/BioSource.hpp          |    38 +-
 c++/include/objects/seqfeat/Delta_item.hpp         |    94 +
 c++/include/objects/seqfeat/Gb_qual.hpp            |     6 +-
 c++/include/objects/seqfeat/OrgMod.hpp             |    13 +-
 c++/include/objects/seqfeat/SeqFeatData.hpp        |    12 +-
 c++/include/objects/seqfeat/Seq_feat.hpp           |     6 +-
 c++/include/objects/seqfeat/SubSource.hpp          |     3 +-
 c++/include/objects/seqfeat/Trna_ext.hpp           |     2 +-
 c++/include/objects/seqfeat/Variation_ref.hpp      |    22 +-
 c++/include/objects/seqloc/Seq_loc.hpp             |    18 +-
 c++/include/objects/seqset/Bioseq_set.hpp          |     5 +-
 c++/include/objects/taxon1/Taxon2_data.hpp         |     2 +-
 c++/include/objects/taxon1/taxon1.hpp              |     7 +-
 c++/include/objects/trackmgr/TMgr_ClientInfo.hpp   |     2 +-
 c++/include/objects/trackmgr/TMgr_DTrackId.hpp     |    13 +-
 .../objects/trackmgr/displaytrack_client.hpp       |    47 +-
 c++/include/objects/trackmgr/gridrpcclient.hpp     |   149 +-
 c++/include/objects/valerr/ValidErrItem.hpp        |    20 +-
 c++/include/objects/valerr/ValidError.hpp          |     6 +-
 c++/include/objects/valid/Comment_rule.hpp         |     2 +-
 c++/include/objects/varrep/AaInterval.hpp          |    90 +
 c++/include/objects/varrep/AaLocation.hpp          |    90 +
 c++/include/objmgr/annot_selector.hpp              |    49 +-
 c++/include/objmgr/annot_types_ci.hpp              |     5 +-
 c++/include/objmgr/bioseq_handle.hpp               |     2 +-
 c++/include/objmgr/data_loader.hpp                 |     2 +-
 c++/include/objmgr/impl/annot_collector.hpp        |    97 +-
 c++/include/objmgr/impl/annot_object_index.hpp     |     8 +-
 c++/include/objmgr/impl/bioseq_base_info.hpp       |     6 +-
 c++/include/objmgr/impl/bioseq_info.hpp            |     2 +-
 c++/include/objmgr/impl/data_source.hpp            |     2 +-
 c++/include/objmgr/impl/scope_impl.hpp             |     2 +-
 c++/include/objmgr/impl/seq_annot_info.hpp         |    56 +-
 c++/include/objmgr/impl/seq_entry_info.hpp         |    43 +-
 c++/include/objmgr/impl/seq_id_sort.hpp            |     2 +-
 c++/include/objmgr/impl/seq_table_info.hpp         |    46 +-
 c++/include/objmgr/impl/seq_table_setters.hpp      |    10 +-
 c++/include/objmgr/impl/seq_vector_cvt_gen.hpp     |    26 +-
 c++/include/objmgr/impl/snp_annot_info.hpp         |    19 +-
 c++/include/objmgr/impl/snp_info.hpp               |    20 +-
 c++/include/objmgr/impl/tse_info.hpp               |     3 +-
 c++/include/objmgr/impl/tse_info_object.hpp        |     5 +-
 c++/include/objmgr/impl/tse_split_info.hpp         |     3 +-
 c++/include/objmgr/object_manager.hpp              |     2 +-
 c++/include/objmgr/objmgr_exception.hpp            |     2 +-
 c++/include/objmgr/scope.hpp                       |     2 +-
 c++/include/objmgr/seq_feat_handle.hpp             |    39 +-
 c++/include/objmgr/seq_loc_mapper.hpp              |    86 +-
 c++/include/objmgr/seq_map.hpp                     |     2 +-
 c++/include/objmgr/seq_map_ci.hpp                  |     2 +-
 c++/include/objmgr/seq_vector_ci.hpp               |    17 +-
 c++/include/objmgr/split/size.hpp                  |     4 +-
 c++/include/objmgr/util/create_defline.hpp         |     3 +
 c++/include/objmgr/util/feature.hpp                |    11 +-
 c++/include/objmgr/util/obj_sniff.hpp              |    23 +-
 c++/include/objmgr/util/seq_loc_util.hpp           |     6 +-
 c++/include/objmgr/util/sequence.hpp               |    46 +-
 .../objtools/align_format/align_format_util.hpp    |    55 +-
 c++/include/objtools/align_format/format_flags.hpp |     5 +-
 c++/include/objtools/align_format/showalign.hpp    |    12 +-
 c++/include/objtools/align_format/showdefline.hpp  |    32 +-
 c++/include/objtools/align_format/tabular.hpp      |    33 +-
 c++/include/objtools/align_format/taxFormat.hpp    |    74 +-
 c++/include/objtools/alnmgr/sparse_aln.hpp         |    29 +-
 .../blast/blastdb_format/blastdb_dataextract.hpp   |    84 +-
 .../blast/blastdb_format/blastdb_seqid.hpp         |     2 +-
 .../blast/blastdb_format/seq_formatter.hpp         |   197 +
 .../objtools/blast/blastdb_format/seq_writer.hpp   |     6 +-
 .../blast/seqdb_reader/impl/seqdbatlas.hpp         |    16 +-
 .../blast/seqdb_reader/impl/seqdbgeneral.hpp       |    13 +-
 c++/include/objtools/blast/seqdb_reader/seqdb.hpp  |     5 +-
 .../objtools/blast/seqdb_writer/build_db.hpp       |    15 +-
 .../objtools/blast/seqdb_writer/impl/criteria.hpp  |     9 +-
 .../objtools/blast/seqdb_writer/writedb.hpp        |    10 +-
 .../objtools/blast/services/blast_services.hpp     |     7 +-
 c++/include/objtools/cleanup/cleanup.hpp           |    94 +-
 c++/include/objtools/cleanup/cleanup_change.hpp    |     3 +-
 .../data_loaders/genbank/cache/writer_cache.hpp    |     2 +-
 .../objtools/data_loaders/genbank/gbloader.hpp     |     2 +-
 .../data_loaders/genbank/impl/dispatcher.hpp       |     2 +-
 .../data_loaders/genbank/impl/info_cache.hpp       |     8 +-
 .../data_loaders/genbank/impl/reader_id1_base.hpp  |     2 +-
 .../data_loaders/genbank/impl/reader_id2_base.hpp  |    25 +-
 .../data_loaders/genbank/impl/request_result.hpp   |     2 +-
 .../objtools/data_loaders/genbank/reader.hpp       |     2 +-
 .../data_loaders/genbank/reader_interface.hpp      |     2 +-
 .../objtools/data_loaders/genbank/writer.hpp       |     2 +-
 .../data_loaders/genbank/writer_interface.hpp      |     2 +-
 c++/include/objtools/data_loaders/loaders.hpp      |     2 +-
 c++/include/objtools/edit/apply_object.hpp         |     2 +-
 c++/include/objtools/edit/autodef.hpp              |    23 +-
 .../objtools/edit/autodef_feature_clause.hpp       |     9 +-
 .../objtools/edit/autodef_feature_clause_base.hpp  |    41 +-
 c++/include/objtools/edit/autodef_mod_combo.hpp    |     2 +-
 c++/include/objtools/edit/autodef_options.hpp      |    12 +-
 c++/include/objtools/edit/cds_fix.hpp              |     2 +-
 c++/include/objtools/edit/feattable_edit.hpp       |    13 +-
 c++/include/objtools/edit/gaps_edit.hpp            |    39 +-
 c++/include/objtools/edit/mail_report.hpp          |     4 +-
 c++/include/objtools/edit/publication_edit.hpp     |     2 +-
 c++/include/objtools/edit/rna_edit.hpp             |    11 +-
 c++/include/objtools/edit/seq_entry_edit.hpp       |     2 +-
 c++/include/objtools/edit/seqid_guesser.hpp        |     6 +-
 c++/include/objtools/edit/string_constraint.hpp    |     4 +-
 c++/include/objtools/edit/struc_comm_field.hpp     |     2 +-
 c++/include/objtools/error_codes.hpp               |     2 +-
 c++/include/objtools/format/context.hpp            |    17 +-
 c++/include/objtools/format/flat_file_config.hpp   |    61 +-
 c++/include/objtools/format/gather_items.hpp       |     2 +-
 c++/include/objtools/format/genbank_gather.hpp     |     2 +-
 c++/include/objtools/format/item_formatter.hpp     |     5 +-
 c++/include/objtools/format/items/comment_item.hpp |     9 +-
 c++/include/objtools/format/items/feature_item.hpp |    21 +-
 .../objtools/format/items/flat_qual_slots.hpp      |     3 +-
 c++/include/objtools/format/items/gene_finder.hpp  |     2 +-
 c++/include/objtools/format/items/locus_item.hpp   |    11 +-
 c++/include/objtools/format/items/tsa_item.hpp     |     2 +-
 c++/include/objtools/readers/aln_reader.hpp        |    72 +-
 c++/include/objtools/readers/bed_reader.hpp        |    92 +-
 c++/include/objtools/readers/fasta.hpp             |    75 +-
 c++/include/objtools/readers/gff2_data.hpp         |    14 +-
 c++/include/objtools/readers/gff2_reader.hpp       |    98 +-
 c++/include/objtools/readers/gff3_reader.hpp       |     7 +-
 c++/include/objtools/readers/gff3_sofa.hpp         |    40 +-
 c++/include/objtools/readers/gtf_reader.hpp        |    14 +-
 c++/include/objtools/readers/gvf_reader.hpp        |    73 +-
 c++/include/objtools/readers/microarray_reader.hpp |     8 +-
 c++/include/objtools/readers/reader_base.hpp       |    14 +-
 c++/include/objtools/readers/readfeat.hpp          |    15 -
 c++/include/objtools/readers/source_mod_parser.hpp |     2 +-
 c++/include/objtools/readers/struct_cmt_reader.hpp |    96 +
 c++/include/objtools/readers/track_data.hpp        |    77 +
 c++/include/objtools/readers/vcf_reader.hpp        |     6 +-
 c++/include/objtools/readers/wiggle_reader.hpp     |     4 +-
 c++/include/serial/impl/enumerated.hpp             |    17 +-
 c++/include/serial/impl/objectiter.inl             |     7 +-
 c++/include/serial/impl/objistrasnb.inl            |    23 +-
 c++/include/serial/impl/objstack.hpp               |    13 +-
 c++/include/serial/impl/objstack.inl               |    21 +-
 c++/include/serial/impl/objstrasnb.inl             |     4 +-
 c++/include/serial/impl/stdtypes.hpp               |    12 +-
 c++/include/serial/objectiter.hpp                  |     3 +-
 c++/include/serial/objhook.hpp                     |    23 +-
 c++/include/serial/objistr.hpp                     |     5 +-
 c++/include/serial/objistrasnb.hpp                 |     3 +-
 c++/include/serial/objostr.hpp                     |    11 +-
 c++/include/serial/objostrxml.hpp                  |     4 +-
 c++/include/serial/rpcbase.hpp                     |    15 +-
 c++/include/serial/rpcbase_impl.hpp                |     2 +-
 c++/include/serial/serialbase.hpp                  |    25 +-
 c++/include/serial/serialdef.hpp                   |     4 +-
 c++/include/serial/serialimpl.hpp                  |     6 +-
 c++/include/serial/typeinfo.hpp                    |     9 +-
 c++/include/util/align_range_coll.hpp              |    14 +-
 c++/include/util/bitset/bm.h                       |   194 +-
 c++/include/util/bitset/bmalgo_impl.h              |    37 +
 c++/include/util/bitset/bmalloc.h                  |     4 +-
 c++/include/util/bitset/bmblocks.h                 |   230 +-
 c++/include/util/bitset/bmconst.h                  |    10 +-
 c++/include/util/bitset/bmdbg.h                    |    10 +-
 c++/include/util/bitset/bmdef.h                    |     3 +-
 c++/include/util/bitset/bmfunc.h                   |   225 +-
 c++/include/util/bitset/bmrandom.h                 |     1 -
 c++/include/util/bitset/bmserial.h                 |   206 +-
 c++/include/util/bitset/bmsse2.h                   |     3 +
 c++/include/util/bitset/bmsse4.h                   |    18 +-
 c++/include/util/bitset/bmtrans.h                  |    40 +-
 c++/include/util/bitset/bmutil.h                   |     4 +-
 c++/include/util/bitset/bmvmin.h                   |     6 +-
 c++/include/util/bitset/encoding.h                 |    13 +-
 c++/include/util/bitset/ncbi_bitset_util.hpp       |     2 +-
 c++/include/util/cache/icache_cf.hpp               |     2 +-
 c++/include/util/compress/bzip2/bzlib.h            |    71 +-
 c++/include/util/file_manifest.hpp                 |     2 +-
 c++/include/util/format_guess.hpp                  |    47 +-
 c++/include/util/id_mux.hpp                        |     6 +-
 c++/include/util/rangemap.hpp                      |    10 +-
 c++/include/util/resize_iter.hpp                   |    21 +-
 c++/include/util/resource_pool.hpp                 |     4 +-
 c++/include/util/simple_buffer.hpp                 |    17 +-
 c++/include/util/static_set.hpp                    |    16 +-
 c++/include/util/stream_source.hpp                 |     4 +-
 c++/include/util/strsearch.hpp                     |     4 +-
 c++/include/util/table_printer.hpp                 |     4 +-
 c++/include/util/tables/raw_scoremat.h             |     4 +-
 c++/include/util/timsort.hpp                       |   666 +
 c++/include/util/value_convert.hpp                 |     2 +-
 c++/include/util/value_convert_policy.hpp          |     2 +-
 c++/scripts/common/add_vdb.sh                      |    10 +-
 c++/scripts/common/check/check_add.sh              |    11 +-
 c++/scripts/common/check/check_make_cfg.sh         |     2 +-
 c++/scripts/common/check/check_make_unix.sh        |     9 +-
 .../common/check/inspxe-suppressions/_vs.sup       |    54 +-
 .../common/check/inspxe-suppressions/connect.sup   |    14 +
 .../common/check/inspxe-suppressions/corelib.sup   |    24 +
 .../common/check/inspxe-suppressions/misc.sup      |    41 +
 c++/scripts/common/check/inspxe.sh                 |     2 +-
 c++/scripts/common/check/valgrind.supp             |    25 +-
 c++/scripts/common/impl/compress_tests.sh          |     2 +-
 c++/scripts/common/impl/install.sh                 |     2 +-
 c++/scripts/common/impl/python-config.py           |    25 +
 c++/scripts/common/new_project.sh                  |     5 +-
 c++/scripts/common/new_project.wsf                 |     3 +
 c++/scripts/common/new_project_msvc7.bat           |    45 -
 c++/scripts/common/project_utilits.js              |    91 +-
 c++/scripts/projects/blast/LICENSE                 |   505 +
 c++/scripts/projects/blast/Manifest                |    24 +-
 c++/scripts/projects/blast/components.link         |    16 +-
 .../projects/blast/post_build/blast_utils.py       |     8 +-
 .../projects/blast/post_build/macosx/ncbi-blast.sh |     5 +-
 .../projects/blast/post_build/make_installers.py   |    26 +-
 .../projects/blast/post_build/win/make_win.py      |    11 +-
 .../projects/blast/post_build/win/ncbi-blast.nsi   |    12 +
 c++/scripts/projects/blast/project.lst             |     3 +
 c++/scripts/projects/cobalt/Manifest               |     2 +-
 c++/scripts/projects/datatool/ChangeLog            |     4 +-
 c++/scripts/projects/datatool/Manifest             |     4 +-
 c++/scripts/projects/dispatcher/Manifest           |     4 +-
 c++/scripts/projects/gumbel_params/Manifest        |     2 +-
 c++/scripts/projects/igblast/ChangeLog             |    10 +
 c++/scripts/projects/igblast/LICENSE               |   505 +
 c++/scripts/projects/igblast/Manifest              |    17 +-
 c++/scripts/projects/igblast/README                |    17 +-
 c++/scripts/projects/igblast/components.link       |    16 +-
 .../projects/igblast/post_build/blast_utils.py     |    15 +-
 .../projects/igblast/post_build/make_installers.py |    37 +-
 .../projects/igblast/post_build/win/make_win.py    |    11 +-
 .../projects/igblast/post_build/win/ncbi-blast.nsi |     6 +
 c++/scripts/projects/igblast/project.lst           |     3 +
 c++/scripts/projects/magicblast/ChangeLog          |    11 +
 c++/scripts/projects/magicblast/LICENSE            |   524 +
 c++/scripts/projects/magicblast/Manifest           |    50 +
 c++/scripts/projects/magicblast/README             |   170 +
 c++/scripts/projects/magicblast/components.link    |     9 +
 .../projects/magicblast/post_build/blast_utils.py  |   128 +
 .../post_build/macosx/large-Blue_ncbi_logo.tiff    |   Bin 0 -> 5536538 bytes
 .../post_build/macosx/ncbi-magicblast.sh           |    86 +
 .../macosx/uninstall_ncbi_magicblast.zip           |   Bin 0 -> 58778 bytes
 .../magicblast/post_build/macosx/welcome.txt       |     2 +
 .../magicblast/post_build/make_installers.py       |   112 +
 .../projects/magicblast/post_build/rpm/make_rpm.py |   173 +
 .../magicblast/post_build/rpm/ncbi-magicblast.spec |    41 +
 .../magicblast/post_build/win/EnvVarUpdate.nsh     |   568 +
 .../projects/magicblast/post_build/win/make_win.py |    91 +
 .../magicblast/post_build/win/ncbi-blast.nsi       |   102 +
 .../magicblast/post_build/win/ncbilogo.ico         |   Bin 0 -> 25214 bytes
 .../magicblast/post_build/win/unix2dos.nsh         |    56 +
 c++/scripts/projects/magicblast/project.lst        |    85 +
 c++/scripts/projects/ncbi_applog/ChangeLog         |    20 +-
 c++/scripts/projects/ncbi_applog/Manifest          |     6 +-
 c++/scripts/projects/ncbi_applog/project.lst       |     2 +
 c++/scripts/projects/ncbi_gui_base.lst             |     1 +
 c++/scripts/projects/netcache/ChangeLog            |    35 +
 c++/scripts/projects/netschedule/ChangeLog         |    39 +
 c++/scripts/projects/netschedule/Manifest          |     9 +-
 c++/scripts/projects/netstorage/Manifest           |     4 +-
 c++/scripts/projects/netstorage/components.link    |     9 +-
 c++/scripts/projects/netstorage/project.lst        |     1 -
 c++/scripts/projects/netstorage_gc/project.lst     |     9 +
 .../projects/project_tree_builder/ChangeLog        |     8 +
 c++/scripts/projects/project_tree_builder/Manifest |     5 +-
 c++/scripts/projects/public/Manifest               |    31 +-
 c++/scripts/projects/public/components.link        |    23 +-
 c++/scripts/projects/python_ncbi_dbapi/ChangeLog   |     8 +
 .../projects/python_ncbi_dbapi/components.link     |     6 +-
 c++/scripts/projects/python_ncbi_dbapi/project.lst |    10 +
 c++/scripts/projects/rmblastn/Manifest             |     4 +-
 c++/scripts/projects/testres-kernel/ChangeLog      |     7 +-
 c++/scripts/projects/testres-kernel/Manifest       |     7 +-
 .../projects/testres-kernel/components.link        |     6 +-
 c++/scripts/projects/testres-scheduler/ChangeLog   |     3 +
 c++/scripts/projects/testres-scheduler/Manifest    |     6 +-
 .../projects/testres-scheduler/components.link     |     6 +-
 c++/scripts/projects/xmlwrapp/Manifest             |    18 +-
 c++/src/Makefile.in                                |     2 +-
 c++/src/algo/blast/Makefile.blast_macros.mk        |     8 +-
 c++/src/algo/blast/Makefile.in                     |     6 +-
 c++/src/algo/blast/api/Makefile.xblast.lib         |     6 +-
 .../algo/blast/api/bioseq_extract_data_priv.cpp    |    51 +-
 .../algo/blast/api/bioseq_extract_data_priv.hpp    |     9 +-
 c++/src/algo/blast/api/blast_aux.cpp               |    68 +-
 c++/src/algo/blast/api/blast_aux_priv.cpp          |     8 +-
 c++/src/algo/blast/api/blast_mtlock.cpp            |     7 +-
 c++/src/algo/blast/api/blast_nucl_options.cpp      |     4 +-
 c++/src/algo/blast/api/blast_objmgr_priv.hpp       |    13 +-
 c++/src/algo/blast/api/blast_objmgr_tools.cpp      |     4 -
 c++/src/algo/blast/api/blast_options_builder.cpp   |    29 +-
 c++/src/algo/blast/api/blast_options_cxx.cpp       |   119 +-
 c++/src/algo/blast/api/blast_options_handle.cpp    |    43 +-
 .../algo/blast/api/blast_options_local_priv.cpp    |     7 +-
 .../algo/blast/api/blast_options_local_priv.hpp    |    99 +-
 c++/src/algo/blast/api/blast_results.cpp           |     7 +-
 c++/src/algo/blast/api/blast_seqalign.cpp          |   232 +-
 c++/src/algo/blast/api/blast_seqalign.hpp          |    23 +-
 c++/src/algo/blast/api/blast_seqinfosrc_aux.cpp    |    45 +-
 c++/src/algo/blast/api/blast_setup.hpp             |     8 +-
 c++/src/algo/blast/api/blast_setup_cxx.cpp         |    65 +-
 c++/src/algo/blast/api/cdd_pssm_input.cpp          |     8 +-
 c++/src/algo/blast/api/deltablast.cpp              |    10 +-
 c++/src/algo/blast/api/dust_filter.cpp             |     7 +-
 c++/src/algo/blast/api/local_blast.cpp             |     5 +-
 c++/src/algo/blast/api/local_db_adapter.cpp        |     4 -
 c++/src/algo/blast/api/local_search.cpp            |     4 -
 c++/src/algo/blast/api/magicblast.cpp              |   346 +
 c++/src/algo/blast/api/magicblast_options.cpp      |   224 +
 c++/src/algo/blast/api/msa_pssm_input.cpp          |     4 -
 c++/src/algo/blast/api/objmgr_query_data.cpp       |     4 -
 c++/src/algo/blast/api/objmgrfree_query_data.cpp   |     4 -
 c++/src/algo/blast/api/prelim_search_runner.hpp    |    19 +-
 c++/src/algo/blast/api/prelim_stage.cpp            |     4 -
 c++/src/algo/blast/api/psi_pssm_input.cpp          |     4 -
 c++/src/algo/blast/api/psibl2seq.cpp               |     4 -
 c++/src/algo/blast/api/psiblast.cpp                |     4 -
 c++/src/algo/blast/api/psiblast_aux_priv.cpp       |     4 -
 c++/src/algo/blast/api/psiblast_impl.cpp           |     4 -
 c++/src/algo/blast/api/psiblast_iteration.cpp      |     4 -
 c++/src/algo/blast/api/pssm_engine.cpp             |     4 -
 c++/src/algo/blast/api/query_data.cpp              |     4 -
 c++/src/algo/blast/api/remote_blast.cpp            |    21 +-
 c++/src/algo/blast/api/remote_search.cpp           |     4 -
 c++/src/algo/blast/api/repeats_filter_cxx.cpp      |     7 +-
 c++/src/algo/blast/api/rps_aux.cpp                 |     4 -
 c++/src/algo/blast/api/rpstblastn_options.cpp      |     4 +-
 c++/src/algo/blast/api/seedtop.cpp                 |     4 +-
 c++/src/algo/blast/api/seqinfosrc_bioseq.cpp       |     4 -
 c++/src/algo/blast/api/seqinfosrc_bioseq.hpp       |     2 +-
 c++/src/algo/blast/api/seqinfosrc_seqdb.cpp        |     4 -
 c++/src/algo/blast/api/seqinfosrc_seqvec.cpp       |     4 -
 c++/src/algo/blast/api/seqsrc_seqdb.cpp            |   231 +-
 c++/src/algo/blast/api/setup_factory.cpp           |    31 +-
 c++/src/algo/blast/api/split_query_aux_priv.cpp    |     8 +-
 c++/src/algo/blast/api/split_query_blk.cpp         |     4 -
 c++/src/algo/blast/api/split_query_cxx.cpp         |     4 -
 c++/src/algo/blast/api/traceback_stage.cpp         |     4 -
 c++/src/algo/blast/api/uniform_search.cpp          |     4 -
 c++/src/algo/blast/api/winmask_filter.cpp          |     7 +-
 .../algo/blast/blastinput/Makefile.blastinput.lib  |     9 +-
 c++/src/algo/blast/blastinput/Makefile.in          |     2 +-
 c++/src/algo/blast/blastinput/blast_args.cpp       |   417 +-
 c++/src/algo/blast/blastinput/blast_asn1_input.cpp |   365 +
 .../algo/blast/blastinput/blast_fasta_input.cpp    |   734 +-
 c++/src/algo/blast/blastinput/blast_input.cpp      |    33 +-
 c++/src/algo/blast/blastinput/blast_input_aux.cpp  |    45 +-
 c++/src/algo/blast/blastinput/blast_scope_src.cpp  |    29 +-
 c++/src/algo/blast/blastinput/blastn_args.cpp      |     7 +-
 c++/src/algo/blast/blastinput/blastp_args.cpp      |     7 +-
 c++/src/algo/blast/blastinput/blastx_args.cpp      |     7 +-
 c++/src/algo/blast/blastinput/cmdline_flags.cpp    |    31 +-
 c++/src/algo/blast/blastinput/deltablast_args.cpp  |     7 +-
 c++/src/algo/blast/blastinput/igblastn_args.cpp    |     9 +-
 c++/src/algo/blast/blastinput/igblastp_args.cpp    |     7 +-
 c++/src/algo/blast/blastinput/kblastp_args.cpp     |   105 +
 c++/src/algo/blast/blastinput/magicblast_args.cpp  |   278 +
 c++/src/algo/blast/blastinput/psiblast_args.cpp    |     9 +-
 c++/src/algo/blast/blastinput/rmblastn_args.cpp    |     7 +-
 c++/src/algo/blast/blastinput/rpsblast_args.cpp    |     7 +-
 c++/src/algo/blast/blastinput/rpstblastn_args.cpp  |    15 +-
 c++/src/algo/blast/blastinput/tblastn_args.cpp     |     7 +-
 c++/src/algo/blast/blastinput/tblastx_args.cpp     |     7 +-
 .../unit_test/Makefile.blastinput_unit_test.app    |     4 +-
 .../unit_test/blast_input_unit_test_aux.hpp        |    37 +-
 .../unit_test/blast_scope_src_unit_test.cpp        |    14 +-
 .../blastinput/unit_test/blastinput_unit_test.cpp  |   326 +-
 .../blastinput/unit_test/data/paired_reads.asn     |    84 +
 .../blastinput/unit_test/data/paired_reads.fa      |    12 +
 .../blastinput/unit_test/data/paired_reads.fastq   |    24 +
 .../blastinput/unit_test/data/paired_reads_1.asn   |    42 +
 .../blastinput/unit_test/data/paired_reads_1.fa    |     6 +
 .../blastinput/unit_test/data/paired_reads_1.fastq |    12 +
 .../blastinput/unit_test/data/paired_reads_2.asn   |    42 +
 .../blastinput/unit_test/data/paired_reads_2.fa    |     6 +
 .../blastinput/unit_test/data/paired_reads_2.fastq |    12 +
 .../algo/blast/composition_adjustment/compo_heap.c |     5 -
 .../composition_adjustment/compo_mode_condition.c  |     5 -
 .../composition_adjustment.c                       |    18 +-
 .../composition_adjustment/matrix_frequency_data.c |     4 -
 .../composition_adjustment/nlm_linear_algebra.c    |     4 -
 .../composition_adjustment/optimize_target_freq.c  |     4 -
 .../blast/composition_adjustment/redo_alignment.c  |    52 +-
 .../blast/composition_adjustment/smith_waterman.c  |     4 -
 .../blast/composition_adjustment/unified_pvalues.c |     4 -
 c++/src/algo/blast/core/Makefile.blast.lib         |     8 +-
 c++/src/algo/blast/core/aa_ungapped.c              |     7 +-
 c++/src/algo/blast/core/blast_aalookup.c           |     7 +-
 c++/src/algo/blast/core/blast_aascan.c             |     7 +-
 c++/src/algo/blast/core/blast_diagnostics.c        |     7 +-
 c++/src/algo/blast/core/blast_dynarray.c           |     7 +-
 c++/src/algo/blast/core/blast_encoding.c           |     7 +-
 c++/src/algo/blast/core/blast_engine.c             |   812 +-
 c++/src/algo/blast/core/blast_extend.c             |     7 +-
 c++/src/algo/blast/core/blast_filter.c             |    20 +-
 c++/src/algo/blast/core/blast_gapalign.c           |  1133 +-
 c++/src/algo/blast/core/blast_hits.c               |   195 +-
 c++/src/algo/blast/core/blast_hspstream.c          |    39 +-
 c++/src/algo/blast/core/blast_hspstream_mt_utils.c |     7 +-
 c++/src/algo/blast/core/blast_hspstream_mt_utils.h |     2 +-
 c++/src/algo/blast/core/blast_itree.c              |     7 +-
 c++/src/algo/blast/core/blast_kappa.c              |   714 +-
 c++/src/algo/blast/core/blast_lookup.c             |   198 +-
 c++/src/algo/blast/core/blast_message.c            |     7 +-
 c++/src/algo/blast/core/blast_nalookup.c           |   937 +-
 c++/src/algo/blast/core/blast_nascan.c             |   368 +-
 c++/src/algo/blast/core/blast_options.c            |   144 +-
 c++/src/algo/blast/core/blast_parameters.c         |    26 +-
 c++/src/algo/blast/core/blast_posit.c              |     4 -
 c++/src/algo/blast/core/blast_program.c            |    16 +-
 c++/src/algo/blast/core/blast_psi.c                |     4 -
 c++/src/algo/blast/core/blast_psi_priv.c           |     4 -
 c++/src/algo/blast/core/blast_query_info.c         |    27 +-
 c++/src/algo/blast/core/blast_seg.c                |  2730 +--
 c++/src/algo/blast/core/blast_seqsrc.c             |     9 +-
 c++/src/algo/blast/core/blast_setup.c              |    93 +-
 c++/src/algo/blast/core/blast_stat.c               |     8 +-
 c++/src/algo/blast/core/blast_sw.c                 |    10 +-
 c++/src/algo/blast/core/blast_traceback.c          |    29 +-
 c++/src/algo/blast/core/blast_traceback_mt_priv.c  |     7 +-
 c++/src/algo/blast/core/blast_tune.c               |     7 +-
 c++/src/algo/blast/core/blast_util.c               |    27 +-
 c++/src/algo/blast/core/boost_erf.c                |     2 +-
 c++/src/algo/blast/core/boost_erf.h                |     2 +-
 c++/src/algo/blast/core/gapinfo.c                  |     7 +-
 c++/src/algo/blast/core/gencode_singleton.c        |     7 +-
 c++/src/algo/blast/core/greedy_align.c             |     8 +-
 c++/src/algo/blast/core/hspfilter_besthit.c        |    18 +-
 c++/src/algo/blast/core/hspfilter_collector.c      |    15 +-
 c++/src/algo/blast/core/hspfilter_culling.c        |    15 +-
 c++/src/algo/blast/core/hspfilter_mapper.c         |  4353 +++++
 c++/src/algo/blast/core/jumper.c                   |  4025 +++++
 c++/src/algo/blast/core/jumper.h                   |   279 +
 c++/src/algo/blast/core/link_hsps.c                |     7 +-
 c++/src/algo/blast/core/lookup_util.c              |     9 +-
 c++/src/algo/blast/core/lookup_wrap.c              |    29 +-
 c++/src/algo/blast/core/matrix_freq_ratios.c       |     4 -
 c++/src/algo/blast/core/na_ungapped.c              |   545 +-
 c++/src/algo/blast/core/ncbi_math.c                |     7 +-
 c++/src/algo/blast/core/ncbi_std.c                 |     7 +-
 c++/src/algo/blast/core/pattern.c                  |     7 +-
 c++/src/algo/blast/core/phi_extend.c               |     7 +-
 c++/src/algo/blast/core/phi_gapalign.c             |     8 +-
 c++/src/algo/blast/core/phi_lookup.c               |     8 +-
 c++/src/algo/blast/core/split_query.c              |     7 +-
 c++/src/algo/blast/dbindex/dbindex_factory.cpp     |    40 +-
 c++/src/algo/blast/dbindex/makeindex/main.cpp      |     4 +-
 c++/src/algo/blast/format/blast_format.cpp         |   153 +-
 c++/src/algo/blast/format/blastfmtutil.cpp         |    16 +-
 c++/src/algo/blast/format/blastxml_format.cpp      |     8 +-
 c++/src/algo/blast/format/data4xmlformat.cpp       |     4 -
 c++/src/algo/blast/format/sam.cpp                  |     5 +-
 c++/src/algo/blast/format/vecscreen_run.cpp        |     4 -
 c++/src/algo/blast/igblast/igblast.cpp             |    74 +-
 .../unit_tests/api/Makefile.aalookup_unit_test.app |     2 +-
 .../unit_tests/api/Makefile.aascan_unit_test.app   |     2 +-
 .../unit_tests/api/Makefile.bl2seq_unit_test.app   |     4 +-
 .../unit_tests/api/Makefile.blast_unit_test.app    |     4 +-
 .../api/Makefile.blast_unit_test_util.lib          |     2 +-
 .../api/Makefile.blastdiag_unit_test.app           |     2 +-
 .../api/Makefile.blastengine_unit_test.app         |     2 +-
 .../api/Makefile.blastextend_unit_test.app         |     2 +-
 .../api/Makefile.blastfilter_unit_test.app         |     2 +-
 .../api/Makefile.blasthits_unit_test.app           |     2 +-
 .../api/Makefile.blastoptions_unit_test.app        |     2 +-
 .../api/Makefile.blastsetup_unit_test.app          |     2 +-
 .../unit_tests/api/Makefile.delta_unit_test.app    |     2 +-
 .../unit_tests/api/Makefile.gapinfo_unit_test.app  |     2 +-
 .../api/Makefile.gencode_singleton_unit_test.app   |     2 +-
 .../api/Makefile.hspfilter_besthit_unit_test.app   |     4 +-
 .../api/Makefile.hspfilter_culling_unit_test.app   |     4 +-
 .../api/Makefile.hspstream_unit_test.app           |     4 +-
 c++/src/algo/blast/unit_tests/api/Makefile.in      |     7 +-
 .../unit_tests/api/Makefile.linkhsp_unit_test.app  |     4 +-
 .../api/Makefile.magicblast_unit_test.app          |    16 +
 .../unit_tests/api/Makefile.msa2pssm_unit_test.app |     4 +-
 .../unit_tests/api/Makefile.ntlookup_unit_test.app |     6 +-
 .../unit_tests/api/Makefile.ntscan_unit_test.app   |     2 +-
 .../api/Makefile.optionshandle_unit_test.app       |     4 +-
 .../unit_tests/api/Makefile.phiblast_unit_test.app |     4 +-
 .../api/Makefile.prelimsearch_unit_test.app        |     2 +-
 .../api/Makefile.psibl2seq_unit_test.app           |     4 +-
 .../api/Makefile.psiblast_iteration_unit_test.app  |     4 +-
 .../unit_tests/api/Makefile.psiblast_unit_test.app |     4 +-
 .../api/Makefile.pssmcreate_unit_test.app          |     2 +-
 .../Makefile.pssmenginefreqratios_unit_test.app    |     2 +-
 .../api/Makefile.querydata_unit_test.app           |     4 +-
 .../api/Makefile.queryinfo_unit_test.app           |     4 +-
 .../api/Makefile.redoalignment_unit_test.app       |     8 +-
 .../api/Makefile.remote_blast_unit_test.app        |     2 +-
 .../unit_tests/api/Makefile.rps_unit_test.app      |     2 +-
 .../unit_tests/api/Makefile.scoreblk_unit_test.app |     2 +-
 .../api/Makefile.search_strategy_unit_test.app     |     2 +-
 .../unit_tests/api/Makefile.seqalign_util.lib      |     2 +-
 .../api/Makefile.seqinfosrc_unit_test.app          |     2 +-
 .../unit_tests/api/Makefile.seqsrc_unit_test.app   |     2 +-
 .../api/Makefile.setupfactory_unit_test.app        |     2 +-
 .../api/Makefile.split_query_unit_test.app         |     2 +-
 .../unit_tests/api/Makefile.stat_unit_test.app     |     2 +-
 .../api/Makefile.subj_ranges_unit_test.app         |     4 +-
 .../api/Makefile.traceback_unit_test.app           |     2 +-
 .../api/Makefile.tracebacksearch_unit_test.app     |     2 +-
 .../api/Makefile.uniform_search_unit_test.app      |     2 +-
 .../api/Makefile.version_reference_unit_test.app   |     6 +-
 .../blast/unit_tests/api/aalookup_unit_test.cpp    |     3 +-
 .../algo/blast/unit_tests/api/aascan_unit_test.cpp |     3 +-
 .../algo/blast/unit_tests/api/bl2seq_unit_test.cpp |    12 +-
 .../blast/unit_tests/api/blastdiag_unit_test.cpp   |     4 +-
 .../blast/unit_tests/api/blastengine_unit_test.cpp |    24 +-
 .../blast/unit_tests/api/blastfilter_unit_test.cpp |    15 +-
 .../blast/unit_tests/api/blasthits_unit_test.cpp   |   474 +-
 .../unit_tests/api/blastoptions_unit_test.cpp      |     5 +-
 .../blast/unit_tests/api/blastsetup_unit_test.cpp  |    14 +-
 .../unit_tests/api/data/magicblast_paired.asn      |    50 +
 .../unit_tests/api/data/magicblast_queries.asn     |    74 +
 c++/src/algo/blast/unit_tests/api/data/pombe.nhr   |   Bin 0 -> 124 bytes
 c++/src/algo/blast/unit_tests/api/data/pombe.nin   |   Bin 0 -> 128 bytes
 c++/src/algo/blast/unit_tests/api/data/pombe.nog   |   Bin 0 -> 36 bytes
 c++/src/algo/blast/unit_tests/api/data/pombe.nsd   |     2 +
 c++/src/algo/blast/unit_tests/api/data/pombe.nsi   |   Bin 0 -> 64 bytes
 c++/src/algo/blast/unit_tests/api/data/pombe.nsq   |   Bin 0 -> 613250 bytes
 .../algo/blast/unit_tests/api/delta_unit_test.cpp  |    14 +-
 .../unit_tests/api/hspfilter_besthit_unit_test.cpp |     4 +-
 .../unit_tests/api/hspfilter_culling_unit_test.cpp |     4 +-
 .../blast/unit_tests/api/hspstream_unit_test.cpp   |     6 +-
 .../blast/unit_tests/api/linkhsp_unit_test.cpp     |     4 +-
 .../blast/unit_tests/api/magicblast_unit_test.cpp  |   447 +
 .../blast/unit_tests/api/magicblast_unit_test.ini  |     3 +
 .../blast/unit_tests/api/ntlookup_unit_test.cpp    |   199 +-
 .../blast/unit_tests/api/ntlookup_unit_test.ini    |     4 +-
 .../algo/blast/unit_tests/api/ntscan_unit_test.cpp |     3 +-
 .../blast/unit_tests/api/phiblast_unit_test.cpp    |     4 +-
 .../api/psiblast_iteration_unit_test.cpp           |    18 +-
 .../blast/unit_tests/api/psiblast_unit_test.cpp    |     2 +-
 .../blast/unit_tests/api/querydata_unit_test.cpp   |    48 +-
 .../blast/unit_tests/api/queryinfo_unit_test.cpp   |    74 +-
 .../unit_tests/api/redoalignment_unit_test.cpp     |     4 +-
 .../unit_tests/api/remote_blast_unit_test.cpp      |     4 +-
 .../algo/blast/unit_tests/api/rps_unit_test.cpp    |    10 +-
 .../blast/unit_tests/api/split_query_unit_test.cpp |     4 +-
 .../algo/blast/unit_tests/api/stat_unit_test.cpp   |     2 +-
 .../algo/blast/unit_tests/api/stat_unit_test.ini   |     3 +
 .../blast/unit_tests/api/traceback_unit_test.cpp   |    10 +-
 .../unit_tests/api/tracebacksearch_unit_test.cpp   |    95 +-
 .../unit_tests/api/version_reference_unit_test.cpp |     4 +-
 .../Makefile.blast_format_unit_test.app            |     4 +-
 .../blast_format/blastfmtutil_unit_test.cpp        |     4 +-
 .../blast_format/vecscreen_run_unit_test.cpp       |     8 +-
 .../blastdb/Makefile.bdbloader_unit_test.app       |     5 +-
 .../seqdb_reader/Makefile.seqdb_unit_test.app      |     2 +-
 .../unit_tests/seqdb_reader/seqdb_unit_test.cpp    |    15 +-
 .../unit_tests/seqdb_reader/seqdb_unit_test.ini    |    10 +-
 c++/src/app/Makefile.in                            |     8 +-
 c++/src/app/blast/Makefile.blastn.app              |     5 +-
 c++/src/app/blast/Makefile.in                      |     2 +-
 c++/src/app/blast/blast_app_util.cpp               |   143 +-
 c++/src/app/blast/blast_app_util.hpp               |    10 +-
 c++/src/app/blast/blast_formatter.cpp              |    12 +-
 c++/src/app/blast/blastn_app.cpp                   |    10 +-
 c++/src/app/blast/blastp_app.cpp                   |    10 +-
 c++/src/app/blast/blastx_app.cpp                   |    10 +-
 c++/src/app/blast/deltablast_app.cpp               |    21 +-
 c++/src/app/blast/psiblast_app.cpp                 |    18 +-
 c++/src/app/blast/rpsblast_app.cpp                 |    12 +-
 c++/src/app/blast/rpstblastn_app.cpp               |    12 +-
 c++/src/app/blast/seedtop_app.cpp                  |     9 +-
 c++/src/app/blast/tblastn_app.cpp                  |    13 +-
 c++/src/app/blast/tblastx_app.cpp                  |    10 +-
 c++/src/app/blast/update_blastdb.pl                |     4 +-
 c++/src/app/blastdb/Makefile.convert2blastmask.app |     2 +-
 c++/src/app/blastdb/Makefile.makeblastdb.app       |     2 +-
 c++/src/app/blastdb/Makefile.makeprofiledb.app     |     2 +-
 c++/src/app/blastdb/blastdb_aliastool.cpp          |    64 +-
 c++/src/app/blastdb/blastdbcheck.cpp               |     4 +-
 c++/src/app/blastdb/blastdbcmd.cpp                 |   589 +-
 c++/src/app/blastdb/blastdbcp.cpp                  |     4 +-
 c++/src/app/blastdb/convert2blastmask.cpp          |     4 +-
 c++/src/app/blastdb/makeblastdb.cpp                |    25 +-
 c++/src/app/blastdb/makeprofiledb.cpp              |     4 +-
 c++/src/app/dustmasker/Makefile.dustmasker.app     |     4 +-
 c++/src/app/dustmasker/main.cpp                    |     4 +-
 c++/src/app/segmasker/Makefile.segmasker.app       |     4 +-
 c++/src/app/segmasker/segmasker.cpp                |     4 +-
 c++/src/app/winmasker/Makefile.winmasker.app       |     6 +-
 c++/src/app/winmasker/main.cpp                     |     4 +-
 c++/src/build-system/Makefile.app.in               |     2 +-
 c++/src/build-system/Makefile.meta_l               |     4 +-
 c++/src/build-system/Makefile.mk.in                |    41 +-
 c++/src/build-system/Makefile.rules.in             |     4 +-
 c++/src/build-system/NEWS                          |     2 +
 c++/src/build-system/aclocal.m4                    |    14 +-
 c++/src/build-system/config.h.in                   |    33 +-
 c++/src/build-system/configure                     |  1433 +-
 c++/src/build-system/configure.ac                  |   493 +-
 c++/src/build-system/datatool_version.txt          |     2 +-
 .../helpers/Makefile.run_with_lock.app             |     2 +-
 c++/src/build-system/helpers/run_with_lock.c       |    22 +-
 c++/src/build-system/install.sh.in                 |     2 +-
 c++/src/build-system/library_relations.txt         |   439 +-
 c++/src/build-system/ncbi_package_version          |     2 +-
 c++/src/build-system/project_tree_builder.ini      |   147 +-
 .../project_tree_builder/msvc_prj_generator.cpp    |     2 +-
 .../project_tree_builder/msvc_prj_utils.cpp        |    14 +-
 .../project_tree_builder/msvc_prj_utils.hpp        |     3 +-
 .../project_tree_builder/proj_builder_app.cpp      |    19 +-
 .../project_tree_builder/proj_tree_builder.cpp     |   292 +-
 c++/src/build-system/ptb_version.txt               |     2 +-
 c++/src/build-system/relocate.sh.in                |     2 +-
 c++/src/cgi/cgiapp.cpp                             |    18 +-
 c++/src/cgi/cgictx.cpp                             |    23 +-
 c++/src/cgi/fcgi_run.cpp                           |     8 +-
 c++/src/cgi/ncbicgi.cpp                            |     2 +-
 c++/src/cgi/ncbicgir.cpp                           |    10 +-
 c++/src/cgi/user_agent.cpp                         |    11 +-
 c++/src/connect/Makefile.connect.lib               |     6 +-
 c++/src/connect/Makefile.connect.lib.unix          |     3 +-
 c++/src/connect/Makefile.connssl.lib               |    10 +-
 c++/src/connect/Makefile.xconnect.lib              |     6 +-
 c++/src/connect/Makefile.xthrserv.lib              |     6 +-
 c++/src/connect/Makefile.xxconnect.lib             |    11 +-
 c++/src/connect/connection_pool.cpp                |   176 +-
 c++/src/connect/connection_pool.hpp                |    37 +-
 c++/src/connect/ncbi_buffer.c                      |    44 +-
 c++/src/connect/ncbi_comm.h                        |    40 +-
 c++/src/connect/ncbi_conn_stream.cpp               |    16 +-
 c++/src/connect/ncbi_conn_test.cpp                 |    67 +-
 c++/src/connect/ncbi_connection.c                  |    21 +-
 c++/src/connect/ncbi_connector.c                   |    41 +-
 c++/src/connect/ncbi_connutil.c                    |   173 +-
 c++/src/connect/ncbi_core.c                        |    10 +-
 c++/src/connect/ncbi_core_cxx.cpp                  |   237 +-
 c++/src/connect/ncbi_dispd.c                       |     8 +-
 c++/src/connect/ncbi_ftp_connector.c               |   196 +-
 c++/src/connect/ncbi_gnutls.c                      |    43 +-
 c++/src/connect/ncbi_http_connector.c              |    31 +-
 c++/src/connect/ncbi_http_session.cpp              |   184 +-
 c++/src/connect/ncbi_lbos.c                        |  1067 +-
 c++/src/connect/ncbi_lbos.h                        |    11 +-
 c++/src/connect/ncbi_lbos_cxx.cpp                  |   583 +-
 c++/src/connect/ncbi_lbosp.h                       |    95 +-
 c++/src/connect/ncbi_lbosp.hpp                     |    71 +-
 c++/src/connect/ncbi_monkey.cpp                    |  1681 ++
 c++/src/connect/ncbi_monkeyp.hpp                   |    81 +
 c++/src/connect/ncbi_priv.c                        |    30 +-
 c++/src/connect/ncbi_priv.h                        |    94 +-
 c++/src/connect/ncbi_server_info.c                 |    57 +-
 c++/src/connect/ncbi_service.c                     |    22 +-
 c++/src/connect/ncbi_service_connector.c           |    27 +-
 c++/src/connect/ncbi_socket.c                      |   249 +-
 c++/src/connect/ncbi_util.c                        |     6 +-
 c++/src/connect/parson.c                           |  1767 ++
 c++/src/connect/parson.h                           |   223 +
 c++/src/connect/server.cpp                         |   139 +-
 c++/src/connect/services/Makefile.xconnserv.lib    |     4 +-
 c++/src/connect/services/grid_client.cpp           |     2 +-
 c++/src/connect/services/grid_control_thread.cpp   |     2 +-
 c++/src/connect/services/grid_worker.cpp           |    44 +-
 c++/src/connect/services/grid_worker_app.cpp       |     2 +-
 c++/src/connect/services/grid_worker_impl.hpp      |     8 +-
 c++/src/connect/services/json_over_uttp.cpp        |   300 +-
 c++/src/connect/services/netcache_api.cpp          |     6 +-
 c++/src/connect/services/netcache_api_impl.hpp     |    16 +-
 c++/src/connect/services/netcache_rw.cpp           |     2 +-
 c++/src/connect/services/netcache_search.cpp       |   556 +
 c++/src/connect/services/neticache_client.cpp      |    35 +-
 c++/src/connect/services/netschedule_api.cpp       |   134 +-
 c++/src/connect/services/netschedule_api_admin.cpp |     2 +-
 .../connect/services/netschedule_api_executor.cpp  |    97 +-
 .../connect/services/netschedule_api_getjob.cpp    |    55 +-
 .../connect/services/netschedule_api_getjob.hpp    |     6 +-
 c++/src/connect/services/netschedule_api_impl.hpp  |    37 +-
 .../connect/services/netschedule_api_reader.cpp    |    14 +-
 .../connect/services/netschedule_api_submitter.cpp |     8 +-
 c++/src/connect/services/netservice_api.cpp        |     5 +-
 c++/src/connect/services/netservice_api_impl.hpp   |     2 +-
 c++/src/connect/services/netstorage.cpp            |    11 +-
 c++/src/connect/services/netstorage_direct_nc.cpp  |     7 +-
 c++/src/connect/services/netstorage_direct_nc.hpp  |     2 +-
 c++/src/connect/services/netstorage_rpc.cpp        |    77 +-
 c++/src/connect/services/netstorage_rpc.hpp        |    15 +-
 c++/src/connect/services/netstorageobjectinfo.cpp  |    19 +-
 c++/src/connect/services/netstorageobjectloc.cpp   |     2 +-
 c++/src/connect/services/ns_output_parser.cpp      |   242 +-
 c++/src/connect/services/srv_connections.cpp       |     2 +-
 c++/src/connect/services/tmp_wn_info.cpp           |    22 +-
 c++/src/connect/services/wn_main_loop.cpp          |     5 +-
 c++/src/corelib/ddumpable.cpp                      |     2 +-
 c++/src/corelib/env_reg.cpp                        |    13 +-
 c++/src/corelib/expr.cpp                           |     4 +-
 c++/src/corelib/ncbi_cookies.cpp                   |    16 +-
 c++/src/corelib/ncbi_param.cpp                     |    54 +-
 c++/src/corelib/ncbi_stack.cpp                     |    13 +-
 c++/src/corelib/ncbi_stack_linux.cpp               |    11 +-
 c++/src/corelib/ncbi_stack_solaris.cpp             |     4 +-
 c++/src/corelib/ncbi_stack_win32.cpp               |     4 +-
 c++/src/corelib/ncbi_stack_win64.cpp               |     4 +-
 c++/src/corelib/ncbi_system.cpp                    |     9 +-
 c++/src/corelib/ncbi_url.cpp                       |     4 +-
 c++/src/corelib/ncbiapp.cpp                        |   142 +-
 c++/src/corelib/ncbiargs.cpp                       |   280 +-
 c++/src/corelib/ncbidiag.cpp                       |   270 +-
 c++/src/corelib/ncbidiag_p.hpp                     |     4 +-
 c++/src/corelib/ncbienv.cpp                        |     4 +-
 c++/src/corelib/ncbierror.cpp                      |   185 +-
 c++/src/corelib/ncbifile.cpp                       |   141 +-
 c++/src/corelib/ncbimtx.cpp                        |    16 +-
 c++/src/corelib/ncbireg.cpp                        |    66 +-
 c++/src/corelib/ncbistr.cpp                        |   137 +-
 c++/src/corelib/ncbitime.cpp                       |    16 +-
 c++/src/corelib/request_ctx.cpp                    |    71 +-
 c++/src/corelib/stream_utils.cpp                   |     9 +-
 c++/src/corelib/teamcity_boost.cpp                 |   150 +-
 c++/src/corelib/teamcity_messages.cpp              |   101 +-
 c++/src/corelib/teamcity_messages.h                |    32 +-
 c++/src/corelib/test_boost.cpp                     |    51 +-
 c++/src/corelib/version.cpp                        |    10 +-
 c++/src/dbapi/blobstream.cpp                       |     4 +-
 c++/src/dbapi/blobstream.hpp                       |     4 +-
 c++/src/dbapi/conn_impl.cpp                        |     6 +-
 c++/src/dbapi/dbapi.cpp                            |     4 +-
 c++/src/dbapi/driver/dbapi_conn_factory.cpp        |    40 +-
 c++/src/dbapi/driver/dbapi_driver_conn_mgr.cpp     |     2 +-
 c++/src/dbapi/driver/dbapi_driver_conn_params.cpp  |     3 +-
 c++/src/dbapi/driver/dbapi_driver_utils.cpp        |    33 +-
 c++/src/dbapi/driver/dbapi_impl_cmd.cpp            |     2 +-
 c++/src/dbapi/driver/dbapi_impl_connection.cpp     |    13 +-
 c++/src/dbapi/driver/dbapi_impl_context.cpp        |    75 +-
 c++/src/dbapi/driver/dbapi_object_convert.cpp      |     2 +-
 c++/src/dbapi/driver/dbapi_svc_mapper.cpp          |    26 +-
 c++/src/dbapi/driver/interfaces.cpp                |     6 +-
 c++/src/dbapi/driver/memory_store.cpp              |     2 +-
 c++/src/dbapi/driver/memory_store.hpp              |     2 +-
 c++/src/dbapi/driver/odbc/bcp.cpp                  |     2 +-
 c++/src/dbapi/driver/odbc/connection.cpp           |    23 +-
 c++/src/dbapi/driver/odbc/cursor.cpp               |     2 +-
 c++/src/dbapi/driver/odbc/result.cpp               |     2 +-
 c++/src/dbapi/driver/public.cpp                    |     2 +-
 c++/src/dbapi/driver/types.cpp                     |     2 +-
 c++/src/dbapi/driver_mgr.cpp                       |     4 +-
 c++/src/dbapi/rs_impl.cpp                          |     4 +-
 c++/src/dbapi/rw_impl.cpp                          |     2 +-
 c++/src/dbapi/rw_impl.hpp                          |     2 +-
 c++/src/dbapi/stmt_impl.cpp                        |     4 +-
 c++/src/dbapi/stmt_impl.hpp                        |     4 +-
 c++/src/dbapi/variant.cpp                          |     4 +-
 c++/src/html/indentstream.cpp                      |     4 +-
 c++/src/html/selection.cpp                         |     4 +-
 c++/src/misc/CMakeLists.txt                        |    22 +
 c++/src/misc/Makefile.in                           |    10 +
 c++/src/misc/third_party/CMakeLists.txt            |     6 +
 c++/src/misc/third_party/Makefile.in               |    10 +
 .../Makefile.third_party_dll_install.msvcproj      |    11 +
 .../Makefile.third_party_dll_install.msvcproj.msvc |     4 +
 .../Makefile.third_party_msvcdll_install.msvcproj  |    11 +
 c++/src/misc/third_party_static/CMakeLists.txt     |     6 +
 c++/src/misc/third_party_static/Makefile.in        |    10 +
 ...akefile.third_party_msvcstatic_install.msvcproj |    11 +
 .../Makefile.third_party_static_install.msvcproj   |    11 +
 ...kefile.third_party_static_install.msvcproj.msvc |     4 +
 c++/src/objects/Makefile.in                        |     4 +-
 c++/src/objects/biblio/Auth_list.cpp               |     6 +-
 c++/src/objects/biblio/Cit_gen.cpp                 |     4 +-
 c++/src/objects/biblio/biblio.def                  |    13 +
 c++/src/objects/biotree/DistanceMatrix.cpp         |     4 +-
 c++/src/objects/blast/doc/blast.htm                |    18 +-
 c++/src/objects/entrez2/entrez2.def                |    18 +-
 c++/src/objects/general/Dbtag.cpp                  |   285 +-
 c++/src/objects/general/Name_std.cpp               |    63 +-
 c++/src/objects/general/User_field.cpp             |     8 +-
 c++/src/objects/general/User_object.cpp            |    27 +-
 .../genomecoll/GCClient_GetAssemblyBySequ.cpp      |    81 +
 c++/src/objects/genomecoll/GC_Assembly.cpp         |   108 +-
 c++/src/objects/genomecoll/cached_assembly.cpp     |    56 +-
 c++/src/objects/genomecoll/gencoll_client.asn      |    38 +-
 c++/src/objects/genomecoll/gencoll_client.def      |     2 +-
 c++/src/objects/genomecoll/genome_collection.asn   |     3 +-
 .../objects/genomecoll/genomic_collections_cli.cpp |    59 +-
 c++/src/objects/macro/String_constraint.cpp        |     8 +-
 c++/src/objects/macro/Suspect_rule.cpp             |   377 +-
 c++/src/objects/macro/product_rules.inc            | 17000 ++++++++++++-------
 c++/src/objects/macro/product_rules.prt            | 16797 +++++++++++-------
 c++/src/objects/medline/Medline_entry.cpp          |     6 +-
 c++/src/objects/medline/medline.def                |     8 +
 c++/src/objects/pub/Pub.cpp                        |     6 +-
 c++/src/objects/pub/Pub_equiv.cpp                  |    10 +-
 c++/src/objects/pub/pub.def                        |     4 +
 c++/src/objects/seq/Bioseq.cpp                     |    20 +-
 c++/src/objects/seq/Delta_ext.cpp                  |     6 +-
 c++/src/objects/seq/Linkage_evidence.cpp           |     4 +-
 c++/src/objects/seq/Seq_gap.cpp                    |     4 +-
 c++/src/objects/seq/Seq_inst.cpp                   |    86 +-
 c++/src/objects/seq/Seq_literal.cpp                |     4 +-
 c++/src/objects/seq/seq.def                        |     4 +
 c++/src/objects/seq/seq_align_mapper_base.cpp      |    63 +-
 c++/src/objects/seq/seq_id_handle.cpp              |     4 +-
 c++/src/objects/seq/seq_id_tree.cpp                |   137 +-
 c++/src/objects/seq/seq_id_tree.hpp                |    14 +-
 c++/src/objects/seq/seq_loc_from_string.cpp        |     5 +-
 c++/src/objects/seq/seq_loc_mapper_base.cpp        |   279 +-
 c++/src/objects/seq/sofa_map.cpp                   |    97 +-
 c++/src/objects/seqalign/Sparse_align.cpp          |     7 +-
 c++/src/objects/seqalign/Sparse_seg.cpp            |     5 +-
 c++/src/objects/seqalign/Spliced_seg.cpp           |    12 +-
 c++/src/objects/seqalign/Std_seg.cpp               |     5 +-
 c++/src/objects/seqcode/seqcode.def                |     8 +
 c++/src/objects/seqfeat/BioSource.cpp              |   327 +-
 c++/src/objects/seqfeat/Delta_item.cpp             |    81 +
 c++/src/objects/seqfeat/Gb_qual.cpp                |    31 +-
 c++/src/objects/seqfeat/Genetic_code_table.cpp     |    67 +-
 c++/src/objects/seqfeat/OrgMod.cpp                 |    92 +-
 c++/src/objects/seqfeat/OrgName.cpp                |    34 +-
 c++/src/objects/seqfeat/RNA_ref.cpp                |     2 +-
 c++/src/objects/seqfeat/SeqFeatData.cpp            |   759 +-
 c++/src/objects/seqfeat/Seq_feat.cpp               |    33 +-
 c++/src/objects/seqfeat/SubSource.cpp              |   162 +-
 c++/src/objects/seqfeat/Trna_ext.cpp               |     6 +-
 c++/src/objects/seqfeat/Variation_ref.cpp          |   103 +-
 c++/src/objects/seqfeat/ecnum_deleted.inc          |     2 +-
 c++/src/objects/seqfeat/ecnum_replaced.inc         |    20 +-
 c++/src/objects/seqfeat/ecnum_replaced.txt         |    18 +-
 c++/src/objects/seqfeat/ecnum_specific.inc         |    86 +-
 c++/src/objects/seqfeat/ecnum_specific.txt         |    84 +-
 c++/src/objects/seqfeat/institution_codes.inc      |   502 +-
 c++/src/objects/seqfeat/institution_codes.txt      |   500 +-
 c++/src/objects/seqfeat/lat_lon_country.inc        |    12 +-
 c++/src/objects/seqfeat/lat_lon_country.txt        |   282 +-
 c++/src/objects/seqfeat/seqfeat.asn                |     5 +-
 c++/src/objects/seqloc/Seq_id.cpp                  |     2 +-
 c++/src/objects/seqloc/Seq_loc.cpp                 |   135 +-
 c++/src/objects/seqloc/accguide.inc                |    59 +-
 c++/src/objects/seqloc/accguide.txt                |    57 +-
 c++/src/objects/seqset/Bioseq_set.cpp              |    33 +-
 c++/src/objects/taxon1/Taxon2_data.cpp             |     2 +-
 c++/src/objects/taxon1/taxon1.cpp                  |    24 +-
 c++/src/objects/taxon1/taxon1.def                  |    12 +
 c++/src/objects/trackmgr/TMgr_ClientInfo.cpp       |     4 +-
 c++/src/objects/trackmgr/displaytrack_client.cpp   |    83 +-
 c++/src/objects/trackmgr/trackmgr.asn              |    13 +-
 c++/src/objects/valerr/ValidErrItem.cpp            |  1436 +-
 c++/src/objects/valerr/ValidError.cpp              |    19 +-
 c++/src/objects/valid/Comment_rule.cpp             |     2 +-
 c++/src/objects/valid/Comment_set.cpp              |     4 +-
 c++/src/objects/valid/validrules.inc               |     9 +-
 c++/src/objects/valid/validrules.prt               |     7 +-
 c++/src/objects/varrep/AaInterval.cpp              |    82 +
 c++/src/objects/varrep/AaLocation.cpp              |    77 +
 c++/src/objects/varrep/Makefile.in                 |     3 +
 c++/src/objects/varrep/Makefile.varrep.lib         |     3 +
 c++/src/objects/varrep/varrep.asn                  |   296 +
 c++/src/objects/varrep/varrep.def                  |    17 +
 c++/src/objects/varrep/varrep.module               |     1 +
 c++/src/objmgr/Makefile.objmgr.lib                 |     4 +-
 c++/src/objmgr/annot_collector.cpp                 |   300 +-
 c++/src/objmgr/annot_object_index.cpp              |     4 +-
 c++/src/objmgr/annot_selector.cpp                  |    20 +-
 c++/src/objmgr/annot_types_ci.cpp                  |     8 +-
 c++/src/objmgr/bioseq_base_info.cpp                |    31 +-
 c++/src/objmgr/bioseq_handle.cpp                   |     2 +-
 c++/src/objmgr/bioseq_info.cpp                     |    17 +-
 c++/src/objmgr/bioseq_set_info.cpp                 |     8 +-
 c++/src/objmgr/data_loader.cpp                     |     2 +-
 c++/src/objmgr/data_source.cpp                     |     2 +-
 c++/src/objmgr/edits_db_saver.cpp                  |   282 +-
 c++/src/objmgr/gc_assembly_parser.cpp              |     6 +-
 c++/src/objmgr/mapped_feat.cpp                     |    20 +-
 c++/src/objmgr/objmgr_exception.cpp                |     2 +-
 c++/src/objmgr/prefetch_actions.cpp                |     4 +-
 c++/src/objmgr/scope.cpp                           |     2 +-
 c++/src/objmgr/scope_impl.cpp                      |    34 +-
 c++/src/objmgr/scope_info.cpp                      |    15 +-
 c++/src/objmgr/seq_annot_info.cpp                  |   156 +-
 c++/src/objmgr/seq_entry_info.cpp                  |    61 +-
 c++/src/objmgr/seq_feat_handle.cpp                 |   134 +-
 c++/src/objmgr/seq_id_sort.cpp                     |     2 +-
 c++/src/objmgr/seq_loc_cvt.cpp                     |    16 +-
 c++/src/objmgr/seq_loc_mapper.cpp                  |    93 +-
 c++/src/objmgr/seq_map.cpp                         |    19 +-
 c++/src/objmgr/seq_map_ci.cpp                      |     4 +-
 c++/src/objmgr/seq_map_switch.cpp                  |    14 +-
 c++/src/objmgr/seq_table_info.cpp                  |   186 +-
 c++/src/objmgr/seq_table_setters.cpp               |    30 +-
 c++/src/objmgr/seq_vector.cpp                      |    22 +-
 c++/src/objmgr/snp_annot_info.cpp                  |    32 +-
 c++/src/objmgr/split/annot_piece.cpp               |     4 +-
 c++/src/objmgr/split/blob_splitter_impl.cpp        |     5 +-
 c++/src/objmgr/split/blob_splitter_maker.cpp       |    20 +-
 c++/src/objmgr/split/id_range.cpp                  |    12 +-
 c++/src/objmgr/split/object_splitinfo.cpp          |     4 +-
 c++/src/objmgr/split/size.cpp                      |     8 +-
 c++/src/objmgr/split_parser.cpp                    |     8 +-
 c++/src/objmgr/tse_assigner.cpp                    |     7 +-
 c++/src/objmgr/tse_handle.cpp                      |     4 +-
 c++/src/objmgr/tse_info.cpp                        |    23 +-
 c++/src/objmgr/tse_split_info.cpp                  |    11 +-
 c++/src/objmgr/unsupp_editsaver.cpp                |     6 +-
 c++/src/objmgr/util/Makefile.util.lib              |     4 +-
 c++/src/objmgr/util/create_defline.cpp             |    65 +-
 c++/src/objmgr/util/feature.cpp                    |   201 +-
 c++/src/objmgr/util/obj_sniff.cpp                  |    75 +-
 c++/src/objmgr/util/objutil.cpp                    |    13 +-
 c++/src/objmgr/util/seq_loc_util.cpp               |    32 +-
 c++/src/objmgr/util/seqtitle.cpp                   |     6 +-
 c++/src/objmgr/util/sequence.cpp                   |   376 +-
 c++/src/objmgr/util/weight.cpp                     |     6 +-
 .../objtools/align_format/align_format_util.cpp    |   164 +-
 c++/src/objtools/align_format/aln_printer.cpp      |     5 +-
 c++/src/objtools/align_format/format_flags.cpp     |    11 +-
 c++/src/objtools/align_format/seqalignfilter.cpp   |     7 +-
 c++/src/objtools/align_format/showalign.cpp        |    90 +-
 c++/src/objtools/align_format/showdefline.cpp      |    37 +-
 c++/src/objtools/align_format/tabular.cpp          |    46 +-
 c++/src/objtools/align_format/taxFormat.cpp        |   114 +-
 .../unit_test/Makefile.align_format_unit_test.app  |     6 +-
 .../data/in_showalign_use_this_gi_ext.asn          |  1073 ++
 .../align_format/unit_test/showalign_unit_test.cpp |    57 +-
 .../unit_test/showdefline_unit_test.cpp            |     8 +-
 .../unit_test/tabularinof_unit_test.cpp            |    20 +-
 c++/src/objtools/align_format/vectorscreen.cpp     |     9 +-
 c++/src/objtools/alnmgr/Makefile.alnmgr.lib        |     5 +-
 c++/src/objtools/alnmgr/Makefile.in                |     4 +-
 c++/src/objtools/alnmgr/aln_builders.cpp           |     2 +-
 c++/src/objtools/alnmgr/alnvec.cpp                 |     5 +-
 c++/src/objtools/alnmgr/score_builder_base.cpp     |     5 +-
 c++/src/objtools/alnmgr/sparse_aln.cpp             |    23 +-
 .../blastdb_format/Makefile.blastdb_format.lib     |     4 +-
 .../blast/blastdb_format/blastdb_dataextract.cpp   |   379 +-
 .../blast/blastdb_format/blastdb_formatter.cpp     |     7 +-
 .../blast/blastdb_format/seq_formatter.cpp         |   543 +
 .../objtools/blast/blastdb_format/seq_writer.cpp   |    88 +-
 .../Makefile.blastdb_format_unit_test.app          |     6 +-
 .../unit_test/seq_formatter_unit_test.cpp          |   386 +
 .../unit_test/seq_writer_unit_test.cpp             |    67 +-
 .../gene_info_reader/demo/gene_info_reader_app.cpp |     4 +-
 .../objtools/blast/gene_info_reader/file_utils.cpp |     7 +-
 .../objtools/blast/gene_info_reader/gene_info.cpp  |     7 +-
 .../blast/gene_info_reader/gene_info_reader.cpp    |     7 +-
 c++/src/objtools/blast/seqdb_reader/seqdb.cpp      |    16 +-
 c++/src/objtools/blast/seqdb_reader/seqdbalias.cpp |     7 +-
 c++/src/objtools/blast/seqdb_reader/seqdbatlas.cpp |     7 +-
 .../objtools/blast/seqdb_reader/seqdbbitset.cpp    |     7 +-
 c++/src/objtools/blast/seqdb_reader/seqdbblob.cpp  |     7 +-
 c++/src/objtools/blast/seqdb_reader/seqdbcol.cpp   |     7 +-
 .../objtools/blast/seqdb_reader/seqdbcommon.cpp    |    29 +-
 .../objtools/blast/seqdb_reader/seqdbexpert.cpp    |     7 +-
 c++/src/objtools/blast/seqdb_reader/seqdbfile.cpp  |     7 +-
 .../objtools/blast/seqdb_reader/seqdbfilter.cpp    |     7 +-
 .../objtools/blast/seqdb_reader/seqdbgilistset.cpp |     7 +-
 .../objtools/blast/seqdb_reader/seqdbgimask.cpp    |     7 +-
 c++/src/objtools/blast/seqdb_reader/seqdbimpl.cpp  |    58 +-
 c++/src/objtools/blast/seqdb_reader/seqdbimpl.hpp  |    20 +-
 c++/src/objtools/blast/seqdb_reader/seqdbisam.cpp  |    11 +-
 c++/src/objtools/blast/seqdb_reader/seqdbobj.cpp   |     7 +-
 .../objtools/blast/seqdb_reader/seqdboidlist.cpp   |     7 +-
 c++/src/objtools/blast/seqdb_reader/seqdbtax.cpp   |     7 +-
 c++/src/objtools/blast/seqdb_reader/seqdbvol.cpp   |    21 +-
 .../objtools/blast/seqdb_reader/seqdbvolset.cpp    |     7 +-
 .../blast/seqdb_reader/test/seqdb_perf.cpp         |     9 +-
 .../objtools/blast/seqdb_writer/build-alias-index  |     2 +-
 c++/src/objtools/blast/seqdb_writer/build_db.cpp   |    56 +-
 .../blast/seqdb_writer/mask_info_registry.cpp      |     5 -
 .../blast/seqdb_writer/multisource_util.cpp        |     7 +-
 c++/src/objtools/blast/seqdb_writer/taxid_set.cpp  |     7 +-
 .../unit_test/Makefile.writedb_unit_test.app       |     4 +-
 .../seqdb_writer/unit_test/data/some_prots.fsa     |   142 +
 .../seqdb_writer/unit_test/writedb_unit_test.cpp   |   454 +-
 c++/src/objtools/blast/seqdb_writer/writedb.cpp    |    14 +-
 .../objtools/blast/seqdb_writer/writedb_column.cpp |     7 +-
 .../blast/seqdb_writer/writedb_convert.cpp         |     7 +-
 .../objtools/blast/seqdb_writer/writedb_files.cpp  |     7 +-
 .../blast/seqdb_writer/writedb_general.cpp         |     7 +-
 .../objtools/blast/seqdb_writer/writedb_gimask.cpp |     7 +-
 .../objtools/blast/seqdb_writer/writedb_impl.cpp   |    66 +-
 .../objtools/blast/seqdb_writer/writedb_impl.hpp   |    20 +-
 .../objtools/blast/seqdb_writer/writedb_isam.cpp   |     7 +-
 .../objtools/blast/seqdb_writer/writedb_volume.cpp |    10 +-
 .../blast/services/Makefile.blast_services.lib     |     5 +-
 c++/src/objtools/blast/services/blast_services.cpp |    10 +-
 c++/src/objtools/cleanup/Makefile.cleanup.lib      |     6 +-
 c++/src/objtools/cleanup/autogenerated_cleanup.cpp |   309 +-
 c++/src/objtools/cleanup/autogenerated_cleanup.hpp |    43 +-
 c++/src/objtools/cleanup/autogenerated_cleanup.txt |     2 +-
 .../cleanup/autogenerated_extended_cleanup.cpp     |     3 +-
 .../cleanup/autogenerated_extended_cleanup.hpp     |     2 +-
 .../cleanup/autogenerated_extended_cleanup.txt     |     2 -
 c++/src/objtools/cleanup/cleanup.cpp               |   983 +-
 c++/src/objtools/cleanup/cleanup_utils.cpp         |     3 +-
 c++/src/objtools/cleanup/newcleanupp.cpp           |   534 +-
 c++/src/objtools/cleanup/newcleanupp.hpp           |     3 +-
 c++/src/objtools/data_loaders/Makefile.in          |     4 +-
 .../objtools/data_loaders/blastdb/bdbloader.cpp    |     6 +-
 .../data_loaders/blastdb/bdbloader_rmt.cpp         |     6 +-
 .../data_loaders/blastdb/cached_sequence.cpp       |     6 +-
 .../data_loaders/blastdb/local_blastdb_adapter.cpp |     6 +-
 .../blastdb/remote_blastdb_adapter.cpp             |     6 +-
 .../data_loaders/genbank/Makefile.ncbi_xreader.lib |     4 +-
 .../data_loaders/genbank/cache/reader_cache.cpp    |     2 +-
 .../data_loaders/genbank/cache/writer_cache.cpp    |     2 +-
 .../objtools/data_loaders/genbank/dispatcher.cpp   |     2 +-
 c++/src/objtools/data_loaders/genbank/gbloader.cpp |    17 +-
 .../data_loaders/genbank/gicache/Makefile.in       |     4 +-
 .../gicache/Makefile.ncbi_xreader_gicache.lib      |     7 +-
 .../data_loaders/genbank/gicache/gicache.c         |  2570 +--
 .../data_loaders/genbank/gicache/gicache.h         |    60 +-
 .../data_loaders/genbank/gicache/gicache_cxx.cpp   |    38 -
 .../genbank/gicache/reader_gicache.cpp             |    15 +-
 .../data_loaders/genbank/id1/reader_id1.cpp        |     4 +-
 .../data_loaders/genbank/id2/reader_id2.cpp        |     4 +-
 .../objtools/data_loaders/genbank/info_cache.cpp   |     2 +-
 .../objtools/data_loaders/genbank/processors.cpp   |    57 +-
 c++/src/objtools/data_loaders/genbank/reader.cpp   |     2 +-
 .../data_loaders/genbank/reader_id1_base.cpp       |     2 +-
 .../data_loaders/genbank/reader_id2_base.cpp       |   585 +-
 .../data_loaders/genbank/reader_service.cpp        |     5 +-
 .../objtools/data_loaders/genbank/reader_snp.cpp   |     2 +-
 .../data_loaders/genbank/request_result.cpp        |     2 +-
 c++/src/objtools/edit/Makefile.edit.lib            |     4 +-
 c++/src/objtools/edit/apply_object.cpp             |     2 +-
 c++/src/objtools/edit/autodef.cpp                  |    46 +-
 .../objtools/edit/autodef_available_modifier.cpp   |    87 +-
 c++/src/objtools/edit/autodef_feature_clause.cpp   |   164 +-
 .../objtools/edit/autodef_feature_clause_base.cpp  |   109 +-
 c++/src/objtools/edit/autodef_mod_combo.cpp        |     4 +-
 c++/src/objtools/edit/autodef_options.cpp          |    22 +-
 c++/src/objtools/edit/cds_fix.cpp                  |     3 +-
 c++/src/objtools/edit/feattable_edit.cpp           |   296 +-
 c++/src/objtools/edit/gaps_edit.cpp                |   135 +-
 c++/src/objtools/edit/loc_edit.cpp                 |     2 +-
 c++/src/objtools/edit/mail_report.cpp              |    24 +-
 c++/src/objtools/edit/publication_edit.cpp         |     2 +-
 c++/src/objtools/edit/remote_updater.cpp           |     2 +-
 c++/src/objtools/edit/rna_edit.cpp                 |   195 +-
 c++/src/objtools/edit/seq_entry_edit.cpp           |    13 +-
 c++/src/objtools/edit/string_constraint.cpp        |    66 +-
 c++/src/objtools/edit/struc_comm_field.cpp         |     2 +-
 c++/src/objtools/format/Makefile.xformat.lib       |     4 +-
 c++/src/objtools/format/comment_item.cpp           |   102 +-
 c++/src/objtools/format/context.cpp                |    10 +-
 c++/src/objtools/format/dbsource_item.cpp          |     9 +-
 c++/src/objtools/format/feature_item.cpp           |   102 +-
 c++/src/objtools/format/flat_file_config.cpp       |    57 +-
 c++/src/objtools/format/flat_file_generator.cpp    |    16 +-
 c++/src/objtools/format/flat_qual_slots.cpp        |     3 +-
 c++/src/objtools/format/flat_seqloc.cpp            |     2 +-
 c++/src/objtools/format/gather_items.cpp           |   129 +-
 c++/src/objtools/format/genbank_formatter.cpp      |    70 +-
 c++/src/objtools/format/genbank_gather.cpp         |     2 +-
 c++/src/objtools/format/gene_finder.cpp            |     3 +-
 c++/src/objtools/format/inst_info_map.cpp          |    18 +-
 c++/src/objtools/format/inst_info_map.hpp          |     2 +-
 c++/src/objtools/format/item_formatter.cpp         |    12 +-
 c++/src/objtools/format/keywords_item.cpp          |     2 +-
 c++/src/objtools/format/locus_item.cpp             |     7 +-
 c++/src/objtools/format/qualifiers.cpp             |    14 +-
 c++/src/objtools/readers/Makefile.in               |     4 +-
 c++/src/objtools/readers/Makefile.xobjread.lib     |    10 +-
 c++/src/objtools/readers/Makefile.xobjreadex.lib   |     4 +-
 c++/src/objtools/readers/agp_util.cpp              |    31 +-
 c++/src/objtools/readers/aln_reader.cpp            |    24 +-
 c++/src/objtools/readers/bed_reader.cpp            |   729 +-
 c++/src/objtools/readers/fasta.cpp                 |   319 +-
 c++/src/objtools/readers/gff2_data.cpp             |   223 +-
 c++/src/objtools/readers/gff2_reader.cpp           |   806 +-
 c++/src/objtools/readers/gff3_reader.cpp           |   248 +-
 c++/src/objtools/readers/gff3_sofa.cpp             |    34 +-
 c++/src/objtools/readers/gff_reader.cpp            |     2 +-
 c++/src/objtools/readers/gtf_reader.cpp            |   162 +-
 c++/src/objtools/readers/gvf_reader.cpp            |   623 +-
 c++/src/objtools/readers/idmapper_config.cpp       |     6 +-
 c++/src/objtools/readers/microarray_reader.cpp     |    50 +-
 c++/src/objtools/readers/read_util.cpp             |     2 +-
 c++/src/objtools/readers/reader_base.cpp           |    57 +-
 c++/src/objtools/readers/reader_data.cpp           |    52 +-
 c++/src/objtools/readers/reader_data.hpp           |    29 +-
 c++/src/objtools/readers/readfeat.cpp              |   483 +-
 c++/src/objtools/readers/source_mod_parser.cpp     |    10 +-
 c++/src/objtools/readers/struct_cmt_reader.cpp     |   130 +
 c++/src/objtools/readers/track_data.cpp            |   144 +
 c++/src/objtools/readers/vcf_reader.cpp            |    33 +-
 c++/src/objtools/readers/wiggle_reader.cpp         |     3 +-
 c++/src/objtools/seqmasks_io/mask_bdb_reader.cpp   |     7 +-
 c++/src/objtools/seqmasks_io/mask_cmdline_args.cpp |     7 +-
 c++/src/objtools/seqmasks_io/mask_fasta_reader.cpp |     7 +-
 c++/src/objtools/seqmasks_io/mask_writer.cpp       |     7 +-
 .../seqmasks_io/mask_writer_blastdb_maskinfo.cpp   |     7 +-
 c++/src/objtools/seqmasks_io/mask_writer_fasta.cpp |     7 +-
 c++/src/objtools/seqmasks_io/mask_writer_int.cpp   |     7 +-
 .../objtools/seqmasks_io/mask_writer_seqloc.cpp    |     7 +-
 c++/src/objtools/seqmasks_io/mask_writer_tab.cpp   |     7 +-
 c++/src/serial/aliasinfo.cpp                       |    12 +-
 c++/src/serial/choice.cpp                          |     2 +-
 c++/src/serial/classinfo.cpp                       |     2 +-
 c++/src/serial/datatool/aliasstr.cpp               |     4 +-
 c++/src/serial/datatool/choiceptrstr.cpp           |     4 +-
 c++/src/serial/datatool/choicestr.cpp              |     4 +-
 c++/src/serial/datatool/classstr.cpp               |     4 +-
 c++/src/serial/datatool/datatool.cpp               |     4 +-
 c++/src/serial/datatool/datatool.hpp               |     7 +-
 c++/src/serial/datatool/dtdaux.cpp                 |     4 +-
 c++/src/serial/datatool/dtdparser.cpp              |    14 +-
 c++/src/serial/datatool/enumtype.cpp               |     7 +-
 c++/src/serial/datatool/exceptions.hpp             |     8 +-
 c++/src/serial/datatool/filecode.cpp               |     4 +-
 c++/src/serial/datatool/fileutil.cpp               |     9 +-
 c++/src/serial/datatool/module.cpp                 |     6 +-
 c++/src/serial/datatool/parser.cpp                 |     4 +-
 c++/src/serial/datatool/srcutil.cpp                |     4 +-
 c++/src/serial/datatool/statictype.cpp             |    18 +-
 c++/src/serial/datatool/statictype.hpp             |     7 +-
 c++/src/serial/datatool/stdstr.cpp                 |     9 +-
 c++/src/serial/datatool/stdstr.hpp                 |     3 +-
 .../serial/datatool/traversal_code_generator.cpp   |    18 +-
 c++/src/serial/datatool/traversal_node.cpp         |    14 +-
 .../datatool/traversal_pattern_match_callback.cpp  |     4 +-
 .../serial/datatool/traversal_spec_file_parser.cpp |     7 +-
 c++/src/serial/datatool/type.cpp                   |    12 +-
 c++/src/serial/datatool/typestr.cpp                |     9 +-
 c++/src/serial/datatool/typestr.hpp                |     8 +-
 c++/src/serial/datatool/wsdlparser.cpp             |    22 +-
 c++/src/serial/datatool/wsdlstr.cpp                |     8 +-
 c++/src/serial/datatool/xsdlexer.cpp               |     6 +-
 c++/src/serial/datatool/xsdparser.cpp              |     8 +-
 c++/src/serial/enumerated.cpp                      |     4 +-
 c++/src/serial/exception.cpp                       |     4 +-
 c++/src/serial/member.cpp                          |     6 +-
 c++/src/serial/memberid.cpp                        |     8 +-
 c++/src/serial/objectio.cpp                        |    15 +-
 c++/src/serial/objhook.cpp                         |    41 +-
 c++/src/serial/objistr.cpp                         |    12 +-
 c++/src/serial/objistrasn.cpp                      |    22 +-
 c++/src/serial/objistrasnb.cpp                     |    38 +-
 c++/src/serial/objistrjson.cpp                     |    44 +-
 c++/src/serial/objistrxml.cpp                      |    22 +-
 c++/src/serial/objostr.cpp                         |    24 +-
 c++/src/serial/objostrasn.cpp                      |    21 +-
 c++/src/serial/objostrasnb.cpp                     |    25 +-
 c++/src/serial/objostrjson.cpp                     |    16 +-
 c++/src/serial/objostrxml.cpp                      |    43 +-
 c++/src/serial/objstack.cpp                        |     4 +-
 c++/src/serial/rpcbase.cpp                         |     5 +-
 c++/src/serial/serialobject.cpp                    |     4 +-
 c++/src/serial/stdtypes.cpp                        |    57 +-
 c++/src/serial/typeinfo.cpp                        |     5 +-
 c++/src/util/Makefile.util.lib                     |     4 +-
 c++/src/util/bytesrc.cpp                           |    10 +-
 c++/src/util/compress/api/archive_zip.cpp          |     4 +-
 c++/src/util/compress/api/stream.cpp               |    10 +-
 c++/src/util/compress/api/stream_util.cpp          |    18 +-
 c++/src/util/compress/api/streambuf.cpp            |    56 +-
 c++/src/util/compress/api/zlib.cpp                 |     4 +-
 c++/src/util/compress/bzip2/CHANGES                |    74 +
 c++/src/util/compress/bzip2/LICENSE                |    13 +-
 c++/src/util/compress/bzip2/README                 |   126 +-
 .../compress/bzip2/README.COMPILATION.PROBLEMS     |   130 +-
 c++/src/util/compress/bzip2/README.XML.STUFF       |    45 +
 c++/src/util/compress/bzip2/Y2K_INFO               |    34 -
 c++/src/util/compress/bzip2/blocksort.c            |    77 +-
 c++/src/util/compress/bzip2/bzdiff                 |     4 +-
 c++/src/util/compress/bzip2/bzgrep                 |     6 +-
 c++/src/util/compress/bzip2/bzip.css               |    74 +
 c++/src/util/compress/bzip2/bzip2.1                |    17 +-
 c++/src/util/compress/bzip2/bzip2.1.preformatted   |   398 -
 c++/src/util/compress/bzip2/bzip2.c                |   219 +-
 c++/src/util/compress/bzip2/bzip2.txt              |   119 +-
 c++/src/util/compress/bzip2/bzip2recover.c         |    90 +-
 c++/src/util/compress/bzip2/bzlib.c                |   151 +-
 c++/src/util/compress/bzip2/bzlib_private.h        |    98 +-
 c++/src/util/compress/bzip2/compress.c             |    98 +-
 c++/src/util/compress/bzip2/crctable.c             |    60 +-
 c++/src/util/compress/bzip2/decompress.c           |   102 +-
 c++/src/util/compress/bzip2/dlltest.c              |     5 +-
 c++/src/util/compress/bzip2/huffman.c              |    85 +-
 c++/src/util/compress/bzip2/manual.html            |  2657 ++-
 c++/src/util/compress/bzip2/manual.pdf             |   Bin 298267 -> 256905 bytes
 c++/src/util/compress/bzip2/manual.texi            |  2243 ---
 c++/src/util/compress/bzip2/manual.xml             |  2964 ++++
 c++/src/util/compress/bzip2/manual_1.html          |    81 -
 c++/src/util/compress/bzip2/manual_2.html          |   579 -
 c++/src/util/compress/bzip2/manual_3.html          |  1855 --
 c++/src/util/compress/bzip2/manual_4.html          |   530 -
 c++/src/util/compress/bzip2/manual_abt.html        |   201 -
 c++/src/util/compress/bzip2/manual_ovr.html        |    54 -
 c++/src/util/compress/bzip2/manual_toc.html        |   163 -
 c++/src/util/compress/bzip2/mk251.c                |    15 +
 c++/src/util/compress/bzip2/ncbi_bz2_compress.c    |   706 +-
 c++/src/util/compress/bzip2/randtable.c            |    60 +-
 c++/src/util/compress/bzip2/spewG.c                |    15 +
 c++/src/util/compress/bzip2/unzcrash.c             |    17 +-
 c++/src/util/file_manifest.cpp                     |     2 +-
 c++/src/util/format_guess.cpp                      |   532 +-
 c++/src/util/retry_ctx.cpp                         |     2 +-
 c++/src/util/scheduler.cpp                         |    10 +-
 c++/src/util/sequtil/sequtil_convert_imp.cpp       |    10 +-
 c++/src/util/sequtil/sequtil_convert_imp.hpp       |     2 +-
 c++/src/util/strbuffer.cpp                         |    11 +-
 c++/src/util/stream_source.cpp                     |     2 +-
 c++/src/util/table_printer.cpp                     |     6 +-
 c++/src/util/tables/raw_scoremat.c                 |     9 +-
 c++/src/util/thread_pool.cpp                       |     2 +-
 1444 files changed, 102689 insertions(+), 37619 deletions(-)

diff --git a/c++/compilers/unix/GCC.sh b/c++/compilers/unix/GCC.sh
index 7d0a5e6..c1af4dc 100755
--- a/c++/compilers/unix/GCC.sh
+++ b/c++/compilers/unix/GCC.sh
@@ -3,7 +3,7 @@
 # Setup the local working environment for the "configure" script
 #   Compiler:   GCC
 #
-# $Revision: 491045 $  // by Denis Vakatov, NCBI (vakatov at ncbi.nlm.nih.gov)
+# $Revision: 491630 $  // by Denis Vakatov, NCBI (vakatov at ncbi.nlm.nih.gov)
 #############################################################################
 
 
diff --git a/c++/compilers/unix/ICC.sh b/c++/compilers/unix/ICC.sh
index 385338e..8175035 100755
--- a/c++/compilers/unix/ICC.sh
+++ b/c++/compilers/unix/ICC.sh
@@ -5,7 +5,7 @@
 #   OS:         Linux
 #   Processor:  Intel X86(-64)
 #
-# $Revision: 492739 $  // Dmitriy Beloslyudtsev, NCBI (beloslyu at ncbi.nlm.nih.gov)
+# $Revision: 492694 $  // Dmitriy Beloslyudtsev, NCBI (beloslyu at ncbi.nlm.nih.gov)
 #############################################################################
 
 
diff --git a/c++/compilers/vs2013/build_exec.bat b/c++/compilers/vs2013/build_exec.bat
index ba9a4ae..2ce0164 100644
--- a/c++/compilers/vs2013/build_exec.bat
+++ b/c++/compilers/vs2013/build_exec.bat
@@ -1,5 +1,5 @@
 @ECHO OFF
-REM $Id: build_exec.bat 430635 2014-03-27 17:34:42Z gouriano $
+REM $Id: build_exec.bat 505228 2016-06-23 12:54:48Z ivanov $
 REM ===========================================================================
 REM 
 REM                            PUBLIC DOMAIN NOTICE
@@ -43,6 +43,7 @@ exit 1
 
 :be_build
 set arch=Win32
+if _%5_ == __CONFIGURE__ set arch=x86
 if _%3_ == _64_ set arch=x64
 
 rem Next command should be executed last! No other code after it, please.
diff --git a/c++/compilers/vs2013/configure.bat b/c++/compilers/vs2013/configure.bat
index 9354ee8..14339f6 100644
--- a/c++/compilers/vs2013/configure.bat
+++ b/c++/compilers/vs2013/configure.bat
@@ -1,5 +1,5 @@
 @echo off
-REM $Id: configure.bat 449189 2014-10-14 14:54:57Z gouriano $
+REM $Id: configure.bat 505229 2016-06-23 13:04:20Z gouriano $
 REM ===========================================================================
 REM 
 REM                            PUBLIC DOMAIN NOTICE
diff --git a/c++/compilers/vs2013/dll/build/gbench/ncbi_gbench.sln b/c++/compilers/vs2013/dll/build/gbench/ncbi_gbench.sln
index a54e846..dda40e3 100644
--- a/c++/compilers/vs2013/dll/build/gbench/ncbi_gbench.sln
+++ b/c++/compilers/vs2013/dll/build/gbench/ncbi_gbench.sln
@@ -1,33 +1,33 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 2013
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_DIALOG_", "UtilityProjects\_CONFIGURE_DIALOG_.vcxproj", "{6DEFDB58-C014-4026-A166-299146BD9947}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		DebugDLL|Win32 = DebugDLL|Win32
 		DebugDLL|x64 = DebugDLL|x64
-		ReleaseDLL|Win32 = ReleaseDLL|Win32
+		DebugDLL|x86 = DebugDLL|x86
 		ReleaseDLL|x64 = ReleaseDLL|x64
+		ReleaseDLL|x86 = ReleaseDLL|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{6DEFDB58-C014-4026-A166-299146BD9947}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{6DEFDB58-C014-4026-A166-299146BD9947}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
 		{6DEFDB58-C014-4026-A166-299146BD9947}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
 		{6DEFDB58-C014-4026-A166-299146BD9947}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{6DEFDB58-C014-4026-A166-299146BD9947}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{6DEFDB58-C014-4026-A166-299146BD9947}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{6DEFDB58-C014-4026-A166-299146BD9947}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{6DEFDB58-C014-4026-A166-299146BD9947}.DebugDLL|x86.Build.0 = DebugDLL|Win32
 		{6DEFDB58-C014-4026-A166-299146BD9947}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
 		{6DEFDB58-C014-4026-A166-299146BD9947}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{6DEFDB58-C014-4026-A166-299146BD9947}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{6DEFDB58-C014-4026-A166-299146BD9947}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/c++/compilers/vs2013/dll/build/gui/ncbi_gui_dll.sln b/c++/compilers/vs2013/dll/build/gui/ncbi_gui_dll.sln
index 80e21b2..f76dc11 100644
--- a/c++/compilers/vs2013/dll/build/gui/ncbi_gui_dll.sln
+++ b/c++/compilers/vs2013/dll/build/gui/ncbi_gui_dll.sln
@@ -1,33 +1,33 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 2013
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_DIALOG_", "UtilityProjects\_CONFIGURE_DIALOG_.vcxproj", "{9BAE6EEC-8C80-44F0-84A9-3379631A8654}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		DebugDLL|Win32 = DebugDLL|Win32
 		DebugDLL|x64 = DebugDLL|x64
-		ReleaseDLL|Win32 = ReleaseDLL|Win32
+		DebugDLL|x86 = DebugDLL|x86
 		ReleaseDLL|x64 = ReleaseDLL|x64
+		ReleaseDLL|x86 = ReleaseDLL|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
 		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
 		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.DebugDLL|x86.Build.0 = DebugDLL|Win32
 		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
 		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/c++/compilers/vs2013/dll/build/ncbi_cpp_dll.sln b/c++/compilers/vs2013/dll/build/ncbi_cpp_dll.sln
index 55e5b0e..ec1ea74 100644
--- a/c++/compilers/vs2013/dll/build/ncbi_cpp_dll.sln
+++ b/c++/compilers/vs2013/dll/build/ncbi_cpp_dll.sln
@@ -1,33 +1,33 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 2013
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_DIALOG_", "UtilityProjects\_CONFIGURE_DIALOG_.vcxproj", "{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		DebugDLL|Win32 = DebugDLL|Win32
 		DebugDLL|x64 = DebugDLL|x64
-		ReleaseDLL|Win32 = ReleaseDLL|Win32
+		DebugDLL|x86 = DebugDLL|x86
 		ReleaseDLL|x64 = ReleaseDLL|x64
+		ReleaseDLL|x86 = ReleaseDLL|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
 		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
 		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.DebugDLL|x86.Build.0 = DebugDLL|Win32
 		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
 		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/c++/compilers/vs2013/make.bat b/c++/compilers/vs2013/make.bat
index 8ebc67e..88d4e1f 100644
--- a/c++/compilers/vs2013/make.bat
+++ b/c++/compilers/vs2013/make.bat
@@ -1,5 +1,5 @@
 @ECHO OFF
-REM $Id: make.bat 485599 2015-11-24 13:11:05Z ivanov $
+REM $Id: make.bat 509501 2016-08-05 19:08:31Z fukanchi $
 REM ===========================================================================
 REM
 REM                            PUBLIC DOMAIN NOTICE
@@ -62,7 +62,9 @@ set libdll=%~3
 set arch=%~4
 
 set archw=Win32
-if _%arch%_ == _64_ set archw=x64
+set archwc=x86
+if _%arch%_ == _64_  set archw=x64
+if _%arch%_ == _64_  set archwc=x64
 
 shift
 shift
@@ -81,9 +83,9 @@ rem ----------------------------------------------------------------------------
 :NOARGS
 
 if exist configure_make.bat (
-  configure_make.bat
+   configure_make.bat
 ) else (
-  goto USAGE
+   goto USAGE
 )
 
 :USAGE
@@ -152,7 +154,7 @@ if not "%with_openmp%" == "" (
 
 time /t
 echo INFO: Configure "%libdll%\%solution% [ReleaseDLL|%arch%]"
-%DEVENV% %libdll%\build\%solution%.sln /build "ReleaseDLL|%archw%" /project "_CONFIGURE_"
+%DEVENV% %libdll%\build\%solution%.sln /build "ReleaseDLL|%archwc%" /project "_CONFIGURE_"
 if errorlevel 1 goto ABORT
 if not _%cmd% == _make goto COMPLETE
 
diff --git a/c++/compilers/vs2013/ptb.bat b/c++/compilers/vs2013/ptb.bat
index 0f39f16..c756021 100644
--- a/c++/compilers/vs2013/ptb.bat
+++ b/c++/compilers/vs2013/ptb.bat
@@ -1,5 +1,5 @@
 @echo off
-REM $Id: ptb.bat 434581 2014-05-08 16:47:33Z gouriano $
+REM $Id: ptb.bat 507295 2016-07-18 15:40:58Z gouriano $
 REM ===========================================================================
 REM 
 REM                            PUBLIC DOMAIN NOTICE
@@ -51,6 +51,10 @@ set PTBGUI="%TREE_ROOT%\src\build-system\project_tree_builder_gui\bin\ptbgui.jar
 set DEFPTB_VERSION_FILE=%TREE_ROOT%\src\build-system\ptb_version.txt
 set PTB_INI=%TREE_ROOT%\src\build-system\project_tree_builder.ini
 set PTB_SLN=%BUILD_TREE_ROOT%\static\build\UtilityProjects\PTB.sln
+set NCBICONF_MSVC=%TREE_ROOT%\include\common\config\ncbiconf_msvc_site.h
+if exist "%NCBICONF_MSVC%" (
+  set NCBICONF_MSVC=
+)
 
 REM --- get solution dir ---
 call :XSLNPATH %SLN_PATH%
@@ -199,6 +203,9 @@ if not exist "%PTB_EXE%" (
   echo ******************************************************************************
   rem --- @echo msbuild "%BUILD_TREE_ROOT%\static\build\ncbi_cpp.sln" /t:"project_tree_builder_exe:Rebuild" /p:Configuration=ReleaseDLL;Platform=%PTB_PLATFORM% /maxcpucount:1
   rem --- msbuild "%BUILD_TREE_ROOT%\static\build\ncbi_cpp.sln" /t:"project_tree_builder_exe:Rebuild" /p:Configuration=ReleaseDLL;Platform=%PTB_PLATFORM% /maxcpucount:1
+  if not "%NCBICONF_MSVC%"=="" (
+    echo // > "%NCBICONF_MSVC%"
+  )
   if exist "%PTB_SLN%" (
     @echo %DEVENV% "%PTB_SLN%" /rebuild "ReleaseDLL|%PTB_PLATFORM%" /project "project_tree_builder.exe"
     %DEVENV% "%PTB_SLN%" /rebuild "ReleaseDLL|%PTB_PLATFORM%" /project "project_tree_builder.exe"
@@ -206,6 +213,9 @@ if not exist "%PTB_EXE%" (
     @echo %DEVENV% "%BUILD_TREE_ROOT%\static\build\ncbi_cpp.sln" /rebuild "ReleaseDLL|%PTB_PLATFORM%" /project "project_tree_builder.exe"
     %DEVENV% "%BUILD_TREE_ROOT%\static\build\ncbi_cpp.sln" /rebuild "ReleaseDLL|%PTB_PLATFORM%" /project "project_tree_builder.exe"
   )
+  if not "%NCBICONF_MSVC%"=="" (
+    del "%NCBICONF_MSVC%"
+  )
 ) else (
   echo ******************************************************************************
   echo Using PREBUILT project tree builder at %PTB_EXE%
diff --git a/c++/compilers/vs2013/static/build/gui/ncbi_gui.sln b/c++/compilers/vs2013/static/build/gui/ncbi_gui.sln
index a2bae45..da8a9e5 100644
--- a/c++/compilers/vs2013/static/build/gui/ncbi_gui.sln
+++ b/c++/compilers/vs2013/static/build/gui/ncbi_gui.sln
@@ -1,33 +1,33 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 2013
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_DIALOG_", "UtilityProjects\_CONFIGURE_DIALOG_.vcxproj", "{FDC9447A-C7F1-492D-B84F-D54A1E610F16}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		DebugDLL|Win32 = DebugDLL|Win32
 		DebugDLL|x64 = DebugDLL|x64
-		ReleaseDLL|Win32 = ReleaseDLL|Win32
+		DebugDLL|x86 = DebugDLL|x86
 		ReleaseDLL|x64 = ReleaseDLL|x64
+		ReleaseDLL|x86 = ReleaseDLL|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
 		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
 		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.DebugDLL|x86.Build.0 = DebugDLL|Win32
 		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
 		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/c++/compilers/vs2013/static/build/ncbi_cpp.sln b/c++/compilers/vs2013/static/build/ncbi_cpp.sln
index 38ca7de..c972e4c 100644
--- a/c++/compilers/vs2013/static/build/ncbi_cpp.sln
+++ b/c++/compilers/vs2013/static/build/ncbi_cpp.sln
@@ -6,28 +6,28 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProje
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		DebugDLL|Win32 = DebugDLL|Win32
 		DebugDLL|x64 = DebugDLL|x64
-		ReleaseDLL|Win32 = ReleaseDLL|Win32
+		DebugDLL|x86 = DebugDLL|x86
 		ReleaseDLL|x64 = ReleaseDLL|x64
+		ReleaseDLL|x86 = ReleaseDLL|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
 		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
 		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.DebugDLL|x86.Build.0 = DebugDLL|Win32
 		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
 		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
 		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
 		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.DebugDLL|x86.Build.0 = DebugDLL|Win32
 		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
 		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/c++/compilers/vs2013/user/build/ncbi_user.sln b/c++/compilers/vs2013/user/build/ncbi_user.sln
index 7cf10ad..04aa823 100644
--- a/c++/compilers/vs2013/user/build/ncbi_user.sln
+++ b/c++/compilers/vs2013/user/build/ncbi_user.sln
@@ -1,33 +1,33 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 2013
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_DIALOG_", "UtilityProjects\_CONFIGURE_DIALOG_.vcxproj", "{EB043EAF-58D4-4179-AC32-538D9059BB8B}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		DebugDLL|Win32 = DebugDLL|Win32
 		DebugDLL|x64 = DebugDLL|x64
-		ReleaseDLL|Win32 = ReleaseDLL|Win32
+		DebugDLL|x86 = DebugDLL|x86
 		ReleaseDLL|x64 = ReleaseDLL|x64
+		ReleaseDLL|x86 = ReleaseDLL|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
-		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
 		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
 		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.DebugDLL|x86.Build.0 = DebugDLL|Win32
 		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
 		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/c++/compilers/vs2015/Makefile.WinMain.app.msvc b/c++/compilers/vs2015/Makefile.WinMain.app.msvc
new file mode 100644
index 0000000..3ccfcd0
--- /dev/null
+++ b/c++/compilers/vs2015/Makefile.WinMain.app.msvc
@@ -0,0 +1,11 @@
+[Rule]
+Priority  = 127
+
+
+[Linker]
+subSystem = 2
+
+
+[AddToProject]
+SourceFiles = ../../src/gui/winmain
+
diff --git a/c++/compilers/vs2015/Makefile.wxWidgets.app.msvc b/c++/compilers/vs2015/Makefile.wxWidgets.app.msvc
new file mode 100644
index 0000000..1f2ace2
--- /dev/null
+++ b/c++/compilers/vs2015/Makefile.wxWidgets.app.msvc
@@ -0,0 +1,11 @@
+[Rule]
+Priority  = 127
+
+
+[Linker]
+subSystem = 2
+
+
+[AddToProject]
+; SourceFiles = ../../src/gui/winmain
+
diff --git a/c++/compilers/vs2015/build.sh b/c++/compilers/vs2015/build.sh
new file mode 100644
index 0000000..81db32d
--- /dev/null
+++ b/c++/compilers/vs2015/build.sh
@@ -0,0 +1,264 @@
+#! /bin/sh
+# $Id: build.sh 498022 2016-04-12 18:52:45Z ivanov $
+# Author:  Vladimir Ivanov (ivanov at ncbi.nlm.nih.gov)
+#
+# Build C++ Toolkit.
+
+
+#---------------- Arguments ----------------
+
+script="$0"
+cfgs="${1:-DebugDLL ReleaseDLL}"
+arch="$2"
+
+
+#---------------- Configuration ----------------
+
+# Configure with Unicode configurations enabled
+
+NCBI_CONFIG____ENABLEDUSERREQUESTS__NCBI_UNICODE=1
+export NCBI_CONFIG____ENABLEDUSERREQUESTS__NCBI_UNICODE
+#NCBI_CONFIG____ENABLEDUSERREQUESTS__TWEAKVTUNE=1
+#export NCBI_CONFIG____ENABLEDUSERREQUESTS__TWEAKVTUNE
+
+# Bootstrap mode
+
+#PREBUILT_PTB_EXE=bootstrap
+#export PREBUILT_PTB_EXE
+#PREBUILT_DATATOOL_EXE=bootstrap
+#export PREBUILT_DATATOOL_EXE
+
+
+#---------------- Global variables ----------------
+
+build_trees='static dll'
+sol_static="ncbi_cpp.sln gui/ncbi_gui.sln"
+sol_dll="ncbi_cpp_dll.sln gui/ncbi_gui_dll.sln"
+timer="date +'%H:%M'"
+
+# TRUE if parallell project build system is enabled in Visual Studio
+is_ppb=false
+need_ppb_check=true
+
+
+
+#-------------- Functions --------------
+
+error()
+{
+    echo "[`basename $script`] ERROR:  $1"
+    exit 1
+}
+
+generate_vs2015_error_check_file()
+{
+    cat <<-EOF >$1
+	/.*--* (Reb|B)uild( All | )started: Project:/ {
+	  expendable = ""
+	}
+
+	/^--* Project:/ {
+	  expendable = ""
+	}
+
+	/EXPENDABLE project/ {
+	  expendable = \$0
+	}
+
+	/(| : |The source )([fatal ]*error [A-Z]*[0-9]* *: |The .* are both configured to produce|.*: error [0-9]*:|: general error |Error executing |ERROR: This project depends)/ {
+	if (!expendable) {
+	  print \$0
+	  exit
+	  }
+	}
+	EOF
+}
+
+generate_simple_log()
+{
+    echo Parallel project build detected! Creating simplified log.
+    echo
+       
+    log=$1
+    tree=$2
+    sol=$3
+    cfg=$4
+
+    # Get solution directory
+    sol_dir=`echo $sol | sed 's%/[^/]*$%%'`
+    if [ $sol_dir = $sol ] ; then
+        sol_dir=''
+    fi 
+
+    # Get built projects
+    projects=`grep '.*--* Build started:' $log | awk '{ sub(/^.* started:/, ""); gsub(/ /,"#"); print $0}'`
+
+    for p in $projects ; do
+        echo "------$p" | awk '{gsub(/[#]/," "); print}'
+        prj_name=`echo $p | awk '{gsub(/[#,]/," "); print $2}'`
+###        cfg=`echo $p | awk '{gsub(/[#,]/," "); print $4}'`
+
+        # Get path for specified project name from solution
+        s=`grep \"$prj_name\" $tree/build/$sol | awk '{gsub(/,/," "); print $4}' | sed -e 's%"%%g' -e 's%\\\%/%g' -e 's%.vcxproj%%'`
+
+        target_dir=`echo $s | sed 's%/[^/]*$%%'`
+        test $target_dir = $s  &&  target_dir=''
+        target_name=`echo $s | sed 's%^.*/%%'`
+
+        # Path to regular logfile for current project
+        prj_log="$tree/build/$sol_dir/$target_dir/$cfg/$prj_name/$target_name.log"
+
+        # Add it to new combined log
+        if test ! -f "$prj_log" ; then
+            # Not all projects have a log file in the ${prj_name} sub-directory
+            prj_log_short="$tree/build/$sol_dir/$target_dir/$cfg/$target_name.log"
+            if test ! -f "$prj_log_short" ; then
+                echo "BUILD_SYSTEM_ERROR: Cannot find log file for this project: $prj_log"
+                echo
+                continue
+            fi
+            prj_log=$prj_log_short
+        fi
+        # Remove 3 first bytes from logfile (EF BB BF) and some garbage from a multi-projects build
+        cat $prj_log | tr -d '\357\273\277' | sed 's/\( *\)1>/\1  /g'
+        echo
+    done
+    grep '.*========== Build:' $log
+    echo
+}
+
+
+#---------------- Main ----------------
+
+# Get build dir
+build_dir=`dirname $script`
+build_dir=`(cd "$build_dir"; pwd)`
+
+if [ ! -d $build_dir ] ; then
+    error "Build directory $build_dir not found"
+    exit 1
+fi
+cd $build_dir
+
+# Configuration to build configure
+cfg_configure='ReleaseDLL'
+out=".build.$$"
+
+# Get directory for build logfiles
+log_dir="$build_dir/../../logs"
+mkdir $log_dir >/dev/null 2>&1
+log_dir=`(cd "$log_dir"; pwd)`
+rm $log_dir/* >/dev/null 2>&1
+
+
+chmod +x $build_dir/build_exec.bat
+rm -f $build_dir/cfgs.log
+
+
+# Configure
+
+for tree in $build_trees ; do
+    sols=`eval echo "$"sol_${tree}""`
+    for sol in $sols ; do
+        if test ! -f "$tree/build/$sol" ; then
+            echo "INFO: Solution not found, skipped."
+            continue
+        fi
+        alias=`echo $sol | sed -e 's|\\\\.*$||g' -e 's|_.*$||g'`
+        start=`eval $timer`
+        echo
+        echo Start time: $start
+        echo "INFO: Configure \"$tree\\$alias\""
+        echo "Command line: " $build_dir/build_exec.bat "$tree\\build\\$sol" build "$arch" "$cfg_configure" "_CONFIGURE_" $out
+        $build_dir/build_exec.bat "$tree\\build\\$sol" build "$arch" "$cfg_configure" "_CONFIGURE_" $out >/dev/null
+        echo
+        status=$?
+        # Wait a bit to allow compiler to exit and flush logfile
+        sleep 20
+        if $need_ppb_check; then
+            need_ppb_check=false
+            grep '^1>------ Build started:' $out >/dev/null 2>&1  &&  is_ppb=true
+        fi
+        if $is_ppb; then
+            generate_simple_log $out $tree "$sol" $cfg_configure > $out.simple
+            mv $out $cfg.configure.log
+            mv $out.simple $out
+        fi 
+        cat $out
+        cat $out >> ${log_dir}/${tree}_${cfg_configure}.log
+        echo "Build time: $start - `eval $timer`"
+        echo STATUS = $status
+        if [ $status -ne 0 ] ; then
+            echo "FAILED: Configure $tree\\build\\$sol, $cfg_configure"
+        fi
+        rm -f $out >/dev/null 2>&1
+        if [ $status -ne 0 ] ; then
+            exit 3
+        fi
+    done
+done
+
+
+
+# Generate errors check script
+
+check_awk=$build_dir/build_check.awk
+generate_vs2015_error_check_file $check_awk
+
+
+# Build
+
+for tree in $build_trees ; do
+    for cfg in $cfgs ; do
+        if [ $tree = dll ] ; then
+            echo "$cfg" | grep '.*DLL$' >/dev/null  ||  continue
+        fi
+        sols=`eval echo "$"sol_${tree}""`
+        for sol in $sols ; do
+            if test ! -f "$tree/build/$sol" ; then
+                echo "INFO: Solution not found, skipped."
+                continue
+            fi
+            alias=`echo $sol | sed -e 's|\\\\.*$||g' -e 's|_.*$||g'`
+            start=`eval $timer`
+            echo
+            echo Start time: $start
+            echo "$tree,$sol,$cfg" >> $build_dir/cfgs.log
+            echo "INFO: Building \"$tree\\$cfg\\$alias\""
+            echo "Command line: " $build_dir/build_exec.bat "$tree\\build\\$sol" build "$arch" "$cfg" "_BUILD_ALL_" $out
+            echo
+            $build_dir/build_exec.bat "$tree\\build\\$sol" build "$arch" "$cfg" "_BUILD_ALL_" $out >/dev/null
+            status=$?
+            # Wait a bit to allow compiler to exit and flush logfile
+            sleep 20
+            if $is_ppb; then
+                generate_simple_log $out $tree "$sol" $cfg > $out.simple
+                mv $out $cfg.build.log
+                mv $out.simple $out
+            fi 
+            cat $out
+            cat $out >> ${log_dir}/${tree}_${cfg}.log
+            echo "Build time: $start - `eval $timer`"
+            echo STATUS = $status
+            if [ $status -ne 0 ] ; then
+                # Check on errors (skip expendable projects)
+                failed="1"
+                awk -f $check_awk $out >$out.res 2>/dev/null  &&  test ! -s $out.res  &&  failed="0"
+                if [ "$failed" = "1" ]; then
+                    echo "FAILED: Build $tree\\build\\$sol, $cfg"
+                    echo "FAILED: Build $tree\\build\\$sol, $cfg" > failed.build.log
+                    echo     >> failed.build.log
+                    cat $out >> failed.build.log
+                    cat $tree/build/${sol}_watchers.txt > failed.watchers.log
+                fi
+                rm -f $out $out.res >/dev/null 2>&1
+                if [ "$failed" = "1" ]; then
+                    exit 4
+                fi
+            fi
+            rm -f $out >/dev/null 2>&1
+        done
+    done
+done
+
+exit 0
diff --git a/c++/compilers/vs2015/build_exec.bat b/c++/compilers/vs2015/build_exec.bat
new file mode 100644
index 0000000..2ce0164
--- /dev/null
+++ b/c++/compilers/vs2015/build_exec.bat
@@ -0,0 +1,51 @@
+ at ECHO OFF
+REM $Id: build_exec.bat 505228 2016-06-23 12:54:48Z ivanov $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Vladimir Ivanov
+REM
+REM Auxiliary script for build.sh to run C++ build for specified project
+REM and configuration. Cygwin cannot run devenv directly inside shell-script.
+REM
+REM ===========================================================================
+
+call msvcvars.bat
+
+if _%1% == _  goto be_abort
+goto be_build
+
+:be_abort
+rem You should specify logfile or you will not see an output
+echo Usage: "%0 <solution> <command> <arch> <cfg> <target> <logfile>"
+exit 1
+
+:be_build
+set arch=Win32
+if _%5_ == __CONFIGURE__ set arch=x86
+if _%3_ == _64_ set arch=x64
+
+rem Next command should be executed last! No other code after it, please.
+
+%DEVENV% %1 /%2 "%4|%arch%" /project "%5" /out "%6"
diff --git a/c++/compilers/vs2015/build_util.sh b/c++/compilers/vs2015/build_util.sh
new file mode 100644
index 0000000..7d41933
--- /dev/null
+++ b/c++/compilers/vs2015/build_util.sh
@@ -0,0 +1,67 @@
+#! /bin/sh
+# $Id: build_util.sh 492980 2016-02-23 16:24:57Z gouriano $
+# Author:  Vladimir Ivanov (ivanov at ncbi.nlm.nih.gov)
+#
+# Utility functions for building C++ Toolkit.
+
+
+#---------------- Arguments ----------------
+
+arg="$1"
+
+script=`basename $0`
+script_dir=`dirname $0`
+script_dir=`(cd "$script_dir"; pwd)`
+
+
+
+#-------------- Functions --------------
+
+error()
+{
+    echo "[$script] ERROR:  $1"
+    exit 1
+}
+
+
+#---------------- Main ----------------
+
+case "$arg" in
+
+  --with-openmp )
+
+      makefile="$script_dir/../../src/build-system/Makefile.mk.in.msvc"
+      if [ ! -f $makefile ] ; then
+          error "$makefile not found"
+          exit 1
+      fi
+      tmp=/tmp/build_util_$$
+      trap "rm -f $tmp $tmp.awk" 0 1 2 15
+
+      cat <<-EOF >$tmp.awk
+	    /^\[Compiler\]/ {
+	       comp = 1
+	    }
+	    /^AdditionalOptions=/ {
+	       if (comp == 1) {
+	          gsub("/openmp","")
+	          gsub("AdditionalOptions=","AdditionalOptions=/openmp ")
+	          gsub("  ", " ")
+	          comp = 0
+	       }
+	    }
+	    /.*/ {
+	       print
+	    }
+	EOF
+      awk -f $tmp.awk $makefile >$tmp || exit 1
+      touch -r $makefile $tmp
+      cp -fp $tmp $makefile  || exit 2
+      ;;
+
+  * )
+      error "Unknown command: $arg"
+      ;;
+esac
+
+exit 0
diff --git a/c++/compilers/vs2015/check.sh b/c++/compilers/vs2015/check.sh
new file mode 100644
index 0000000..9b4458e
--- /dev/null
+++ b/c++/compilers/vs2015/check.sh
@@ -0,0 +1,276 @@
+#! /bin/sh
+# $Id: check.sh 492980 2016-02-23 16:24:57Z gouriano $
+# Author:  Vladimir Ivanov (ivanov at ncbi.nlm.nih.gov)
+#
+# Check C++ Toolkit in all previously built configurations
+# (see 'cfgs.log', generated with 'build.sh' script).
+#
+# USAGE:
+#     check.sh {run | concat | concat_err | concat_cfg | load_to_db}
+#
+# Use 'run' command first, than use other commands.
+# For 'concat_cfg' -- use 'run', 'concat' and 'concat_err' commands first.
+
+
+
+########### Arguments
+
+script="$0"
+method="$1"
+
+# Maximum number of parallel running test configurations
+max_tasks=2
+# Sleep timeout between checks on finished 'run' tasks (seconds)
+sleeptime=60
+
+
+########## Functions
+
+Error()
+{
+    echo "[`basename $script`] ERROR:  $1"
+    exit 1
+}
+
+ParseConfig()
+{
+    if [ -z "$1" ] ; then
+        Error "Unknown configuration name"
+    fi
+    x_tree=`echo $1 | sed -e 's/,.*$//'`
+    x_sol=`echo $1 | sed -e 's/^[^,]*,//' -e 's/,.*$//' -e 's/\.sln//' -e 's|\\\|/|g'`
+    x_cfg=`echo $1 | sed -e 's/^.*,//'`
+}
+
+CopyConfigLogs()
+{
+    cat ${tasks_dir[$1]}/check.sh.log >> $res_log
+    cat ${tasks_dir[$1]}/check.sh.log >> \
+        $build_dir/check.sh.${tasks_tree[$1]}_${tasks_cfg[$1]}.log
+}
+
+
+
+########## Main
+
+errcode=0
+
+# Get build directory
+build_dir=`dirname $script`
+build_dir=`(cd "$build_dir"; pwd)`
+timer="date +'%H:%M'"
+
+if [ ! -d $build_dir ] ; then
+    Error "Build directory $build_dir not found"
+fi
+cd $build_dir  ||  Error "Cannot change directory"
+
+res_log="$build_dir/check.sh.log"
+res_concat="$build_dir/check.sh.out"
+res_concat_err="$build_dir/check.sh.out_err"
+
+cfgs="`cat cfgs.log`"
+if [ -z "$cfgs" ] ; then
+    Error "Build some configurations first"
+fi
+
+
+# --- Initialization
+
+case "$method" in
+    run )
+        rm -f "$res_log"
+        rm -f "$build_dir/check.sh.*.log" > /dev/null 2>&1
+        # Init checks
+        $build_dir/../../scripts/common/check/check_make_win_cfg.sh init  || \
+            Error "Check initialization failed"
+        # Init task list
+        i=0
+        while [ $i -lt $max_tasks ] ; do
+            tasks_name[$i]=""
+            tasks_tree[$i]=""
+            tasks_cfg[$i]=""
+            tasks_dir[$i]=""
+            tasks_start[$i]=""
+            i=`expr $i + 1`
+        done
+        ;;
+    clean )
+        # not implemented, 'clean' method is not used on Windows 
+        exit 0
+        ;;
+    concat )
+        cp $res_log $res_concat
+        ;;
+    concat_err )
+        egrep 'ERR \[|TO  -' $res_log > $res_concat_err
+        ;;
+    concat_cfg )
+        rm -f "$build_dir/check.sh.*.out_err" > /dev/null 2>&1
+        ;;
+    load_to_db )
+        rm -f "$build_dir/test_stat_load.log" > /dev/null 2>&1
+        ;;
+    * )
+        Error "Invalid method name"
+        ;;
+esac
+
+
+
+# --- Run checks for each previously built configuration
+
+
+for cfg in $cfgs ; do
+
+    ParseConfig $cfg
+    cd $build_dir
+
+    check_name=$x_tree/$x_sol/$x_cfg
+    check_dir="$x_tree/build/${x_sol}.check/$x_cfg"
+    if [ ! -d "$check_dir" ] ; then
+        Error "Check directory \"$check_dir\" not found"
+    fi
+
+    # Special processing for 'run' to allow parallel test runs
+
+    if [ "$method" = "run" ]; then
+
+        while true; do 
+            i=0
+            idx=999
+
+            while [ $i -lt $max_tasks ]; do
+                # Find first free slot
+                if [ -z "${tasks_name[$i]}" ]; then
+                    idx=$i
+                    break
+                fi
+                # Check on finished tasks
+                if [ -f "${tasks_dir[$i]}/check.success" ]; then
+                    idx=$i
+                fi
+                if [ -f "${tasks_dir[$i]}/check.failed" ]; then
+                    idx=$i
+                    errcode=1
+                fi
+                if [ $idx -lt $max_tasks ]; then
+                    CopyConfigLogs $idx
+                    echo `eval $timer`
+                    echo CHECK_$method: finished: ${tasks_name[$idx]} \(${tasks_start[idx]} - `eval $timer`\)
+                    tasks_name[$idx]=""
+                    break 
+                fi
+                i=`expr $i + 1`
+            done
+        
+            if [ $idx -lt $max_tasks ]; then
+               # Run tests for current configuration $cfg
+               tasks_name[$idx]="$x_tree/$x_sol/$x_cfg"
+               tasks_tree[$idx]="$x_tree"
+               tasks_cfg[$idx]="$x_cfg"
+               tasks_dir[$idx]="$check_dir"
+               tasks_start[$idx]=`eval $timer`
+
+               echo ${tasks_start[$idx]}
+               echo CHECK_$method: started : ${tasks_name[$idx]}
+               rm ${tasks_dir[$idx]}/check.success ${tasks_dir[$idx]}/check.failed >/dev/null 2>&1
+
+               ../../scripts/common/check/check_make_win_cfg.sh create "$x_sol" "$x_tree" "$x_cfg"  || \
+                   Error "Creating check script for \"$check_dir\" failed"
+               test -x "${tasks_dir[$idx]}/check.sh"  || \
+                   Error "Cannot find $check_dir/check.sh"
+
+               ${tasks_dir[$idx]}/check.sh run >/dev/null 2>&1 &
+
+               # Move to next configuration
+               break
+            else
+               # All slots busy -- waiting
+               sleep $sleeptime
+            fi
+        done
+
+        continue
+    fi
+
+
+    # All actions except 'run'
+
+    test -x "$check_dir/check.sh"  ||  \
+        Error "Run checks first. $check_dir/check.sh not found."
+
+    echo `eval $timer`
+    echo CHECK_$method: $check_name
+   
+    case "$method" in
+        concat )
+            $check_dir/check.sh concat
+            cat $check_dir/check.sh.out >> $res_concat
+            ;;
+        concat_err )
+            $check_dir/check.sh concat_err
+            cat $check_dir/check.sh.out_err >> $res_concat_err
+            ;;
+        concat_cfg )
+            # Copy log entries
+            egrep 'ERR \[|TO  -' $check_dir/check.sh.log >> $build_dir/check.sh.${x_tree}_${x_cfg}.out_err
+            # See below for copying of failed tests outputs,
+            # it should be printed after log entries for all configurations.
+            ;;
+        load_to_db )
+            $check_dir/check.sh load_to_db
+            ;;
+    esac
+done
+
+
+# --- Waiting unfinished tasks for 'run'
+
+if [ "$method" = "run" ]; then
+    while true; do 
+        i=0
+        idx=999
+        active=false
+
+        while [ $i -lt $max_tasks ]; do
+            if [ -n "${tasks_name[$i]}" ]; then
+                # Check on finished tasks
+                if [ -f "${tasks_dir[$i]}/check.success" ]; then
+                    idx=$i
+                fi
+                if [ -f "${tasks_dir[$i]}/check.failed" ]; then
+                    idx=$i
+                    errcode=1
+                fi
+                if [ $idx -lt $max_tasks ]; then
+                    CopyConfigLogs $idx
+                    echo `eval $timer`
+                    echo CHECK_$method: finished: ${tasks_name[$idx]} \(${tasks_start[$idx]} - `eval $timer`\)
+                    tasks_name[$idx]=""
+                    idx=999
+                else
+                    active=true
+                fi
+            fi
+            i=`expr $i + 1`
+        done
+
+        if $active; then
+           sleep $sleeptime
+        else
+           break
+        fi
+    done
+fi
+
+if [ "$method" = "concat_cfg" ]; then
+    for cfg in $cfgs ; do
+        ParseConfig $cfg
+        cd $build_dir
+        check_dir="$x_tree/build/${x_sol}.check/$x_cfg"
+        cat $check_dir/check.sh.out_err >> $build_dir/check.sh.${x_tree}_${x_cfg}.out_err
+    done
+fi
+
+exit $errcode
diff --git a/c++/compilers/vs2015/configure.bat b/c++/compilers/vs2015/configure.bat
new file mode 100644
index 0000000..14339f6
--- /dev/null
+++ b/c++/compilers/vs2015/configure.bat
@@ -0,0 +1,384 @@
+ at echo off
+REM $Id: configure.bat 505229 2016-06-23 13:04:20Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Andrei Gourianov
+REM
+REM Configure MSVC solution and projects
+REM
+REM ===========================================================================
+
+setlocal
+
+set sln_name=ncbi_cpp
+set use_projectlst=scripts/projects/ncbi_cpp.lst
+
+set use_savedcfg=
+set use_gui=no
+set maybe_gui=yes
+set use_debug=yes
+set use_dll=no
+set use_64=no
+set use_staticstd=no
+set use_arch=Win32
+set use_flags=
+set help_req=no
+set srcroot=../..
+
+REM -----------------------------------------------------------------------------
+REM  silently ignored  options
+set noops=
+set noops=%noops% --without-optimization
+set noops=%noops% --with-profiling
+set noops=%noops% --with-tcheck
+set noops=%noops% --with-static
+set noops=%noops% --with-plugin-auto-load
+set noops=%noops% --with-bin-release
+set noops=%noops% --with-mt
+set noops=%noops% --without-exe
+set noops=%noops% --with-runpath
+set noops=%noops% --with-lfs
+set noops=%noops% --with-autodep
+set noops=%noops% --with-build-root
+set noops=%noops% --with-fake-root
+set noops=%noops% --without-suffix
+set noops=%noops% --with-hostspec
+set noops=%noops% --without-version
+set noops=%noops% --with-build-root-sfx
+set noops=%noops% --without-execopy
+set noops=%noops% --with-bincopy
+set noops=%noops% --with-lib-rebuilds
+set noops=%noops% --with-lib-rebuilds
+set noops=%noops% --without-deactivation
+set noops=%noops% --without-makefile-auto-update
+set noops=%noops% --without-flat-makefile
+set noops=%noops% --with-check
+set noops=%noops% --with-check-tools
+set noops=%noops% --with-ncbi-public
+set noops=%noops% --with-strip
+set noops=%noops% --with-pch
+set noops=%noops% --with-caution
+set noops=%noops% --without-caution
+set noops=%noops% --without-ccache
+set noops=%noops% --with-distcc
+set noops=%noops% --without-ncbi-c
+set noops=%noops% --without-sss
+set noops=%noops% --without-utils
+set noops=%noops% --without-sssdb
+set noops=%noops% --with-included-sss
+set noops=%noops% --with-z
+set noops=%noops% --without-z
+set noops=%noops% --with-bz2
+set noops=%noops% --without-bz2
+set noops=%noops% --with-lzo
+set noops=%noops% --without-lzo
+set noops=%noops% --with-pcre
+set noops=%noops% --without-pcre
+set noops=%noops% --with-gnutls
+set noops=%noops% --without-gnutls
+set noops=%noops% --with-openssl
+set noops=%noops% --without-openssl
+set noops=%noops% --without-sybase
+set noops=%noops% --with-sybase-local
+set noops=%noops% --with-sybase-new
+set noops=%noops% --without-ftds
+set noops=%noops% --with-ftds
+set noops=%noops% --without-ftds-renamed
+set noops=%noops% --without-mysql
+set noops=%noops% --with-mysql
+set noops=%noops% --without-opengl
+set noops=%noops% --with-opengl
+set noops=%noops% --without-mesa
+set noops=%noops% --with-mesa
+set noops=%noops% --without-glut
+set noops=%noops% --with-glut
+set noops=%noops% --without-wxwin
+set noops=%noops% --with-wxwin
+set noops=%noops% --without-wxwidgets
+set noops=%noops% --with-wxwidgets
+set noops=%noops% --with-wxwidgets-ucs
+set noops=%noops% --without-wxwidgets-ucs
+set noops=%noops% --without-freetype
+set noops=%noops% --with-freetype
+set noops=%noops% --without-fastcgi
+set noops=%noops% --with-fastcgi
+set noops=%noops% --with-fastcgi
+set noops=%noops% --without-bdb
+set noops=%noops% --with-bdb
+set noops=%noops% --without-sp
+set noops=%noops% --without-orbacus
+set noops=%noops% --with-orbacus
+set noops=%noops% --with-odbc
+set noops=%noops% --with-python
+set noops=%noops% --without-python
+set noops=%noops% --with-boost
+set noops=%noops% --without-boost
+set noops=%noops% --with-boost-tag
+set noops=%noops% --without-boost-tag
+set noops=%noops% --with-sqlite
+set noops=%noops% --without-sqlite
+set noops=%noops% --with-sqlite3
+set noops=%noops% --without-sqlite3
+set noops=%noops% --with-icu
+set noops=%noops% --without-icu
+set noops=%noops% --with-expat
+set noops=%noops% --without-expat
+set noops=%noops% --with-sablot
+set noops=%noops% --without-sablot
+set noops=%noops% --with-libxml
+set noops=%noops% --without-libxml
+set noops=%noops% --with-libxslt
+set noops=%noops% --without-libxslt
+set noops=%noops% --with-xerces
+set noops=%noops% --without-xerces
+set noops=%noops% --with-xalan
+set noops=%noops% --without-xalan
+set noops=%noops% --with-oechem
+set noops=%noops% --without-oechem
+set noops=%noops% --with-sge
+set noops=%noops% --without-sge
+set noops=%noops% --with-muparser
+set noops=%noops% --without-muparser
+set noops=%noops% --with-hdf5
+set noops=%noops% --without-hdf5
+set noops=%noops% --with-gif
+set noops=%noops% --without-gif
+set noops=%noops% --with-jpeg
+set noops=%noops% --without-jpeg \
+set noops=%noops% --with-png
+set noops=%noops% --without-png
+set noops=%noops% --with-tiff
+set noops=%noops% --without-tiff
+set noops=%noops% --with-xpm
+set noops=%noops% --without-xpm
+set noops=%noops% --without-local-lbsm
+set noops=%noops% --without-ncbi-crypt
+set noops=%noops% --without-connext
+set noops=%noops% --without-serial
+set noops=%noops% --without-objects
+set noops=%noops% --without-dbapi
+set noops=%noops% --without-app
+set noops=%noops% --without-ctools
+set noops=%noops% --without-gui
+set noops=%noops% --without-algo
+set noops=%noops% --without-internal
+set noops=%noops% --with-gbench
+set noops=%noops% --without-gbench
+set noops=%noops% --with-x
+
+
+set initial_dir=%CD%
+set script_name=%0
+cd %~p0
+for /f "delims=" %%a in ('cd') do (set script_dir=%%a)
+cd %srcroot%
+for /f "delims=" %%a in ('cd') do (set srcroot=%%a)
+cd %initial_dir%
+
+REM --------------------------------------------------------------------------------
+REM parse arguments
+
+set unknown=
+set ignore_unknown=no
+set dest=
+:PARSEARGS
+if "%1"=="" goto ENDPARSEARGS
+if "%dest%"=="lst"                      (set use_projectlst=%1&  set dest=& goto CONTINUEPARSEARGS)
+if "%dest%"=="cfg"                      (set use_savedcfg=%~1&   set dest=& goto CONTINUEPARSEARGS)
+if "%1"=="--help"                       (set help_req=yes&       goto CONTINUEPARSEARGS)
+if "%1"=="--with-configure-dialog"      (set use_gui=yes&        goto CONTINUEPARSEARGS)
+if "%1"=="--without-configure-dialog"   (set use_gui=no&         goto CONTINUEPARSEARGS)
+if "%1"=="--with-saved-settings"        (set dest=cfg&           goto CONTINUEPARSEARGS)
+if "%1"=="--without-debug"              (set use_debug=no&       goto CONTINUEPARSEARGS)
+if "%1"=="--with-debug"                 (set use_debug=yes&      goto CONTINUEPARSEARGS)
+if "%1"=="--without-dll"                (set use_dll=no&         goto CONTINUEPARSEARGS)
+if "%1"=="--with-dll"                   (set use_dll=yes&        goto CONTINUEPARSEARGS)
+if "%1"=="--with-64"                    (set use_64=yes&         goto CONTINUEPARSEARGS)
+if "%1"=="--with-static-exe"            (set use_staticstd=yes&  goto CONTINUEPARSEARGS)
+if "%1"=="--with-projects"              (set dest=lst&           goto CONTINUEPARSEARGS)
+if "%1"=="--ignore-unsupported-options" (set ignore_unknown=yes& goto CONTINUEPARSEARGS)
+set unknown=%unknown% %1
+:CONTINUEPARSEARGS
+set maybe_gui=no
+shift
+goto PARSEARGS
+:ENDPARSEARGS
+if "%maybe_gui%"=="yes" (
+  set use_gui=yes
+)
+
+REM --------------------------------------------------------------------------------
+REM check and report unknown options
+
+set invalid_unknown=no
+for %%u in (%unknown%) do (
+  call :CHECKUNKNOWN %%u
+)
+if "%invalid_unknown%"=="yes" exit /b 1
+goto DONEUNKNOWN
+
+:CHECKUNKNOWN
+for %%n in (%noops%) do (
+  if "%1"=="%%n" (
+    echo Ignored:  %1
+    goto :eof
+  )
+)
+for /f "eol=-" %%a in ('echo %1') do goto :eof
+if "%ignore_unknown%"=="no" (
+  echo Unsupported option:  %1
+  set invalid_unknown=yes
+) else (
+  echo Ignored unsupported:  %1
+)
+goto :eof
+:DONEUNKNOWN
+
+REM --------------------------------------------------------------------------------
+REM print usage
+
+:PRINTUSAGE
+if "%help_req%"=="yes" (
+  echo  USAGE:
+  echo    %script_name% [OPTION]...
+  echo  SYNOPSIS:
+  echo    configure NCBI C++ toolkit for MSVC build system.
+  echo  OPTIONS:
+  echo    --help                      -- print Usage
+  echo    --with-configure-dialog     -- use Configuration GUI application
+  echo    --without-configure-dialog  -- do not use Configuration GUI application
+  echo    --with-saved-settings=FILE  -- load configuration settings from FILE
+  echo    --without-debug             -- build non-debug versions of libs and apps
+  echo    --with-debug                -- build debug versions of libs and apps
+  echo    --without-dll               -- build all toolkit libraries as static ones
+  echo    --with-dll                  -- assemble toolkit libraries into DLLs
+  echo                                     where requested
+  echo    --with-64                   -- compile to 64-bit code
+  echo    --with-static-exe           -- use static C++ standard libraries
+  echo    --with-projects=FILE        -- build projects listed in "%srcroot%\FILE"
+  echo             FILE can also be a name of a subdirectory
+  echo             examples:   --with-projects=src/corelib
+  echo                         --with-projects=scripts/projects/ncbi_cpp.lst
+  echo    --ignore-unsupported-options   -- ignore unsupported options
+  exit /b 0
+)
+
+REM --------------------------------------------------------------------------------
+REM target architecture, solution path, configuration and flags
+
+if "%use_64%"=="yes" (
+  set use_arch=x64
+) else (
+  set use_arch=Win32
+)
+if "%use_dll%"=="yes" (
+  if "%use_debug%"=="yes" (
+    set CONFIGURATION=DebugDLL
+  ) else (
+    set CONFIGURATION=ReleaseDLL
+  )
+) else (
+  if "%use_debug%"=="yes" (
+    if "%use_staticstd%"=="yes" (
+      set CONFIGURATION=DebugMT
+    ) else (
+      set CONFIGURATION=DebugDLL
+    )
+  ) else (
+    if "%use_staticstd%"=="yes" (
+      set CONFIGURATION=ReleaseMT
+    ) else (
+      set CONFIGURATION=ReleaseDLL
+    )
+  )
+)
+if "%use_gui%"=="yes" (
+  set use_flags=%use_flags% -cfg
+)
+if "%use_dll%"=="yes" (
+  set build_results=dll
+  set sln_name=%sln_name%_dll
+  set use_flags=%use_flags% -dll
+) else (
+  set build_results=static
+)
+set use_projectlst=%use_projectlst:/=\%
+
+
+REM --------------------------------------------------------------------------------
+REM prepare and run ptb.bat
+cd %script_dir%
+set PTB_PLATFORM=%use_arch%
+set PTB_FLAGS=%use_flags%
+set PTB_PATH=./static/bin/ReleaseDLL
+set SLN_PATH=%script_dir%\%build_results%\build\%sln_name%.sln
+set TREE_ROOT=%srcroot%
+set BUILD_TREE_ROOT=.
+set PTB_PROJECT_REQ=%use_projectlst%
+
+if "%use_savedcfg%"=="" (
+  set PTB_SAVED_CFG_REQ=
+) else (
+  if exist "%use_savedcfg%" (
+    set PTB_SAVED_CFG_REQ="%use_savedcfg%"
+  ) else (
+    if exist "%initial_dir%\%use_savedcfg%" (
+      set PTB_SAVED_CFG_REQ="%initial_dir%\%use_savedcfg%"
+    ) else (
+      echo ERROR: "%use_savedcfg%" not found
+      exit /b 1
+    )
+  )
+)
+
+call ./ptb.bat
+if errorlevel 1 (
+  cd %initial_dir%
+  exit /b 1
+)
+
+REM --------------------------------------------------------------------------------
+REM generate configure_make.bat
+
+cd %script_dir%
+set mk_cmnd=make.bat build %sln_name% %build_results%
+if "%use_64%"=="yes" (
+  set mk_cmnd=%mk_cmnd% 64
+) else (
+  set mk_cmnd=%mk_cmnd% 32
+)
+set mk_cmnd=%mk_cmnd% %CONFIGURATION%
+echo %mk_cmnd% > configure_make.bat
+
+
+REM ------------------------------------------------------------------------------
+echo To build the solution %SLN_PATH%
+echo execute the following commands:
+echo cd %script_dir%
+echo make
+
+cd %initial_dir%
+endlocal
+exit /b 0
diff --git a/c++/compilers/vs2015/datatool.bat b/c++/compilers/vs2015/datatool.bat
new file mode 100644
index 0000000..36a4fed
--- /dev/null
+++ b/c++/compilers/vs2015/datatool.bat
@@ -0,0 +1,188 @@
+ at echo off
+REM $Id: datatool.bat 492980 2016-02-23 16:24:57Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Andrei Gourianov
+REM
+REM Run datatool.exe to generate sources from ASN/DTD/Schema specifications
+REM
+REM DO NOT ATTEMPT to run this bat file manually
+REM
+REM ===========================================================================
+
+set ORIGINAL_ARGS=%*
+
+REM ---------------- begin workaround FOR MSVC2010! ---------------------------------
+set input_asn_path=
+set input_asn_name=
+set input_def_path=
+set subtree=
+set srcroot=
+:PARSEARGS
+if _%1==_ goto ENDPARSEARGS
+if "%dest%"=="inASN"    (set input_asn_path=%~1& set input_asn_name=%~n1& set dest=& goto CONTINUEPARSEARGS)
+if "%dest%"=="inDEF"    (set input_def_path=%~1& set dest=& goto CONTINUEPARSEARGS)
+if "%dest%"=="subtree"  (set subtree=%1&     set dest=& goto CONTINUEPARSEARGS)
+if "%dest%"=="srcroot"  (set srcroot=%1&     set dest=& goto CONTINUEPARSEARGS)
+if "%1"=="-m"           (set dest=inASN&                goto CONTINUEPARSEARGS)
+if "%1"=="-od"          (set dest=inDEF&                goto CONTINUEPARSEARGS)
+if "%1"=="-or"          (set dest=subtree&              goto CONTINUEPARSEARGS)
+if "%1"=="-oR"          (set dest=srcroot&              goto CONTINUEPARSEARGS)
+if "%1"=="-M"           (goto ENDPARSEARGS)
+:CONTINUEPARSEARGS
+shift
+REM echo parsing %1
+goto PARSEARGS
+:ENDPARSEARGS
+set src_subtree=%CD%\%srcroot%src\%subtree%
+set dest_spec=%BUILD_TREE_ROOT%\static\build\%subtree%
+if not exist "%dest_spec%" mkdir "%dest_spec%"
+if not exist "%dest_spec%" set dest_spec=.
+
+set copied_asn=0
+for /f %%a in ('xcopy "%input_asn_path%" "%dest_spec%" /q /d /y') do (set copied_asn=%%a)
+set copied_def=0
+if not exist "%input_def_path%" echo [-] > "%input_def_path%"
+if exist "%input_def_path%" for /f %%a in ('xcopy "%input_def_path%" "%dest_spec%" /q /d /y') do (set copied_def=%%a)
+if not %copied_asn%==0 goto DOGENERATE
+if not %copied_def%==0 goto DOGENERATE
+if not exist "%src_subtree%%input_asn_name%.files"   goto DOGENERATE
+if not exist "%src_subtree%%input_asn_name%__.cpp"   goto DOGENERATE
+if not exist "%src_subtree%%input_asn_name%___.cpp"  goto DOGENERATE
+echo generation NOT needed
+exit /b 0
+:DOGENERATE
+REM ----------------   end workaround --------------------------------------
+
+set DEFDT_LOCATION=\\snowman\win-coremake\App\Ncbi\cppcore\datatool
+
+for %%v in ("%DATATOOL_PATH%" "%TREE_ROOT%" "%BUILD_TREE_ROOT%" "%PTB_PLATFORM%") do (
+  if %%v=="" (
+    echo ERROR: required environment variable is missing
+    echo DO NOT ATTEMPT to run this bat file manually
+    exit /b 1
+  )
+)
+set DEFDT_VERSION_FILE=%TREE_ROOT%\src\build-system\datatool_version.txt
+set PTB_SLN=%BUILD_TREE_ROOT%\static\build\UtilityProjects\PTB.sln
+set DT=datatool.exe
+
+call "%BUILD_TREE_ROOT%\msvcvars.bat"
+
+
+REM -------------------------------------------------------------------------
+REM get DT version: from DEFDT_VERSION_FILE  or from PREBUILT_DATATOOL_EXE
+
+set DEFDT_VERSION=
+if exist "%DEFDT_VERSION_FILE%" (
+  for /f %%a in ('type "%DEFDT_VERSION_FILE%"') do (set DEFDT_VERSION=%%a& goto donedf)
+  :donedf
+  set DEFDT_VERSION=%DEFDT_VERSION: =%
+)
+if exist "%PREBUILT_DATATOOL_EXE%" (
+  set ptbver=
+  for /f "tokens=2" %%a in ('"%PREBUILT_DATATOOL_EXE%" -version') do (set ptbver=%%a& goto donepb)
+  :donepb
+  set ptbver=%ptbver: =%
+  if not "%DEFDT_VERSION%"=="%ptbver%" (
+    echo WARNING: requested %DT% version %ptbver% does not match default one: %DEFDT_VERSION%
+    set DEFDT_VERSION=%ptbver%
+  )
+)
+
+if "%DEFDT_VERSION%"=="" (
+  echo ERROR: DEFDT_VERSION not specified
+  exit /b 1
+)
+for /f "tokens=1-3 delims=." %%a in ('echo %DEFDT_VERSION%') do (set DT_VER=%%a%%b%%c& set DT_VER_MAJOR=%%a)
+
+
+REM -------------------------------------------------------------------------
+REM Identify DATATOOL_EXE
+
+set DT_COPY_HERE=NO
+if "%PREBUILT_DATATOOL_EXE%"=="bootstrap" (
+  set DEF_DT=%DATATOOL_PATH%\%DT%
+) else if not "%PREBUILT_DATATOOL_EXE%"=="" (
+  if exist "%PREBUILT_DATATOOL_EXE%" (
+    set DEF_DT=%PREBUILT_DATATOOL_EXE%
+  ) else (
+    echo ERROR: "%PREBUILT_DATATOOL_EXE%" not found
+    exit /b 1
+  )
+) else (
+  set DEF_DT=%DEFDT_LOCATION%\msvc\%DEFDT_VERSION%\%DT%
+  if not "%COPY_DATATOOL_EXE%"=="NO" (
+    set DT_COPY_HERE=YES
+  )
+)
+if exist "%DEF_DT%" (
+  set DATATOOL_EXE=%DEF_DT%
+) else (
+  echo %DT% not found at %DEF_DT%
+  set DATATOOL_EXE=%DATATOOL_PATH%\%DT%
+  set DT_COPY_HERE=NO
+)
+
+
+REM -------------------------------------------------------------------------
+REM Build DATATOOL_EXE if needed
+
+if not exist "%DATATOOL_EXE%" (
+  if exist "%PTB_SLN%" (
+    echo ******************************************************************************
+    echo Building %DT% locally, please wait
+    echo ******************************************************************************
+    @echo %DEVENV% "%PTB_SLN%" /rebuild "ReleaseDLL|%PTB_PLATFORM%" /project "datatool.exe"
+    %DEVENV% "%PTB_SLN%" /rebuild "ReleaseDLL|%PTB_PLATFORM%" /project "datatool.exe"
+  ) else (
+    echo ERROR: do not know how to build %DT%
+  )
+) else (
+  echo ******************************************************************************
+  echo Using PREBUILT %DT% at %DATATOOL_EXE%
+  echo ******************************************************************************
+)
+if not exist "%DATATOOL_EXE%" (
+  echo ERROR: "%DATATOOL_EXE%" not found
+  exit /b 1
+)
+
+REM -------------------------------------------------------------------------
+REM Copy datatool from network to the local tree (to make it work faster)
+
+set DT_LOCAL=%BUILD_TREE_ROOT%\static\build\UtilityProjects\%DEFDT_VERSION%_%DT%
+if "%DT_COPY_HERE%"=="YES" (
+  if not exist "%DT_LOCAL%" (
+    xcopy "%DATATOOL_EXE%" "%BUILD_TREE_ROOT%\static\build\UtilityProjects\" /q /d /y >NUL
+    rename "%BUILD_TREE_ROOT%\static\build\UtilityProjects\%DT%" "%DEFDT_VERSION%_%DT%"
+  )
+  set DATATOOL_EXE=%DT_LOCAL%
+)
+
+REM -------------------------------------------------------------------------
+REM Run DATATOOL_EXE
+
+"%DATATOOL_EXE%" %ORIGINAL_ARGS%
diff --git a/c++/compilers/vs2015/dll/build/UtilityProjects/_CONFIGURE_.vcxproj b/c++/compilers/vs2015/dll/build/UtilityProjects/_CONFIGURE_.vcxproj
new file mode 100644
index 0000000..56dd94a
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/UtilityProjects/_CONFIGURE_.vcxproj
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>_CONFIGURE_</ProjectName>
+    <ProjectGuid>{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}</ProjectGuid>
+    <RootNamespace>MasterProject</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">_CONFIGURE_</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuild Include="configure._">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Configure solution : $(SolutionName)</Message>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/dll/build/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj b/c++/compilers/vs2015/dll/build/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj
new file mode 100644
index 0000000..02c6d53
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>_CONFIGURE_DIALOG_</ProjectName>
+    <ProjectGuid>{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}</ProjectGuid>
+    <RootNamespace>MasterProject</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">_CONFIGURE_DIALOG_</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuild Include="configure_dialog._">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Configure solution : $(SolutionName)</Message>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/dll/build/UtilityProjects/configure._ b/c++/compilers/vs2015/dll/build/UtilityProjects/configure._
new file mode 100644
index 0000000..7d4011f
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/UtilityProjects/configure._
@@ -0,0 +1,4 @@
+set PTB_FLAGS= -dll
+set PTB_PROJECT_REQ=scripts\projects\ncbi_cpp_dll.lst
+call "%BUILD_TREE_ROOT%\ptb.bat"
+if errorlevel 1 exit 1
diff --git a/c++/compilers/vs2015/dll/build/UtilityProjects/configure_dialog._ b/c++/compilers/vs2015/dll/build/UtilityProjects/configure_dialog._
new file mode 100644
index 0000000..f4e04b9
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/UtilityProjects/configure_dialog._
@@ -0,0 +1,4 @@
+set PTB_FLAGS= -dll -cfg
+set PTB_PROJECT_REQ=scripts\projects\ncbi_cpp_dll.lst
+call "%BUILD_TREE_ROOT%\ptb.bat"
+if errorlevel 1 exit 1
diff --git a/c++/compilers/vs2015/dll/build/all.bat b/c++/compilers/vs2015/dll/build/all.bat
new file mode 100644
index 0000000..d1e7a34
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/all.bat
@@ -0,0 +1,42 @@
+ at ECHO OFF
+REM $Id: all.bat 492988 2016-02-23 17:04:54Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Vladimir Ivanov
+REM
+REM Build all C++ Toolkit DLL projects
+REM
+REM ===========================================================================
+
+
+CALL all_ncbi.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
+IF ERRORLEVEL 1 GOTO _ABORT_
+
+CALL all_gui.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
+IF ERRORLEVEL 1 GOTO _ABORT_
+
+CALL all_gbench.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
+
+:_ABORT_
\ No newline at end of file
diff --git a/c++/compilers/vs2015/dll/build/all_gbench.bat b/c++/compilers/vs2015/dll/build/all_gbench.bat
new file mode 100644
index 0000000..dff15ed
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/all_gbench.bat
@@ -0,0 +1,75 @@
+ at ECHO OFF
+REM $Id: all_gbench.bat 492988 2016-02-23 17:04:54Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Anton Lavrentiev
+REM
+REM Build GBENCH
+REM
+REM ===========================================================================
+
+call "..\..\msvcvars.bat"
+
+IF _%1% == _    GOTO BUILDALL
+IF _%1% == _ALL GOTO BUILDALL
+GOTO CONFIG
+
+:BUILDALL
+CALL %0 DebugDLL ReleaseDLL
+GOTO EXIT
+
+:CONFIG
+TIME /T
+ECHO INFO: Configure "dll\gbench"
+msbuild gbench\ncbi_gbench.sln /t:"_CONFIGURE_:Rebuild" /p:Configuration=ReleaseDLL
+IF ERRORLEVEL 1 GOTO ABORT
+
+SET CFG=%1%
+
+:ARGLOOP
+IF %CFG% == DebugDLL GOTO CONTINUE
+IF %CFG% == ReleaseDLL GOTO CONTINUE
+ECHO INFO: The following configuration names are recognized:
+ECHO       DebugDLL ReleaseDLL
+ECHO FATAL: Unknown configuration name %CFG%. Please correct.
+GOTO EXIT
+
+:CONTINUE
+TIME /T
+ECHO INFO: Building "dll\gbench\%CFG%"
+msbuild gbench\ncbi_gbench.sln /t:"_BUILD_ALL_" /p:Configuration=%CFG%
+IF ERRORLEVEL 1 GOTO ABORT
+
+SHIFT
+IF _%1% == _ GOTO COMPLETE
+SET CFG=%1%
+GOTO ARGLOOP
+
+:ABORT
+ECHO INFO: Build failed.
+GOTO EXIT
+:COMPLETE
+ECHO INFO: Build complete.
+:EXIT
diff --git a/c++/compilers/vs2015/dll/build/all_gui.bat b/c++/compilers/vs2015/dll/build/all_gui.bat
new file mode 100644
index 0000000..7cf2cf1
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/all_gui.bat
@@ -0,0 +1,75 @@
+ at ECHO OFF
+REM $Id: all_gui.bat 492988 2016-02-23 17:04:54Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Anton Lavrentiev
+REM
+REM Build C++ GUI libraries, tests and samples
+REM
+REM ===========================================================================
+
+call "..\..\msvcvars.bat"
+
+IF _%1% == _    GOTO BUILDALL
+IF _%1% == _ALL GOTO BUILDALL
+GOTO CONFIG
+
+:BUILDALL
+CALL %0 DebugDLL ReleaseDLL
+GOTO EXIT
+
+:CONFIG
+TIME /T
+ECHO INFO: Configure "dll\gui"
+msbuild gui\ncbi_gui_dll.sln /t:"_CONFIGURE_:Rebuild" /p:Configuration=ReleaseDLL
+IF ERRORLEVEL 1 GOTO ABORT
+
+SET CFG=%1%
+
+:ARGLOOP
+IF %CFG% == DebugDLL GOTO CONTINUE
+IF %CFG% == ReleaseDLL GOTO CONTINUE
+ECHO INFO: The following configuration names are recognized:
+ECHO       DebugDLL ReleaseDLL
+ECHO FATAL: Unknown configuration name %CFG%. Please correct.
+GOTO EXIT
+
+:CONTINUE
+TIME /T
+ECHO INFO: Building "dll\gui\%CFG%"
+msbuild gui\ncbi_gui_dll.sln /t:"_BUILD_ALL_" /p:Configuration=%CFG%
+IF ERRORLEVEL 1 GOTO ABORT
+
+SHIFT
+IF _%1% == _ GOTO COMPLETE
+SET CFG=%1%
+GOTO ARGLOOP
+
+:ABORT
+ECHO INFO: Build failed.
+GOTO EXIT
+:COMPLETE
+ECHO INFO: Build complete.
+:EXIT
diff --git a/c++/compilers/vs2015/dll/build/all_ncbi.bat b/c++/compilers/vs2015/dll/build/all_ncbi.bat
new file mode 100644
index 0000000..830c221
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/all_ncbi.bat
@@ -0,0 +1,75 @@
+ at ECHO OFF
+REM $Id: all_ncbi.bat 492988 2016-02-23 17:04:54Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Anton Lavrentiev
+REM
+REM Build NCBI C++ core libraries, tests and samples
+REM
+REM ===========================================================================
+
+call "..\..\msvcvars.bat"
+
+IF _%1% == _    GOTO BUILDALL
+IF _%1% == _ALL GOTO BUILDALL
+GOTO CONFIG
+
+:BUILDALL
+CALL %0 DebugDLL ReleaseDLL
+GOTO EXIT
+
+:CONFIG
+TIME /T
+ECHO INFO: Configure "dll\ncbi"
+msbuild ncbi_cpp_dll.sln /t:"_CONFIGURE_:Rebuild" /p:Configuration=ReleaseDLL
+IF ERRORLEVEL 1 GOTO ABORT
+
+SET CFG=%1%
+
+:ARGLOOP
+IF %CFG% == DebugDLL GOTO CONTINUE
+IF %CFG% == ReleaseDLL GOTO CONTINUE
+ECHO INFO: The following configuration names are recognized:
+ECHO       DebugDLL ReleaseDLL
+ECHO FATAL: Unknown configuration name %CFG%. Please correct.
+GOTO EXIT
+
+:CONTINUE
+TIME /T
+ECHO INFO: Building "dll\ncbi\%CFG%"
+msbuild ncbi_cpp_dll.sln /t:"_BUILD_ALL_" /p:Configuration=%CFG%
+IF ERRORLEVEL 1 GOTO ABORT
+
+SHIFT
+IF _%1% == _ GOTO COMPLETE
+SET CFG=%1%
+GOTO ARGLOOP
+
+:ABORT
+ECHO INFO: Build failed.
+GOTO EXIT
+:COMPLETE
+ECHO INFO: Build complete.
+:EXIT
diff --git a/c++/compilers/vs2015/dll/build/gbench/UtilityProjects/_CONFIGURE_.vcxproj b/c++/compilers/vs2015/dll/build/gbench/UtilityProjects/_CONFIGURE_.vcxproj
new file mode 100644
index 0000000..3bfcfd8
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/gbench/UtilityProjects/_CONFIGURE_.vcxproj
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>_CONFIGURE_</ProjectName>
+    <ProjectGuid>{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}</ProjectGuid>
+    <RootNamespace>MasterProject</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">_CONFIGURE_</TargetName>
+
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">_CONFIGURE_</TargetName>
+
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">_CONFIGURE_</TargetName>
+
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">_CONFIGURE_</TargetName>
+
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuild Include="configure._">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gbench.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gbench.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gbench.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gbench.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Configure solution : $(SolutionName)</Message>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/dll/build/gbench/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj b/c++/compilers/vs2015/dll/build/gbench/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj
new file mode 100644
index 0000000..cc572dd
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/gbench/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>_CONFIGURE_DIALOG_</ProjectName>
+    <ProjectGuid>{6DEFDB58-C014-4026-A166-299146BD9947}</ProjectGuid>
+    <RootNamespace>MasterProject</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">_CONFIGURE_DIALOG_</TargetName>
+
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">_CONFIGURE_DIALOG_</TargetName>
+
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">_CONFIGURE_DIALOG_</TargetName>
+
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">_CONFIGURE_DIALOG_</TargetName>
+
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuild Include="configure_dialog._">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gbench.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gbench.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gbench.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gbench.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Configure solution : $(SolutionName)</Message>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/dll/build/gbench/UtilityProjects/configure._ b/c++/compilers/vs2015/dll/build/gbench/UtilityProjects/configure._
new file mode 100644
index 0000000..6be17e9
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/gbench/UtilityProjects/configure._
@@ -0,0 +1,5 @@
+set NCBI_CONFIG____ENABLEDUSERREQUESTS__NCBI-UNICODE=1
+set PTB_FLAGS= -dll
+set PTB_PROJECT_REQ=scripts\projects\ncbi_gbench.lst
+call "%BUILD_TREE_ROOT%\ptb.bat"
+if errorlevel 1 exit 1
diff --git a/c++/compilers/vs2015/dll/build/gbench/UtilityProjects/configure_dialog._ b/c++/compilers/vs2015/dll/build/gbench/UtilityProjects/configure_dialog._
new file mode 100644
index 0000000..b6f1b6c
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/gbench/UtilityProjects/configure_dialog._
@@ -0,0 +1,5 @@
+set NCBI_CONFIG____ENABLEDUSERREQUESTS__NCBI-UNICODE=1
+set PTB_FLAGS= -dll -cfg
+set PTB_PROJECT_REQ=scripts\projects\ncbi_gbench.lst
+call "%BUILD_TREE_ROOT%\ptb.bat"
+if errorlevel 1 exit 1
diff --git a/c++/compilers/vs2015/dll/build/gbench/configure_prebuild.bat b/c++/compilers/vs2015/dll/build/gbench/configure_prebuild.bat
new file mode 100644
index 0000000..5b68e06
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/gbench/configure_prebuild.bat
@@ -0,0 +1,48 @@
+ at echo off
+REM $Id: configure_prebuild.bat 492989 2016-02-23 17:05:09Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Andrei Gourianov
+REM
+REM This script is called by compilers/msvcNNN_prj/ptb.bat
+REM when building CONFIGURE project, before performing any meaningful actions.
+REM
+REM So, this is a good place to put any custom PRE-BUILD operations.
+REM For example, set environment variables.
+REM
+REM ===========================================================================
+
+set initial_dir=%CD%
+set script_name=%~nx0
+cd %~dp0
+for /f "delims=" %%a in ('cd') do (set script_dir=%%a)
+cd %initial_dir%
+
+set cfgs=project_tree_builder.ini.custom
+
+set NCBI_CONFIG____ENABLEDUSERREQUESTS__NCBI-UNICODE=
+if not exist "%script_dir%\%cfgs%" (
+  set NCBI_CONFIG____ENABLEDUSERREQUESTS__NCBI-UNICODE=1
+)
diff --git a/c++/compilers/vs2015/dll/build/gbench/gbench_install/gbench-install.vcxproj b/c++/compilers/vs2015/dll/build/gbench/gbench_install/gbench-install.vcxproj
new file mode 100644
index 0000000..bb816ca
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/gbench/gbench_install/gbench-install.vcxproj
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugDLL|Win32">
+      <Configuration>Unicode_DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugDLL|x64">
+      <Configuration>Unicode_DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseDLL|Win32">
+      <Configuration>Unicode_ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseDLL|x64">
+      <Configuration>Unicode_ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugDLL|Win32">
+      <Configuration>VTune_DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugDLL|x64">
+      <Configuration>VTune_DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseDLL|Win32">
+      <Configuration>VTune_ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseDLL|x64">
+      <Configuration>VTune_ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{6C23686B-1522-4B44-8D48-7E3176C36247}</ProjectGuid>
+    <RootNamespace>gbench-install</RootNamespace>
+    <Keyword>MakeFileProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">DebugDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">DebugDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">DebugDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">DebugDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ReleaseDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ReleaseDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ReleaseDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ReleaseDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">Unicode_DebugDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">Unicode_DebugDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">Unicode_DebugDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">Unicode_DebugDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">Unicode_ReleaseDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">Unicode_ReleaseDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">Unicode_ReleaseDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">Unicode_ReleaseDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">VTune_DebugDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">VTune_DebugDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">VTune_DebugDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">VTune_DebugDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">VTune_ReleaseDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">VTune_ReleaseDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">VTune_ReleaseDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">VTune_ReleaseDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak all IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">gbench-install.exe</NMakeOutput>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="..\..\..\..\..\..\src\app\gbench\gbench_install\gbench_install.win32.mak" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/c++/compilers/vs2015/dll/build/gbench/ncbi_gbench.sln b/c++/compilers/vs2015/dll/build/gbench/ncbi_gbench.sln
new file mode 100644
index 0000000..9513fb0
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/gbench/ncbi_gbench.sln
@@ -0,0 +1,35 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_DIALOG_", "UtilityProjects\_CONFIGURE_DIALOG_.vcxproj", "{6DEFDB58-C014-4026-A166-299146BD9947}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		DebugDLL|x64 = DebugDLL|x64
+		DebugDLL|x86 = DebugDLL|x86
+		ReleaseDLL|x64 = ReleaseDLL|x64
+		ReleaseDLL|x86 = ReleaseDLL|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{6DEFDB58-C014-4026-A166-299146BD9947}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{6DEFDB58-C014-4026-A166-299146BD9947}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{6DEFDB58-C014-4026-A166-299146BD9947}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{6DEFDB58-C014-4026-A166-299146BD9947}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{6DEFDB58-C014-4026-A166-299146BD9947}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{6DEFDB58-C014-4026-A166-299146BD9947}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{6DEFDB58-C014-4026-A166-299146BD9947}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{6DEFDB58-C014-4026-A166-299146BD9947}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA58}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/c++/compilers/vs2015/dll/build/gui/UtilityProjects/_CONFIGURE_.vcxproj b/c++/compilers/vs2015/dll/build/gui/UtilityProjects/_CONFIGURE_.vcxproj
new file mode 100644
index 0000000..0804bcb
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/gui/UtilityProjects/_CONFIGURE_.vcxproj
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>_CONFIGURE_</ProjectName>
+    <ProjectGuid>{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}</ProjectGuid>
+    <RootNamespace>MasterProject</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">_CONFIGURE_</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuild Include="configure._">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Configure solution : $(SolutionName)</Message>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/dll/build/gui/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj b/c++/compilers/vs2015/dll/build/gui/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj
new file mode 100644
index 0000000..4d2da5b
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/gui/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>_CONFIGURE_DIALOG_</ProjectName>
+    <ProjectGuid>{9BAE6EEC-8C80-44F0-84A9-3379631A8654}</ProjectGuid>
+    <RootNamespace>MasterProject</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">_CONFIGURE_DIALOG_</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuild Include="configure_dialog._">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui_dll.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Configure solution : $(SolutionName)</Message>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/dll/build/gui/UtilityProjects/configure._ b/c++/compilers/vs2015/dll/build/gui/UtilityProjects/configure._
new file mode 100644
index 0000000..b86cc7e
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/gui/UtilityProjects/configure._
@@ -0,0 +1,4 @@
+set PTB_FLAGS= -dll
+set PTB_PROJECT_REQ=scripts\projects\ncbi_gui.lst
+call "%BUILD_TREE_ROOT%\ptb.bat"
+if errorlevel 1 exit 1
diff --git a/c++/compilers/vs2015/dll/build/gui/UtilityProjects/configure_dialog._ b/c++/compilers/vs2015/dll/build/gui/UtilityProjects/configure_dialog._
new file mode 100644
index 0000000..78a9181
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/gui/UtilityProjects/configure_dialog._
@@ -0,0 +1,4 @@
+set PTB_FLAGS= -dll -cfg
+set PTB_PROJECT_REQ=scripts\projects\ncbi_gui.lst
+call "%BUILD_TREE_ROOT%\ptb.bat"
+if errorlevel 1 exit 1
diff --git a/c++/compilers/vs2015/dll/build/gui/ncbi_gui_dll.sln b/c++/compilers/vs2015/dll/build/gui/ncbi_gui_dll.sln
new file mode 100644
index 0000000..3ec883f
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/gui/ncbi_gui_dll.sln
@@ -0,0 +1,35 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_DIALOG_", "UtilityProjects\_CONFIGURE_DIALOG_.vcxproj", "{9BAE6EEC-8C80-44F0-84A9-3379631A8654}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		DebugDLL|x64 = DebugDLL|x64
+		DebugDLL|x86 = DebugDLL|x86
+		ReleaseDLL|x64 = ReleaseDLL|x64
+		ReleaseDLL|x86 = ReleaseDLL|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{9BAE6EEC-8C80-44F0-84A9-3379631A8654}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA56}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/c++/compilers/vs2015/dll/build/internal/gbench/gbench_install_internal/gbench-install-internal.vcxproj b/c++/compilers/vs2015/dll/build/internal/gbench/gbench_install_internal/gbench-install-internal.vcxproj
new file mode 100644
index 0000000..7d3fdd3
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/internal/gbench/gbench_install_internal/gbench-install-internal.vcxproj
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugDLL|Win32">
+      <Configuration>Unicode_DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugDLL|x64">
+      <Configuration>Unicode_DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseDLL|Win32">
+      <Configuration>Unicode_ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseDLL|x64">
+      <Configuration>Unicode_ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugDLL|Win32">
+      <Configuration>VTune_DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugDLL|x64">
+      <Configuration>VTune_DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseDLL|Win32">
+      <Configuration>VTune_ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseDLL|x64">
+      <Configuration>VTune_ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{6C23686B-1522-4B44-8D48-7E3176C36248}</ProjectGuid>
+    <RootNamespace>gbench-install</RootNamespace>
+    <Keyword>MakeFileProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">DebugDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">DebugDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">DebugDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">DebugDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ReleaseDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ReleaseDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ReleaseDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ReleaseDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">Unicode_DebugDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">Unicode_DebugDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">Unicode_DebugDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">Unicode_DebugDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">Unicode_ReleaseDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">Unicode_ReleaseDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">Unicode_ReleaseDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">Unicode_ReleaseDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">VTune_DebugDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">VTune_DebugDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">VTune_DebugDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">VTune_DebugDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">VTune_ReleaseDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">VTune_ReleaseDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">VTune_ReleaseDLL\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">VTune_ReleaseDLL\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak all IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f ..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">gbench-install.exe</NMakeOutput>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="..\..\..\..\..\..\..\src\internal\gbench\install\gbench_install_internal.win32.mak" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/c++/compilers/vs2015/dll/build/ncbi_cpp_dll.sln b/c++/compilers/vs2015/dll/build/ncbi_cpp_dll.sln
new file mode 100644
index 0000000..234c31c
--- /dev/null
+++ b/c++/compilers/vs2015/dll/build/ncbi_cpp_dll.sln
@@ -0,0 +1,35 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_DIALOG_", "UtilityProjects\_CONFIGURE_DIALOG_.vcxproj", "{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		DebugDLL|x64 = DebugDLL|x64
+		DebugDLL|x86 = DebugDLL|x86
+		ReleaseDLL|x64 = ReleaseDLL|x64
+		ReleaseDLL|x86 = ReleaseDLL|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{67EC51FA-3A0D-46B8-8F89-49EE209C8CB8}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAAC9}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/c++/compilers/vs2015/dll/dll_main.cpp b/c++/compilers/vs2015/dll/dll_main.cpp
new file mode 100644
index 0000000..7bd913f
--- /dev/null
+++ b/c++/compilers/vs2015/dll/dll_main.cpp
@@ -0,0 +1,18 @@
+
+#include <ncbi_pch.hpp>
+
+#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
+// Windows Header Files:
+#include <windows.h>
+
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+					 )
+{
+    return TRUE;
+}
+
+
+
+
diff --git a/c++/compilers/vs2015/dll/third_party_dll_install.mak b/c++/compilers/vs2015/dll/third_party_dll_install.mak
new file mode 100644
index 0000000..b008b71
--- /dev/null
+++ b/c++/compilers/vs2015/dll/third_party_dll_install.mak
@@ -0,0 +1,62 @@
+# $Id: third_party_dll_install.mak 492981 2016-02-23 16:27:34Z gouriano $
+#################################################################
+
+
+INSTALL          = .\bin
+INSTALL_BINPATH  = $(INSTALL)\$(INTDIR)
+THIRDPARTY_MAKEFILES_DIR =  .
+
+
+META_MAKE = $(THIRDPARTY_MAKEFILES_DIR)\..\third_party_install.meta.mk
+!IF EXIST($(META_MAKE))
+!INCLUDE $(META_MAKE)
+!ELSE
+!ERROR  $(META_MAKE)  not found
+!ENDIF
+
+THIRD_PARTY_LIBS = \
+	install_berkeleydb \
+	install_gnutls     \
+	install_glew       \
+	install_lzo        \
+	install_mssql      \
+	install_mysql      \
+	install_openssl    \
+	install_sqlite     \
+	install_sqlite3    \
+	install_sybase     \
+	install_wxwidgets  \
+	install_wxwindows  \
+	install_xalan      \
+	install_xerces     \
+	install_libxml     \
+	install_libxslt    \
+	install_vdb
+
+CLEAN_THIRD_PARTY_LIBS = \
+	clean_berkeleydb \
+	clean_gnutls     \
+	clean_glew       \
+	clean_lzo        \
+	clean_mssql      \
+	clean_mysql      \
+	clean_openssl    \
+	clean_sqlite     \
+	clean_sqlite3    \
+	clean_sybase     \
+	clean_wxwidgets  \
+	clean_wxwindows  \
+	clean_xalan      \
+	clean_xerces     \
+	clean_libxml     \
+	clean_libxslt    \
+	clean_vdb
+
+all : dirs $(THIRD_PARTY_LIBS)
+
+clean : $(CLEAN_THIRD_PARTY_LIBS)
+
+rebuild : clean all
+
+dirs :
+    @if not exist $(INSTALL_BINPATH) (echo Creating directory $(INSTALL_BINPATH)... & mkdir $(INSTALL_BINPATH))
diff --git a/c++/compilers/vs2015/dll/third_party_dll_install.vcxproj b/c++/compilers/vs2015/dll/third_party_dll_install.vcxproj
new file mode 100644
index 0000000..fb0b465
--- /dev/null
+++ b/c++/compilers/vs2015/dll/third_party_dll_install.vcxproj
@@ -0,0 +1,433 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMT|Win32">
+      <Configuration>DebugMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMT|x64">
+      <Configuration>DebugMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseMT|Win32">
+      <Configuration>ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseMT|x64">
+      <Configuration>ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugDLL|Win32">
+      <Configuration>Unicode_DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugDLL|x64">
+      <Configuration>Unicode_DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugMT|Win32">
+      <Configuration>Unicode_DebugMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugMT|x64">
+      <Configuration>Unicode_DebugMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseDLL|Win32">
+      <Configuration>Unicode_ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseDLL|x64">
+      <Configuration>Unicode_ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseMT|Win32">
+      <Configuration>Unicode_ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseMT|x64">
+      <Configuration>Unicode_ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugDLL|Win32">
+      <Configuration>VTune_DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugDLL|x64">
+      <Configuration>VTune_DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugMT|Win32">
+      <Configuration>VTune_DebugMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugMT|x64">
+      <Configuration>VTune_DebugMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseDLL|Win32">
+      <Configuration>VTune_ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseDLL|x64">
+      <Configuration>VTune_ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseMT|Win32">
+      <Configuration>VTune_ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseMT|x64">
+      <Configuration>VTune_ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{9E4B5381-9B6C-4867-BF8A-F1AAA1FD580F}</ProjectGuid>
+    <Keyword>MakeFileProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">dlls-install.exe</NMakeOutput>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="third_party_dll_install.mak" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/c++/compilers/vs2015/dll/third_party_msvcdll_install.vcxproj b/c++/compilers/vs2015/dll/third_party_msvcdll_install.vcxproj
new file mode 100644
index 0000000..c7b2fc7
--- /dev/null
+++ b/c++/compilers/vs2015/dll/third_party_msvcdll_install.vcxproj
@@ -0,0 +1,433 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMT|Win32">
+      <Configuration>DebugMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMT|x64">
+      <Configuration>DebugMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseMT|Win32">
+      <Configuration>ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseMT|x64">
+      <Configuration>ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugDLL|Win32">
+      <Configuration>VTune_DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugDLL|x64">
+      <Configuration>VTune_DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugMT|Win32">
+      <Configuration>VTune_DebugMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugMT|x64">
+      <Configuration>VTune_DebugMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseDLL|Win32">
+      <Configuration>VTune_ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseDLL|x64">
+      <Configuration>VTune_ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseMT|Win32">
+      <Configuration>VTune_ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseMT|x64">
+      <Configuration>VTune_ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugDLL|Win32">
+      <Configuration>Unicode_DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugDLL|x64">
+      <Configuration>Unicode_DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugMT|Win32">
+      <Configuration>Unicode_DebugMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugMT|x64">
+      <Configuration>Unicode_DebugMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseDLL|Win32">
+      <Configuration>Unicode_ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseDLL|x64">
+      <Configuration>Unicode_ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseMT|Win32">
+      <Configuration>Unicode_ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseMT|x64">
+      <Configuration>Unicode_ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{9E4B5381-9B6C-4867-BF8A-F1AAA1FD581F}</ProjectGuid>
+    <Keyword>MakeFileProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_dll_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">dlls-install.exe</NMakeOutput>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="third_party_dll_install.mak" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/c++/compilers/vs2015/install.sh b/c++/compilers/vs2015/install.sh
new file mode 100644
index 0000000..0a891f6
--- /dev/null
+++ b/c++/compilers/vs2015/install.sh
@@ -0,0 +1,186 @@
+#! /bin/sh
+# $Id: install.sh 493164 2016-02-24 19:08:26Z ivanov $
+# Authors:  Denis Vakatov    (vakatov at ncbi.nlm.nih.gov)
+#           Anton Lavrentiev (lavr at ncbi.nlm.nih.gov)
+#
+# Deploy sources, headers, libraries and executables for the further use
+# by the "external" users' projects
+
+
+# Cmd.-line args  -- source and destination
+script="$0"
+builddir="$1"
+target="$2"
+compiler="${3:-vs2015}"
+
+# Real number of argument is 2.
+# The 3th argument do not used here (32|64-bit architecture),
+# but is needed for master installation script.
+if test -n "$4" ; then
+  echo "USAGE:  `basename $script` [build_dir] [install_dir]"
+fi
+
+
+error()
+{
+  echo "[`basename $script`] ERROR:  $1"
+  exit 1
+}
+
+
+makedir()
+{
+  test -d "$1"  ||  mkdir $2 "$1"  ||  error "Cannot create \"$1\""
+}
+
+
+echo "[`basename $script`] NCBI C++:  \"$builddir\" to \"$target\"..."
+
+
+# Derive the destination dirs
+docdir="$target"/doc
+scriptdir="$target"/scripts
+incdir="$target"/include
+srcdir="$target"/src
+libdir="$target"/lib
+bindir="$target"/bin
+cldir="$target"/compilers
+logdir="$target"/logs
+tmpdir="$target"/tmp
+
+
+install()
+{
+    test -d "$1"  ||  return;
+    makedir "$2" -p
+    tmp_cwd=`pwd`
+    cd "$1"
+    find . -type f |
+    grep -v '/\.svn/' > "$tmpdir"/flist
+    tar cf - -T "$tmpdir"/flist | (cd "$2" ; tar xf - )
+    cd "$tmp_cwd"
+}
+
+
+
+# Check
+test -d "$builddir"  ||  error "Absent build dir \"$builddir\""
+
+
+# Reset the public directory
+test -d "$target"  &&  find "$target" -type f -exec rm -f {} \; >/dev/null 2>&1
+makedir "$target" -p
+makedir "$tmpdir" -p
+
+
+# Documentation
+echo "[`basename $script`] Installing documentation..."
+install "$builddir/doc" "$docdir"
+
+# Scripts
+echo "[`basename $script`] Installing scripts..."
+install "$builddir/scripts" "$scriptdir"
+
+# Include dir
+echo "[`basename $script`] Installing include files..."
+install "$builddir/include" "$incdir"
+
+# Source dir
+echo "[`basename $script`] Installing source files..."
+install "$builddir/src" "$srcdir"
+
+# Build logs
+echo "[`basename $script`] Installing build logs..."
+install "$builddir/logs" "$logdir"
+
+rm -rf "$tmpdir"
+
+
+# Libraries
+echo "[`basename $script`] Installing libraries..."
+for i in 'Debug' 'Release' ; do
+  for j in '' 'DLL' ; do
+    for b in 'static' 'dll' ; do
+
+      if test -d "$builddir"/compilers/$compiler/$b/lib/$i$j ; then
+        makedir "$libdir/$b/$i$j" -p
+        cd "$builddir"/compilers/$compiler/$b/lib/$i$j
+        cp -p *.lib "$libdir/$b/$i$j"
+      fi
+      if test "$b"=='dll' ; then
+        if test -d "$builddir"/compilers/$compiler/$b/bin/$i$j ; then
+          makedir "$libdir/$b/$i$j" -p
+          cd "$builddir"/compilers/$compiler/$b/bin/$i$j
+          cp -p *.lib *.dll *.exp "$libdir/$b/$i$j"
+        fi
+      fi
+    done
+  done
+done
+
+
+# Executables
+echo "[`basename $script`] Installing executables..."
+makedir "$bindir" -p
+for i in 'DLL' '' ; do
+  if test -d "$builddir"/compilers/$compiler/static/bin/Release$i ; then
+    cd "$builddir"/compilers/$compiler/static/bin/Release$i
+    if ls *.exe >/dev/null 2>&1 ; then
+      cp -p *.exe *.dll *.exp *.manifest "$bindir"
+      break
+    fi
+  fi
+done
+
+
+# Install additional files (scripts and etc) into binary directory
+cp -p "$builddir"/src/app/blast/legacy_blast.pl "$bindir"
+
+
+# Gbench public installation
+echo "[`basename $script`] Installing Gbench..."
+for i in ReleaseDLL DebugDLL; do
+  if test -d "$builddir"/compilers/$compiler/dll/bin/"$i" ; then
+    cp -pr "$builddir"/compilers/$compiler/dll/bin/$i/gbench "$bindir"
+    break
+  fi
+done
+
+
+# Compiler dir (copy all .pdb and configurable files files for debug purposes)
+echo "[`basename $script`] Installing .pdb files..."
+makedir "$cldir" -p
+pdb_files=`find "$builddir/compilers/$compiler" -type f -a \( -name '*.pdb' -o  -name '*.c' -o  -name '*.cpp' \) 2>/dev/null`
+cd "$cldir"
+for pdb in $pdb_files ; do
+  # Do not copy .pdb for executable files to save space
+  exe=`echo $pdb | sed -e 's|\.pdb$|\.exe|'`
+  if test -x "$exe" ; then
+    continue
+  fi
+  rel_dir=`echo $pdb | sed -e "s|$builddir/compilers/||" -e 's|/[^/]*$||'`
+  makedir "$rel_dir" -p
+  cp -pr "$pdb" "$rel_dir"
+done
+
+
+# Compiler dir (other common stuff)
+makedir "$cldir"/$compiler/static -p
+makedir "$cldir"/$compiler/dll -p
+cp -p  "$builddir"/compilers/$compiler/*          "$cldir"/$compiler
+cp -p  "$builddir"/compilers/$compiler/static/*   "$cldir"/$compiler/static
+cp -p  "$builddir"/compilers/$compiler/dll/*      "$cldir"/$compiler/dll
+for b in 'static' 'dll' ; do
+  cp -pr "$builddir"/compilers/$compiler/$b/inc "$cldir"/$compiler/$b
+  for c in 'DebugMT' 'ReleaseMT' 'DebugDLL' 'ReleaseDLL'; do
+    cp -pr "$builddir"/compilers/$compiler/$b/$c "$cldir"/$compiler/$b
+  done 
+done 
+
+# Makefile.*.mk files
+find "$builddir/src" -type f -name 'Makefile.*.mk' -exec cp -pr {} "$srcdir"/build-system/ \;
+
+# Copy info files
+cp -p "$builddir"/*_info "$target"
+
+exit 0
diff --git a/c++/compilers/vs2015/lock_ptb_config.bat b/c++/compilers/vs2015/lock_ptb_config.bat
new file mode 100644
index 0000000..94da10d
--- /dev/null
+++ b/c++/compilers/vs2015/lock_ptb_config.bat
@@ -0,0 +1,94 @@
+ at echo off
+REM $Id: lock_ptb_config.bat 492980 2016-02-23 16:24:57Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Andrei Gourianov
+REM
+REM Check platform name and create a lock to prevent
+REM running more than one instance of project_tree_builder.exe at the same time.
+REM
+REM ===========================================================================
+
+set CFG_PLATFORM=__configured_platform
+set CFG_LIST=Win32 x64
+set PTB_RUNNING=__configure.lock
+
+if _%PTB_PLATFORM%==_ (
+  echo PTB_PLATFORM is undefined
+  goto return_error
+)
+if _%1%==_  goto report_usage
+if _%2%==_  goto report_usage
+set MSVC_PRJ=%~2%
+if %1%==ON  goto do_ON
+if %1%==OFF goto do_OFF
+
+
+:report_usage
+echo The script checks MSVC platform name and creates a lock to prevent
+echo running more than one -CONFIGURE- at the same time.
+echo Usage:
+echo    lock_ptb_config ON msvc_prj_folder, or
+echo    lock_ptb_config OFF msvc_prj_folder
+goto return_error
+
+:return_error
+exit /b 1
+
+:do_ON
+for %%c in ( %CFG_LIST% ) do (
+  if exist "%MSVC_PRJ%%CFG_PLATFORM%.%%c" (
+    if not %%c==%PTB_PLATFORM% (
+      echo ******************************************************************************
+      echo Requested platform %PTB_PLATFORM% does not match already configured %%c
+      echo If you believe it is not so, - delete '%MSVC_PRJ%%CFG_PLATFORM%.%%c' file
+      echo ******************************************************************************
+      goto return_error
+    )
+    goto do_ON_lock
+  )
+)
+echo %CFG_PLATFORM% > "%MSVC_PRJ%%CFG_PLATFORM%.%PTB_PLATFORM%"
+
+:do_ON_lock
+if exist "%MSVC_PRJ%%PTB_RUNNING%" (
+  echo ******************************************************************************
+  echo There is another CONFIGURE process running in this tree.
+  echo If you believe it is not so, - delete '%MSVC_PRJ%%PTB_RUNNING%' file
+  echo ******************************************************************************
+  goto return_error
+)
+echo ptb_running > "%MSVC_PRJ%%PTB_RUNNING%"
+goto done
+
+
+:do_OFF
+if exist "%MSVC_PRJ%%PTB_RUNNING%" (
+  del "%MSVC_PRJ%%PTB_RUNNING%"
+)
+goto done
+
+:done
+
diff --git a/c++/compilers/vs2015/make.bat b/c++/compilers/vs2015/make.bat
new file mode 100644
index 0000000..88352cd
--- /dev/null
+++ b/c++/compilers/vs2015/make.bat
@@ -0,0 +1,223 @@
+ at ECHO OFF
+REM $Id: make.bat 509501 2016-08-05 19:08:31Z fukanchi $
+REM ===========================================================================
+REM
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM
+REM  Please cite the author in any work or product based on this material.
+REM
+REM ===========================================================================
+REM
+REM Author:  Vladimir Ivanov
+REM
+REM Configure/build/check NCBI C++ tree in specified configuration(s)
+REM
+REM     make.bat <configure|build|make|check> <solution> <static|dll> <32|64> [cfgs..]
+REM
+REM     %1% - Configure, build, make (configure and build_ or check build tree.
+REM     %2% - Solution file name without extention (relative path from build directory).
+REM     %3% - Type of used libraries (static, dll).
+REM     %4% - 32/64-bits architerture.
+REM     %5% - Configuration name(s)
+REM           (DebugDLL, DebugMT, ReleaseDLL, ReleaseMT, Unicode_*).
+REM           By default (if not specified) build DebugDLL and ReleaseDLL only.
+REM     ... - Options (--with-openmp)
+REM
+REM ===========================================================================
+
+
+
+rem --- Configuration
+
+set compiler=vs2015
+set default_cfgs=ReleaseDLL DebugDLL
+
+rem Always configure with additional Unicode configurations
+if _%SRV_NAME% == _ set SRV_NAME=%COMPUTERNAME%
+
+call msvcvars.bat > NUL
+
+
+rem --- Required parameters
+
+set cmd=%~1%
+set solution=%~2
+set libdll=%~3
+set arch=%~4
+
+set archw=Win32
+set archwc=x86
+if _%arch%_ == _64_  set archw=x64
+if _%arch%_ == _64_  set archwc=x64
+
+shift
+shift
+shift
+shift
+
+if "%cmd%"      == ""  goto NOARGS
+if "%solution%" == ""  goto USAGE
+if "%libdll%"   == ""  goto USAGE
+if "%arch%"     == ""  goto USAGE
+
+goto PARSEARGS
+
+
+rem --------------------------------------------------------------------------------
+:NOARGS
+
+if exist configure_make.bat (
+   configure_make.bat
+) else (
+   goto USAGE
+)
+
+:USAGE
+
+echo FATAL: Invalid parameters. See script description.
+echo FATAL: Passed arguments: %*
+goto ABORT
+
+
+
+rem --------------------------------------------------------------------------------
+rem Parse arguments
+:PARSEARGS
+
+set with_openmp=
+set cfgs=
+set unknown=
+
+:PARSEARGSLOOP
+if "%1" == "" goto ENDPARSEARGS
+if "%1" == "--with-openmp"       (set with_openmp=%1 & goto CONTINUEPARSEARGS)
+if "%1" == "DebugDLL"            (set cfgs=%cfgs% %1 & goto CONTINUEPARSEARGS)
+if "%1" == "DebugMT"             (set cfgs=%cfgs% %1 & goto CONTINUEPARSEARGS)
+if "%1" == "ReleaseDLL"          (set cfgs=%cfgs% %1 & goto CONTINUEPARSEARGS)
+if "%1" == "ReleaseMT"           (set cfgs=%cfgs% %1 & goto CONTINUEPARSEARGS)
+if "%1" == "Unicode_DebugDLL"    (set cfgs=%cfgs% %1 & goto CONTINUEPARSEARGS)
+if "%1" == "Unicode_DebugMT"     (set cfgs=%cfgs% %1 & goto CONTINUEPARSEARGS)
+if "%1" == "Unicode_ReleaseDLL"  (set cfgs=%cfgs% %1 & goto CONTINUEPARSEARGS) 
+if "%1" == "Unicode_ReleaseMT"   (set cfgs=%cfgs% %1 & goto CONTINUEPARSEARGS)
+set unknown=%unknown% %1
+:CONTINUEPARSEARGS
+shift
+goto PARSEARGSLOOP
+
+:ENDPARSEARGS
+
+if not "%unknown%" == "" (
+   echo FATAL: Unknown configuration names or options specified:%unknown%.
+   echo %cmd%
+   goto ABORT
+)
+
+if "%cfgs%" == "" set cfgs=%default_cfgs%
+
+rem -- Check command
+
+if _%cmd% == _configure goto CONFIG
+if _%cmd% == _make      goto CONFIG
+if _%cmd% == _build     goto CFGLOOP
+if _%cmd% == _check     goto CFGLOOP
+echo FATAL: Unknown action name %cmd%. Please correct.
+echo The following action names are recognized: configure, build, make, check.
+goto ABORT
+
+
+rem --------------------------------------------------------------------------------
+rem Configure: always use ReleaseDLL
+:CONFIG
+
+rem --- Process options
+if not "%with_openmp%" == "" (
+   echo INFO: Ebable OpenMP.
+   bash -c "./build_util.sh %with_openmp%; exit $?"
+   if errorlevel 1 goto ABORT
+)
+
+time /t
+echo INFO: Configure "%libdll%\%solution% [ReleaseDLL|%arch%]"
+%DEVENV% %libdll%\build\%solution%.sln /build "ReleaseDLL|%archwc%" /project "_CONFIGURE_"
+if errorlevel 1 goto ABORT
+if not _%cmd% == _make goto COMPLETE
+
+
+rem --------------------------------------------------------------------------------
+rem Process all configurations
+:CFGLOOP
+
+for %%c in (%cfgs%) do (
+   time /t
+   if _%cmd% == _build (
+      call :build %%c
+   )
+   if _%cmd% == _check (
+      call :check %%c
+   )
+   if _%cmd% == _make (
+      call :build %%c
+      if errorlevel 1 goto ABORT
+      call :check %%c
+   )
+   if errorlevel 1 goto ABORT
+)
+goto COMPLETE
+
+
+rem --------------------------------------------------------------------------------
+rem Subroutines
+
+:build
+   echo INFO: Building "%libdll%\%solution% [%1|%arch%]"
+   %DEVENV% %libdll%\build\%solution%.sln /build "%1|%archw%" /project "_BUILD_ALL_"
+   exit /b %errorlevel%
+
+:check
+   echo INFO: Checking init
+   bash -c "../../scripts/common/check/check_make_win_cfg.sh init; exit $?"
+   set err=0
+   echo INFO: Create check script for "%libdll%\%solution% [%1|%arch%]"
+   bash -c "../../scripts/common/check/check_make_win_cfg.sh create %solution% %libdll% %1; exit $?"
+   if errorlevel 1 exit /b %errorlevel%
+   echo INFO: Checking "%libdll%\%solution% [%1|%arch%]"
+   SET CHECKSH=%libdll%/build/%solution%.check/%1/check.sh
+   bash -c "%CHECKSH% run; exit $?"
+   if errorlevel 1 set err=1
+   bash -c "cp %CHECKSH%.journal check.sh.%libdll%_%1.journal; cp %CHECKSH%.log check.sh.%libdll%_%1.log"
+   rem Load testsuite results into DB works only if NCBI_AUTOMATED_BUILD is set to 1
+   if _%NCBI_AUTOMATED_BUILD% == _1 (
+      bash -c "%CHECKSH% load_to_db; exit $?"
+      if errorlevel 1 set err=1
+   )
+   copy /y /b check.sh.*.journal check.sh.journal
+   copy /y /b check.sh.*.log     check.sh.log
+   exit /b %err%
+
+
+rem --------------------------------------------------------------------------------
+
+:ABORT
+echo INFO: %cmd% failed.
+exit /b 1
+
+:COMPLETE
+echo INFO: %cmd% complete.
+exit /b 0
+
diff --git a/c++/compilers/vs2015/make_ncbi.bat b/c++/compilers/vs2015/make_ncbi.bat
new file mode 100644
index 0000000..745ee5b
--- /dev/null
+++ b/c++/compilers/vs2015/make_ncbi.bat
@@ -0,0 +1,60 @@
+ at ECHO OFF
+REM $Id: make_ncbi.bat 492980 2016-02-23 16:24:57Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Vladimir Ivanov
+REM
+REM Configure/build/check NCBI C++ core tree in specified configuration(s)
+REM
+REM     make_ncbi.bat <configure|build|make|check> <static|dll> <32|64> [cfgs..]
+REM
+REM     %1% - Configure, build, check or build and configure (make) build tree.
+REM     %2% - Type of used libraries (static, dll).
+REM     %3% - 32/64-bits architerture.
+REM     %4% - Configuration name(s)
+REM           (DEFAULT, DebugDLL, DebugMT, ReleaseDLL, ReleaseMT, Unicode_*).
+REM           By default build DebugDLL and ReleaseDLL only.
+REM     ... - Options (--with-openmp)
+REM
+REM ===========================================================================
+
+
+set cmd=%~1
+set libdll=%~2
+set arch=%~3
+
+shift
+shift
+shift
+
+goto:%libdll% 2>NUL
+
+:static
+ at call make.bat %cmd% ncbi_cpp     %libdll% %arch% %1 %2 %3 %4 %5 %6 %7 %8 %9
+exit %ERRORLEVEL%
+
+:dll
+ at call make.bat %cmd% ncbi_cpp_dll %libdll% %arch% %1 %2 %3 %4 %5 %6 %7 %8 %9
+exit %ERRORLEVEL%
diff --git a/c++/compilers/vs2015/msvcvars.bat b/c++/compilers/vs2015/msvcvars.bat
new file mode 100644
index 0000000..d1729c5
--- /dev/null
+++ b/c++/compilers/vs2015/msvcvars.bat
@@ -0,0 +1,14 @@
+ at echo off
+REM
+REM $Id: msvcvars.bat 492980 2016-02-23 16:24:57Z gouriano $
+REM
+
+ at if not "%VSINSTALLDIR%"=="" goto devenv
+ at call "%VS140COMNTOOLS%vsvars32.bat"
+
+:devenv
+
+if exist "%VS140COMNTOOLS%..\IDE\VCExpress.*" set DEVENV="%VS140COMNTOOLS%..\IDE\VCExpress"
+if exist "%VS140COMNTOOLS%..\IDE\devenv.*" set DEVENV="%VS140COMNTOOLS%..\IDE\devenv"
+
+:end
diff --git a/c++/compilers/vs2015/ncbi.rc b/c++/compilers/vs2015/ncbi.rc
new file mode 100644
index 0000000..9bcbca1
--- /dev/null
+++ b/c++/compilers/vs2015/ncbi.rc
@@ -0,0 +1 @@
+ncbilogo ICON "ncbilogo.ico"
diff --git a/c++/compilers/vs2015/ncbilogo.ico b/c++/compilers/vs2015/ncbilogo.ico
new file mode 100644
index 0000000..44e71d4
Binary files /dev/null and b/c++/compilers/vs2015/ncbilogo.ico differ
diff --git a/c++/compilers/vs2015/ptb.bat b/c++/compilers/vs2015/ptb.bat
new file mode 100644
index 0000000..42dbd49
--- /dev/null
+++ b/c++/compilers/vs2015/ptb.bat
@@ -0,0 +1,288 @@
+ at echo off
+REM $Id: ptb.bat 507295 2016-07-18 15:40:58Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Andrei Gourianov
+REM
+REM Run project_tree_builder.exe to generate MSVC solution and project files
+REM
+REM DO NOT ATTEMPT to run this bat file manually
+REM It should be run by CONFIGURE project only
+REM (open a solution and build or rebuild CONFIGURE project)
+REM
+REM ===========================================================================
+
+setlocal
+set DEFPTB_LOCATION=\\snowman\win-coremake\App\Ncbi\cppcore\ptb
+set IDE=1400
+set PTB_EXTRA=
+
+for %%v in ("%PTB_PATH%" "%SLN_PATH%" "%TREE_ROOT%" "%BUILD_TREE_ROOT%" "%PTB_PLATFORM%") do (
+  if %%v=="" (
+    echo ERROR: required environment variable is missing
+    echo DO NOT ATTEMPT to run this bat file manually
+    echo It should be run by CONFIGURE project only
+    exit /b 1
+  )
+)
+set PTBGUI="%TREE_ROOT%\src\build-system\project_tree_builder_gui\bin\ptbgui.jar"
+set DEFPTB_VERSION_FILE=%TREE_ROOT%\src\build-system\ptb_version.txt
+set PTB_INI=%TREE_ROOT%\src\build-system\project_tree_builder.ini
+set PTB_SLN=%BUILD_TREE_ROOT%\static\build\UtilityProjects\PTB.sln
+set NCBICONF_MSVC=%TREE_ROOT%\include\common\config\ncbiconf_msvc_site.h
+if exist "%NCBICONF_MSVC%" (
+  set NCBICONF_MSVC=
+)
+
+REM --- get solution dir ---
+call :XSLNPATH %SLN_PATH%
+goto DONE
+:XSLNPATH
+set SLN_DIR=%~dp1
+goto :eof
+:DONE
+REM --- call pre-configure script if it exists ---
+if exist "%SLN_DIR%configure_prebuild.bat" (
+  call "%SLN_DIR%configure_prebuild.bat"
+)
+
+call "%BUILD_TREE_ROOT%\msvcvars.bat"
+
+REM -------------------------------------------------------------------------
+REM get PTB version: from DEFPTB_VERSION_FILE  or from PREBUILT_PTB_EXE
+
+set DEFPTB_VERSION=
+if exist "%DEFPTB_VERSION_FILE%" (
+  for /f %%a in ('type "%DEFPTB_VERSION_FILE%"') do (set DEFPTB_VERSION=%%a& goto donedf)
+  :donedf
+  set DEFPTB_VERSION=%DEFPTB_VERSION: =%
+)
+if exist "%PREBUILT_PTB_EXE%" (
+  set ptbver=
+  for /f "tokens=2" %%a in ('"%PREBUILT_PTB_EXE%" -version') do (set ptbver=%%a& goto donepb)
+  :donepb
+  set ptbver=%ptbver: =%
+  if not "%DEFPTB_VERSION%"=="%ptbver%" (
+    echo WARNING: requested PTB version %ptbver% does not match default one: %DEFPTB_VERSION%
+    set DEFPTB_VERSION=%ptbver%
+  )
+)
+
+if "%DEFPTB_VERSION%"=="" (
+  echo ERROR: DEFPTB_VERSION not specified
+  exit /b 1
+)
+for /f "tokens=1-3 delims=." %%a in ('echo %DEFPTB_VERSION%') do (set PTB_VER=%%a%%b%%c& set PTB_VER_MAJOR=%%a)
+
+
+REM -------------------------------------------------------------------------
+REM See if we should and can use Java GUI
+
+set REQ_GUI_CFG=NO
+set USE_GUI_CFG=NO
+for /f "tokens=*" %%i in ('echo %PTB_FLAGS%') do call :PARSE %%i
+goto :endparse
+:PARSE
+if "%1"=="" goto :eof
+if "%1"=="-cfg" (set REQ_GUI_CFG=YES& goto :eof)
+shift
+goto :PARSE
+:endparse
+if "%REQ_GUI_CFG%"=="YES" (
+REM  if %PTB_VER_MAJOR% GEQ 2 (
+    if exist "%PTBGUI%" (
+      java -version >NUL 2>&1
+      if errorlevel 1 (
+        echo WARNING: Java not found, cannot run configuration GUI
+      ) else (
+        set USE_GUI_CFG=YES
+      )
+    ) else (
+      echo WARNING: "%PTBGUI%" not found
+    )
+REM  )
+)
+
+
+REM -------------------------------------------------------------------------
+REM See if we should and can use saved settings
+
+set PTB_SAVED_CFG=
+if not "%PTB_SAVED_CFG_REQ%"=="" (
+  if not exist "%PTB_SAVED_CFG_REQ%" (
+    echo ERROR: %PTB_SAVED_CFG_REQ% not found
+    exit /b 1
+  )
+  if %PTB_VER_MAJOR% GEQ 2 (
+    if %PTB_VER% GEQ 220 (
+      set PTB_SAVED_CFG=-args %PTB_SAVED_CFG_REQ%
+REM PTB will read PTB_PROJECT from the saved settings
+      set PTB_PROJECT_REQ=""
+    )
+  )
+)
+
+
+REM -------------------------------------------------------------------------
+REM Identify PTB_EXE
+
+if "%PREBUILT_PTB_EXE%"=="bootstrap" (
+  set DEF_PTB=%PTB_PATH%\project_tree_builder.exe
+) else if not "%PREBUILT_PTB_EXE%"=="" (
+  if exist "%PREBUILT_PTB_EXE%" (
+    set DEF_PTB=%PREBUILT_PTB_EXE%
+  ) else (
+    echo ERROR: "%PREBUILT_PTB_EXE%" not found
+    exit /b 1
+  )
+) else (
+REM  if %PTB_VER% GEQ 180 (
+    set DEF_PTB=%DEFPTB_LOCATION%\msvc\%DEFPTB_VERSION%\project_tree_builder.exe
+REM  ) else (
+REM    if "%PTB_PLATFORM%"=="x64" (
+REM      set DEF_PTB=%DEFPTB_LOCATION%\msvc9.64\%DEFPTB_VERSION%\project_tree_builder.exe
+REM    ) else (
+REM      set DEF_PTB=%DEFPTB_LOCATION%\msvc9\%DEFPTB_VERSION%\project_tree_builder.exe
+REM    )
+  )
+)
+if exist "%DEF_PTB%" (
+  set PTB_EXE=%DEF_PTB%
+) else (
+  echo project_tree_builder.exe not found at %DEF_PTB%
+  set PTB_EXE=%PTB_PATH%\project_tree_builder.exe
+)
+
+REM -------------------------------------------------------------------------
+REM Misc settings
+
+REM if %PTB_VER% GEQ 180 (
+  set PTB_EXTRA=%PTB_EXTRA% -ide %IDE% -arch %PTB_PLATFORM%
+REM )
+if not exist "%PTB_INI%" (
+  echo ERROR: "%PTB_INI%" not found
+  exit /b 1
+)
+set PTB_PROJECT_LST=
+if "%PTB_PROJECT%"=="" (
+  set PTB_PROJECT_LST=%PTB_PROJECT_REQ%
+) else (
+  set PTB_PROJECT_LST=%PTB_PROJECT%
+)
+
+
+REM -------------------------------------------------------------------------
+REM Build PTB_EXE if needed
+
+set NCBI_CONFIG__DIAG__POST_FILTER=!(807,9)
+if not exist "%PTB_EXE%" (
+  echo ******************************************************************************
+  echo Building project tree builder locally, please wait
+  echo ******************************************************************************
+  rem --- @echo msbuild "%BUILD_TREE_ROOT%\static\build\ncbi_cpp.sln" /t:"project_tree_builder_exe:Rebuild" /p:Configuration=ReleaseDLL;Platform=%PTB_PLATFORM% /maxcpucount:1
+  rem --- msbuild "%BUILD_TREE_ROOT%\static\build\ncbi_cpp.sln" /t:"project_tree_builder_exe:Rebuild" /p:Configuration=ReleaseDLL;Platform=%PTB_PLATFORM% /maxcpucount:1
+  if not "%NCBICONF_MSVC%"=="" (
+    echo // > "%NCBICONF_MSVC%"
+  )
+  if exist "%PTB_SLN%" (
+    @echo %DEVENV% "%PTB_SLN%" /rebuild "ReleaseDLL|%PTB_PLATFORM%" /project "project_tree_builder.exe"
+    %DEVENV% "%PTB_SLN%" /rebuild "ReleaseDLL|%PTB_PLATFORM%" /project "project_tree_builder.exe"
+  ) else (
+    @echo %DEVENV% "%BUILD_TREE_ROOT%\static\build\ncbi_cpp.sln" /rebuild "ReleaseDLL|%PTB_PLATFORM%" /project "project_tree_builder.exe"
+    %DEVENV% "%BUILD_TREE_ROOT%\static\build\ncbi_cpp.sln" /rebuild "ReleaseDLL|%PTB_PLATFORM%" /project "project_tree_builder.exe"
+  )
+  if not "%NCBICONF_MSVC%"=="" (
+    del "%NCBICONF_MSVC%"
+  )
+) else (
+  echo ******************************************************************************
+  echo Using PREBUILT project tree builder at %PTB_EXE%
+  echo ******************************************************************************
+)
+set NCBI_CONFIG__DIAG__POST_FILTER=
+
+if not exist "%PTB_EXE%" (
+  echo ERROR: "%PTB_EXE%" not found
+  exit /b 1
+)
+"%PTB_EXE%" -version
+if errorlevel 1 (
+  echo ERROR: cannot find working %PTB_EXE%
+  exit /b 1
+)
+
+
+REM -------------------------------------------------------------------------
+REM Run PTB_EXE
+
+call "%BUILD_TREE_ROOT%\lock_ptb_config.bat" ON "%BUILD_TREE_ROOT%\"
+if errorlevel 1 exit /b 1
+
+echo ******************************************************************************
+echo Running -CONFIGURE- please wait
+echo ******************************************************************************
+echo "%PTB_EXE%" %PTB_FLAGS% %PTB_EXTRA% %PTB_SAVED_CFG% -logfile "%SLN_PATH%_configuration_log.txt" -conffile "%PTB_INI%" "%TREE_ROOT%" %PTB_PROJECT_LST% "%SLN_PATH%"
+if "%USE_GUI_CFG%"=="YES" (
+  java -jar %PTBGUI% "%PTB_EXE%" -i %PTB_FLAGS% %PTB_EXTRA% %PTB_SAVED_CFG% -logfile "%SLN_PATH%_configuration_log.txt" -conffile "%PTB_INI%" "%TREE_ROOT%" %PTB_PROJECT_LST% "%SLN_PATH%"
+) else (
+  "%PTB_EXE%" %PTB_FLAGS% %PTB_EXTRA% %PTB_SAVED_CFG% -logfile "%SLN_PATH%_configuration_log.txt" -conffile "%PTB_INI%" "%TREE_ROOT%" %PTB_PROJECT_LST% "%SLN_PATH%"
+)
+if errorlevel 1 (set PTB_RESULT=1) else (set PTB_RESULT=0)
+
+call "%BUILD_TREE_ROOT%\lock_ptb_config.bat" OFF "%BUILD_TREE_ROOT%\"
+
+if "%PTB_RESULT%"=="1" (
+  echo ******************************************************************************
+  echo -CONFIGURE- has failed
+  echo Configuration log was saved at "file://%SLN_PATH%_configuration_log.txt"
+  echo ******************************************************************************
+  if exist "%SLN_PATH%_configuration_log.txt" (
+    if "%DIAG_SILENT_ABORT%"=="" start "" "%SLN_PATH%_configuration_log.txt"
+  )
+  exit /b 1
+) else (
+  echo ******************************************************************************
+  echo -CONFIGURE- has succeeded
+  echo Configuration log was saved at "file://%SLN_PATH%_configuration_log.txt"
+  echo ******************************************************************************
+)
+
+set ALLOBJ="_generate_all_objects.dataspec"
+type "%SLN_PATH%" | %SystemRoot%\system32\find /C %ALLOBJ% >NUL 2>&1
+if not errorlevel 1 (
+  echo ******************************************************************************
+  echo ******************************************************************************
+  echo ==============  Generating objects source code.                 ==============
+  echo ==============  DO NOT RELOAD THE SOLUTION NOW!                 ============== 
+  echo ******************************************************************************
+  echo %DEVENV% "%SLN_PATH%" /build "ReleaseDLL|%PTB_PLATFORM%" /project %ALLOBJ%
+  %DEVENV% "%SLN_PATH%" /build "ReleaseDLL|%PTB_PLATFORM%" /project %ALLOBJ%
+)
+echo -
+echo -
+echo ******************************************************************************
+echo ==============  It is now safe to reload the solution:          ==============
+echo ==============  Please, close it and open again                 ============== 
+echo ******************************************************************************
diff --git a/c++/compilers/vs2015/static/build/UtilityProjects/PTB.sln b/c++/compilers/vs2015/static/build/UtilityProjects/PTB.sln
new file mode 100644
index 0000000..ae40085
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/UtilityProjects/PTB.sln
@@ -0,0 +1,79 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_DIALOG_", "_CONFIGURE_DIALOG_.vcxproj", "{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xncbi.lib", "..\corelib\xncbi.lib.vcxproj", "{1EDB6A26-ADB9-4591-B907-505E8D1A8157}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xser.lib", "..\serial\xser.lib.vcxproj", "{1F5BCB57-26A5-46C7-B87C-FA74072CF5F6}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xutil.lib", "..\util\xutil.lib.vcxproj", "{1DCE18CD-4A7E-43B8-B7AF-48972EFE51E7}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msbuild_dataobj.lib", "..\build-system\project_tree_builder\msbuild\msbuild_dataobj.lib.vcxproj", "{FCA4C590-AB16-40F4-8C05-C41EF2A0F2FB}"
+	ProjectSection(ProjectDependencies) = postProject
+		{BB57FAAE-2EFE-46A0-8157-8879C5AC76C9} = {BB57FAAE-2EFE-46A0-8157-8879C5AC76C9}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "datatool.exe", "..\serial\datatool\datatool.exe.vcxproj", "{BB57FAAE-2EFE-46A0-8157-8879C5AC76C9}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "project_tree_builder.exe", "..\build-system\project_tree_builder\project_tree_builder.exe.vcxproj", "{8D5B9C1E-5941-44F8-B017-25F6201E822B}"
+	ProjectSection(ProjectDependencies) = postProject
+		{BB57FAAE-2EFE-46A0-8157-8879C5AC76C9} = {BB57FAAE-2EFE-46A0-8157-8879C5AC76C9}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xregexp.lib", "..\util\xregexp\xregexp.lib.vcxproj", "{E46C5B0B-675C-4C37-B618-02608C379C67}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "regexp.lib", "..\util\regexp\regexp.lib.vcxproj", "{DFDE1494-ED69-4C4F-84D3-0D19DB1B424C}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		ReleaseDLL|Win32 = ReleaseDLL|Win32
+		ReleaseDLL|x64 = ReleaseDLL|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{1EDB6A26-ADB9-4591-B907-505E8D1A8157}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
+		{1EDB6A26-ADB9-4591-B907-505E8D1A8157}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{1EDB6A26-ADB9-4591-B907-505E8D1A8157}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{1EDB6A26-ADB9-4591-B907-505E8D1A8157}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{1F5BCB57-26A5-46C7-B87C-FA74072CF5F6}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
+		{1F5BCB57-26A5-46C7-B87C-FA74072CF5F6}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{1F5BCB57-26A5-46C7-B87C-FA74072CF5F6}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{1F5BCB57-26A5-46C7-B87C-FA74072CF5F6}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{1DCE18CD-4A7E-43B8-B7AF-48972EFE51E7}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
+		{1DCE18CD-4A7E-43B8-B7AF-48972EFE51E7}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{1DCE18CD-4A7E-43B8-B7AF-48972EFE51E7}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{1DCE18CD-4A7E-43B8-B7AF-48972EFE51E7}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{FCA4C590-AB16-40F4-8C05-C41EF2A0F2FB}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
+		{FCA4C590-AB16-40F4-8C05-C41EF2A0F2FB}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{FCA4C590-AB16-40F4-8C05-C41EF2A0F2FB}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{FCA4C590-AB16-40F4-8C05-C41EF2A0F2FB}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{BB57FAAE-2EFE-46A0-8157-8879C5AC76C9}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
+		{BB57FAAE-2EFE-46A0-8157-8879C5AC76C9}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{BB57FAAE-2EFE-46A0-8157-8879C5AC76C9}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{BB57FAAE-2EFE-46A0-8157-8879C5AC76C9}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8D5B9C1E-5941-44F8-B017-25F6201E822B}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
+		{8D5B9C1E-5941-44F8-B017-25F6201E822B}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{8D5B9C1E-5941-44F8-B017-25F6201E822B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8D5B9C1E-5941-44F8-B017-25F6201E822B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{E46C5B0B-675C-4C37-B618-02608C379C67}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
+		{E46C5B0B-675C-4C37-B618-02608C379C67}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{E46C5B0B-675C-4C37-B618-02608C379C67}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{E46C5B0B-675C-4C37-B618-02608C379C67}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{DFDE1494-ED69-4C4F-84D3-0D19DB1B424C}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
+		{DFDE1494-ED69-4C4F-84D3-0D19DB1B424C}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
+		{DFDE1494-ED69-4C4F-84D3-0D19DB1B424C}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{DFDE1494-ED69-4C4F-84D3-0D19DB1B424C}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/c++/compilers/vs2015/static/build/UtilityProjects/_CONFIGURE_.vcxproj b/c++/compilers/vs2015/static/build/UtilityProjects/_CONFIGURE_.vcxproj
new file mode 100644
index 0000000..bd6c758
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/UtilityProjects/_CONFIGURE_.vcxproj
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>_CONFIGURE_</ProjectName>
+    <ProjectGuid>{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}</ProjectGuid>
+    <RootNamespace>MasterProject</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">_CONFIGURE_</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuild Include="configure._">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Configure solution : $(SolutionName)</Message>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/static/build/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj b/c++/compilers/vs2015/static/build/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj
new file mode 100644
index 0000000..74fc097
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>_CONFIGURE_DIALOG_</ProjectName>
+    <ProjectGuid>{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}</ProjectGuid>
+    <RootNamespace>MasterProject</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">_CONFIGURE_DIALOG_</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuild Include="configure_dialog._">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_cpp.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Configure solution : $(SolutionName)</Message>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/static/build/UtilityProjects/configure._ b/c++/compilers/vs2015/static/build/UtilityProjects/configure._
new file mode 100644
index 0000000..49cbd64
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/UtilityProjects/configure._
@@ -0,0 +1,4 @@
+set PTB_FLAGS=
+set PTB_PROJECT_REQ=scripts\projects\ncbi_cpp.lst
+call "%BUILD_TREE_ROOT%\ptb.bat"
+if errorlevel 1 exit 1
diff --git a/c++/compilers/vs2015/static/build/UtilityProjects/configure_dialog._ b/c++/compilers/vs2015/static/build/UtilityProjects/configure_dialog._
new file mode 100644
index 0000000..cdd8acd
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/UtilityProjects/configure_dialog._
@@ -0,0 +1,4 @@
+set PTB_FLAGS= -cfg
+set PTB_PROJECT_REQ=scripts\projects\ncbi_cpp.lst
+call "%BUILD_TREE_ROOT%\ptb.bat"
+if errorlevel 1 exit 1
diff --git a/c++/compilers/vs2015/static/build/all.bat b/c++/compilers/vs2015/static/build/all.bat
new file mode 100644
index 0000000..5e748b5
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/all.bat
@@ -0,0 +1,39 @@
+ at ECHO OFF
+REM $Id: all.bat 493022 2016-02-23 18:18:54Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Vladimir Ivanov
+REM
+REM Build all C++ Toolkit STATIC projects
+REM
+REM ===========================================================================
+
+
+CALL all_ncbi.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
+IF ERRORLEVEL 1 GOTO _ABORT_
+
+CALL all_gui.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
+
+:_ABORT_
\ No newline at end of file
diff --git a/c++/compilers/vs2015/static/build/all_gui.bat b/c++/compilers/vs2015/static/build/all_gui.bat
new file mode 100644
index 0000000..4881c6a
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/all_gui.bat
@@ -0,0 +1,79 @@
+ at ECHO OFF
+REM $Id: all_gui.bat 493022 2016-02-23 18:18:54Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Anton Lavrentiev
+REM
+REM Build NCBI C++ GUI core libraries, tests and samples
+REM
+REM ===========================================================================
+
+call "..\..\msvcvars.bat"
+
+IF _%1% == _    GOTO BUILDALL
+IF _%1% == _ALL GOTO BUILDALL
+GOTO CONFIG
+
+:BUILDALL
+CALL %0 DebugDLL ReleaseDLL
+GOTO EXIT
+
+:CONFIG
+TIME /T
+ECHO INFO: Configure "static\gui"
+msbuild gui\ncbi_gui.sln /t:"_CONFIGURE_:Rebuild" /p:Configuration=ReleaseDLL
+IF ERRORLEVEL 1 GOTO ABORT
+
+SET CFG=%1%
+
+:ARGLOOP
+IF %CFG% == DebugMT GOTO CONTINUE
+IF %CFG% == DebugDLL GOTO CONTINUE
+IF %CFG% == ReleaseMT GOTO CONTINUE
+IF %CFG% == ReleaseDLL GOTO CONTINUE
+ECHO INFO: The following configuration names are recognized:
+ECHO       DebugMT DebugDLL ReleaseMT ReleaseDLL
+ECHO FATAL: Unknown configuration name %CFG%. Please correct.
+GOTO EXIT
+
+:CONTINUE
+TIME /T
+ECHO INFO: Building "static\gui\%CFG%"
+msbuild gui\ncbi_gui.sln /t:"_BUILD_ALL_" /p:Configuration=%CFG%
+REM vcbuild /M2 /time gui\ncbi_gui.sln "%CFG%|Win32"
+IF ERRORLEVEL 1 GOTO ABORT
+
+SHIFT
+IF _%1% == _ GOTO COMPLETE
+SET CFG=%1%
+GOTO ARGLOOP
+
+:ABORT
+ECHO INFO: Build failed.
+GOTO EXIT
+:COMPLETE
+ECHO INFO: Build complete.
+:EXIT
+set CFG=
diff --git a/c++/compilers/vs2015/static/build/all_ncbi.bat b/c++/compilers/vs2015/static/build/all_ncbi.bat
new file mode 100644
index 0000000..b6259d2
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/all_ncbi.bat
@@ -0,0 +1,79 @@
+ at ECHO OFF
+REM $Id: all_ncbi.bat 493022 2016-02-23 18:18:54Z gouriano $
+REM ===========================================================================
+REM 
+REM                            PUBLIC DOMAIN NOTICE
+REM               National Center for Biotechnology Information
+REM 
+REM  This software/database is a "United States Government Work" under the
+REM  terms of the United States Copyright Act.  It was written as part of
+REM  the author's official duties as a United States Government employee and
+REM  thus cannot be copyrighted.  This software/database is freely available
+REM  to the public for use. The National Library of Medicine and the U.S.
+REM  Government have not placed any restriction on its use or reproduction.
+REM 
+REM  Although all reasonable efforts have been taken to ensure the accuracy
+REM  and reliability of the software and data, the NLM and the U.S.
+REM  Government do not and cannot warrant the performance or results that
+REM  may be obtained by using this software or data. The NLM and the U.S.
+REM  Government disclaim all warranties, express or implied, including
+REM  warranties of performance, merchantability or fitness for any particular
+REM  purpose.
+REM 
+REM  Please cite the author in any work or product based on this material.
+REM  
+REM ===========================================================================
+REM 
+REM Author:  Anton Lavrentiev
+REM
+REM Build NCBI C++ core libraries, tests and samples
+REM
+REM ===========================================================================
+
+call "..\..\msvcvars.bat"
+
+IF _%1% == _    GOTO BUILDALL
+IF _%1% == _ALL GOTO BUILDALL
+GOTO CONFIG
+
+:BUILDALL
+CALL %0 DebugDLL ReleaseDLL
+GOTO EXIT
+
+:CONFIG
+TIME /T
+ECHO INFO: Configure "static\ncbi"
+msbuild ncbi_cpp.sln /t:"_CONFIGURE_:Rebuild" /p:Configuration=ReleaseDLL
+IF ERRORLEVEL 1 GOTO ABORT
+
+SET CFG=%1%
+
+:ARGLOOP
+IF %CFG% == DebugMT GOTO CONTINUE
+IF %CFG% == DebugDLL GOTO CONTINUE
+IF %CFG% == ReleaseMT GOTO CONTINUE
+IF %CFG% == ReleaseDLL GOTO CONTINUE
+ECHO INFO: The following configuration names are recognized:
+ECHO       DebugMT DebugDLL ReleaseMT ReleaseDLL
+ECHO FATAL: Unknown configuration name %CFG%. Please correct.
+GOTO EXIT
+
+:CONTINUE
+TIME /T
+ECHO INFO: Building "static\ncbi\%CFG%"
+msbuild ncbi_cpp.sln /t:"_BUILD_ALL_" /p:Configuration=%CFG%
+REM vcbuild /M2 /time ncbi_cpp.sln "%CFG%|Win32"
+IF ERRORLEVEL 1 GOTO ABORT
+
+SHIFT
+IF _%1% == _ GOTO COMPLETE
+SET CFG=%1%
+GOTO ARGLOOP
+
+:ABORT
+ECHO INFO: Build failed.
+GOTO EXIT
+:COMPLETE
+ECHO INFO: Build complete.
+:EXIT
+set CFG=
diff --git a/c++/compilers/vs2015/static/build/build-system/project_tree_builder/msbuild/msbuild_dataobj.lib.vcxproj b/c++/compilers/vs2015/static/build/build-system/project_tree_builder/msbuild/msbuild_dataobj.lib.vcxproj
new file mode 100644
index 0000000..fa1d48a
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/build-system/project_tree_builder/msbuild/msbuild_dataobj.lib.vcxproj
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="14.0">
+  <PropertyGroup Label="Globals"><ProjectGuid>{FCA4C590-AB16-40F4-8C05-C41EF2A0F2FB}</ProjectGuid><Keyword>Win32Proj</Keyword><ProjectName>msbuild_dataobj.lib</ProjectName>
+  </PropertyGroup>
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration"><ConfigurationType>StaticLibrary</ConfigurationType><CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration"><ConfigurationType>StaticLibrary</ConfigurationType><CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
+  <ImportGroup Label="ExtensionSettings"></ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Label="LocalAppDataPlatform"/>
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Label="LocalAppDataPlatform"/>
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros"></PropertyGroup>
+  <PropertyGroup><_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+      <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">..\..\..\..\lib\$(Configuration)\</OutDir>
+      <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+      <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">msbuild_dataobj</TargetName>
+      <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">..\..\..\..\lib\$(Configuration)\</OutDir>
+      <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</IntDir>
+      <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">msbuild_dataobj</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\..\include\</AdditionalIncludeDirectories>
+      <AdditionalOptions/>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <BrowseInformation>false</BrowseInformation>
+      <BufferSecurityCheck>TRUE</BufferSecurityCheck>
+      <CallingConvention>Cdecl</CallingConvention>
+      <CompileAs>Default</CompileAs>
+      <DebugInformationFormat/>
+      <DisableSpecificWarnings/>
+      <EnableFunctionLevelLinking>TRUE</EnableFunctionLevelLinking>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <IgnoreStandardIncludePath>FALSE</IgnoreStandardIncludePath>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <MinimalRebuild>FALSE</MinimalRebuild>
+      <OmitFramePointers>TRUE</OmitFramePointers>
+      <Optimization>MaxSpeed</Optimization>
+      <PrecompiledHeader></PrecompiledHeader>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;</PreprocessorDefinitions>
+      <ProgramDataBaseFileName>$(IntDir)msbuild_dataobj.pdb</ProgramDataBaseFileName>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <RuntimeTypeInfo>TRUE</RuntimeTypeInfo>
+      <StringPooling>FALSE</StringPooling>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <UndefinePreprocessorDefinitions/>
+      <WarningLevel>Level3</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories/>
+      <AdditionalOptions/>
+      <IgnoreAllDefaultLibraries>FALSE</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries/>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+    </Lib>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories/>
+      <AdditionalOptions/>
+      <PreprocessorDefinitions/>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\..\include\</AdditionalIncludeDirectories>
+      <AdditionalOptions/>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <BrowseInformation>false</BrowseInformation>
+      <BufferSecurityCheck>TRUE</BufferSecurityCheck>
+      <CallingConvention>Cdecl</CallingConvention>
+      <CompileAs>Default</CompileAs>
+      <DebugInformationFormat/>
+      <DisableSpecificWarnings/>
+      <EnableFunctionLevelLinking>TRUE</EnableFunctionLevelLinking>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <IgnoreStandardIncludePath>FALSE</IgnoreStandardIncludePath>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <MinimalRebuild>FALSE</MinimalRebuild>
+      <OmitFramePointers>TRUE</OmitFramePointers>
+      <Optimization>MaxSpeed</Optimization>
+      <PrecompiledHeader></PrecompiledHeader>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;</PreprocessorDefinitions>
+      <ProgramDataBaseFileName>$(IntDir)msbuild_dataobj.pdb</ProgramDataBaseFileName>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <RuntimeTypeInfo>TRUE</RuntimeTypeInfo>
+      <StringPooling>FALSE</StringPooling>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <UndefinePreprocessorDefinitions/>
+      <WarningLevel>Level3</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <AdditionalLibraryDirectories/>
+      <AdditionalOptions/>
+      <IgnoreAllDefaultLibraries>FALSE</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries/>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+    </Lib>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories/>
+      <AdditionalOptions/>
+      <PreprocessorDefinitions/>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\..\..\..\src\build-system\project_tree_builder\msbuild\msbuild_dataobj__.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\..\src\build-system\project_tree_builder\msbuild\msbuild_dataobj___.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <CustomBuild Include="..\..\..\..\..\..\..\src\build-system\project_tree_builder\msbuild\msbuild_dataobj.xsd">
+      <FileType>Document</FileType>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Using datatool to create a C++ object from ASN/DTD/Schema %(FullPath)</Message>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set DATATOOL_PATH=$(ProjectDir)..\..\..\..\..\static\bin\ReleaseDLL&#xa;set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..\..&#xa;set PTB_PLATFORM=$(PlatformName)&#xa;set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..\..\..\vs2013&#xa;call "%BUILD_TREE_ROOT%\datatool.bat" -oex "" -pch ncbi_pch.hpp -m "%(FullPath)" -oA -oc "%(Filename)" -od "%(RootDir)%(Direct [...]
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(RootDir)%(Directory)%(Filename).def;</AdditionalInputs>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(RootDir)%(Directory)%(Filename).files;%(RootDir)%(Directory)%(Filename)__.cpp;%(RootDir)%(Directory)%(Filename)___.cpp</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Using datatool to create a C++ object from ASN/DTD/Schema %(FullPath)</Message>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set DATATOOL_PATH=$(ProjectDir)..\..\..\..\..\static\bin\ReleaseDLL&#xa;set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..\..&#xa;set PTB_PLATFORM=$(PlatformName)&#xa;set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..\..\..\vs2013&#xa;call "%BUILD_TREE_ROOT%\datatool.bat" -oex "" -pch ncbi_pch.hpp -m "%(FullPath)" -oA -oc "%(Filename)" -od "%(RootDir)%(Director [...]
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(RootDir)%(Directory)%(Filename).def;</AdditionalInputs>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(RootDir)%(Directory)%(Filename).files;%(RootDir)%(Directory)%(Filename)__.cpp;%(RootDir)%(Directory)%(Filename)___.cpp</Outputs>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
+  <ImportGroup Label="ExtensionTargets"></ImportGroup>
+</Project>
diff --git a/c++/compilers/vs2015/static/build/build-system/project_tree_builder/project_tree_builder.exe.vcxproj b/c++/compilers/vs2015/static/build/build-system/project_tree_builder/project_tree_builder.exe.vcxproj
new file mode 100644
index 0000000..cc11884
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/build-system/project_tree_builder/project_tree_builder.exe.vcxproj
@@ -0,0 +1,415 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{8D5B9C1E-5941-44F8-B017-25F6201E822B}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">..\..\..\bin\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">..\..\..\bin\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">false</LinkIncremental>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">project_tree_builder</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">project_tree_builder</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+    <PreBuildEvent>
+      <Command>%40echo EXPENDABLE project
+</Command>
+    </PreBuildEvent>
+    <ClCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_CONSOLE;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <ProgramDataBaseFileName>$(IntDir)project_tree_builder.pdb</ProgramDataBaseFileName>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CallingConvention>Cdecl</CallingConvention>
+      <CompileAs>Default</CompileAs>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+    </ClCompile>
+    <ResourceCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <Link>
+      <AdditionalOptions>ws2_32.lib dbghelp.lib %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)project_tree_builder.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <ImportLibrary>$(OutDir)project_tree_builder.lib</ImportLibrary>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <PreBuildEvent>
+      <Command>%40echo EXPENDABLE project
+</Command>
+    </PreBuildEvent>
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_CONSOLE;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <ProgramDataBaseFileName>$(IntDir)project_tree_builder.pdb</ProgramDataBaseFileName>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CallingConvention>Cdecl</CallingConvention>
+      <CompileAs>Default</CompileAs>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+    </ClCompile>
+    <ResourceCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <Link>
+      <AdditionalOptions>ws2_32.lib dbghelp.lib %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)project_tree_builder.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <ImportLibrary>$(OutDir)project_tree_builder.lib</ImportLibrary>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\configurable_file.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\file_contents.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc71_project__.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc71_project___.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_configure.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_configure_prj_generator.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_dlls_info.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_makefile.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_masterproject_generator.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_prj_files_collector.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_prj_generator.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_prj_utils.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_project_context.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_site.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_sln_generator.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_builder_app.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_datatool_generated_src.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_item.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_projects.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_src_resolver.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_tree.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_tree_builder.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_utils.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\ptb_gui.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\resolver.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\ptb_registry.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\configurable_file.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Configuration.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Configuration_.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Configurations.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Configurations_.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\File.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\File_.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\file_contents.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\FileConfiguration.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\FileConfiguration_.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Files.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Files_.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Filter.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Filter_.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc71_project__.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_configure.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_configure_prj_generator.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_dlls_info.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_dlls_info_utils.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_makefile.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_masterproject_generator.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_prj_defines.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_prj_files_collector.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_prj_generator.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_prj_utils.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_project_context.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_site.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_sln_generator.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_tools_implement.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc_traits.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Platform.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Platform_.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Platforms.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Platforms_.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_builder_app.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_datatool_generated_src.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_item.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_projects.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_src_resolver.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_tree.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_tree_builder.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\proj_utils.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\resolver.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\stl_msvc_usage.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Tool.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\Tool_.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\VisualStudioProject.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\VisualStudioProject_.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\src\build-system\project_tree_builder\ptb_gui.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="..\..\..\..\..\..\src\build-system\project_tree_builder\ptb_gui.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <CustomBuild Include="..\..\..\..\..\..\src\build-system\project_tree_builder\msvc71_project.dtd">
+<FileType>Document</FileType>
+<Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Using datatool to create a C++ object from ASN/DTD/Schema %(FullPath)</Message>
+<Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set DATATOOL_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL&#xa;set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..&#xa;set PTB_PLATFORM=$(PlatformName)&#xa;set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..\..\vs2013&#xa;call "%BUILD_TREE_ROOT%\datatool.bat" -oex "" -pch ncbi_pch.hpp -m "%(FullPath)" -oA -oc "%(Filename)" -od "%(RootDir)%(Directory)%(Filename) [...]
+<AdditionalInputs
+         Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(RootDir)%(Directory)%(Filename).def;</AdditionalInputs>
+<Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(RootDir)%(Directory)%(Filename).files;%(RootDir)%(Directory)%(Filename)__.cpp;%(RootDir)%(Directory)%(Filename)___.cpp</Outputs>
+
+<FileType>Document</FileType>
+<Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Using datatool to create a C++ object from ASN/DTD/Schema %(FullPath)</Message>
+<Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set DATATOOL_PATH=$(ProjectDir)..\..\..\..\static\bin\ReleaseDLL&#xa;set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..&#xa;set PTB_PLATFORM=$(PlatformName)&#xa;set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..\..\vs2013&#xa;call "%BUILD_TREE_ROOT%\datatool.bat" -oex "" -pch ncbi_pch.hpp -m "%(FullPath)" -oA -oc "%(Filename)" -od "%(RootDir)%(Directory)%(Filename).d [...]
+<AdditionalInputs
+         Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(RootDir)%(Directory)%(Filename).def;</AdditionalInputs>
+<Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(RootDir)%(Directory)%(Filename).files;%(RootDir)%(Directory)%(Filename)__.cpp;%(RootDir)%(Directory)%(Filename)___.cpp</Outputs>
+    </CustomBuild>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\corelib\xncbi.lib.vcxproj">
+      <Project>{1edb6a26-adb9-4591-b907-505e8d1a8157}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\serial\xser.lib.vcxproj">
+      <Project>{1f5bcb57-26a5-46c7-b87c-fa74072cf5f6}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\util\regexp\regexp.lib.vcxproj">
+      <Project>{dfde1494-ed69-4c4f-84d3-0d19db1b424c}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\util\xregexp\xregexp.lib.vcxproj">
+      <Project>{e46c5b0b-675c-4c37-b618-02608c379c67}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\util\xutil.lib.vcxproj">
+      <Project>{1dce18cd-4a7e-43b8-b7af-48972efe51e7}</Project>
+    </ProjectReference>
+    <ProjectReference Include="msbuild\msbuild_dataobj.lib.vcxproj">
+      <Project>{FCA4C590-AB16-40F4-8C05-C41EF2A0F2FB}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/static/build/corelib/xncbi.lib.vcxproj b/c++/compilers/vs2015/static/build/corelib/xncbi.lib.vcxproj
new file mode 100644
index 0000000..b6b136e
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/corelib/xncbi.lib.vcxproj
@@ -0,0 +1,509 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{1EDB6A26-ADB9-4591-B907-505E8D1A8157}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">..\..\lib\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">..\..\lib\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">xncbi</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">xncbi</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+    <ClCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <ProgramDataBaseFileName>$(IntDir)xncbi.pdb</ProgramDataBaseFileName>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CallingConvention>Cdecl</CallingConvention>
+      <CompileAs>Default</CompileAs>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+    </ClCompile>
+    <ResourceCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <ProgramDataBaseFileName>$(IntDir)xncbi.pdb</ProgramDataBaseFileName>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CallingConvention>Cdecl</CallingConvention>
+      <CompileAs>Default</CompileAs>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+    </ClCompile>
+    <ResourceCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ddumpable.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\env_reg.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\metareg.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbi_config.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbi_os_mswin.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbi_param.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbi_process.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbi_safe_static.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbi_system.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbiapp.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbiargs.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbiatomic.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbidbg.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbidiag.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbidiag_p.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbidll.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbienv.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbiexec.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbiexpt.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbifile.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbimempool.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbimtx.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbiobj.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbireg.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbistr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbistre.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbithr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbitime.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\obj_store.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\plugin_manager.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\plugin_manager_store.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\rwstreambuf.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\syslog.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\version.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\stream_utils.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbi_stack.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\request_ctx.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\request_control.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\expr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\guard.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbierror.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\blob_storage.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbi_signal.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbi_strings.c">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\resource_info.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\interprocess_lock.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbi_autoinit.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\perf_log.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbi_url.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbi_cookies.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\..\src\corelib\ncbicfg.c.in">
+      <FileType>Document</FileType>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">CompileAsC</CompileAs>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">CompileAsC</CompileAs>
+    </ClCompile>
+    <None Include="..\..\..\..\..\include\corelib\ncbidiag.inl" />
+    <None Include="..\..\..\..\..\include\corelib\ncbimtx.inl" />
+    <None Include="..\..\..\..\..\include\corelib\ncbiobj.inl" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\..\include\corelib\ddumpable.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\guard.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\metareg.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\mswin_export.h" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbi_bswap.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbi_config.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbi_limits.h" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbi_limits.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbi_os_mac.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbi_os_mswin.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbi_os_unix.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbi_param.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbi_process.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbi_safe_static.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbi_system.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbi_tree.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbiapp.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbiargs.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbiatomic.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbicfg.h" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbicntr.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbidbg.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbidiag.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbidll.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbienv.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbiexec.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbiexpt.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbifile.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbifloat.h" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbimisc.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbimtx.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbiobj.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbireg.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbistd.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbistl.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbistr.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbistre.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbithr.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbithr_conf.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbitime.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbitype.h" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\ncbiutil.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\obj_store.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\plugin_manager.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\plugin_manager_impl.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\plugin_manager_store.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\impl\rwstreambuf.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\syslog.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\test_mt.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\corelib\version.hpp" />
+    <ClInclude Include="..\..\..\..\..\src\corelib\ncbiargs_p.hpp" />
+    <ClInclude Include="..\..\..\..\..\src\corelib\ncbidbg_p.hpp" />
+    <ClInclude Include="..\..\..\..\..\src\corelib\ncbidiag_p.hpp" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/static/build/gui/UtilityProjects/_CONFIGURE_.vcxproj b/c++/compilers/vs2015/static/build/gui/UtilityProjects/_CONFIGURE_.vcxproj
new file mode 100644
index 0000000..8be3ea2
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/gui/UtilityProjects/_CONFIGURE_.vcxproj
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>_CONFIGURE_</ProjectName>
+    <ProjectGuid>{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}</ProjectGuid>
+    <RootNamespace>MasterProject</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">_CONFIGURE_</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuild Include="configure._">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Configure solution : $(SolutionName)</Message>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/static/build/gui/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj b/c++/compilers/vs2015/static/build/gui/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj
new file mode 100644
index 0000000..5c3eb4e
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/gui/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>_CONFIGURE_DIALOG_</ProjectName>
+    <ProjectGuid>{FDC9447A-C7F1-492D-B84F-D54A1E610F16}</ProjectGuid>
+    <RootNamespace>MasterProject</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">_CONFIGURE_DIALOG_</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuild Include="configure_dialog._">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_gui.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Configure solution : $(SolutionName)</Message>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/static/build/gui/UtilityProjects/configure._ b/c++/compilers/vs2015/static/build/gui/UtilityProjects/configure._
new file mode 100644
index 0000000..3589c55
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/gui/UtilityProjects/configure._
@@ -0,0 +1,4 @@
+set PTB_FLAGS=
+set PTB_PROJECT_REQ=scripts\projects\ncbi_gui.lst
+call "%BUILD_TREE_ROOT%\ptb.bat"
+if errorlevel 1 exit 1
diff --git a/c++/compilers/vs2015/static/build/gui/UtilityProjects/configure_dialog._ b/c++/compilers/vs2015/static/build/gui/UtilityProjects/configure_dialog._
new file mode 100644
index 0000000..4907743
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/gui/UtilityProjects/configure_dialog._
@@ -0,0 +1,4 @@
+set PTB_FLAGS= -cfg
+set PTB_PROJECT_REQ=scripts\projects\ncbi_gui.lst
+call "%BUILD_TREE_ROOT%\ptb.bat"
+if errorlevel 1 exit 1
diff --git a/c++/compilers/vs2015/static/build/gui/ncbi_gui.sln b/c++/compilers/vs2015/static/build/gui/ncbi_gui.sln
new file mode 100644
index 0000000..a4fd1fb
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/gui/ncbi_gui.sln
@@ -0,0 +1,35 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_DIALOG_", "UtilityProjects\_CONFIGURE_DIALOG_.vcxproj", "{FDC9447A-C7F1-492D-B84F-D54A1E610F16}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		DebugDLL|x64 = DebugDLL|x64
+		DebugDLL|x86 = DebugDLL|x86
+		ReleaseDLL|x64 = ReleaseDLL|x64
+		ReleaseDLL|x86 = ReleaseDLL|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{FDC9447A-C7F1-492D-B84F-D54A1E610F16}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAAA7E}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/c++/compilers/vs2015/static/build/ncbi_cpp.sln b/c++/compilers/vs2015/static/build/ncbi_cpp.sln
new file mode 100644
index 0000000..1b1eaec
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/ncbi_cpp.sln
@@ -0,0 +1,35 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_DIALOG_", "UtilityProjects\_CONFIGURE_DIALOG_.vcxproj", "{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		DebugDLL|x64 = DebugDLL|x64
+		DebugDLL|x86 = DebugDLL|x86
+		ReleaseDLL|x64 = ReleaseDLL|x64
+		ReleaseDLL|x86 = ReleaseDLL|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{E7DBEF6D-5DA9-4B0D-9375-C3F26659827B}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA105}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/c++/compilers/vs2015/static/build/serial/datatool/datatool.exe.vcxproj b/c++/compilers/vs2015/static/build/serial/datatool/datatool.exe.vcxproj
new file mode 100644
index 0000000..e1a2ba8
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/serial/datatool/datatool.exe.vcxproj
@@ -0,0 +1,506 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{BB57FAAE-2EFE-46A0-8157-8879C5AC76C9}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">..\..\..\bin\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">..\..\..\bin\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">false</LinkIncremental>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">datatool</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">datatool</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <ClCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_CONSOLE;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <ProgramDataBaseFileName>$(IntDir)datatool.pdb</ProgramDataBaseFileName>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CallingConvention>Cdecl</CallingConvention>
+      <CompileAs>Default</CompileAs>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+    </ClCompile>
+    <ResourceCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <Link>
+      <AdditionalOptions>ws2_32.lib dbghelp.lib %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)datatool.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <ImportLibrary>$(OutDir)datatool.lib</ImportLibrary>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_CONSOLE;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <ProgramDataBaseFileName>$(IntDir)datatool.pdb</ProgramDataBaseFileName>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CallingConvention>Cdecl</CallingConvention>
+      <CompileAs>Default</CompileAs>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+    </ClCompile>
+    <ResourceCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <Link>
+      <AdditionalOptions>ws2_32.lib dbghelp.lib %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)datatool.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <ImportLibrary>$(OutDir)datatool.lib</ImportLibrary>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\alexer.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\aliasstr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\aparser.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\blocktype.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\choiceptrstr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\choicestr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\choicetype.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\classstr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\code.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\comments.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\datatool.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\dtdaux.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\dtdlexer.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\dtdparser.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\enumstr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\enumtype.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\exceptions.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\filecode.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\fileutil.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\generate.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\lexer.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\mcontainer.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\module.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\moduleset.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\namespace.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\parser.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\ptrstr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\reftype.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\rpcgen.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\srcutil.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\statictype.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\stdstr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\stlstr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\type.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\typestr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\unitype.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\value.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\xsdlexer.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\xsdparser.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\wsdllexer.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\wsdlparser.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\wsdlstr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\traversal_code_generator.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\traversal_merger.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\traversal_node.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\traversal_pattern_match_callback.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\serial\datatool\traversal_spec_file_parser.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\alexer.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\aliasstr.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\aparser.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\atoken.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\blocktype.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\choiceptrstr.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\choicestr.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\choicetype.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\classctx.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\classstr.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\code.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\comments.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\datatool.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\dtdaux.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\dtdlexer.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\dtdparser.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\enumstr.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\enumtype.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\exceptions.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\filecode.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\fileutil.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\generate.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\lexer.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\mcontainer.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\module.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\moduleset.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\namespace.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\parser.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\ptrstr.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\reftype.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\rpcgen.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\srcutil.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\statictype.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\stdstr.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\stlstr.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\tokens.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\type.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\typestr.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\unitype.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\serial\datatool\value.hpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="..\..\..\..\ncbi.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\corelib\xncbi.lib.vcxproj">
+      <Project>{1edb6a26-adb9-4591-b907-505e8d1a8157}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\util\xutil.lib.vcxproj">
+      <Project>{1dce18cd-4a7e-43b8-b7af-48972efe51e7}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\xser.lib.vcxproj">
+      <Project>{1f5bcb57-26a5-46c7-b87c-fa74072cf5f6}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/static/build/serial/xser.lib.vcxproj b/c++/compilers/vs2015/static/build/serial/xser.lib.vcxproj
new file mode 100644
index 0000000..032a875
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/serial/xser.lib.vcxproj
@@ -0,0 +1,533 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{1F5BCB57-26A5-46C7-B87C-FA74072CF5F6}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">..\..\lib\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">..\..\lib\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">xser</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">xser</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <ClCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <ProgramDataBaseFileName>$(IntDir)xser.pdb</ProgramDataBaseFileName>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CallingConvention>Cdecl</CallingConvention>
+      <CompileAs>Default</CompileAs>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+    </ClCompile>
+    <ResourceCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <ProgramDataBaseFileName>$(IntDir)xser.pdb</ProgramDataBaseFileName>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CallingConvention>Cdecl</CallingConvention>
+      <CompileAs>Default</CompileAs>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+    </ClCompile>
+    <ResourceCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\..\src\serial\aliasinfo.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\autoptrinfo.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\choice.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\choiceptr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\classinfo.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\classinfob.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\continfo.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\delaybuf.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\enumerated.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\exception.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\hookdata.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\hookdatakey.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\item.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\iterator.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\member.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\memberid.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\memberlist.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objcopy.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objectinfo.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objectio.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objectiter.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objhook.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objistr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objistrasn.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objistrasnb.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objistrxml.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objlist.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objostr.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objostrasn.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objostrasnb.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objostrxml.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objostrjson.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objistrjson.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\objstack.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\pack_string.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\pathhook.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\ptrinfo.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\serial.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\serializable.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\serialobject.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\stdtypes.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\stltypes.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\typeinfo.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\typemap.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\typeref.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\serial\variant.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\..\include\serial\aliasinfo.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\asntypes.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\autoptrinfo.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\choice.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\choiceptr.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\classinfo.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\classinfob.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\classinfohelper.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\continfo.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\delaybuf.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\enumerated.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\enumvalues.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\exception.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\hookdata.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\hookdataimpl.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\hookdatakey.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\hookfunc.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\item.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\iterator.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\iteratorbase.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\member.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\memberid.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\memberlist.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objcopy.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\object.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objectinfo.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objectio.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objectiter.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objecttype.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objhook.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objistr.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objistrasn.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objistrasnb.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objistrimpl.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objistrxml.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objlist.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objostr.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objostrasn.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objostrasnb.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objostrxml.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objstack.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objstrasnb.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\objstrb.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\pack_string.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\pathhook.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\ptrinfo.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\rpcbase.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\serial.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\serialasn.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\serialasndef.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\serialbase.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\serialdef.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\serialimpl.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\serializable.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\serialutil.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\stdtypeinfo.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\stdtypes.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\stdtypesimpl.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\stltypes.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\stltypesimpl.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\timetypeinfo.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\typeinfo.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\typeinfoimpl.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\typemap.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\typemapimpl.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\typemapper.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\typeref.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\serial\variant.hpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\..\..\..\include\serial\choice.inl" />
+    <None Include="..\..\..\..\..\include\serial\classinfo.inl" />
+    <None Include="..\..\..\..\..\include\serial\classinfob.inl" />
+    <None Include="..\..\..\..\..\include\serial\continfo.inl" />
+    <None Include="..\..\..\..\..\include\serial\item.inl" />
+    <None Include="..\..\..\..\..\include\serial\iterator.inl" />
+    <None Include="..\..\..\..\..\include\serial\iteratorbase.inl" />
+    <None Include="..\..\..\..\..\include\serial\member.inl" />
+    <None Include="..\..\..\..\..\include\serial\memberid.inl" />
+    <None Include="..\..\..\..\..\include\serial\memberlist.inl" />
+    <None Include="..\..\..\..\..\include\serial\objcopy.inl" />
+    <None Include="..\..\..\..\..\include\serial\object.inl" />
+    <None Include="..\..\..\..\..\include\serial\objectinfo.inl" />
+    <None Include="..\..\..\..\..\include\serial\objectio.inl" />
+    <None Include="..\..\..\..\..\include\serial\objectiter.inl" />
+    <None Include="..\..\..\..\..\include\serial\objistr.inl" />
+    <None Include="..\..\..\..\..\include\serial\objistrasnb.inl" />
+    <None Include="..\..\..\..\..\include\serial\objistrimpl.inl" />
+    <None Include="..\..\..\..\..\include\serial\objistrxml.inl" />
+    <None Include="..\..\..\..\..\include\serial\objlist.inl" />
+    <None Include="..\..\..\..\..\include\serial\objostr.inl" />
+    <None Include="..\..\..\..\..\include\serial\objostrasnb.inl" />
+    <None Include="..\..\..\..\..\include\serial\objostrxml.inl" />
+    <None Include="..\..\..\..\..\include\serial\objstack.inl" />
+    <None Include="..\..\..\..\..\include\serial\objstrasnb.inl" />
+    <None Include="..\..\..\..\..\include\serial\ptrinfo.inl" />
+    <None Include="..\..\..\..\..\include\serial\serial.inl" />
+    <None Include="..\..\..\..\..\include\serial\serialdef.inl" />
+    <None Include="..\..\..\..\..\include\serial\stdtypes.inl" />
+    <None Include="..\..\..\..\..\include\serial\typeinfo.inl" />
+    <None Include="..\..\..\..\..\include\serial\typeinfoimpl.inl" />
+    <None Include="..\..\..\..\..\include\serial\typeref.inl" />
+    <None Include="..\..\..\..\..\include\serial\variant.inl" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/static/build/util/regexp/regexp.lib.vcxproj b/c++/compilers/vs2015/static/build/util/regexp/regexp.lib.vcxproj
new file mode 100644
index 0000000..64e7191
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/util/regexp/regexp.lib.vcxproj
@@ -0,0 +1,363 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{DFDE1494-ED69-4C4F-84D3-0D19DB1B424C}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">..\..\..\lib\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">..\..\..\lib\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">regexp</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">regexp</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\include\; ..\..\..\..\..\..\include\internal\; ..\..\..\..\..\..\include\util\regexp\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <ProgramDataBaseFileName>$(IntDir)regexp.pdb</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <MinimalRebuild>false</MinimalRebuild>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <StringPooling>false</StringPooling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <CallingConvention>Cdecl</CallingConvention>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <Lib>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+    </Lib>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <ResourceCompile>
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\include\; ..\..\..\..\..\..\include\internal\; ..\..\..\..\..\..\include\util\regexp\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <ProgramDataBaseFileName>$(IntDir)regexp.pdb</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <MinimalRebuild>false</MinimalRebuild>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <StringPooling>false</StringPooling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <CallingConvention>Cdecl</CallingConvention>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <Lib>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+    </Lib>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <ResourceCompile>
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_chartables.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_compile.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_config.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_dfa_exec.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_exec.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_fullinfo.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_get.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_globals.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_info.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_maketables.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_newline.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_ord2utf8.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_refcount.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_study.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_tables.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_try_flipped.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_ucd.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_valid_utf8.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_version.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcre_xclass.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\regexp\pcreposix.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+      </PrecompiledHeaderFile>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+      </PrecompiledHeaderFile>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\..\..\include\util\regexp\pcre.h" />
+    <ClInclude Include="..\..\..\..\..\..\include\util\regexp\pcreposix.h" />
+    <ClInclude Include="..\..\..\..\..\..\src\util\regexp\pcre_config.h" />
+    <ClInclude Include="..\..\..\..\..\..\src\util\regexp\pcre_internal.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/static/build/util/xregexp/xregexp.lib.vcxproj b/c++/compilers/vs2015/static/build/util/xregexp/xregexp.lib.vcxproj
new file mode 100644
index 0000000..f8bcb98
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/util/xregexp/xregexp.lib.vcxproj
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{E46C5B0B-675C-4C37-B618-02608C379C67}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">..\..\..\lib\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">..\..\..\lib\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">xregexp</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">xregexp</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\include\; ..\..\..\..\..\..\include\internal\; ..\..\..\..\..\..\include\util\regexp\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <ProgramDataBaseFileName>$(IntDir)xregexp.pdb</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <MinimalRebuild>false</MinimalRebuild>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <StringPooling>false</StringPooling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <CallingConvention>Cdecl</CallingConvention>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <Lib>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+    </Lib>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <ResourceCompile>
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\..\..\..\..\include\; ..\..\..\..\..\..\include\internal\; ..\..\..\..\..\..\include\util\regexp\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <ProgramDataBaseFileName>$(IntDir)xregexp.pdb</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <MinimalRebuild>false</MinimalRebuild>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <StringPooling>false</StringPooling>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <CallingConvention>Cdecl</CallingConvention>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <Lib>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+    </Lib>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <ResourceCompile>
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\..\..\src\util\xregexp\arg_regexp.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\xregexp\mask_regexp.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Use</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Use</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\..\src\util\xregexp\regexp.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Use</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Use</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\..\..\include\util\xregexp\arg_regexp.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\util\xregexp\mask_regexp.hpp" />
+    <ClInclude Include="..\..\..\..\..\..\include\util\xregexp\regexp.hpp" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/static/build/util/xutil.lib.vcxproj b/c++/compilers/vs2015/static/build/util/xutil.lib.vcxproj
new file mode 100644
index 0000000..2d7988d
--- /dev/null
+++ b/c++/compilers/vs2015/static/build/util/xutil.lib.vcxproj
@@ -0,0 +1,308 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{1DCE18CD-4A7E-43B8-B7AF-48972EFE51E7}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">..\..\lib\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">..\..\lib\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">xutil</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">xutil</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <ClCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <ProgramDataBaseFileName>$(IntDir)xutil.pdb</ProgramDataBaseFileName>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CallingConvention>Cdecl</CallingConvention>
+      <CompileAs>Default</CompileAs>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+    </ClCompile>
+    <ResourceCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..\..\..\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
+      <StringPooling>false</StringPooling>
+      <MinimalRebuild>false</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <ProgramDataBaseFileName>$(IntDir)xutil.pdb</ProgramDataBaseFileName>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <BufferSecurityCheck>true</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+      <CallingConvention>Cdecl</CallingConvention>
+      <CompileAs>Default</CompileAs>
+      <DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <UndefinePreprocessorDefinitions>%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+    </ClCompile>
+    <ResourceCompile>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>FALSE;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\..\src\util\ascii85.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\bytesrc.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\checksum.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\ddump_viewer.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\dictionary.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\file_obsolete.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\format_guess.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\itree.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\logrotate.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\md5.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\random_gen.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\smalldns.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\strbuffer.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\strsearch.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\thread_nonstop.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\thread_pool.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\unicode.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\utf8.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\..\src\util\util_exception.cpp">
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">ncbi_pch.hpp</PrecompiledHeaderFile>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">NCBI_USE_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">ncbi_pch.hpp</PrecompiledHeaderFile>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\..\include\util\ascii85.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\bytesrc.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\checksum.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\ddump_viewer.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\dictionary.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\file_obsolete.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\format_guess.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\itree.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\lightstr.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\linkedset.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\logrotate.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\md5.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\ncbi_table.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\random_gen.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\range.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\range_coll.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\rangemap.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\reader_writer.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\regexp.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\resize_iter.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\resource_pool.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\rwstream.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\smalldns.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\static_map.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\static_set.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\strbuffer.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\strsearch.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\thread_nonstop.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\thread_pool.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\unicode.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\utf8.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\util_exception.hpp" />
+    <ClInclude Include="..\..\..\..\..\include\util\weakmap.hpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\..\..\..\include\util\checksum.inl" />
+    <None Include="..\..\..\..\..\include\util\itree.inl" />
+    <None Include="..\..\..\..\..\include\util\rangemap.inl" />
+    <None Include="..\..\..\..\..\include\util\strbuffer.inl" />
+    <None Include="..\..\..\..\..\include\util\weakmap.inl" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/static/third_party_msvcstatic_install.vcxproj b/c++/compilers/vs2015/static/third_party_msvcstatic_install.vcxproj
new file mode 100644
index 0000000..a97d32c
--- /dev/null
+++ b/c++/compilers/vs2015/static/third_party_msvcstatic_install.vcxproj
@@ -0,0 +1,433 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMT|Win32">
+      <Configuration>DebugMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMT|x64">
+      <Configuration>DebugMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseMT|Win32">
+      <Configuration>ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseMT|x64">
+      <Configuration>ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugDLL|Win32">
+      <Configuration>VTune_DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugDLL|x64">
+      <Configuration>VTune_DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugMT|Win32">
+      <Configuration>VTune_DebugMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugMT|x64">
+      <Configuration>VTune_DebugMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseDLL|Win32">
+      <Configuration>VTune_ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseDLL|x64">
+      <Configuration>VTune_ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseMT|Win32">
+      <Configuration>VTune_ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseMT|x64">
+      <Configuration>VTune_ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugDLL|Win32">
+      <Configuration>Unicode_DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugDLL|x64">
+      <Configuration>Unicode_DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugMT|Win32">
+      <Configuration>Unicode_DebugMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugMT|x64">
+      <Configuration>Unicode_DebugMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseDLL|Win32">
+      <Configuration>Unicode_ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseDLL|x64">
+      <Configuration>Unicode_ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseMT|Win32">
+      <Configuration>Unicode_ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseMT|x64">
+      <Configuration>Unicode_ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{9E4B5381-9B6C-4867-BF8A-F1AAA1FD581E}</ProjectGuid>
+    <Keyword>MakeFileProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_install IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_rebuild IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" msvc_clean IntDir=$(IntDir) MSVC_SRC="vs2015.64"</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">dlls-install.exe</NMakeOutput>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="third_party_static_install.mak" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/c++/compilers/vs2015/static/third_party_static_install.mak b/c++/compilers/vs2015/static/third_party_static_install.mak
new file mode 100644
index 0000000..9405bdc
--- /dev/null
+++ b/c++/compilers/vs2015/static/third_party_static_install.mak
@@ -0,0 +1,62 @@
+# $Id: third_party_static_install.mak 493015 2016-02-23 18:12:07Z gouriano $
+#################################################################
+
+
+INSTALL          = .\bin
+INSTALL_BINPATH  = $(INSTALL)\$(INTDIR)
+THIRDPARTY_MAKEFILES_DIR =  .
+
+
+META_MAKE = $(THIRDPARTY_MAKEFILES_DIR)\..\third_party_install.meta.mk
+!IF EXIST($(META_MAKE))
+!INCLUDE $(META_MAKE)
+!ELSE
+!ERROR  $(META_MAKE)  not found
+!ENDIF
+
+THIRD_PARTY_LIBS = \
+	install_berkeleydb \
+	install_gnutls     \
+	install_glew       \
+	install_lzo        \
+	install_mssql      \
+	install_mysql      \
+	install_openssl    \
+	install_sqlite     \
+	install_sqlite3    \
+	install_sybase     \
+	install_wxwidgets  \
+	install_wxwindows  \
+	install_xalan      \
+	install_xerces     \
+	install_libxml     \
+	install_libxslt    \
+	install_vdb
+
+CLEAN_THIRD_PARTY_LIBS = \
+	clean_berkeleydb \
+	clean_gnutls     \
+	clean_glew       \
+	clean_lzo        \
+	clean_mssql      \
+	clean_mysql      \
+	clean_openssl    \
+	clean_sqlite     \
+	clean_sqlite3    \
+	clean_sybase     \
+	clean_wxwidgets  \
+	clean_wxwindows  \
+	clean_xalan      \
+	clean_xerces     \
+	clean_libxml     \
+	clean_libxslt    \
+	clean_vdb
+
+all : dirs $(THIRD_PARTY_LIBS)
+
+clean : $(CLEAN_THIRD_PARTY_LIBS)
+
+rebuild : clean all
+
+dirs :
+    @if not exist $(INSTALL_BINPATH) (echo Creating directory $(INSTALL_BINPATH)... & mkdir $(INSTALL_BINPATH))
diff --git a/c++/compilers/vs2015/static/third_party_static_install.vcxproj b/c++/compilers/vs2015/static/third_party_static_install.vcxproj
new file mode 100644
index 0000000..ce23796
--- /dev/null
+++ b/c++/compilers/vs2015/static/third_party_static_install.vcxproj
@@ -0,0 +1,433 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMT|Win32">
+      <Configuration>DebugMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMT|x64">
+      <Configuration>DebugMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseMT|Win32">
+      <Configuration>ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseMT|x64">
+      <Configuration>ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugDLL|Win32">
+      <Configuration>Unicode_DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugDLL|x64">
+      <Configuration>Unicode_DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugMT|Win32">
+      <Configuration>Unicode_DebugMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_DebugMT|x64">
+      <Configuration>Unicode_DebugMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseDLL|Win32">
+      <Configuration>Unicode_ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseDLL|x64">
+      <Configuration>Unicode_ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseMT|Win32">
+      <Configuration>Unicode_ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Unicode_ReleaseMT|x64">
+      <Configuration>Unicode_ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugDLL|Win32">
+      <Configuration>VTune_DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugDLL|x64">
+      <Configuration>VTune_DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugMT|Win32">
+      <Configuration>VTune_DebugMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_DebugMT|x64">
+      <Configuration>VTune_DebugMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseDLL|Win32">
+      <Configuration>VTune_ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseDLL|x64">
+      <Configuration>VTune_ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseMT|Win32">
+      <Configuration>VTune_ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="VTune_ReleaseMT|x64">
+      <Configuration>VTune_ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{9E4B5381-9B6C-4867-BF8A-F1AAA1FD580E}</ProjectGuid>
+    <Keyword>MakeFileProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'" Label="Configuration">
+    <ConfigurationType>Makefile</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugMT|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugMT|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugMT|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseMT|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Unicode_ReleaseDLL|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugMT|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|Win32'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_DebugDLL|x64'">gbench-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseMT|x64'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|Win32'">dlls-install.exe</NMakeOutput>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">$(Configuration)\</IntDir>
+    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" all IntDir=$(IntDir)</NMakeBuildCommandLine>
+    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">nmake -f "$(ProjectDir)\third_party_static_install.mak" rebuild IntDir=$(IntDir)</NMakeReBuildCommandLine>
+    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">call "$(ProjectDir)..\msvcvars.bat" & nmake -f "$(ProjectDir)\third_party_static_install.mak" clean IntDir=$(IntDir)</NMakeCleanCommandLine>
+    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='VTune_ReleaseDLL|x64'">dlls-install.exe</NMakeOutput>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="third_party_static_install.mak" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/c++/compilers/vs2015/third_party_install.meta.mk b/c++/compilers/vs2015/third_party_install.meta.mk
new file mode 100644
index 0000000..581fee1
--- /dev/null
+++ b/c++/compilers/vs2015/third_party_install.meta.mk
@@ -0,0 +1,330 @@
+# $Id: third_party_install.meta.mk 492980 2016-02-23 16:24:57Z gouriano $
+
+#################################################################
+#
+# Third party DLLs installation makefile
+#
+# Author: Andrei Gourianov
+#
+#################################################################
+
+
+# Build configuration name
+INTDIR = $(INTDIR:.\=)
+ALTDIR = $(INTDIR:VTune_=)
+!IF ("$(INTDIR)"=="$(ALTDIR)")
+ALTDIR = $(INTDIR:Unicode_=)
+!ENDIF
+
+# Extensions of files to copy
+EXTENSIONS         = dll pdb manifest
+
+# MSVC DLLs
+#  MSVC_SRC must be defined elsewhere (eg, in command line)
+#MSVCRT_SRC = \\snowman\win-coremake\Lib\ThirdParty\msvc\msvc71\7.1\bin
+#MSVCRT_SRC = \\snowman\win-coremake\Lib\ThirdParty\msvc\msvc8\8\bin
+
+MSVCRT_SRC = \\snowman\win-coremake\Lib\ThirdParty\msvc\$(MSVC_SRC)\bin
+
+
+
+#################################################################
+# Source folders
+#
+# x_BINPATH macros are defined in Makefile.third_party.mk 
+# generated by project_tree_builder
+#
+
+PTB_GENERATED = $(THIRDPARTY_MAKEFILES_DIR)\$(INTDIR)\Makefile.third_party.mk
+!IF EXIST($(PTB_GENERATED))
+!INCLUDE $(PTB_GENERATED)
+!ELSE
+!ERROR  $(PTB_GENERATED)  not found
+!ENDIF
+
+
+BERKELEYDB_SRC = $(BERKELEYDB_BINPATH)\$(INTDIR)
+!IF !EXIST($(BERKELEYDB_SRC))
+BERKELEYDB_SRC = $(BERKELEYDB_BINPATH)\$(ALTDIR)
+!ENDIF
+
+GNUTLS_SRC = $(GNUTLS_BINPATH)\$(INTDIR)
+!IF !EXIST($(GNUTLS_SRC))
+GNUTLS_SRC = $(GNUTLS_BINPATH)\$(ALTDIR)
+!ENDIF
+
+GLEW_SRC = $(GLEW_BINPATH)\$(INTDIR)
+!IF !EXIST($(GLEW_SRC))
+GLEW_SRC = $(GLEW_BINPATH)\$(ALTDIR)
+!ENDIF
+
+LZO_SRC = $(LZO_BINPATH)\$(INTDIR)
+!IF !EXIST($(LZO_SRC))
+LZO_SRC = $(LZO_BINPATH)\$(ALTDIR)
+!ENDIF
+
+MSSQL_SRC = $(MSSQL_BINPATH)\$(INTDIR)
+!IF !EXIST($(MSSQL_SRC))
+MSSQL_SRC = $(MSSQL_BINPATH)\$(ALTDIR)
+!ENDIF
+
+MYSQL_SRC = $(MYSQL_BINPATH)\$(INTDIR)
+!IF !EXIST($(MYSQL_SRC))
+MYSQL_SRC = $(MYSQL_BINPATH)\$(ALTDIR)
+!ENDIF
+
+OPENSSL_SRC = $(OPENSSL_BINPATH)\$(INTDIR)
+!IF !EXIST($(OPENSSL_SRC))
+OPENSSL_SRC = $(OPENSSL_BINPATH)\$(ALTDIR)
+!ENDIF
+
+SQLITE_SRC = $(SQLITE_BINPATH)\$(INTDIR)
+!IF !EXIST($(SQLITE_SRC))
+SQLITE_SRC = $(SQLITE_BINPATH)\$(ALTDIR)
+!ENDIF
+
+SQLITE3_SRC = $(SQLITE3_BINPATH)\$(INTDIR)
+!IF !EXIST($(SQLITE3_SRC))
+SQLITE3_SRC = $(SQLITE3_BINPATH)\$(ALTDIR)
+!ENDIF
+
+# SYBASE_SRC = $(SYBASE_BINPATH)\$(INTDIR)
+# !IF !EXIST($(SYBASE_SRC))
+# SYBASE_SRC = $(SYBASE_BINPATH)\$(ALTDIR)
+# !ENDIF
+SYBASE_SRC = $(SYBASE_BINPATH)\$(INTDIR:Debug=Release)
+!IF !EXIST($(SYBASE_SRC))
+SYBASE_SRC = $(SYBASE_BINPATH)\$(ALTDIR:Debug=Release)
+!ENDIF
+
+WXWIDGETS_SRC = $(WXWIDGETS_BINPATH)\$(INTDIR)
+!IF !EXIST($(WXWIDGETS_SRC))
+WXWIDGETS_SRC = $(WXWIDGETS_BINPATH)\$(ALTDIR)
+!ENDIF
+
+WXWINDOWS_SRC = $(WXWINDOWS_BINPATH)\$(INTDIR)
+!IF !EXIST($(WXWINDOWS_SRC))
+WXWINDOWS_SRC = $(WXWINDOWS_BINPATH)\$(ALTDIR)
+!ENDIF
+
+XALAN_SRC = $(XALAN_BINPATH)\$(INTDIR)
+!IF !EXIST($(XALAN_SRC))
+XALAN_SRC = $(XALAN_BINPATH)\$(ALTDIR)
+!ENDIF
+
+XERCES_SRC = $(XERCES_BINPATH)\$(INTDIR)
+!IF !EXIST($(XERCES_SRC))
+XERCES_SRC = $(XERCES_BINPATH)\$(ALTDIR)
+!ENDIF
+
+LIBXML_SRC = $(LIBXML_BINPATH)\$(INTDIR)
+!IF !EXIST($(LIBXML_SRC))
+LIBXML_SRC = $(LIBXML_BINPATH)\$(ALTDIR)
+!ENDIF
+
+LIBXSLT_SRC = $(LIBXSLT_BINPATH)\$(INTDIR)
+!IF !EXIST($(LIBXSLT_SRC))
+LIBXSLT_SRC = $(LIBXSLT_BINPATH)\$(ALTDIR)
+!ENDIF
+
+VDB_SRC = $(VDB_BINPATH)
+
+
+
+#################################################################
+
+INSTALL_CMD = \
+	@if exist "$*" ( for %%e in ($(EXTENSIONS)) do @( \
+	    if exist "$*\*.%%e" ( \
+	      for /f "delims=" %%i in ('dir /a-d/b "$*\*.%%e"') do @( \
+	        xcopy /Y /D /F "$*\%%i" "$(INSTALL_BINPATH)" ) \
+	    )) \
+	) else (echo WARNING:   "$*" not found)
+
+CLEAN_CMD = \
+	@if exist "$*" ( for %%e in ($(EXTENSIONS)) do @( \
+	    if exist "$*\*.%%e" ( \
+	      for /f "delims=" %%i in ('dir /a-d/b "$*\*.%%e"') do @( \
+	        if exist "$(INSTALL_BINPATH)\%%i" ( \
+	          echo $(INSTALL_BINPATH)\%%i & del /F "$(INSTALL_BINPATH)\%%i" )))) \
+	) else (echo WARNING:   "$*" not found)
+
+
+
+#################################################################
+# Targets
+#
+
+$(BERKELEYDB_SRC).berkeleydb_install :
+	@echo ---- & echo Copying BerkeleyDB DLLs & $(INSTALL_CMD)
+$(BERKELEYDB_SRC).berkeleydb_clean :
+	@echo ---- & echo Deleting BerkeleyDB DLLs & $(CLEAN_CMD)
+install_berkeleydb : $(BERKELEYDB_SRC).berkeleydb_install
+clean_berkeleydb : $(BERKELEYDB_SRC).berkeleydb_clean
+
+
+
+$(GNUTLS_SRC).gnutls_install :
+	@echo ---- & echo Copying GNUTLS DLLs & $(INSTALL_CMD)
+$(GNUTLS_SRC).gnutls_clean :
+	@echo ---- & echo Deleting GNUTLS DLLs & $(CLEAN_CMD)
+install_gnutls : $(GNUTLS_SRC).gnutls_install
+clean_gnutls : $(GNUTLS_SRC).gnutls_clean
+
+
+
+$(GLEW_SRC).glew_install :
+	@echo ---- & echo Copying GLEW DLLs & $(INSTALL_CMD)
+$(GLEW_SRC).glew_clean :
+	@echo ---- & echo Deleting GLEW DLLs & $(CLEAN_CMD)
+install_glew : $(GLEW_SRC).glew_install
+clean_glew : $(GLEW_SRC).glew_clean
+
+
+
+$(LZO_SRC).lzo_install :
+	@echo ---- & echo Copying LZO DLLs & $(INSTALL_CMD)
+$(LZO_SRC).lzo_clean :
+	@echo ---- & echo Deleting LZO DLLs & $(CLEAN_CMD)
+install_lzo : $(LZO_SRC).lzo_install
+clean_lzo : $(LZO_SRC).lzo_clean
+
+
+
+$(MYSQL_SRC).mysql_install :
+	@echo ---- & echo Copying MySQL DLLs & $(INSTALL_CMD)
+$(MYSQL_SRC).mysql_clean :
+	@echo ---- & echo Deleting MySQL DLLs & $(CLEAN_CMD)
+install_mysql : $(MYSQL_SRC).mysql_install
+clean_mysql : $(MYSQL_SRC).mysql_clean
+
+
+
+$(MSSQL_SRC).mssql_install :
+	@echo ---- & echo Copying MSSQL DLLs & $(INSTALL_CMD)
+$(MSSQL_SRC).mssql_clean :
+	@echo ---- & echo Deleting MSSQL DLLs & $(CLEAN_CMD)
+install_mssql : $(MSSQL_SRC).mssql_install
+clean_mssql : $(MSSQL_SRC).mssql_clean
+
+
+
+$(OPENSSL_SRC).openssl_install :
+	@echo ---- & echo Copying OpenSSL DLLs & $(INSTALL_CMD)
+$(OPENSSL_SRC).openssl_clean :
+	@echo ---- & echo Deleting OpenSSL DLLs & $(CLEAN_CMD)
+install_openssl : $(OPENSSL_SRC).openssl_install
+clean_openssl : $(OPENSSL_SRC).openssl_clean
+
+
+
+$(SQLITE_SRC).sqlite_install :
+	@echo ---- & echo Copying SQLite DLLs & $(INSTALL_CMD)
+$(SQLITE_SRC).sqlite_clean :
+	@echo ---- & echo Deleting SQLite DLLs & $(CLEAN_CMD)
+install_sqlite : $(SQLITE_SRC).sqlite_install
+clean_sqlite : $(SQLITE_SRC).sqlite_clean
+
+
+
+$(SQLITE3_SRC).sqlite3_install :
+	@echo ---- & echo Copying SQLite3 DLLs & $(INSTALL_CMD)
+$(SQLITE3_SRC).sqlite3_clean :
+	@echo ---- & echo Deleting SQLite3 DLLs & $(CLEAN_CMD)
+install_sqlite3 : $(SQLITE3_SRC).sqlite3_install
+clean_sqlite3 : $(SQLITE3_SRC).sqlite3_clean
+
+
+
+$(SYBASE_SRC).sybase_install :
+	@echo ---- & echo Copying Sybase DLLs & $(INSTALL_CMD)
+$(SYBASE_SRC).sybase_clean :
+	@echo ---- & echo Deleting Sybase DLLs & $(CLEAN_CMD)
+install_sybase : $(SYBASE_SRC).sybase_install
+clean_sybase : $(SYBASE_SRC).sybase_clean
+
+
+
+$(WXWIDGETS_SRC).wxwidgets_install :
+	@echo ---- & echo Copying wxWidgets DLLs & $(INSTALL_CMD)
+$(WXWIDGETS_SRC).wxwidgets_clean :
+	@echo ---- & echo Deleting wxWidgets DLLs & $(CLEAN_CMD)
+install_wxwidgets : $(WXWIDGETS_SRC).wxwidgets_install
+clean_wxwidgets : $(WXWIDGETS_SRC).wxwidgets_clean
+
+
+
+$(WXWINDOWS_SRC).wxwindows_install :
+	@echo ---- & echo Copying wxWindows DLLs & $(INSTALL_CMD)
+$(WXWINDOWS_SRC).wxwindows_clean :
+	@echo ---- & echo Deleting wxWindows DLLs & $(CLEAN_CMD)
+install_wxwindows : $(WXWINDOWS_SRC).wxwindows_install
+clean_wxwindows : $(WXWINDOWS_SRC).wxwindows_clean
+
+
+
+$(XALAN_SRC).xalan_install :
+	@echo ---- & echo Copying Xalan DLLs & $(INSTALL_CMD)
+$(XALAN_SRC).xalan_clean :
+	@echo ---- & echo Deleting Xalan DLLs & $(CLEAN_CMD)
+install_xalan : $(XALAN_SRC).xalan_install
+clean_xalan : $(XALAN_SRC).xalan_clean
+
+
+
+$(XERCES_SRC).xerces_install :
+	@echo ---- & echo Copying Xerces DLLs & $(INSTALL_CMD)
+$(XERCES_SRC).xerces_clean :
+	@echo ---- & echo Deleting Xerces DLLs & $(CLEAN_CMD)
+install_xerces : $(XERCES_SRC).xerces_install
+clean_xerces : $(XERCES_SRC).xerces_clean
+
+
+
+$(LIBXML_SRC).libxml_install :
+	@echo ---- & echo Copying LIBXML DLLs & $(INSTALL_CMD)
+$(LIBXML_SRC).libxml_clean :
+	@echo ---- & echo Deleting LIBXML DLLs & $(CLEAN_CMD)
+install_libxml : $(LIBXML_SRC).libxml_install
+clean_libxml : $(LIBXML_SRC).libxml_clean
+
+
+
+$(LIBXSLT_SRC).libxslt_install :
+	@echo ---- & echo Copying LIBXSLT DLLs & $(INSTALL_CMD)
+$(LIBXSLT_SRC).libxslt_clean :
+	@echo ---- & echo Deleting LIBXSLT DLLs & $(CLEAN_CMD)
+install_libxslt : $(LIBXSLT_SRC).libxslt_install
+clean_libxslt : $(LIBXSLT_SRC).libxslt_clean
+
+
+VDB_ORIG = $(INSTALL_BINPATH)\ncbi-vdb-md.dll
+VDB_COPY = $(INSTALL_BINPATH)\ncbi-vdb-dll-md.dll
+$(VDB_SRC).vdb_install :
+	@echo ---- & echo Copying VDB DLLs & $(INSTALL_CMD)
+# The trailing * suppresses a spurious prompt, per
+# http://stackoverflow.com/a/26034267/1231
+	@if exist "$(VDB_ORIG)" xcopy /Y /D /F "$(VDB_ORIG)" "$(VDB_COPY)"*
+$(VDB_SRC).vdb_clean :
+	@echo ---- & echo Deleting VDB DLLs & $(CLEAN_CMD)
+	@if exist "$(VDB_COPY)" ( echo $(VDB_COPY) & del /f "$(VDB_COPY)" )
+install_vdb : $(VDB_SRC).vdb_install
+clean_vdb : $(VDB_SRC).vdb_clean
+
+
+
+# -----------------------------------------
+# MSVC RT DLLs are not included into 'all'
+
+msvc_install : dirs $(MSVCRT_SRC).msvc_install
+
+install_msvc : msvc_install
+msvc_clean : $(MSVCRT_SRC).msvc_clean
+clean_msvc : msvc_clean
+msvc_rebuild : msvc_clean msvc_install
+
+$(MSVCRT_SRC).msvc_install :
+	@echo ---- & echo Copying MSVC DLLs & $(INSTALL_CMD)
+$(MSVCRT_SRC).msvc_clean :
+	@echo ---- & echo Deleting MSVC DLLs & $(CLEAN_CMD)
+	
diff --git a/c++/compilers/vs2015/user/build/UtilityProjects/_CONFIGURE_.vcxproj b/c++/compilers/vs2015/user/build/UtilityProjects/_CONFIGURE_.vcxproj
new file mode 100644
index 0000000..ff66059
--- /dev/null
+++ b/c++/compilers/vs2015/user/build/UtilityProjects/_CONFIGURE_.vcxproj
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>_CONFIGURE_</ProjectName>
+    <ProjectGuid>{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}</ProjectGuid>
+    <RootNamespace>MasterProject</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">_CONFIGURE_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">_CONFIGURE_</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuild Include="configure._">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_user.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_user.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_user.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_user.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Configure solution : $(SolutionName)</Message>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/user/build/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj b/c++/compilers/vs2015/user/build/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj
new file mode 100644
index 0000000..eca71d3
--- /dev/null
+++ b/c++/compilers/vs2015/user/build/UtilityProjects/_CONFIGURE_DIALOG_.vcxproj
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>_CONFIGURE_DIALOG_</ProjectName>
+    <ProjectGuid>{EB043EAF-58D4-4179-AC32-538D9059BB8B}</ProjectGuid>
+    <RootNamespace>MasterProject</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>Utility</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">_CONFIGURE_DIALOG_</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">$(Configuration)\$(TargetName)\</IntDir>
+<TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">_CONFIGURE_DIALOG_</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CustomBuild Include="configure_dialog._">
+      <FileType>Document</FileType>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_user.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_user.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_user.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">Configure solution : $(SolutionName)</Message>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(AdditionalInputs)</AdditionalInputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">set PTB_PATH=$(ProjectDir)..\..\..\static\bin\ReleaseDLL
+set TREE_ROOT=$(ProjectDir)..\..\..\..\..
+set SLN_PATH=$(ProjectDir)..\ncbi_user.sln
+set PTB_PLATFORM=$(Platform)
+set BUILD_TREE_ROOT=$(ProjectDir)..\..\..
+copy /Y %(Filename)%(Extension) %(Filename).bat
+call %(Filename).bat
+if errorlevel 1 exit 1
+</Command>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">%(FullPath).aanofile.out;$(ProjectDir)..\..\..\static\bin\ReleaseDLL\project_tree_builder.exe;%(Outputs)</Outputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">Configure solution : $(SolutionName)</Message>
+    </CustomBuild>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/c++/compilers/vs2015/user/build/UtilityProjects/configure._ b/c++/compilers/vs2015/user/build/UtilityProjects/configure._
new file mode 100644
index 0000000..7766ecc
--- /dev/null
+++ b/c++/compilers/vs2015/user/build/UtilityProjects/configure._
@@ -0,0 +1,4 @@
+set PTB_FLAGS=
+set PTB_PROJECT_REQ=scripts\projects\ncbi_user.lst
+call "%BUILD_TREE_ROOT%\ptb.bat"
+if errorlevel 1 exit 1
diff --git a/c++/compilers/vs2015/user/build/UtilityProjects/configure_dialog._ b/c++/compilers/vs2015/user/build/UtilityProjects/configure_dialog._
new file mode 100644
index 0000000..a954163
--- /dev/null
+++ b/c++/compilers/vs2015/user/build/UtilityProjects/configure_dialog._
@@ -0,0 +1,4 @@
+set PTB_FLAGS= -cfg
+set PTB_PROJECT_REQ=scripts\projects\ncbi_user.lst
+call "%BUILD_TREE_ROOT%\ptb.bat"
+if errorlevel 1 exit 1
diff --git a/c++/compilers/vs2015/user/build/ncbi_user.sln b/c++/compilers/vs2015/user/build/ncbi_user.sln
new file mode 100644
index 0000000..8514216
--- /dev/null
+++ b/c++/compilers/vs2015/user/build/ncbi_user.sln
@@ -0,0 +1,35 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_DIALOG_", "UtilityProjects\_CONFIGURE_DIALOG_.vcxproj", "{EB043EAF-58D4-4179-AC32-538D9059BB8B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_CONFIGURE_", "UtilityProjects\_CONFIGURE_.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		DebugDLL|x64 = DebugDLL|x64
+		DebugDLL|x86 = DebugDLL|x86
+		ReleaseDLL|x64 = ReleaseDLL|x64
+		ReleaseDLL|x86 = ReleaseDLL|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{EB043EAF-58D4-4179-AC32-538D9059BB8B}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.DebugDLL|x64.Build.0 = DebugDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.DebugDLL|x86.Build.0 = DebugDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
+		{8BC9CEB8-8B4A-11D0-8D11-AAAAAAAAA108}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/c++/compilers/xcode30_prj/configure b/c++/compilers/xcode30_prj/configure
index 6ea67b6..0346b2a 100755
--- a/c++/compilers/xcode30_prj/configure
+++ b/c++/compilers/xcode30_prj/configure
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# $Id: configure 474742 2015-07-31 13:01:07Z gouriano $
+# $Id: configure 509262 2016-08-04 14:17:42Z ivanov $
 # Author:  Andrei Gourianov, NCBI (gouriano at ncbi.nlm.nih.gov)
 
 #-----------------------------------------------------------------------------
@@ -15,11 +15,9 @@ use_savedcfg=""
 use_gui="no"
 use_debug="yes"
 use_dll="no"
-use_64="no"
-use_universal="no"
+use_64="yes"
 use_staticstd="no"
 use_action=""
-use_arch=""
 srcroot="../.."
 
 mk_name="Makefile"
@@ -38,6 +36,7 @@ noops="\
  --with-plugin-auto-load \
  --with-bin-release \
  --with-mt \
+ --with-64 \
  --without-exe \
  --with-runpath \
  --with-lfs \
@@ -196,9 +195,7 @@ OPTIONS:
   --with-debug               -- build debug versions of libs and apps
   --without-dll              -- build all toolkit libraries as static ones
   --with-dll                 -- assemble toolkit libraries into DLLs where requested
-  --with-64                  -- compile to 64-bit code
-  --with-universal           -- build universal binaries
-  --with-universal=CPU       -- build universal binaries targeting the given CPU
+  --without-64               -- compile to 32-bit code
   --with-static-exe          -- use static C++ standard libraries
   --with-projects=FILE       -- build projects listed in $srcroot/FILE
            FILE can also be a name of a subdirectory
@@ -232,10 +229,8 @@ for cmd_arg in "$@"; do
     --with-debug          )  use_debug="yes" ;;
     --without-dll         )  use_dll="no" ;;
     --with-dll            )  use_dll="yes" ;;
-    --with-64             )  use_64="yes" ;;
-    --with-universal      )  use_universal="yes" ;;
+    --without-64          )  use_64="no" ;;
     --with-static-exe     )  use_staticstd="yes" ;;
-    --with-universal=*    )  use_arch="$cmd_arg" ;;
     --with-projects=*     )  use_projectlst="$cmd_arg" ;;
     --with-extra-action=* )  use_action="$cmd_arg" ;;
     --ignore-unsupported-options ) ignore_unknown="yes" ;;
@@ -275,7 +270,6 @@ if test -n "$use_savedcfg"; then
     fi
   fi
 fi
-use_arch=`echo $use_arch | sed -e s/--with-universal=//`
 use_projectlst=`echo $use_projectlst | sed -e s/--with-projects=//`
 use_action=`echo $use_action | sed -e s/--with-extra-action=//`
 #--------------------------------------------------------------------------------
@@ -286,20 +280,10 @@ arch=`arch`
 platform=`xcodebuild -version 2>/dev/null | grep 'Xcode [0-9][0-9]*' | sed -e 's/[ .]//g'`
 
 # ------- target architecture
-if test -z "$use_arch"; then
-  if test "$use_universal" == "yes"; then
-    if test "$use_64" == "yes"; then
-      use_arch="ppc64 x86_64"
-    else
-      use_arch="ppc i386"
-    fi
-  else
-    if test "$use_64" == "yes"; then
-      use_arch="x86_64"
-    else
-      use_arch="i386"
-    fi
-  fi
+if test "$use_64" == "yes"; then
+  use_arch="x86_64"
+else
+  use_arch="i386"
 fi 
 PTB_PLATFORM="$use_arch"
 
diff --git a/c++/compilers/xcode30_prj/ptb.sh b/c++/compilers/xcode30_prj/ptb.sh
index d8e8cba..9afaf2a 100755
--- a/c++/compilers/xcode30_prj/ptb.sh
+++ b/c++/compilers/xcode30_prj/ptb.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
-# $Id: ptb.sh 471603 2015-06-29 18:48:10Z ucko $
+# $Id: ptb.sh 507307 2016-07-18 16:33:11Z gouriano $
 # ===========================================================================
 # 
 #                            PUBLIC DOMAIN NOTICE
@@ -51,6 +51,10 @@ PTBGUI="${TREE_ROOT}/src/build-system/project_tree_builder_gui/bin/ptbgui.jar"
 DEFPTB_VERSION_FILE="${TREE_ROOT}/src/build-system/ptb_version.txt"
 PTB_INI="${TREE_ROOT}/src/build-system/${ptbname}.ini"
 PTB_SLN="${BUILD_TREE_ROOT}/static/UtilityProjects/PTB.xcodeproj"
+NCBICONF_MSVC="${TREE_ROOT}/include/common/config/ncbiconf_xcode_site.h"
+if test -e "${NCBICONF_MSVC}"; then
+  NCBICONF_MSVC=
+fi
 
 # -------------------------------------------------------------------------
 # get PTB version: from DEFPTB_VERSION_FILE  or from PREBUILT_PTB_EXE
@@ -165,7 +169,13 @@ if test ! -x "$PTB_EXE"; then
   cmd="`dirname $0`/xcodebuild.sh -project $PTB_SLN -target $ptbname -configuration ReleaseDLL"
   echo "$cmd"
   echo "=============================================================================="
+  if test "${NCBICONF_MSVC}" != ""; then
+    echo // > "${NCBICONF_MSVC}"
+  fi
   $cmd
+  if test "${NCBICONF_MSVC}" != ""; then
+    rm "${NCBICONF_MSVC}"
+  fi
 else
   echo "=============================================================================="
   echo "Using PREBUILT $ptbname at $PTB_EXE"
diff --git a/c++/configure b/c++/configure
index 611b517..8095f79 100755
--- a/c++/configure
+++ b/c++/configure
@@ -1,3 +1,3 @@
 #!/bin/sh
 srcdir=`dirname $0`
-exec $srcdir/configure.orig --without-debug --with-strip --with-openmp --with-mt --with-build-root=$srcdir/ReleaseMT ${1+"$@"}
+exec $srcdir/configure.orig --without-debug --with-strip --with-openmp --with-mt --without-vdb --with-build-root=$srcdir/ReleaseMT ${1+"$@"}
diff --git a/c++/include/algo/blast/api/blast_aux.hpp b/c++/include/algo/blast/api/blast_aux.hpp
index 2bb1d41..778a47f 100644
--- a/c++/include/algo/blast/api/blast_aux.hpp
+++ b/c++/include/algo/blast/api/blast_aux.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_aux.hpp 321879 2011-07-26 16:09:25Z camacho $
+/*  $Id: blast_aux.hpp 507721 2016-07-21 14:07:53Z fongah2 $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -43,6 +43,7 @@
 #include <objects/seqloc/Seq_interval.hpp>
 #include <util/range.hpp>       // For TSeqRange
 #include <objects/seq/seqlocinfo.hpp>
+#include <objmgr/scope.hpp>
 
 // BLAST includes
 #include <algo/blast/api/blast_types.hpp>
@@ -178,6 +179,29 @@ NCBI_XBLAST_EXPORT
 CRef<objects::CSeq_loc>
 MaskedQueryRegionsToPackedSeqLoc( const TMaskedQueryRegions & sloc);
 
+struct NCBI_XBLAST_EXPORT CConstRefCSeqId_LessThan
+{
+    bool operator() (const CConstRef<objects::CSeq_id>& a, const CConstRef<objects::CSeq_id>& b) const {
+        if (a.Empty() && b.NotEmpty()) {
+            return true;
+        } else if (a.NotEmpty() && b.Empty()) {
+            return false;
+        } else if (a.Empty() && b.Empty()) {
+            return true;
+        } else {
+            _ASSERT(a.NotEmpty() && b.NotEmpty());
+            return *a < *b;
+        }
+    }
+};
+
+/// This method retrieve sequence data in bulk to scope
+/// @ids  seq id list [in]
+/// @ranges  seq range list [in]
+/// @scope sconfigured with data loader for retrieving seqs [in] | retrieved bioseqs [out]
+NCBI_XBLAST_EXPORT
+void
+LoadSequencesToScope(objects::CScope::TIds& ids, vector<TSeqRange>& ranges, CRef<objects::CScope> & scope);
 
 /// Converts a BlastMaskLoc internal structure into an object returned by the 
 /// C++ API.
diff --git a/c++/include/algo/blast/api/blast_options.hpp b/c++/include/algo/blast/api/blast_options.hpp
index 12943c8..50331db 100644
--- a/c++/include/algo/blast/api/blast_options.hpp
+++ b/c++/include/algo/blast/api/blast_options.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_options.hpp 456407 2015-01-12 15:47:18Z fongah2 $
+/*  $Id: blast_options.hpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -144,6 +144,12 @@ public:
     int GetWordSize() const;
     void SetWordSize(int ws);
 
+    Uint4 GetLookupTableStride() const;
+    void SetLookupTableStride(Uint4 val);
+
+    bool GetLookupDbFilter(void) const;
+    void SetLookupDbFilter(bool val);
+
     /// Megablast only lookup table options
     unsigned char GetMBTemplateLength() const;
     void SetMBTemplateLength(unsigned char len);
@@ -277,6 +283,12 @@ public:
     int GetUnifiedP() const;
     void SetUnifiedP(int u = 0);
 
+    int GetMaxMismatches() const;
+    void SetMaxMismatches(int m);
+
+    int GetMismatchWindow() const;
+    void SetMismatchWindow(int w);
+
     /******************* Hit saving options *************************/
     int GetHitlistSize() const;
     void SetHitlistSize(int s);
@@ -341,6 +353,14 @@ public:
     double GetLowScorePerc() const;
     void SetLowScorePerc(double p = 0.0);
 
+    // Return only paired reads, for mapping
+    bool GetPaired() const;
+    void SetPaired(bool p);
+
+    /// Splice HSPs for each query (for mappring RNA-Seq reads to a genome)
+    bool GetSpliceAlignments() const;
+    void SetSpliceAlignments(bool s);
+
     /************************ Scoring options ************************/
     const char* GetMatrixName() const;
     void SetMatrixName(const char* matrix);
diff --git a/c++/include/algo/blast/api/blast_options_handle.hpp b/c++/include/algo/blast/api/blast_options_handle.hpp
index 6529720..143ac23 100644
--- a/c++/include/algo/blast/api/blast_options_handle.hpp
+++ b/c++/include/algo/blast/api/blast_options_handle.hpp
@@ -1,7 +1,7 @@
 #ifndef ALGO_BLAST_API___BLAST_OPTIONS_HANDLE__HPP
 #define ALGO_BLAST_API___BLAST_OPTIONS_HANDLE__HPP
 
-/*  $Id: blast_options_handle.hpp 472241 2015-07-08 15:24:13Z fongah2 $
+/*  $Id: blast_options_handle.hpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -111,6 +111,7 @@ public:
     enum ETaskSets {
         eNuclNucl,      ///< Nucleotide-nucleotide tasks
         eProtProt,      ///< Protein-protein tasks
+        eMapping,       ///< Mapping tasks
         eAll            ///< Retrieve all available tasks
     };
 
diff --git a/c++/include/algo/blast/api/blast_seqinfosrc.hpp b/c++/include/algo/blast/api/blast_seqinfosrc.hpp
index f7aa39d..5b21f1d 100644
--- a/c++/include/algo/blast/api/blast_seqinfosrc.hpp
+++ b/c++/include/algo/blast/api/blast_seqinfosrc.hpp
@@ -1,7 +1,7 @@
 #ifndef ALGO_BLAST_API__BLAST_SEQINFOSRC__HPP
 #define ALGO_BLAST_API__BLAST_SEQINFOSRC__HPP
 
-/*  $Id: blast_seqinfosrc.hpp 499810 2016-04-28 15:43:25Z ivanov $
+/*  $Id: blast_seqinfosrc.hpp 499693 2016-04-27 17:19:56Z madden $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/algo/blast/api/blast_seqinfosrc_aux.hpp b/c++/include/algo/blast/api/blast_seqinfosrc_aux.hpp
index 75d0ba9..d50a10e 100644
--- a/c++/include/algo/blast/api/blast_seqinfosrc_aux.hpp
+++ b/c++/include/algo/blast/api/blast_seqinfosrc_aux.hpp
@@ -1,7 +1,7 @@
 #ifndef ALGO_BLAST_API___BLAST_SEQINFOSRC_AUX__HPP
 #define ALGO_BLAST_API___BLAST_SEQINFOSRC_AUX__HPP
 
-/*  $Id: blast_seqinfosrc_aux.hpp 140187 2008-09-15 16:35:34Z camacho $
+/*  $Id: blast_seqinfosrc_aux.hpp 520431 2016-11-28 18:26:12Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -73,8 +73,25 @@ void GetSequenceLengthAndId(const IBlastSeqInfoSrc* seqinfo_src,
 NCBI_XBLAST_EXPORT
 void GetFilteredRedundantGis(const IBlastSeqInfoSrc & sisrc,
                              int                      oid,
-                             vector<int>            & gis);
+                             vector<TGi>            & gis);
 
+/// Get Seqids for a sequence in a redundant database.
+///
+/// This function returns a list of GIs or Seqids corresponding to the specified
+/// OID.  This allows a GI list to be built for those GIs found by a
+/// search and included in the associated database; the returned GIs
+/// will be filtered by any OID and GI list filtering that is applied
+/// to the database (if any).
+///
+/// @param sisrc Source of sequence information. [in]
+/// @param oid OID for which to retrieve GIs.    [in]
+/// @param seqids SeqIds found for the specified oid.  [out]
+/// @param use_gis Return only GIs seqids vector [in]
+NCBI_XBLAST_EXPORT
+void GetFilteredRedundantSeqids(const IBlastSeqInfoSrc & sisrc,
+                             int                      oid,
+                             vector<string>            & seqids,
+			     bool		     use_gis=true);
 END_SCOPE(blast)
 END_NCBI_SCOPE
 
diff --git a/c++/include/algo/blast/api/blast_types.hpp b/c++/include/algo/blast/api/blast_types.hpp
index 3499343..475684c 100644
--- a/c++/include/algo/blast/api/blast_types.hpp
+++ b/c++/include/algo/blast/api/blast_types.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_types.hpp 384426 2012-12-26 23:09:56Z camacho $
+/*  $Id: blast_types.hpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -70,6 +70,7 @@ enum EProgram {
     ePHIBlastn,         ///< Nucleotide PHI BLAST
     eDeltaBlast,        ///< Delta Blast
     eVecScreen,         ///< Vector screening
+    eMapper,            ///< Jumper alignment for mapping
     eBlastProgramMax    ///< Undefined program
 };
 
diff --git a/c++/include/algo/blast/api/magicblast.hpp b/c++/include/algo/blast/api/magicblast.hpp
new file mode 100644
index 0000000..faca1c9
--- /dev/null
+++ b/c++/include/algo/blast/api/magicblast.hpp
@@ -0,0 +1,115 @@
+/*  $Id: magicblast.hpp 504861 2016-06-20 15:45:40Z boratyng $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  Greg Boratyn
+ *
+ */
+
+/// @file magicblast.hpp
+/// Declares CMagicBlast, the C++ API for the BLAST RNA-Seq mapping engine.
+
+#ifndef ALGO_BLAST_API___MAGICBLAST__HPP
+#define ALGO_BLAST_API___MAGICBLAST__HPP
+
+#include <algo/blast/api/setup_factory.hpp>
+#include <algo/blast/api/query_data.hpp>
+#include <algo/blast/api/local_db_adapter.hpp>
+#include <algo/blast/api/blast_results.hpp>
+#include <algo/blast/api/magicblast_options.hpp>
+
+/** @addtogroup AlgoBlast
+ *
+ * @{
+ */
+
+BEGIN_NCBI_SCOPE
+BEGIN_SCOPE(blast)
+
+// Forward declarations
+class IQueryFactory;
+
+/// BLAST RNA-Seq mapper
+class NCBI_XBLAST_EXPORT CMagicBlast : public CObject, public CThreadable
+{
+public:
+
+public:
+    /// Constructor to map short reads as queries to a genome as BLAST database
+    /// @param query_factory 
+    ///     Short reads sequence to map [in]
+    /// @param blastdb
+    ///     Adapter to the BLAST database [in]
+    /// @param options
+    ///     MAGIC-BLAST options [in]
+    CMagicBlast(CRef<IQueryFactory> query_factory,
+                CRef<CLocalDbAdapter> blastdb,
+                CRef<CMagicBlastOptionsHandle> options);
+
+    /// Destructor
+    ~CMagicBlast() {}
+
+    /// Run the RNA-Seq mapping
+    CRef<CSeq_align_set> Run(void);
+
+    TSearchMessages GetSearchMessages(void) const
+    {return m_Messages;}
+
+
+protected:
+    /// Prohibit copy constructor
+    CMagicBlast(const CMagicBlast& rhs);
+    /// Prohibit assignment operator
+    CMagicBlast& operator=(const CMagicBlast& rhs);
+
+    /// Perform sanity checks on input arguments
+    void x_Validate(void);
+
+    /// Create results
+    CRef<CSeq_align_set> x_CreateSeqAlignSet(BlastMappingResults* results);
+
+private:
+    /// Queries
+    CRef<IQueryFactory> m_Queries;
+
+    /// Reference to a BLAST subject/database object
+    CRef<CLocalDbAdapter> m_LocalDbAdapter;
+
+    /// Options to configure the search
+    CRef<CBlastOptions> m_Options;
+
+    /// Internal data strctures
+    CRef<SInternalData> m_InternalData;
+
+    /// Warning and error messages
+    TSearchMessages m_Messages;
+};
+
+
+END_SCOPE(blast)
+END_NCBI_SCOPE
+
+/* @} */
+
+#endif  /* ALGO_BLAST_API___MAGICBLAST__HPP */
diff --git a/c++/include/algo/blast/api/magicblast_options.hpp b/c++/include/algo/blast/api/magicblast_options.hpp
new file mode 100644
index 0000000..446ca5e
--- /dev/null
+++ b/c++/include/algo/blast/api/magicblast_options.hpp
@@ -0,0 +1,211 @@
+#ifndef ALGO_BLAST_API___MAGIC_BLAST_OPTIONS__HPP
+#define ALGO_BLAST_API___MAGIC_BLAST_OPTIONS__HPP
+
+/*  $Id: magicblast_options.hpp 504861 2016-06-20 15:45:40Z boratyng $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Authors:  Greg Boratyn
+ *
+ */
+
+/// @file blast_mapper_options.hpp
+/// Declares the CMagicBlastOptionsHandle class.
+
+#include <algo/blast/api/blast_options_handle.hpp>
+
+/** @addtogroup AlgoBlast
+ *
+ * @{
+ */
+
+BEGIN_NCBI_SCOPE
+BEGIN_SCOPE(blast)
+
+/// Handle to the nucleotide mapping options to the BLAST algorithm.
+///
+/// Adapter class for nucleotide-nucleotide BLAST comparisons.
+/// Exposes an interface to allow manipulation the options that are relevant to
+/// this type of search.
+/// 
+///
+
+class NCBI_XBLAST_EXPORT CMagicBlastOptionsHandle : 
+                                         public CBlastOptionsHandle
+{
+public:
+
+    /// Creates object with default options set
+    CMagicBlastOptionsHandle(EAPILocality locality = CBlastOptions::eLocal);
+
+    /// Create Options Handle from Existing CBlastOptions Object
+    CMagicBlastOptionsHandle(CRef<CBlastOptions> opt);
+
+    /// Sets Defaults
+    virtual void SetDefaults();
+
+    virtual void SetRNAToGenomeDefaults();
+    virtual void SetRNAToRNADefaults();
+    virtual void SetGenomeToGenomeDefaults();
+
+    /******************* Lookup table options ***********************/
+
+    /// Return db filtering option for the lookup table
+    ///
+    /// The filtering removes from lookup table words that are frequent in the
+    /// database.
+    /// @return If true, words that are frequent in the dabase will be removed
+    bool GetLookupDbFilter() const { return m_Opts->GetLookupDbFilter(); }
+
+    /// Set db filtering option for the lookup table
+    ///
+    /// The filtering removes from lookup table words that are frequent in the
+    /// database.
+    /// @param b If true, words that are frequent in the dabase will be removed
+    /// from the lookup table
+    void SetLookupDbFilter(bool b) { m_Opts->SetLookupDbFilter(b); }
+
+    /// Return number of words skipped betweem collected ones when creating
+    /// a lookup table
+    int GetLookupTableStride() const { return m_Opts->GetLookupTableStride(); }
+
+    /// Set lookup table stride: number of words skipped between collected ones
+    /// when creating a lookup table
+    /// @param s lookup table stride [in]
+    void SetLookupTableStride(int s) { m_Opts->SetLookupTableStride(s); }
+
+
+    /******************* Query setup options ************************/
+
+    
+    /******************* Initial word options ***********************/
+
+    /// Return word size
+    int GetWordSize() const { return m_Opts->GetWordSize(); }
+
+    /// Set word size
+    /// @param w word size [in]
+    void SetWordSize(int w) { m_Opts->SetWordSize(w); }
+
+    /******************* Gapped extension options *******************/
+
+
+    /************************ Scoring options ************************/
+
+    /// Returns mismatch penalty
+    int GetMismatchPenalty() const { return m_Opts->GetMismatchPenalty(); }
+
+    /// Sets mismatch penalty
+    /// @param p mismatch penalty [in]
+    void SetMismatchPenalty(int p) { m_Opts->SetMismatchPenalty(p); }
+
+    /// Return gap opening cost
+    int GetGapOpeningCost() const { return m_Opts->GetGapOpeningCost(); }
+
+    /// Set gap opening cost
+    /// @param g gap opening cost [in]
+    void SetGapOpeningCost(int g) { m_Opts->SetGapOpeningCost(g); }
+
+    /// Return gap extension cost
+    int GetGapExtensionCost() const { return m_Opts->GetGapExtensionCost(); }
+
+    /// Sets gap extension cost
+    /// @param g gap extension cost [in]
+    void SetGapExtensionCost(int g) { m_Opts->SetGapExtensionCost(g); }
+
+    /// Return a single alignment cutoff score
+    int GetCutoffScore() const { return m_Opts->GetCutoffScore(); }
+
+    /// Set a single alignment cutoff score
+    /// @param s cutoff score [in]
+    void SetCutoffScore(int s) { m_Opts->SetCutoffScore(s); }
+
+
+    /************************ Mapping options ************************/
+
+    /// Are the mapping reads assumed paired
+    /// @returns True if reads are assumed paired, false otherwise
+    bool GetPaired() const { return m_Opts->GetPaired(); }
+
+    /// Set input reads as paired/not paired
+    /// @param p If true, the input sequences are paired [in]
+    void SetPaired(bool p) { m_Opts->SetPaired(p); }
+
+    /// Return the splice/unsplice alignments switch value
+    /// @return True if alignments are spliced, false otherwise
+    bool GetSpliceAlignments() const { return m_Opts->GetSpliceAlignments(); }
+
+    /// Set splicing alignments
+    /// @param s if true alignments will be spliced [in]
+    void SetSpliceAlignments(bool s) { m_Opts->SetSpliceAlignments(s); }
+
+    /// Get max intron length
+    /// @return Max intron length
+    int GetLongestIntronLength(void) const
+    { return m_Opts->GetLongestIntronLength(); }
+
+    /// Set max intron length
+    /// @param len Max inrton length
+    void SetLongestIntronLength(int len) {m_Opts->SetLongestIntronLength(len);}
+
+    
+protected:
+    /// Set the program and service name for remote blast.
+    virtual void SetRemoteProgramAndService_Blast3()
+    {
+//        m_Opts->SetRemoteProgramAndService_Blast3("blastn", "megablast");
+    }
+    
+    /// Overrides LookupTableDefaults for nucleotide options
+    virtual void SetLookupTableDefaults();
+    /// Overrides QueryOptionDefaults for nucleotide options
+    virtual void SetQueryOptionDefaults();
+    /// Overrides InitialWordOptionsDefaults for nucleotide options
+    virtual void SetInitialWordOptionsDefaults();
+    /// Overrides GappedExtensionDefaults for nucleotide options
+    virtual void SetGappedExtensionDefaults();
+    /// Overrides ScoringOptionsDefaults for nucleotide options
+    virtual void SetScoringOptionsDefaults();
+    /// Overrides HitSavingOptionsDefaults for nucleotide options
+    virtual void SetHitSavingOptionsDefaults();
+    /// Overrides EffectiveLengthsOptionsDefaults for nucleotide options
+    virtual void SetEffectiveLengthsOptionsDefaults();
+    /// Overrides SubjectSequenceOptionsDefaults for nucleotide options
+    virtual void SetSubjectSequenceOptionsDefaults();
+
+private:
+    /// Disallow copy constructor
+    CMagicBlastOptionsHandle(const CMagicBlastOptionsHandle& rhs);
+    /// Disallow assignment operator
+    CMagicBlastOptionsHandle& operator=(const CMagicBlastOptionsHandle& rhs);
+};
+
+END_SCOPE(blast)
+END_NCBI_SCOPE
+
+
+/* @} */
+
+
+#endif  /* ALGO_BLAST_API___MAGIC_BLAST_OPTIONS__HPP */
diff --git a/c++/include/algo/blast/api/objmgrfree_query_data.hpp b/c++/include/algo/blast/api/objmgrfree_query_data.hpp
index d84fa4e..ef0df8c 100644
--- a/c++/include/algo/blast/api/objmgrfree_query_data.hpp
+++ b/c++/include/algo/blast/api/objmgrfree_query_data.hpp
@@ -1,4 +1,4 @@
-/* $Id: objmgrfree_query_data.hpp 194794 2010-06-17 14:18:44Z camacho $
+/* $Id: objmgrfree_query_data.hpp 506274 2016-07-06 14:41:04Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -47,8 +47,7 @@ BEGIN_NCBI_SCOPE
 BEGIN_SCOPE(blast)
 
 /// NCBI C++ Object Manager free implementation of IQueryFactory
-/// @deprecated Please use CObjMgr_QueryFactory instead
-NCBI_DEPRECATED_CLASS NCBI_XBLAST_EXPORT CObjMgrFree_QueryFactory : 
+class NCBI_XBLAST_EXPORT CObjMgrFree_QueryFactory : 
     public IQueryFactory
 {
 public:
diff --git a/c++/include/algo/blast/api/remote_blast.hpp b/c++/include/algo/blast/api/remote_blast.hpp
index fb58a12..f0aee84 100644
--- a/c++/include/algo/blast/api/remote_blast.hpp
+++ b/c++/include/algo/blast/api/remote_blast.hpp
@@ -1,7 +1,7 @@
 #ifndef ALGO_BLAST_API___REMOTE_BLAST__HPP
 #define ALGO_BLAST_API___REMOTE_BLAST__HPP
 
-/*  $Id: remote_blast.hpp 495288 2016-03-16 14:51:11Z ivanov $
+/*  $Id: remote_blast.hpp 494040 2016-03-03 14:36:13Z fongah2 $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/algo/blast/api/seqinfosrc_seqdb.hpp b/c++/include/algo/blast/api/seqinfosrc_seqdb.hpp
index 827ffe2..8b5a75a 100644
--- a/c++/include/algo/blast/api/seqinfosrc_seqdb.hpp
+++ b/c++/include/algo/blast/api/seqinfosrc_seqdb.hpp
@@ -1,7 +1,7 @@
 #ifndef ALGO_BLAST_API__SEQINFOSRC_SEQDB__HPP
 #define ALGO_BLAST_API__SEQINFOSRC_SEQDB__HPP
 
-/*  $Id: seqinfosrc_seqdb.hpp 499810 2016-04-28 15:43:25Z ivanov $
+/*  $Id: seqinfosrc_seqdb.hpp 499693 2016-04-27 17:19:56Z madden $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/algo/blast/api/seqinfosrc_seqvec.hpp b/c++/include/algo/blast/api/seqinfosrc_seqvec.hpp
index 023db11..88a8afd 100644
--- a/c++/include/algo/blast/api/seqinfosrc_seqvec.hpp
+++ b/c++/include/algo/blast/api/seqinfosrc_seqvec.hpp
@@ -1,7 +1,7 @@
 #ifndef ALGO_BLAST_API__SEQINFOSRC_SEQVEC__HPP
 #define ALGO_BLAST_API__SEQINFOSRC_SEQVEC__HPP
 
-/*  $Id: seqinfosrc_seqvec.hpp 499810 2016-04-28 15:43:25Z ivanov $
+/*  $Id: seqinfosrc_seqvec.hpp 499693 2016-04-27 17:19:56Z madden $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/algo/blast/api/setup_factory.hpp b/c++/include/algo/blast/api/setup_factory.hpp
index c30627f..310fd12 100644
--- a/c++/include/algo/blast/api/setup_factory.hpp
+++ b/c++/include/algo/blast/api/setup_factory.hpp
@@ -1,4 +1,4 @@
-/* $Id: setup_factory.hpp 354756 2012-02-29 17:40:28Z morgulis $
+/* $Id: setup_factory.hpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE                          
@@ -262,9 +262,11 @@ public:
 
     /// Create a writer to be registered for use by stream
     /// @param opts_memento Memento options object [in]
+    /// @param query Concatenanted query sequence [in]
     /// @param query_info Information about queries [in]
     static BlastHSPWriter* 
     CreateHspWriter(const CBlastOptionsMemento* opts_memento,
+                    BLAST_SequenceBlk* query,
                     BlastQueryInfo* query_info);
 
     /// Create a pipe to be registered for use by stream
diff --git a/c++/include/algo/blast/blastinput/blast_args.hpp b/c++/include/algo/blast/blastinput/blast_args.hpp
index 23584ef..1d1afe2 100644
--- a/c++/include/algo/blast/blastinput/blast_args.hpp
+++ b/c++/include/algo/blast/blastinput/blast_args.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_args.hpp 484853 2015-11-16 18:32:26Z fongah2 $
+/*  $Id: blast_args.hpp 514850 2016-09-26 17:23:32Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -49,6 +49,8 @@
 #include <objects/seqloc/Na_strand.hpp>
 #include <objects/scoremat/PssmWithParameters.hpp>
 
+#include <util/compress/stream_util.hpp>
+
 BEGIN_NCBI_SCOPE
 BEGIN_SCOPE(blast)
 
@@ -108,7 +110,8 @@ class NCBI_BLASTINPUT_EXPORT CStdCmdLineArgs : public IBlastCmdLineArgs
 {
 public:
     /** Default constructor */
-    CStdCmdLineArgs() : m_InputStream(0), m_OutputStream(0) {};
+    CStdCmdLineArgs() : m_InputStream(0), m_OutputStream(0),
+                        m_GzipEnabled(false) {};
     /** Interface method, \sa IBlastCmdLineArgs::SetArgumentDescriptions */
     virtual void SetArgumentDescriptions(CArgDescriptions& arg_desc);
     /** Interface method, \sa IBlastCmdLineArgs::SetArgumentDescriptions */
@@ -121,13 +124,26 @@ public:
     /** Set the input stream if read from a saved search strategy */
     void SetInputStream(CRef<CTmpFile> input_file);
 
+    /** Set automatic decompression of the input file is file name is
+     * recognized
+     * @param g If true input file will be unzgipped if the file name ends with
+     *          ".gz" [in]
+     */
+    void SetGzipEnabled(bool g) {m_GzipEnabled = g;}
+
 private:
     CNcbiIstream* m_InputStream;    ///< Application's input stream
     CNcbiOstream* m_OutputStream;   ///< Application's output stream
+    auto_ptr<CDecompressIStream> m_DecompressIStream;
+    auto_ptr<CCompressOStream> m_CompressOStream;
 
     /// ASN.1 specification of query sequences when read from a saved search
     /// strategy
     CRef<CTmpFile> m_QueryTmpInputFile;
+
+    /// If true input file will be decompressed with gzip if filename ends
+    /// with ".gz"
+    bool m_GzipEnabled;
 };
 
 /** Argument class to populate an application's name and description */
@@ -145,7 +161,7 @@ public:
     /** Interface method, \sa IBlastCmdLineArgs::SetArgumentDescriptions */
     virtual void SetArgumentDescriptions(CArgDescriptions& arg_desc);
 
-private:
+protected:
     string m_ProgName;  ///< Application's name
     string m_ProgDesc;  ///< Application's description
 };
@@ -615,6 +631,55 @@ public:
                                          CBlastOptions& options);
 };
 
+/// Argument class to collect options specific to KBLASTP
+class NCBI_BLASTINPUT_EXPORT CKBlastpArgs : public IBlastCmdLineArgs
+{
+public:
+
+    /// Constructor
+    CKBlastpArgs(void) : m_JDistance(0.05), m_MinHits(0), m_TargetSeqs(5000) {}
+
+    /// Our virtual destructor
+    virtual ~CKBlastpArgs() {}
+
+    /** Interface method, \sa IBlastCmdLineArgs::SetArgumentDescriptions */
+    virtual void SetArgumentDescriptions(CArgDescriptions& arg_desc);
+    /** Interface method, \sa IBlastCmdLineArgs::SetArgumentDescriptions */
+    virtual void ExtractAlgorithmOptions(const CArgs& cmd_line_args, 
+                                         CBlastOptions& options);
+
+    
+    /// Get the Jaccard distance
+    double GetJaccardDistance(void) { return m_JDistance;}
+
+    /// Get the minimum number of LSH matches.
+    int GetMinHits(void) {return m_MinHits;}
+
+    /// The database
+    string GetDatabase(void) {return m_DbIndex;}
+
+    /// Number of target sequences.
+    int GetTargetSeqs(void) {return m_TargetSeqs;}
+
+private:
+    /// Prohibit copy constructor
+    CKBlastpArgs(const CKBlastpArgs& rhs);
+    /// Prohibit assignment operator
+    CKBlastpArgs& operator=(const CKBlastpArgs& rhs);
+
+    /// Jaccard distance
+    double m_JDistance;
+
+    /// Minimum number of hits
+    int m_MinHits;
+
+    /// Database/index
+    string m_DbIndex;
+
+    /// Number of target sequences to try BLAST on.
+    int m_TargetSeqs;
+};
+
 /// Argument class to collect options specific to DELTA-BLAST
 class NCBI_BLASTINPUT_EXPORT CDeltaBlastArgs : public IBlastCmdLineArgs
 {
@@ -654,6 +719,20 @@ private:
     bool m_ShowDomainHits;
 };
 
+
+class NCBI_BLASTINPUT_EXPORT CMappingArgs : public IBlastCmdLineArgs
+{
+public:
+    CMappingArgs(void) {}
+
+    /** Interface method, \sa IBlastCmdLineArgs::SetArgumentDescriptions */
+    virtual void SetArgumentDescriptions(CArgDescriptions& arg_desc);
+    /** Interface method, \sa IBlastCmdLineArgs::SetArgumentDescriptions */
+    virtual void ExtractAlgorithmOptions(const CArgs& cmd_line_args, 
+                                         CBlastOptions& options);
+
+};
+
 /*****************************************************************************/
 // Input options
 
@@ -692,6 +771,7 @@ public:
 
     /// Is the query sequence protein?
     bool QueryIsProtein() const { return m_QueryCannotBeNucl; }
+
 private:
     /// Strand(s) to search
     objects::ENa_strand m_Strand;
@@ -704,9 +784,69 @@ private:
 
     /// only false for blast[xn], and tblastx
     /// true in case of PSI-BLAST
-    bool m_QueryCannotBeNucl;  
+    bool m_QueryCannotBeNucl;
+};
+
+/// Argument class to collect query options for BLAST Mapper
+class NCBI_BLASTINPUT_EXPORT CMapperQueryOptionsArgs : public CQueryOptionsArgs
+{
+public:
+
+    /// Input formats
+    enum EInputFormat {
+        eFasta = 0,
+        eFastc,
+        eFastq,
+        eASN1text,
+        eASN1bin,
+        eSra
+    };
+
+
+    CMapperQueryOptionsArgs(void)
+        : CQueryOptionsArgs(false),
+          m_IsPaired(false),
+          m_InputFormat(eFasta),
+          m_QualityFilter(false),
+          m_MateInputStream(NULL)
+    {}
+
+    /** Interface method, \sa IBlastCmdLineArgs::SetArgumentDescriptions */
+    virtual void SetArgumentDescriptions(CArgDescriptions& arg_desc);
+    /** Interface method, \sa IBlastCmdLineArgs::SetArgumentDescriptions */
+    virtual void ExtractAlgorithmOptions(const CArgs& args, CBlastOptions& opt);
+
+    /// Are query sequences paired
+    bool IsPaired(void) const {return m_IsPaired;}
+
+    /// Are queries provided in Fastc format
+    EInputFormat GetInputFormat(void) const
+    {return m_InputFormat;}
+
+    /// Should low quality sequences be rejected
+    bool DoQualityFilter(void) const {return m_QualityFilter;}
+
+    /// Does the mate input stream exits
+    bool HasMateInputStream(void) const {return m_MateInputStream;}
+
+    /// Get input stream for query mates
+    CNcbiIstream* GetMateInputStream(void) const {return m_MateInputStream;}
+
+    /// Get a list of SRA accessions
+    const vector<string>& GetSraAccessions(void) const
+    {return m_SraAccessions;}
+
+private:
+    bool m_IsPaired;
+    EInputFormat m_InputFormat;
+    bool m_QualityFilter;
+    vector<string> m_SraAccessions;
+
+    CNcbiIstream* m_MateInputStream;
+    auto_ptr<CDecompressIStream> m_DecompressIStream;
 };
 
+
 /// Argument class to collect database/subject arguments
 class NCBI_BLASTINPUT_EXPORT CBlastDatabaseArgs : public IBlastCmdLineArgs
 {
@@ -731,7 +871,8 @@ public:
     /// @param is_deltablast is it DELTA-BLAST?
     CBlastDatabaseArgs(bool request_mol_type = false, 
                        bool is_rpsblast = false,
-                       bool is_igblast = false);
+                       bool is_igblast = false,
+                       bool is_mapper = false);
     /** Interface method, \sa IBlastCmdLineArgs::SetArgumentDescriptions */
     virtual void SetArgumentDescriptions(CArgDescriptions& arg_desc);
     /** Interface method, \sa IBlastCmdLineArgs::SetArgumentDescriptions */
@@ -796,6 +937,7 @@ protected:
     bool m_IsIgBlast;               /**< true if the search is Ig-BLAST */
 
     bool m_IsProtein;               /**< Is the database/subject(s) protein? */
+    bool m_IsMapper;                /**< true for short read mapper */
     CRef<IQueryFactory> m_Subjects; /**< The subject sequences */
     CRef<objects::CScope> m_Scope;  /**< CScope object in which all subject
                                       sequences read are kept */
@@ -879,6 +1021,8 @@ public:
         eXml2_S,
         /// SAM format
         eSAM,
+
+        eTaxFormat,
         /// Sentinel value for error checking
         eEndValue
     };
@@ -972,12 +1116,12 @@ public:
         return m_CustomOutputFormatSpec; 
     }
 
-    bool ArchiveFormatRequested(const CArgs& args) const;
+    virtual bool ArchiveFormatRequested(const CArgs& args) const;
 
     size_t GetLineLength() const {
     	return m_LineLength;
     }
-private:
+protected:
     EOutputFormat m_OutputFormat;   ///< Choice of formatting output
     bool m_ShowGis;                 ///< Display NCBI GIs?
     TSeqPos m_NumDescriptions;      ///< Number of 1-line descr. to show
@@ -990,9 +1134,7 @@ private:
     /// comma-separated value (populated if applicable)
     string m_CustomOutputFormatSpec;
     size_t m_LineLength;
-
     EFormatFlags m_FormatFlags;
-
 };
 
 /// Argument class to collect multi-threaded arguments
@@ -1046,7 +1188,7 @@ private:
 };
 
 /// Argument class to collect debugging options.
-/// Only show in command line if compiled with _DEBUG
+/// Only show in command line if compiled with _BLAST_DEBUG
 class NCBI_BLASTINPUT_EXPORT CDebugArgs : public IBlastCmdLineArgs
 {
 public:
diff --git a/c++/include/algo/blast/blastinput/blast_asn1_input.hpp b/c++/include/algo/blast/blastinput/blast_asn1_input.hpp
new file mode 100644
index 0000000..8660de0
--- /dev/null
+++ b/c++/include/algo/blast/blastinput/blast_asn1_input.hpp
@@ -0,0 +1,119 @@
+/*  $Id: blast_asn1_input.hpp 504861 2016-06-20 15:45:40Z boratyng $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  Greg Boratyn
+ *
+ */
+
+/** @file blast_fasta_input.hpp
+ * Interface for ASN1 files into blast sequence input
+ */
+
+#ifndef ALGO_BLAST_BLASTINPUT___BLAST_ASN1_INPUT__HPP
+#define ALGO_BLAST_BLASTINPUT___BLAST_ASN1_INPUT__HPP
+
+#include <algo/blast/blastinput/blast_input.hpp>
+#include <algo/blast/blastinput/blast_scope_src.hpp>
+
+BEGIN_NCBI_SCOPE
+BEGIN_SCOPE(blast)
+
+
+/// Class representing a text or binary file containing sequences in ASN.1
+/// format as a collection of Seq-entry objects
+class NCBI_BLASTINPUT_EXPORT CASN1InputSourceOMF : public CBlastInputSourceOMF
+{
+public:
+
+    /// Constructor
+    /// @param infile Input stream for query sequences [in]
+    /// @param num_seqs_in_batch Number of sequences to read in a single batch
+    /// [in]
+    /// @param is_bin Is input in binary ASN.1 format [in]
+    /// @param is_paired Are queries paired [in]
+    /// @param validate Should sequence validation be applied to each read
+    /// sequence; if true sequences that do not pass validation will be
+    /// rejected [in]
+    CASN1InputSourceOMF(CNcbiIstream& infile, TSeqPos num_seqs_in_bacth,
+                        bool is_bin = false, bool is_paired = false,
+                        bool validate = true);
+
+    /// Constructor for reading sequences from two files for paired short reads
+    /// @param infile1 Input stream for query sequences [in]
+    /// @param infile2 Input stream for query mates [in]
+    /// @param num_seqs_in_batch Number of sequences to read in a single batch
+    /// [in]
+    /// @param is_bin Is input in binary ASN.1 format [in]
+    /// @param validate Should sequence validation be applied to each read
+    /// sequence; if true sequences that do not pass validation will be
+    /// rejected [in]
+    CASN1InputSourceOMF(CNcbiIstream& infile1, CNcbiIstream& infile2,
+                        TSeqPos num_seqs_in_bacth, bool is_bin = false,
+                        bool validate = true);
+
+    virtual ~CASN1InputSourceOMF() {}
+
+    virtual void GetNextNumSequences(CBioseq_set& bioseq_set, TSeqPos num_seqs);
+    virtual bool End(void) {return m_InputStream->eof();}
+
+
+private:
+    CASN1InputSourceOMF(const CASN1InputSourceOMF&);
+    CASN1InputSourceOMF& operator=(const CASN1InputSourceOMF&);
+
+    bool x_ValidateSequence(const CSeq_data& seq_data, int length);
+    /// Compute dimer entropy for sequence in Ncbi2NA format
+    int x_FindDimerEntropy2NA(const vector<char>& sequence, int length);
+
+    /// Read one sequence from
+    int x_ReadOneSeq(CNcbiIstream& instream);
+
+    /// Read sequences from one stream
+    bool x_ReadFromSingleFile(CBioseq_set& bioseq_set);
+
+    /// Read sequences from two streams
+    bool x_ReadFromTwoFiles(CBioseq_set& bioseq_set);
+
+    TSeqPos m_NumSeqsInBatch;
+    CNcbiIstream* m_InputStream;
+    // for reading paired reads from two FASTA files
+    CNcbiIstream* m_SecondInputStream;
+    /// Are queries paired
+    bool m_IsPaired;
+    /// Validate quereis and reject those that do not pass
+    bool m_Validate;
+    /// Is input binary ASN1
+    bool m_IsBinary;
+    /// Used for indexing Seq-entries when reading from two files
+    int m_Index;
+
+    vector< CRef<CSeq_entry> > m_Entries;
+};
+
+
+END_SCOPE(blast)
+END_NCBI_SCOPE
+
+#endif  /* ALGO_BLAST_BLASTINPUT___BLAST_ASN1_INPUT__HPP */
diff --git a/c++/include/algo/blast/blastinput/blast_fasta_input.hpp b/c++/include/algo/blast/blastinput/blast_fasta_input.hpp
index 730fa79..7835f06 100644
--- a/c++/include/algo/blast/blastinput/blast_fasta_input.hpp
+++ b/c++/include/algo/blast/blastinput/blast_fasta_input.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_fasta_input.hpp 163387 2009-06-15 18:32:16Z camacho $
+/*  $Id: blast_fasta_input.hpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -110,6 +110,86 @@ private:
     void x_InitInputReader();
 };
 
+
+class NCBI_BLASTINPUT_EXPORT CShortReadFastaInputSource
+    : public CBlastInputSourceOMF
+{
+public:
+    /// Input formats
+    enum EInputFormat {
+        eFasta = 0,
+        eFastc,
+        eFastq
+    };
+
+
+    CShortReadFastaInputSource(CNcbiIstream& infile, TSeqPos num_seqs_in_bacth,
+                               EInputFormat format = eFasta,
+                               bool paired = false, bool validate = true);
+
+    CShortReadFastaInputSource(CNcbiIstream& infile1, CNcbiIstream& infile2,
+                               TSeqPos num_seqs_in_bacth,
+                               EInputFormat format = eFasta,
+                               bool validate = true);
+
+    virtual ~CShortReadFastaInputSource() {}
+
+    virtual void GetNextNumSequences(CBioseq_set& bioseq_set, TSeqPos num_seqs);
+    virtual bool End(void) {return m_LineReader->AtEOF();}
+
+    /// Get number of rejected queries
+    Int4 GetNumRejected(void) const {return m_NumRejected;}
+
+private:
+    CShortReadFastaInputSource(const CShortReadFastaInputSource&);
+    CShortReadFastaInputSource& operator=(const CShortReadFastaInputSource&);
+
+    CTempString x_ParseDefline(CTempString& line);
+    bool x_ValidateSequence(const char* sequence, int length);
+
+    /// Read sequences in FASTA format
+    void x_ReadFasta(CBioseq_set& bioseq_set);
+
+    /// Read sequences in FASTQ format
+    void x_ReadFastq(CBioseq_set& bioseq_set);
+
+    /// Read one sequence from a FASTA file
+    int x_ReadFastaOneSeq(CRef<ILineReader> line_reader);
+
+    /// Read one sequence from a FASTQ file
+    int x_ReadFastqOneSeq(CRef<ILineReader> line_reader);
+
+    /// Read sequences from two FASTA or FASTQ files (for paired reads)
+    bool x_ReadFromTwoFiles(CBioseq_set& bioseq_set, EInputFormat format);
+
+    /// Read sequences in FASTC format: defline, new line, a pair of sequences
+    /// on a single line separated by '><'
+    void x_ReadFastc(CBioseq_set& bioseq_set);
+
+    TSeqPos m_NumSeqsInBatch;
+    /// string::capacity() can be used instead
+    TSeqPos m_SeqBuffLen;
+    CRef<ILineReader> m_LineReader;
+    // for reading paired reads from two FASTA files
+    CRef<ILineReader> m_SecondLineReader;
+    string m_Sequence;
+    CTempString m_Line;
+    /// Are paired sequences in the input
+    bool m_IsPaired;
+    /// Validate quereis and reject those that do not pass
+    bool m_Validate;
+    /// Number of queries that did not pass validation and were rejected
+    Int4 m_NumRejected;
+    /// Input format: FASTA, FASTQ, FASTC
+    EInputFormat m_Format;
+    /// Used for indexing Seq-entries when reading from two files
+    int m_Index;
+
+    vector< CRef<CSeq_id> > m_SeqIds;
+    vector< CRef<CSeq_entry> > m_Entries;
+};
+
+
 END_SCOPE(blast)
 END_NCBI_SCOPE
 
diff --git a/c++/include/algo/blast/blastinput/blast_input.hpp b/c++/include/algo/blast/blastinput/blast_input.hpp
index 15104b6..21a3fd8 100644
--- a/c++/include/algo/blast/blastinput/blast_input.hpp
+++ b/c++/include/algo/blast/blastinput/blast_input.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_input.hpp 388133 2013-02-05 19:47:18Z maning $
+/*  $Id: blast_input.hpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -184,6 +184,16 @@ public:
         m_SeqLenThreshold2Guess = val;
     }
 
+    /// Retrieve gaps to Ns converstion option value
+    bool GetConvertGapsToNs(void) const {
+        return m_GapsToNs;
+    }
+
+    /// Turn on/off converting gaps to Ns in read FASTA sequences
+    void SetConvertGapsToNs(bool val) {
+        m_GapsToNs = val;
+    }
+
 private:
     /// Strand to assign to sequences
     objects::ENa_strand m_Strand;  
@@ -203,6 +213,8 @@ private:
     unsigned int m_SeqLenThreshold2Guess;
     /// Custom prefix string passed to CSeqidGenerator
     string m_LocalIdPrefix;
+    /// Convert gaps to Ns in FASTA sequences
+    bool m_GapsToNs;
 };
 
 
@@ -383,6 +395,43 @@ private:
     CRef<CScope> m_scope;
 };
 
+
+class NCBI_BLASTINPUT_EXPORT CBlastInputSourceOMF : public CObject
+{
+protected:
+    virtual ~CBlastInputSourceOMF() {}
+    virtual void GetNextNumSequences(CBioseq_set& bioseq_set,
+                                     TSeqPos num_seqs) = 0;
+
+    virtual bool End(void) = 0;
+
+    friend class CBlastInputOMF;
+};
+
+
+class NCBI_BLASTINPUT_EXPORT CBlastInputOMF : public CObject
+{
+public:
+    CBlastInputOMF(CRef<CBlastInputSourceOMF> source,
+                   TSeqPos num_seqs_in_batch = kMax_Int);
+
+    void GetNextSeqBatch(CBioseq_set& bioseq_set);
+    CRef<CBioseq_set> GetNextSeqBatch(void);
+
+    void SetNumSeqsInBatch(TSeqPos num) {m_NumSeqsInBatch = num;}
+    TSeqPos GetNumSeqsInBatch(void) {return m_NumSeqsInBatch;}
+
+    bool End(void) {return m_Source->End();}
+
+private:
+    CBlastInputOMF(const CBlastInputOMF& rhs);
+    CBlastInputOMF& operator=(const CBlastInputOMF& rhs);
+
+    CRef<CBlastInputSourceOMF> m_Source;
+    TSeqPos m_NumSeqsInBatch;
+    CRef<CBioseq_set> m_BioseqSet;
+};
+
 END_SCOPE(blast)
 END_NCBI_SCOPE
 
diff --git a/c++/include/algo/blast/blastinput/blast_input_aux.hpp b/c++/include/algo/blast/blastinput/blast_input_aux.hpp
index 8e94033..1eb41ce 100644
--- a/c++/include/algo/blast/blastinput/blast_input_aux.hpp
+++ b/c++/include/algo/blast/blastinput/blast_input_aux.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_input_aux.hpp 483345 2015-10-30 14:04:13Z boratyng $
+/*  $Id: blast_input_aux.hpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -265,6 +265,8 @@ GetQueryBatchSize(EProgram program, bool is_ungapped = false, bool remote = fals
  * @param use_lcase_masking true if the subject lowercase sequence characters
  * should be interpreted as masked regions [in]
  * @param sequences output will be placed here [in|out]
+ * @praram gaps_to_Ns convert all gaps in the sequences to Ns (only for
+ * nucleotide sequences) [in]
  * @return CScope object which contains all the sequences read
  */
 NCBI_BLASTINPUT_EXPORT
@@ -274,7 +276,8 @@ ReadSequencesToBlast(CNcbiIstream& in,
                      const TSeqRange& range, 
                      bool parse_deflines,
                      bool use_lcase_masking,
-                     CRef<CBlastQueryVector>& sequences);
+                     CRef<CBlastQueryVector>& sequences,
+                     bool gaps_to_Ns = false);
 
 /// Calculates the formatting parameters based on the maximum number of target
 /// sequences selected (a.k.a.: hitlist size).
@@ -327,6 +330,14 @@ CheckForEmptySequences(CRef<CBlastQueryVector> sequences, string& warnings);
 NCBI_BLASTINPUT_EXPORT void
 CheckForEmptySequences(CRef<objects::CBioseq_set> sequences, string& warnings);
 
+/// Compute entropy of 2-mers in a nucleotide IUPACNA sequence
+/// @param sequence Nucleotide sequence [in]
+/// @param length Sequence length [in]
+/// @return Entropy of 2-base words
+NCBI_BLASTINPUT_EXPORT int
+FindDimerEntropy(const char* sequence, int length);
+
+
 END_SCOPE(blast)
 END_NCBI_SCOPE
 
diff --git a/c++/include/algo/blast/blastinput/blast_scope_src.hpp b/c++/include/algo/blast/blastinput/blast_scope_src.hpp
index e7bae2e..731fcc1 100644
--- a/c++/include/algo/blast/blastinput/blast_scope_src.hpp
+++ b/c++/include/algo/blast/blastinput/blast_scope_src.hpp
@@ -1,7 +1,7 @@
 #ifndef ALGO_BLAST_BLASTINPUT___BLAST_SCOPE_SRC__HPP
 #define ALGO_BLAST_BLASTINPUT___BLAST_SCOPE_SRC__HPP
 
-/*  $Id: blast_scope_src.hpp 165240 2009-07-08 16:21:59Z camacho $
+/*  $Id: blast_scope_src.hpp 516396 2016-10-13 12:26:43Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -137,11 +137,11 @@ private:
     void x_Init(EConfigOpts options, const string& dbname, bool load_proteins);
 
     /// Load the DATA_LOADERS configuration value from the config file
-    void x_LoadDataLoadersConfig(const CMetaRegistry::SEntry& sentry);
+    void x_LoadDataLoadersConfig(const CNcbiRegistry& registry);
 
     /// Load the BLAST database configured to search for the blastdb
     /// DATA_LOADERS option from the config file
-    void x_LoadBlastDbDataLoaderConfig(const CMetaRegistry::SEntry& sentry);
+    void x_LoadBlastDbDataLoaderConfig(const CNcbiRegistry& registry);
 };
 
 
diff --git a/c++/include/algo/blast/blastinput/cmdline_flags.hpp b/c++/include/algo/blast/blastinput/cmdline_flags.hpp
index cf8e59c..449db40 100644
--- a/c++/include/algo/blast/blastinput/cmdline_flags.hpp
+++ b/c++/include/algo/blast/blastinput/cmdline_flags.hpp
@@ -1,4 +1,4 @@
-/*  $Id: cmdline_flags.hpp 499246 2016-04-25 11:32:24Z ivanov $
+/*  $Id: cmdline_flags.hpp 514854 2016-09-26 17:24:36Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -296,6 +296,12 @@ NCBI_BLASTINPUT_EXPORT extern const string kArgGLFocusV;
 NCBI_BLASTINPUT_EXPORT extern const string kArgExtendAlign;
 ///Argument to specify minimal required V length
 NCBI_BLASTINPUT_EXPORT extern const string kArgMinVLength;
+///Argument to specify minimal required J gene length
+NCBI_BLASTINPUT_EXPORT extern const string kArgMinJLength;
+///Argument to specify number of clonotype to show
+NCBI_BLASTINPUT_EXPORT extern const string kArgNumClonotype;
+///Argument to specify number of clonotype file
+NCBI_BLASTINPUT_EXPORT extern const string kArgClonotypeFile;
 /// Arugment to specify if Igblast alignment should be translated to protein
 NCBI_BLASTINPUT_EXPORT extern const string kArgTranslate;
 ///Arugment to specify if Igblast min D gene match
@@ -344,6 +350,23 @@ NCBI_BLASTINPUT_EXPORT extern const string kArgRpsDb;
 /// Default value for domain database name
 NCBI_BLASTINPUT_EXPORT extern const string kDfltArgRpsDb;
 
+/// KBLASTP arguments
+/// Specifies Jaccard distance (threshold)
+NCBI_BLASTINPUT_EXPORT extern const string kArgJDistance;
+/// Default value
+NCBI_BLASTINPUT_EXPORT extern const string kDfltArgJDistance;
+/// Specifies minimal number of LSH matches
+NCBI_BLASTINPUT_EXPORT extern const string kArgMinHits;
+/// Default value
+NCBI_BLASTINPUT_EXPORT extern const string kDfltArgMinHits;
+/// KMER index
+NCBI_BLASTINPUT_EXPORT extern const string kArgKIndex;
+NCBI_BLASTINPUT_EXPORT extern const string kDfltArgKIndex;
+/// Number of sequences to attempt BLAST on.
+NCBI_BLASTINPUT_EXPORT extern const string kArgTargetSeqs;
+NCBI_BLASTINPUT_EXPORT extern const string kDfltArgTargetSeqs;
+
+
 /// Argument to specify inclusion e-value threshold for conserved domains
 NCBI_BLASTINPUT_EXPORT extern const string kArgDomainInclusionEThreshold;
 /// Argument to specify whether show domain hits in DELTA-BLAST
@@ -360,6 +383,32 @@ NCBI_BLASTINPUT_EXPORT extern const string kArgQueryCovHspPerc;
 /// Argument to specify line length for displaying alignments
 NCBI_BLASTINPUT_EXPORT extern const string kArgLineLength;
 
+
+// Mapper arguments
+/// Argument to specify whether mapped reads are paired
+NCBI_BLASTINPUT_EXPORT extern const string kArgPaired;
+/// Argument to specify cutoff score for accepting non-spliced alignment
+NCBI_BLASTINPUT_EXPORT extern const string kArgScore;
+/// Argument to specify filtering lookup tables words by frequency in the
+/// searched database
+NCBI_BLASTINPUT_EXPORT extern const string kArgLimitLookup;
+/// Argument to specify whether to search for spliced alignments
+NCBI_BLASTINPUT_EXPORT extern const string kArgSplice;
+/// Argument to sepcify the stride when creating a lookup table
+NCBI_BLASTINPUT_EXPORT extern const string kArgLookupStride;
+/// Argument to specify input format
+NCBI_BLASTINPUT_EXPORT extern const string kArgInputFormat;
+/// Argyment to specify whether quality filtering is to be done
+NCBI_BLASTINPUT_EXPORT extern const string kArgQualityFilter;
+/// Mates for the query sequences if given in a separate file
+NCBI_BLASTINPUT_EXPORT extern const string kArgQueryMate;
+/// Reference type: genome or transcriptome
+NCBI_BLASTINPUT_EXPORT extern const string kArgRefType;
+/// Argument to specify that the output will be compressed with gzip
+NCBI_BLASTINPUT_EXPORT extern const string kArgOutputGzip;
+/// Argument to specify SRA accessions
+NCBI_BLASTINPUT_EXPORT extern const string kArgSraAccession;
+
 END_SCOPE(blast)
 END_NCBI_SCOPE
 
diff --git a/c++/include/algo/blast/blastinput/kblastp_args.hpp b/c++/include/algo/blast/blastinput/kblastp_args.hpp
new file mode 100644
index 0000000..8797f0e
--- /dev/null
+++ b/c++/include/algo/blast/blastinput/kblastp_args.hpp
@@ -0,0 +1,75 @@
+/*  $Id: kblastp_args.hpp 514851 2016-09-26 17:23:54Z ivanov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author: Tom Madden
+ *
+ */
+
+/** @file kblastp_args.hpp
+ * Main argument class for KBLASTP application
+ */
+
+#ifndef ALGO_BLAST_BLASTINPUT___KBLASTP_ARGS__HPP
+#define ALGO_BLAST_BLASTINPUT___KBLASTP_ARGS__HPP
+
+#include <algo/blast/blastinput/blast_args.hpp>
+
+BEGIN_NCBI_SCOPE
+BEGIN_SCOPE(blast)
+
+/// Handles command line arguments for blastp binary
+class NCBI_BLASTINPUT_EXPORT CKBlastpAppArgs : public CBlastAppArgs
+{
+public:
+    /// Constructor
+    CKBlastpAppArgs();
+
+     double GetJaccardDistance() { return m_KBlastpArgs->GetJaccardDistance(); }
+
+     int GetMinHits() { return m_KBlastpArgs->GetMinHits(); }
+
+     string GetDatabase() {return m_KBlastpArgs->GetDatabase(); }
+
+     int GetTargetSeqs() {return m_KBlastpArgs->GetTargetSeqs(); }
+
+    /// @inheritDoc
+    virtual int GetQueryBatchSize() const;
+
+protected:
+    /// @inheritDoc
+    virtual CRef<CBlastOptionsHandle>
+    x_CreateOptionsHandle(CBlastOptions::EAPILocality locality,
+                          const CArgs& args);
+
+    /// KBlastp search specific arguments
+    CRef<CKBlastpArgs> m_KBlastpArgs;
+
+};
+
+
+END_SCOPE(blast)
+END_NCBI_SCOPE
+
+#endif  /* ALGO_BLAST_BLASTINPUT___KBLASTP_ARGS__HPP */
diff --git a/c++/include/algo/blast/blastinput/magicblast_args.hpp b/c++/include/algo/blast/blastinput/magicblast_args.hpp
new file mode 100644
index 0000000..b9d6560
--- /dev/null
+++ b/c++/include/algo/blast/blastinput/magicblast_args.hpp
@@ -0,0 +1,63 @@
+/*  $Id: magicblast_args.hpp 504861 2016-06-20 15:45:40Z boratyng $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author: Greg Boratyn
+ *
+ */
+
+/** @file blastmaper_args.hpp
+ * Main argument class for MAGICBLAST application
+ */
+
+#ifndef ALGO_BLAST_BLASTINPUT___MAGICBLAST_ARGS__HPP
+#define ALGO_BLAST_BLASTINPUT___MAGICBLAST_ARGS__HPP
+
+#include <algo/blast/blastinput/blast_args.hpp>
+
+BEGIN_NCBI_SCOPE
+BEGIN_SCOPE(blast)
+
+/// Handles command line arguments for blastmapper binary
+class NCBI_BLASTINPUT_EXPORT CMagicBlastAppArgs : public CBlastAppArgs
+{
+public:
+    /// Constructor
+    CMagicBlastAppArgs();
+
+    /// @inheritDoc
+    virtual int GetQueryBatchSize() const;
+
+protected:
+    /// @inheritDoc
+    virtual CRef<CBlastOptionsHandle>
+    x_CreateOptionsHandle(CBlastOptions::EAPILocality locality,
+                          const CArgs& args);
+};
+
+
+END_SCOPE(blast)
+END_NCBI_SCOPE
+
+#endif  /* ALGO_BLAST_BLASTINPUT___MAGICBLAST_ARGS__HPP */
diff --git a/c++/include/algo/blast/composition_adjustment/composition_adjustment.h b/c++/include/algo/blast/composition_adjustment/composition_adjustment.h
index 1178c33..592da64 100644
--- a/c++/include/algo/blast/composition_adjustment/composition_adjustment.h
+++ b/c++/include/algo/blast/composition_adjustment/composition_adjustment.h
@@ -1,4 +1,4 @@
-/* $Id: composition_adjustment.h 500367 2016-05-04 12:06:01Z ivanov $
+/* $Id: composition_adjustment.h 500143 2016-05-02 18:02:52Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/algo/blast/composition_adjustment/redo_alignment.h b/c++/include/algo/blast/composition_adjustment/redo_alignment.h
index e1da0bf..7b5fd46 100644
--- a/c++/include/algo/blast/composition_adjustment/redo_alignment.h
+++ b/c++/include/algo/blast/composition_adjustment/redo_alignment.h
@@ -1,4 +1,4 @@
-/* $Id: redo_alignment.h 416845 2013-10-31 17:01:59Z boratyng $
+/* $Id: redo_alignment.h 505234 2016-06-23 13:16:57Z fongah2 $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -487,6 +487,19 @@ int BlastCompo_EarlyTermination(double evalue,
                                 BlastCompo_Heap significantMatches[],
                                 int numQueries);
 
+#ifndef GET_SEQ_FRAME
+#define GET_SEQ_FRAME(f) ((f<0)?ABS(f)+2: f-1)
+#endif
+
+#ifndef GET_NUCL_LENGTH
+#define GET_NUCL_LENGTH(l) ((l-5)/2 +2)
+#endif
+
+#ifndef GET_TRANSLATED_LENGTH
+#define GET_TRANSLATED_LENGTH(l,f) ((l-f% 3)/3)
+#endif
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/c++/include/algo/blast/core/blast_engine.h b/c++/include/algo/blast/core/blast_engine.h
index a27e703..d464c66 100644
--- a/c++/include/algo/blast/core/blast_engine.h
+++ b/c++/include/algo/blast/core/blast_engine.h
@@ -1,4 +1,4 @@
-/* $Id: blast_engine.h 214207 2010-12-02 16:11:26Z maning $
+/* $Id: blast_engine.h 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -46,6 +46,7 @@
 #include <algo/blast/core/blast_seqsrc.h>
 #include <algo/blast/core/blast_diagnostics.h>   
 #include <algo/blast/core/blast_hspstream.h>
+#include <algo/blast/core/na_ungapped.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -237,6 +238,26 @@ typedef Int2 (*BlastWordFinderType)
       BlastInitHitList*,
       BlastUngappedStats*);
 
+/** Short read mapper function pointer type */
+typedef Int2 (*JumperGappedType)
+     (BLAST_SequenceBlk*,
+      BLAST_SequenceBlk*,
+      BlastQueryInfo*,
+      LookupTableWrap*,
+      const BlastInitialWordParameters*,
+      const BlastScoringParameters*,
+      const BlastHitSavingParameters*,
+      BlastOffsetPair* offset_pairs,
+      MapperWordHits* mapper_wordhits,
+      Int4,
+      BlastGapAlignStruct*,
+      BlastInitHitList*,
+      BlastHSPList**,
+      BlastUngappedStats*,
+      BlastGappedStats*);
+    
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/c++/include/algo/blast/core/blast_gapalign.h b/c++/include/algo/blast/core/blast_gapalign.h
index 8dccbf5..54a1558 100644
--- a/c++/include/algo/blast/core/blast_gapalign.h
+++ b/c++/include/algo/blast/core/blast_gapalign.h
@@ -1,4 +1,4 @@
-/* $Id: blast_gapalign.h 389061 2013-02-13 14:45:04Z maning $
+/* $Id: blast_gapalign.h 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -62,6 +62,9 @@ typedef struct {
 } BlastGapDP;
 
 
+typedef struct JumperGapAlign JumperGapAlign;
+
+
 /** Structure supporting the gapped alignment */
 typedef struct BlastGapAlignStruct {
    Boolean positionBased; /**< Is this PSI-BLAST? */
@@ -76,6 +79,8 @@ typedef struct BlastGapAlignStruct {
    Int4 dp_mem_alloc;  /**< current number of structures allocated */
    BlastScoreBlk* sbp; /**< Pointer to the scoring information block */
    Int4 gap_x_dropoff; /**< X-dropoff parameter to use */
+   Int4 max_mismatches;  /**< Max number of mismatches for jumper */
+   Int4 mismatch_window; /**< Window sie for mismatches for jumper */
    Int4 query_start; /**< query start offset of current alignment */
    Int4 query_stop; /**< query end offseet of current alignment */
    Int4 subject_start;  /**< subject start offset current alignment */
@@ -85,6 +90,8 @@ typedef struct BlastGapAlignStruct {
    Int4 greedy_subject_seed_start;  /**< for greedy alignments, the subject
                                          offset of the gapped start point */
    Int4 score;   /**< Return value: alignment score */
+
+   JumperGapAlign* jumper;   /**< data for jumper alignment */
 } BlastGapAlignStruct;
 
 /** Initializes the BlastGapAlignStruct structure 
diff --git a/c++/include/algo/blast/core/blast_hits.h b/c++/include/algo/blast/core/blast_hits.h
index b227fff..003dea3 100644
--- a/c++/include/algo/blast/core/blast_hits.h
+++ b/c++/include/algo/blast/core/blast_hits.h
@@ -1,4 +1,4 @@
-/* $Id: blast_hits.h 458579 2015-02-06 15:12:03Z fongah2 $
+/* $Id: blast_hits.h 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -49,6 +49,9 @@
 extern "C" {
 #endif
 
+
+typedef struct SequenceOverhangs SequenceOverhangs;
+
 /** Keeps prelim_hitlist_size and HitSavingOptions
     together, mostly for use by hspstream. */
 typedef struct SBlastHitsParameters {
@@ -103,6 +106,22 @@ typedef struct SPHIHspInfo {
     Int4 length; /**< Length of this pattern occurrence in subject. */
 } SPHIHspInfo;
 
+typedef struct JumperEditsBlock JumperEditsBlock;
+
+/** Mapping information for an HSP */
+typedef struct BlastHSPMappingInfo
+{
+   JumperEditsBlock* edits; /**< Information about mismatches and gaps, used
+                               for mapping short reads */
+   Uint1 left_edge;  /**< Two subject bases before the alignment in the four
+                          least significant bits and flags in most significat
+                          bits (for RNA-seq mapping) */
+   Uint1 right_edge; /** < Same as above for subject bases after the alignment
+                          (for RNA-seq mapping) */
+   Int4 flags;             /**< Additional information about this HSP */
+   SequenceOverhangs* subject_overhangs; /**< Unaligned subject subsequence */
+} BlastHSPMappingInfo;
+
 /** Structure holding all information about an HSP */
 typedef struct BlastHSP {
    Int4 score;           /**< This HSP's raw score */
@@ -123,6 +142,9 @@ typedef struct BlastHSP {
    SPHIHspInfo* pat_info; /**< In PHI BLAST, information about this pattern
                                  match. */
    Int4 num_positives;
+
+   BlastHSPMappingInfo* map_info;
+
 } BlastHSP;
 
 /** The structure to hold all HSPs for a given sequence after the gapped 
@@ -154,6 +176,7 @@ typedef struct BlastHitList {
    BlastHSPList** hsplist_array; /**< Array of HSP lists for individual
                                           database hits */
    Int4 hsplist_current; /**< Number of allocated HSP list arrays. */
+   Int4 num_hits;   /**< Number of similar hits for the query (for mapping) */
 } BlastHitList;
 
 /** The structure to contain all BLAST results, for multiple queries */
@@ -226,6 +249,21 @@ Blast_HSPInit(Int4 query_start, Int4 query_end,
               Int4 query_context, Int2 query_frame, Int2 subject_frame,
               Int4 score, GapEditScript* *gap_edit, BlastHSP** ret_hsp);
 
+/** Make a deep copy of an HSP */
+NCBI_XBLAST_EXPORT
+BlastHSP*
+Blast_HSPClone(const BlastHSP* hsp);
+
+/** Deallocate memory for an HSP's additional data structure */
+NCBI_XBLAST_EXPORT
+BlastHSPMappingInfo* BlastHSPMappingInfoFree(BlastHSPMappingInfo* info);
+
+/** Allocate memory for an HSP's additional data structure */
+NCBI_XBLAST_EXPORT
+BlastHSPMappingInfo* BlastHSPMappingInfoNew(void);
+
+
+
 /** Reevaluate the HSP's score and percent identity after taking
  * into account the ambiguity information. Used only for blastn after a greedy
  * gapped extension with traceback. This function can remove part of the 
@@ -650,6 +688,8 @@ Int2 Blast_HSPListAppend(BlastHSPList** old_hsp_list_ptr,
  *                    sequence region containing hsp_list and that
  *                    containing combined_hsp_list [in]
  * @param allow_gap Allow merging HSPs at different diagonals [in]
+ * @param short_reads Assume that queries are shorter than the database
+ *                    overlap region [in]
  * @return 0 if HSP lists have been merged successfully, -1 otherwise.
  */
 NCBI_XBLAST_EXPORT
@@ -658,7 +698,8 @@ Int2 Blast_HSPListsMerge(BlastHSPList** hsp_list,
                    Int4 hsp_num_max, Int4* split_points, 
                    Int4 contexts_per_query,
                    Int4 chunk_overlap_size,
-                   Boolean allow_gap);
+                   Boolean allow_gap,
+                   Boolean short_reads);
                    
 /** Adjust subject offsets in an HSP list if only part of the subject sequence
  * was searched. Used when long subject sequence is split into more manageable
@@ -894,6 +935,63 @@ Int2 Blast_HSPResultsApplyMasklevel(BlastHSPResults *results,
                                     const BlastQueryInfo *query_info,
                                     Int4 masklevel, Int4 query_length);
 
+
+/********************************************************************************
+          Mapping hits API.
+********************************************************************************/
+
+
+/** Structre to store a spliced alignment */
+typedef struct BlastHSPChain
+{
+    Int4 num_hsps;             /**< Number of HSPs in the chain */
+    BlastHSP** hsp_array;      /**< Array of pointers to HSPs */
+
+    Int4 query_index;          /**< Index of query sequence */
+    Int4 oid;                  /**< Oid for the subject sequence */
+    Int4 score;                /**< Alignment score for the chain */
+    Int4 adapter;              /**< Position of detected adapted sequence in
+                                    the query */
+    Int4 polyA;                /**< Position of PolyA seqence in the query */
+
+    struct BlastHSPChain* pair;  /**< Pointer to mapped mate alignment for
+                                      paired short reads */
+
+    Int4 multiplicity;         /**< Number of idependent mappings for the same
+                                    query (including this one) */
+} BlastHSPChain;
+
+
+/** Structure that contains BLAST mapping results */
+typedef struct BlastMappingResults
+{
+    Int4 num_results;
+    BlastHSPChain** chain_array;
+} BlastMappingResults;
+
+
+/** Initialize the chain structure.
+ */
+NCBI_XBLAST_EXPORT
+BlastHSPChain* Blast_HSPChainNew(void);
+
+/** Free the chain structure
+ * @param ch Chain to be freed
+ */
+NCBI_XBLAST_EXPORT
+BlastHSPChain* Blast_HSPChainFree(BlastHSPChain* ch);
+
+/** Initialize BlastMappingResults structure
+ */
+NCBI_XBLAST_EXPORT
+BlastMappingResults* Blast_MappingResultsNew(void);
+
+/** Free BlastMappingResults structure
+ */
+NCBI_XBLAST_EXPORT
+BlastMappingResults* Blast_MappingResultsFree(BlastMappingResults* results);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/c++/include/algo/blast/core/blast_hspfilter.h b/c++/include/algo/blast/core/blast_hspfilter.h
index 6b6b79a..7287fec 100644
--- a/c++/include/algo/blast/core/blast_hspfilter.h
+++ b/c++/include/algo/blast/core/blast_hspfilter.h
@@ -1,4 +1,4 @@
-/*  $Id: blast_hspfilter.h 161402 2009-05-27 17:35:47Z camacho $
+/*  $Id: blast_hspfilter.h 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -48,11 +48,12 @@ extern "C" {
 typedef struct BlastHSPWriter BlastHSPWriter;
 
 /** Function pointer typedef to implement hsp_writer */
-typedef BlastHSPWriter* (*BlastHSPWriterNewFn)  (void*, BlastQueryInfo*);
+typedef BlastHSPWriter* (*BlastHSPWriterNewFn)  (void*, BlastQueryInfo*,
+                                                 BLAST_SequenceBlk*);
 typedef BlastHSPWriter* (*BlastHSPWriterFreeFn) (BlastHSPWriter*);
-typedef int (*BlastHSPWriterInitFn) (void*, BlastHSPResults*);
+typedef int (*BlastHSPWriterInitFn) (void*, void*);
 typedef int (*BlastHSPWriterRunFn)  (void*, BlastHSPList*);
-typedef int (*BlastHSPWriterFinalFn)(void*, BlastHSPResults*);
+typedef int (*BlastHSPWriterFinalFn)(void*, void*);
 
 
 /** ADT definition of BlastHSPWriter */
@@ -77,7 +78,8 @@ typedef struct BlastHSPWriterInfo {
  */
 NCBI_XBLAST_EXPORT
 BlastHSPWriter*
-BlastHSPWriterNew(BlastHSPWriterInfo** writer_info, BlastQueryInfo *query_info);
+BlastHSPWriterNew(BlastHSPWriterInfo** writer_info, BlastQueryInfo *query_info,
+                  BLAST_SequenceBlk* query);
 
 /**--------------------------------pipe------------------------------*/
 /** forwarded declarations */
diff --git a/c++/include/algo/blast/core/blast_hspstream.h b/c++/include/algo/blast/core/blast_hspstream.h
index 1d763df..1a75e89 100644
--- a/c++/include/algo/blast/core/blast_hspstream.h
+++ b/c++/include/algo/blast/core/blast_hspstream.h
@@ -1,4 +1,4 @@
-/*  $Id: blast_hspstream.h 419225 2013-11-22 17:08:29Z camacho $
+/*  $Id: blast_hspstream.h 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -146,6 +146,23 @@ BlastHSPStream* BlastHSPStreamFree(BlastHSPStream* hsp_stream);
 NCBI_XBLAST_EXPORT
 void BlastHSPStreamClose(BlastHSPStream* hsp_stream);
 
+/** Closes the BlastHSPStream structure for writing without any sorting as done
+ * in BlastHSPStreamClose. Any subsequent attempt to write to the stream will
+ * return error.
+ * @param hsp_stream The stream to close [in] [out]
+ */
+NCBI_XBLAST_EXPORT
+void BlastHSPStreamSimpleClose(BlastHSPStream* hsp_stream);
+
+/** Closes BlastHSPStream structure for mapping and produces
+ *  BlastMappingResults
+ * @param hsp_stream The stream to close [in] [out]
+ * @param results The results [in] [out]
+*/
+NCBI_XBLAST_EXPORT
+void BlastHSPStreamMappingClose(BlastHSPStream* hsp_stream,
+                                BlastMappingResults* results);
+
 /** Closes the BlastHSPStream structure after traceback. 
  * This is mainly to provide a chance to apply post-traceback pipes.
  * @param hsp_stream The stream to close [in] [out]
diff --git a/c++/include/algo/blast/core/blast_kappa.h b/c++/include/algo/blast/core/blast_kappa.h
index a7d5d5c..f360152 100644
--- a/c++/include/algo/blast/core/blast_kappa.h
+++ b/c++/include/algo/blast/core/blast_kappa.h
@@ -1,4 +1,4 @@
-/* $Id: blast_kappa.h 496008 2016-03-23 11:29:15Z ivanov $
+/* $Id: blast_kappa.h 495576 2016-03-18 14:26:46Z rackerst $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/algo/blast/core/blast_lookup.h b/c++/include/algo/blast/core/blast_lookup.h
index e190cff..79a605d 100644
--- a/c++/include/algo/blast/core/blast_lookup.h
+++ b/c++/include/algo/blast/core/blast_lookup.h
@@ -1,4 +1,4 @@
-/* $Id: blast_lookup.h 103491 2007-05-04 17:18:18Z kazimird $
+/* $Id: blast_lookup.h 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -127,6 +127,57 @@ static NCBI_INLINE Int4 ComputeTableIndexIncremental(Int4 wordsize,
   return ((index << charsize) | word[wordsize - 1]) & mask;
 }
 
+
+/** Thin backbone cell for nucleotide lookup table with hashed words */
+typedef struct BackboneCell
+{
+    Uint4 word;
+    Int4* offsets;
+    Int4 num_offsets;
+    Int4 allocated;
+    struct BackboneCell* next;
+} BackboneCell;
+
+
+/** Hash function type for the lookup table */
+typedef Uint4 (*TNaLookupHashFunction)(Uint1*, Uint4);
+
+
+BackboneCell* BackboneCellFree(BackboneCell* cell);
+
+/** Create a new cell for a given word and offset
+ *@param word Nucleotide word in 2na [in]
+ *@param offset Offset for the word [in]
+ *@param size Size of the offset array to be allocated [in]
+ */
+BackboneCell* BackboneCellNew(Uint4 word, Int4 offset, Int4 size);
+
+
+/** Add all applicable query offsets to a hashed lookup table
+ *
+ * @param backbone The current list of hashtable cells [in][out]
+ * @param word_length Number of letters in a word [in]
+ * @param charsize Number of bits in one letter [in]
+ * @param lut_word_length Width of the lookup table in letters
+ *                      (must be <= word_length) [in]
+ * @param query The query sequence [in]
+ * @param locations What locations on the query sequence to index? [in]
+ * @param hash_func Hash function for words in 2na [in]
+ * @param counts Word counts in a database, to limit lookup table by databse
+ *               word frequency [in]
+ */
+void BlastHashLookupIndexQueryExactMatches(BackboneCell **backbone,
+                                           Int4 word_length,
+                                           Int4 charsize,
+                                           Int4 lut_word_length,
+                                           BLAST_SequenceBlk* query,
+                                           BlastSeqLoc* locations,
+                                           TNaLookupHashFunction hash_func,
+                                           Uint4 mask,
+                                           Uint1* counts);
+
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/c++/include/algo/blast/core/blast_nalookup.h b/c++/include/algo/blast/core/blast_nalookup.h
index a1d2788..11c1eda 100644
--- a/c++/include/algo/blast/core/blast_nalookup.h
+++ b/c++/include/algo/blast/core/blast_nalookup.h
@@ -1,4 +1,4 @@
-/* $Id: blast_nalookup.h 178819 2009-12-16 19:48:29Z maning $
+/* $Id: blast_nalookup.h 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -36,6 +36,8 @@
 #include <algo/blast/core/blast_lookup.h>
 #include <algo/blast/core/blast_options.h>
 
+#include <algo/blast/core/blast_seqsrc.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -237,7 +239,7 @@ typedef struct BlastMBLookupTable {
     Int4 word_length;      /**< number of exact letter matches that will trigger
                               an ungapped extension */
     Int4 lut_word_length;  /**< number of letters in a lookup table word */
-    Int4 hashsize;       /**< = 4^(lut_word_length) */ 
+    Int8 hashsize;       /**< = 4^(lut_word_length) */ 
     Boolean discontiguous; /**< Are discontiguous words used? */
     Int4 template_length; /**< Length of the discontiguous word template */
     EDiscTemplateType template_type; /**< Type of the discontiguous 
@@ -245,6 +247,8 @@ typedef struct BlastMBLookupTable {
     Boolean two_templates; /**< Use two templates simultaneously */
     EDiscTemplateType second_template_type; /**< Type of the second 
                                                 discontiguous word template */
+
+    Boolean stride;     /**< is lookup table created with a stride */
     Int4 scan_step;     /**< Step size for scanning the database */
     Int4* hashtable;   /**< Array of positions              */
     Int4* hashtable2;  /**< Array of positions for second template */
@@ -262,7 +266,6 @@ typedef struct BlastMBLookupTable {
     Int4 num_unique_pos_added; /**< Number of positions added to the l.t. */
     Int4 num_words_added; /**< Number of words added to the l.t. */
     BlastSeqLoc* masked_locations; /**< masked locations, only non-NULL for soft-masking. */
-
 } BlastMBLookupTable;
 
 /**
@@ -277,13 +280,15 @@ typedef struct BlastMBLookupTable {
  * @param approx_table_entries An upper bound on the number of words
  *        that must be added to the lookup table [in]
  * @param lut_width The number of nucleotides in one lookup table word [in]
+ * @param seqsrc Database sequences [in]
  */
 Int2 BlastMBLookupTableNew(BLAST_SequenceBlk* query, BlastSeqLoc* location,
                            BlastMBLookupTable** mb_lt_ptr,
                            const LookupTableOptions* lookup_options,
                            const QuerySetUpOptions* query_options,
                            Int4 approx_table_entries,
-                           Int4 lut_width);
+                           Int4 lut_width,
+                           BlastSeqSrc* seqsrc);
 
 /** 
  * Deallocate memory used by the Mega BLAST lookup table
@@ -582,6 +587,105 @@ static NCBI_INLINE Int4 ComputeDiscontiguousIndex(Uint8 accum,
    return index;
 }
 
+/** Find an index into a sparse array using pv_array as a bit field
+ * @param index Index to translate [in]
+ * @param pv_array Bit field (lookup table pv_array) [in]
+ * @param pv_array_bts Log2 of pv_array size [in]
+ * @param pv_counts Array of set bit counts, where pv_counts[i] is the number
+ *                   of bits set in pv_array[0..i-1] [in]
+ * @param words_per_bit Number of words represented by one bit in the
+ *                       pv_array [in]
+ * @return Index into the sparse array
+ */
+Int8 FindSparseIndex(Int8 index, PV_ARRAY_TYPE* pv_array, Int4 pv_array_bts,
+                     Int4* pv_counts, Int4 words_per_bit);
+
+
+/** Find an index into a sparse array using pv_array as a bit field, for a
+ * batch of indices
+ * @param in_array Input array of indices to translate [in]
+ * @param out_array Output array of indices to translate [out]
+ * @param length Number of indices to translate [in]
+ * @param pv_array Bit field (lookup table pv_array) [in]
+ * @param pv_array_bts Log2 of pv_array size [in]
+ * @param pv_counts Array of set bit counts, where pv_counts[i] is the number
+ *                   of bits set in pv_array[0..i-1] [in]
+ * @param words_per_bit Number of words represented by one bit in the
+ *                       pv_array [in]
+ * @return Index into the sparse array
+ */
+Int2 FindSparseIndices(Int8* NCBI_RESTRICT in_array, Int8* out_array, Int4 length,
+                       PV_ARRAY_TYPE* pv_array, Int4 pv_array_bts,
+                       Int4* counts, Int4 elems_per_bit);
+
+
+/*----------------------- Hashed Na lookup table -------------------------*/
+
+/** Structure defining one cell of the compacted lookup table */
+typedef struct NaHashLookupBackboneCell {
+
+    Int1 num_words;      /**< number of words stored under the same hash value */
+    Int1 num_offsets[3]; /**< number of offsets for each word if there are
+                              fewer than 3 */
+
+    Uint4 words[3];      /**< words stored under this hash value */
+    Int4 offsets[9];     /**< offset locations for each word */
+
+} NaHashLookupBackboneCell;
+
+
+typedef struct BlastNaHashLookupTable {
+    Int4 mask;             /**< part of index to mask off, that is, top 
+                                (wordsize*charsize) bits should be discarded. */
+    Int4 word_length;      /**< Length in bases of the full word match 
+                                required to trigger extension */
+    Int4 lut_word_length;  /**< Length in bases of a word indexed by the
+                                lookup table */
+    Int4 scan_step;        /**< number of bases between successive words */
+    Int4 backbone_size;    /**< number of cells in the backbone */
+    Int4 longest_chain;    /**< length of the longest chain on the backbone */
+    NaHashLookupBackboneCell * thick_backbone; /**< the "thick" backbone. after 
+                                              queries are indexed, compact the 
+                                              backbone to put at most 
+                                              NA_HITS_PER_CELL hits on the 
+                                              backbone, otherwise point to 
+                                              some overflow storage */
+    Int4* overflow;        /**< the overflow array for the compacted 
+                                lookup table */
+    Int4 offsets_size;     /**< Number of elements in the overflow array */
+    PV_ARRAY_TYPE *pv;     /**< Presence vector bitfield; bit positions that
+                                are set indicate that the corresponding thick
+                                backbone cell contains hits */
+    Int4 pv_array_bts;     /**< power of 2 by which to divide a word to access
+                                PV_ARRAY_TYPE element in pv array */
+    void *scansub_callback; /**< function for scanning subject sequences */
+    void *hash_callback;    /**< hash function to be used for hash table */
+    BlastSeqLoc* masked_locations; /**< masked locations, only non-NULL for
+                                      soft-masking. */
+} BlastNaHashLookupTable;
+
+/* Maximum number of words and offsets that can be strored in thich backbone */
+#define NA_WORDS_PER_HASH 3
+#define NA_OFFSETS_PER_HASH 9
+
+
+Int4 BlastNaHashLookupTableNew(BLAST_SequenceBlk* query,
+                               BlastSeqLoc* locations,
+                               BlastNaHashLookupTable** lut,
+                               const LookupTableOptions* opt, 
+                               const QuerySetUpOptions* query_options,
+                               BlastSeqSrc* seqsrc);
+
+
+/** Free a nucleotide lookup table.
+ *  @param lookup The lookup table structure to be freed
+ *  @return NULL
+ */
+BlastNaHashLookupTable*
+BlastNaHashLookupTableDestruct(BlastNaHashLookupTable* lookup);
+
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/c++/include/algo/blast/core/blast_options.h b/c++/include/algo/blast/core/blast_options.h
index bec10f3..0f2e754 100644
--- a/c++/include/algo/blast/core/blast_options.h
+++ b/c++/include/algo/blast/core/blast_options.h
@@ -1,4 +1,4 @@
-/* $Id: blast_options.h 456407 2015-01-12 15:47:18Z fongah2 $
+/* $Id: blast_options.h 506100 2016-07-01 15:46:25Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -70,6 +70,9 @@ extern "C" {
                                           the word size is explicitly 
                                           overridden) */
 
+#define BLAST_WORDSIZE_MAPPER 16   /**< default word size for mapping rna-seq
+                                        to a genome */
+
 /** Default matrix name: BLOSUM62 */
 #define BLAST_DEFAULT_MATRIX "BLOSUM62"
 
@@ -83,6 +86,7 @@ extern "C" {
 #define BLAST_GAP_OPEN_NUCL 5 /**< default gap open penalty (blastn) */
 #define BLAST_GAP_OPEN_MEGABLAST 0 /**< default gap open penalty (megablast
                                         with greedy gapped alignment) */
+#define BLAST_GAP_OPEN_MAPPER 0
 
 /** cost to extend a gap. */
 #define BLAST_GAP_EXTN_PROT 1 /**< default gap open penalty (all 
@@ -91,6 +95,8 @@ extern "C" {
 #define BLAST_GAP_EXTN_MEGABLAST 0 /**< default gap open penalty (megablast)
                                         with greedy gapped alignment) */
 
+#define BLAST_GAP_EXTN_MAPPER 8
+
 /** neighboring word score thresholds; a threshold of zero
  *  means that only query and subject words that match exactly
  *  will go into the BLAST lookup table when it is generated 
@@ -141,6 +147,9 @@ extern "C" {
 #define BLAST_PENALTY -3        /**< default nucleotide mismatch score */
 #define BLAST_REWARD 1          /**< default nucleotide match score */
 
+#define BLAST_PENALTY_MAPPER -8
+#define BLAST_REWARD_MAPPER 1
+
 /** Default parameters for saving hits */
 #define BLAST_EXPECT_VALUE 10.0 /**< by default, alignments whose expect
                                      value exceeds this number are discarded */
@@ -172,8 +181,9 @@ typedef enum {
     ePhiNaLookupTable,  /**< nucleotide lookup table for phi-blast */
     eRPSLookupTable, /**< RPS lookup table (rpsblast and rpstblastn) */
     eIndexedMBLookupTable, /**< use database index as a lookup structure */
-    eMixedMBLookupTable /**< use when some volumes are searched with index and 
+    eMixedMBLookupTable, /**< use when some volumes are searched with index and 
                              some are not */
+    eNaHashLookupTable  /**< used for 16-base words */
 } ELookupTableType;
 
 /** Options needed to construct a lookup table 
@@ -189,6 +199,11 @@ typedef struct LookupTableOptions {
    Int4 mb_template_type; /**< Type of a discontiguous word template */
    char* phi_pattern;  /**< PHI-BLAST pattern */
    EBlastProgramType program_number; /**< indicates blastn, blastp, etc. */
+   Uint4 stride; /**< number of words to skip after collecting each word */
+   Boolean db_filter; /**< scan the database and include only words that appear
+                           in the database between 1 and 9 times
+                           (currently implemented only for MB lookuptable
+                           and lookup table word size 16) */
 } LookupTableOptions;
 
 /** Options for dust algorithm, applies only to nucl.-nucl. comparisons.
@@ -270,6 +285,7 @@ typedef struct BlastInitialWordOptions {
 typedef enum EBlastPrelimGapExt {
     eDynProgScoreOnly,          /**< standard affine gapping */
     eGreedyScoreOnly,           /**< Greedy extension (megaBlast) */
+    eJumperWithTraceback,       /**< Jumper extension (mapping) */
     eSmithWatermanScoreOnly     /**< Score-only smith-waterman */
 } EBlastPrelimGapExt;
 
@@ -302,6 +318,11 @@ typedef struct BlastExtensionOptions {
                                    if zero then compositional adjustment is
                                    not used */
    Int4 unifiedP; /**< Indicates unified P values to be used in blastp or tblastn */
+
+    Int4 max_mismatches;    /**< Maximum number of mismatches allowed for Jumper */
+
+    Int4 mismatch_window;   /**< Widnow for counting mismatches for Jumper */
+
    EBlastProgramType program_number; /**< indicates blastn, blastp, etc. */
 } BlastExtensionOptions;
 
@@ -386,6 +407,11 @@ typedef struct BlastHitSavingOptions {
      */
    Int4 max_hsps_per_subject;
 
+   /**< Queries are paired reads, for mapping */
+   Boolean paired;
+   /**< Splice HSPs for each query (for mapping RNA-Seq to a genome) */
+   Boolean splice;
+
 } BlastHitSavingOptions;
 
 /** Scoring options block 
diff --git a/c++/include/algo/blast/core/blast_program.h b/c++/include/algo/blast/core/blast_program.h
index c6ffc4f..2859a41 100644
--- a/c++/include/algo/blast/core/blast_program.h
+++ b/c++/include/algo/blast/core/blast_program.h
@@ -1,4 +1,4 @@
-/* $Id: blast_program.h 103498 2007-05-04 18:56:48Z camacho $
+/* $Id: blast_program.h 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -62,6 +62,8 @@ extern "C" {
 #define PSSM_SUBJECT_MASK       (0x1<<7)
 /** This bit is on if the query includes a pattern (PHI-BLAST) */
 #define PATTERN_QUERY_MASK      (0x1<<8)
+/** This bit is on for fast mapping of short reads */
+#define MAPPING_MASK            (0x1<<9)
 
 /******************** Main BLAST program definitions ***********************/
 
@@ -83,6 +85,7 @@ typedef enum {
     eBlastTypeRpsTblastn    = (PSSM_SUBJECT_MASK | eBlastTypeBlastx),
     eBlastTypePhiBlastp     = (PATTERN_QUERY_MASK | eBlastTypeBlastp),
     eBlastTypePhiBlastn     = (PATTERN_QUERY_MASK | eBlastTypeBlastn),
+    eBlastTypeMapping       = (eBlastTypeBlastn | MAPPING_MASK),
     eBlastTypeUndefined     = 0x0
 } EBlastProgramType;
 
@@ -160,12 +163,22 @@ Boolean Blast_ProgramIsPhiBlast(EBlastProgramType p);
 NCBI_XBLAST_EXPORT 
 Boolean Blast_ProgramIsRpsBlast(EBlastProgramType p);
 
+NCBI_XBLAST_EXPORT 
+Boolean Blast_ProgramIsMapping(EBlastProgramType p);
+
+NCBI_XBLAST_EXPORT
+Boolean Blast_QueryIsPattern(EBlastProgramType p);
+
+NCBI_XBLAST_EXPORT 
+Boolean Blast_ProgramIsNucleotide(EBlastProgramType p);
+
 /** Returns true if program is not undefined
  * @param p program type [in]
  */
 NCBI_XBLAST_EXPORT 
 Boolean Blast_ProgramIsValid(EBlastProgramType p);
 
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/c++/include/algo/blast/core/blast_query_info.h b/c++/include/algo/blast/core/blast_query_info.h
index 086abc6..74cc3a1 100644
--- a/c++/include/algo/blast/core/blast_query_info.h
+++ b/c++/include/algo/blast/core/blast_query_info.h
@@ -1,4 +1,4 @@
-/* $Id: blast_query_info.h 419225 2013-11-22 17:08:29Z camacho $
+/* $Id: blast_query_info.h 517499 2016-10-25 17:20:41Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -42,6 +42,20 @@
 extern "C" {
 #endif
 
+/** Information about paired segments (for mapping short reads)
+ */
+typedef enum EMagicBlastSegmentInfo {
+    eNoSegments = 0,             /**< Sequence is not part of a pair */
+    fFirstSegmentFlag = 1,       /**< The first sequence of a pair */
+    fLastSegmentFlag = 1 << 1,   /**< The last sequence of a pair */
+    fPartialFlag = 1 << 2,       /**< The other segment is not present (did not
+                                   pass quality filtering */
+    eFirstSegment = fFirstSegmentFlag, /**< The first sequence of a pair with
+                                            both sequences read and accepted */
+    eLastSegment = fLastSegmentFlag    /** The last sequence of a pair with
+                                           both sequences read and accepted */
+} EMagicBlastSegmentInfo;
+
 /** The context related information */
 typedef struct BlastContextInfo {
     Int4 query_offset;      /**< Offset of this query, strand or frame in the
@@ -55,6 +69,7 @@ typedef struct BlastContextInfo {
                               This field should be set only by the setup code
                               and read by subsequent stages of the BLAST search
                               */
+    Int4 segment_flags;      /**< Flags describing segments for paired reads */
 } BlastContextInfo;
 
 /** Forward declaration of SPHIQueryInfo */
@@ -69,6 +84,8 @@ typedef struct BlastQueryInfo {
     BlastContextInfo * contexts; /**< Information per context */
     Uint4 max_length;    /**< Length of the longest among the concatenated
                             queries */
+    Uint4 min_length;    /**< Length of the shortest among the concatenated
+                            queries */
     struct SPHIQueryInfo* pattern_info; /**< Counts of PHI BLAST pattern
                                       occurrences, used in PHI BLAST only. */
 } BlastQueryInfo;
diff --git a/c++/include/algo/blast/core/blast_stat.h b/c++/include/algo/blast/core/blast_stat.h
index 0b554f0..ae7b902 100644
--- a/c++/include/algo/blast/core/blast_stat.h
+++ b/c++/include/algo/blast/core/blast_stat.h
@@ -1,4 +1,4 @@
-/*  $Id: blast_stat.h 496008 2016-03-23 11:29:15Z ivanov $
+/*  $Id: blast_stat.h 495576 2016-03-18 14:26:46Z rackerst $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/algo/blast/core/hspfilter_mapper.h b/c++/include/algo/blast/core/hspfilter_mapper.h
new file mode 100644
index 0000000..f4ac1ca
--- /dev/null
+++ b/c++/include/algo/blast/core/hspfilter_mapper.h
@@ -0,0 +1,101 @@
+/*  $Id: hspfilter_mapper.h 504861 2016-06-20 15:45:40Z boratyng $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  Greg Boratyn
+ *
+ */
+
+/** @file hspfilter_mapper.h
+ * Implementation of a number of BlastHSPWriters to save the best chain 
+ * of RNA-Seq hits to a genome.
+ */
+
+#ifndef ALGO_BLAST_CORE__HSPFILTER_MAPSPLICED__H
+#define ALGO_BLAST_CORE__HSPFILTER_MAPSPLICED__H
+
+#include <algo/blast/core/ncbi_std.h>
+#include <algo/blast/core/blast_program.h>
+#include <algo/blast/core/blast_options.h>
+#include <algo/blast/core/blast_hspfilter.h>
+#include <algo/blast/core/blast_hits.h>
+#include <connect/ncbi_core.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ScoringOptions
+{
+    Int4 reward;
+    Int4 penalty;
+    Int4 gap_open;
+    Int4 gap_extend;
+    /* score for lack of splice signal */
+    Int4 no_splice_signal;
+} ScoringOptions;
+
+/** Keeps prelim_hitlist_size and HitSavingOptions together. */
+typedef struct BlastHSPMapperParams {
+   EBlastProgramType program;/**< program type */
+   ScoringOptions scoring_options; /**< scores for match, mismatch, and gap */
+   Int4 hitlist_size;        /**< number of hits saved during preliminary
+                                  part of search. */
+   Boolean paired;           /**< mapping with paired reads */
+   Boolean splice;           /**< mapping spliced reads (RNA-seq to a genome) */
+} BlastHSPMapperParams;
+
+/** Sets up parameter set for use by collector.
+ * @param hit_options field hitlist_size and hsp_num_max needed, a pointer to 
+ *      this structure will be stored on resulting structure.[in]
+ * @param scoring_options needed for mismatch and gap penalties, the pointer
+ *      will be stored [in]
+ * @return the pointer to the allocated parameter
+ */
+NCBI_XBLAST_EXPORT
+BlastHSPMapperParams*
+BlastHSPMapperParamsNew(const BlastHitSavingOptions* hit_options,
+                        const BlastScoringOptions* scoring_options);
+
+/** Deallocates the BlastHSPMapperParams structure passed in
+ * @param opts structure to deallocate [in]
+ * @return NULL
+ */
+NCBI_XBLAST_EXPORT
+BlastHSPMapperParams*
+BlastHSPMapperParamsFree(BlastHSPMapperParams* opts);
+
+/** WriterInfo to create a default writer: the collecter
+ * @param params The collector parameters.
+ * @return pointer to WriterInfo
+ */
+NCBI_XBLAST_EXPORT
+BlastHSPWriterInfo* 
+BlastHSPMapperInfoNew(BlastHSPMapperParams* params);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ALGO_BLAST_CORE__HSPFILTER_SPLICED__H */
diff --git a/c++/include/algo/blast/core/lookup_util.h b/c++/include/algo/blast/core/lookup_util.h
index 60391d8..186634a 100644
--- a/c++/include/algo/blast/core/lookup_util.h
+++ b/c++/include/algo/blast/core/lookup_util.h
@@ -1,4 +1,4 @@
-/* $Id: lookup_util.h 144893 2008-11-04 19:56:45Z ivanov $
+/* $Id: lookup_util.h 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -57,7 +57,7 @@ Int4 iexp(Int4 x, Int4 n);
  */
 
 NCBI_XBLAST_EXPORT
-Int4 ilog2(Int4 x);
+Int4 ilog2(Int8 x);
 
 /**
  * generates a de Bruijn sequence containing all substrings
diff --git a/c++/include/algo/blast/core/lookup_wrap.h b/c++/include/algo/blast/core/lookup_wrap.h
index d08b609..d983b4e 100644
--- a/c++/include/algo/blast/core/lookup_wrap.h
+++ b/c++/include/algo/blast/core/lookup_wrap.h
@@ -1,4 +1,4 @@
-/* $Id: lookup_wrap.h 369355 2012-07-18 17:07:15Z morgulis $
+/* $Id: lookup_wrap.h 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -40,6 +40,8 @@
 #include <algo/blast/core/blast_rps.h>
 #include <algo/blast/core/blast_stat.h>
 
+#include <algo/blast/core/blast_seqsrc.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -73,6 +75,7 @@ typedef Boolean (*T_Lookup_Callback)(const LookupTableWrap *, Int4, Int4);
  * @param lookup_wrap_ptr The initialized lookup table [out]
  * @param rps_info Structure containing RPS blast setup information [in]
  * @param error_msg message with warning or errors [in|out]
+ * @param seqsrc Database sequences [in]
  */
 NCBI_XBLAST_EXPORT
 Int2 LookupTableWrapInit(BLAST_SequenceBlk* query, 
@@ -80,7 +83,8 @@ Int2 LookupTableWrapInit(BLAST_SequenceBlk* query,
         const QuerySetUpOptions* query_options,
         BlastSeqLoc* lookup_segments, BlastScoreBlk* sbp, 
         LookupTableWrap** lookup_wrap_ptr, const BlastRPSInfo *rps_info,
-        Blast_Message* *error_msg);
+        Blast_Message* *error_msg,
+        BlastSeqSrc* seqsrc);
 
 /** Deallocate memory for the lookup table */
 NCBI_XBLAST_EXPORT
diff --git a/c++/include/algo/blast/core/na_ungapped.h b/c++/include/algo/blast/core/na_ungapped.h
index 875fd86..bbbb515 100644
--- a/c++/include/algo/blast/core/na_ungapped.h
+++ b/c++/include/algo/blast/core/na_ungapped.h
@@ -1,4 +1,4 @@
-/* $Id: na_ungapped.h 172278 2009-10-02 15:19:28Z maning $
+/* $Id: na_ungapped.h 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -43,6 +43,8 @@
 #include <algo/blast/core/blast_hits.h>
 #include <algo/blast/core/blast_diagnostics.h>
 
+#include <algo/blast/core/blast_gapalign.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -95,6 +97,67 @@ Int2 BlastNaWordFinder(BLAST_SequenceBlk* subject,
 NCBI_XBLAST_EXPORT
 void BlastChooseNaExtend(LookupTableWrap *lookup_wrap);
 
+
+/* A structure to hold several lists of word hits for groups of queries */
+typedef struct MapperWordHits
+{
+    BlastOffsetPair** pair_arrays; /**< lists of word hits */
+    Int4* num;                     /**< number of hits in the list */
+    Int4 num_arrays;               /**< number of pair_arrays */
+    Int4 array_size;               /**< size of each array */
+    Int4* last_diag;               /**< diagnal for the last word hit for each
+                                        query context */
+    Int4* last_pos;                /**< subject position for the last word hit
+                                        for each query context */
+
+    Int4 divisor;                  /**< divisor used to find pair_arrays index
+                                        based on query offset */
+} MapperWordHits;
+
+MapperWordHits* MapperWordHitsFree(MapperWordHits* wh);
+MapperWordHits* MapperWordHitsNew(const BLAST_SequenceBlk* query,
+                                  const BlastQueryInfo* query_info);
+
+
+NCBI_XBLAST_EXPORT
+Int2
+JumperNaWordFinder(BLAST_SequenceBlk * subject,
+                   BLAST_SequenceBlk * query,
+                   BlastQueryInfo * query_info,
+                   LookupTableWrap * lookup_wrap,
+                   const BlastInitialWordParameters * word_params,
+                   const BlastScoringParameters* score_params,
+                   const BlastHitSavingParameters* hit_params,
+                   BlastOffsetPair * offset_pairs,
+                   MapperWordHits* word_hits,
+                   Int4 max_hits,
+                   BlastGapAlignStruct* gap_align,
+                   BlastInitHitList* init_hitlist,
+                   BlastHSPList** hsp_list_ptr,
+                   BlastUngappedStats * ungapped_stats,
+                   BlastGappedStats* gapped_stats);
+
+
+NCBI_XBLAST_EXPORT
+Int2 ShortRead_IndexedWordFinder( 
+        BLAST_SequenceBlk * subject,
+        BLAST_SequenceBlk * query,
+        BlastQueryInfo * query_info,
+        LookupTableWrap * lookup_wrap,
+        const BlastInitialWordParameters * word_params,
+        const BlastScoringParameters* score_params,
+        const BlastHitSavingParameters* hit_params,
+        BlastOffsetPair * offset_pairs,
+        MapperWordHits* word_hits,
+        Int4 max_hits,
+        BlastGapAlignStruct* gap_align,
+        BlastInitHitList* init_hitlist,
+        BlastHSPList** hsp_list,
+        BlastUngappedStats* ungapped_stats,
+        BlastGappedStats* gapped_stats);
+
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/c++/include/algo/blast/format/blast_format.hpp b/c++/include/algo/blast/format/blast_format.hpp
index bc8bb46..1f1a3f8 100644
--- a/c++/include/algo/blast/format/blast_format.hpp
+++ b/c++/include/algo/blast/format/blast_format.hpp
@@ -1,4 +1,4 @@
-/* $Id: blast_format.hpp 495288 2016-03-16 14:51:11Z ivanov $
+/* $Id: blast_format.hpp 513847 2016-09-15 17:36:25Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -47,6 +47,7 @@ Author: Jason Papadopoulos
 #include <objtools/align_format/tabular.hpp>
 #include <objtools/align_format/showalign.hpp>
 #include <objtools/align_format/showdefline.hpp>
+#include <objtools/align_format/taxFormat.hpp>
 #include <algo/blast/format/blastfmtutil.hpp>
 #include <algo/blast/blastinput/blast_input.hpp>
 #include <algo/blast/blastinput/blast_args.hpp>
@@ -55,16 +56,35 @@ Author: Jason Papadopoulos
 #include <algo/blast/format/sam.hpp>
 #include <objects/blast/blast__.hpp>
 
-BEGIN_NCBI_SCOPE
 
+BEGIN_NCBI_SCOPE
+USING_SCOPE(align_format);
 class CCmdLineBlastXML2ReportData;
 
 /// This class formats the BLAST results for command line applications
 class NCBI_XBLASTFORMAT_EXPORT CBlastFormat
 {
 public:
-    /// The line length of pairwise blast output
-    static const int kFormatLineLength = 68;
+
+    ///igblast clone info
+    struct SClone {
+        string na;
+        string chain_type;
+        string aa;
+        string v_gene;
+        string d_gene;
+        string j_gene;
+        string seqid;
+        double identity;
+        string productive;
+    };
+
+    
+    enum {
+        /// The line length of pairwise blast output
+        kFormatLineLength = 68,
+        kMinTaxFormatLineLength = 100
+    };
 
     /// Constructor
     /// @param opts BLAST options used in the search [in]
@@ -208,6 +228,8 @@ public:
     /// @param result position index if index >= 0 [in]
     void PrintOneResultSet(blast::CIgBlastResults& results,
                            CConstRef<blast::CBlastQueryVector> queries, 
+                           SClone& clone_info,
+                           bool fill_clone_info,
                            int index = -1);
 
     /// Print all alignment information for aa PHI-BLAST run.
@@ -367,6 +389,9 @@ private:
 
     string m_Cmdline;
 
+    /// If true, print long sequence ids (database|accession)
+    bool m_LongSeqId;
+
     /// Output the ancillary data for one query that was searched
     /// @param summary The ancillary data to report [in]
     void x_PrintOneQueryFooter(const blast::CBlastAncillaryData& summary);
@@ -428,7 +453,9 @@ private:
 
    /// Prints IgTabular report for one query
    /// @param results Results for one query or Phi-blast iteration [in]
-   void x_PrintIgTabularReport(const blast::CIgBlastResults& results);
+   void x_PrintIgTabularReport(const blast::CIgBlastResults& results,
+                               SClone& clone_info,
+                               bool fill_clone_info);
 
    /// Replace the query with its reversed-compliement
    /// @param results Ig Blast results [in, out]
@@ -458,6 +485,7 @@ private:
    void x_WriteXML2(CCmdLineBlastXML2ReportData & report_data);
 
    void x_InitSAMFormatter();
+   void x_PrintTaxReport(const blast::CSearchResults& results);
 };
 
 END_NCBI_SCOPE
diff --git a/c++/include/algo/blast/igblast/igblast.hpp b/c++/include/algo/blast/igblast/igblast.hpp
index 0700193..c5863c5 100644
--- a/c++/include/algo/blast/igblast/igblast.hpp
+++ b/c++/include/algo/blast/igblast/igblast.hpp
@@ -1,4 +1,4 @@
-/*  $Id: igblast.hpp 499246 2016-04-25 11:32:24Z ivanov $
+/*  $Id: igblast.hpp 514854 2016-09-26 17:24:36Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -79,6 +79,7 @@ public:
     bool m_Translate;                // should translation be displayed
     bool m_ExtendAlign;
     int m_MinVLength;
+    int m_MinJLength;
 };
 
 class CIgAnnotation : public CObject
@@ -330,7 +331,7 @@ private:
 
     
     /// Append annotation info to the final results
-    static void s_SetAnnotation(vector<CRef <CIgAnnotation> > &annot,
+    void x_SetAnnotation(vector<CRef <CIgAnnotation> > &annot,
                                 CRef<CSearchResultSet> &final_results);
 
     void x_FindDJ(CRef<CSearchResultSet>& results_D,
@@ -354,7 +355,7 @@ private:
                      bool va_or_vd_as_heavy_chain);
 
     void x_ExtendAlign(CRef<CSearchResultSet> & results);
-    void x_ScreenV(CRef<CSearchResultSet> & results);
+    void x_ScreenByAlignLength(CRef<CSearchResultSet> & results, int length);
     void x_FillJDomain(CRef<CSeq_align> & align, CRef <CIgAnnotation> & annot);
     
 };
diff --git a/c++/include/cgi/cgi_session.hpp b/c++/include/cgi/cgi_session.hpp
index 667dc00..5297bd5 100644
--- a/c++/include/cgi/cgi_session.hpp
+++ b/c++/include/cgi/cgi_session.hpp
@@ -1,7 +1,7 @@
 #ifndef CGI___SESSION__HPP
 #define CGI___SESSION__HPP
 
-/*  $Id: cgi_session.hpp 497377 2016-04-06 13:21:42Z ivanov $
+/*  $Id: cgi_session.hpp 497034 2016-04-04 12:46:26Z dicuccio $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/cgi/cgiapp.hpp b/c++/include/cgi/cgiapp.hpp
index c5679fb..a5e35b2 100644
--- a/c++/include/cgi/cgiapp.hpp
+++ b/c++/include/cgi/cgiapp.hpp
@@ -1,7 +1,7 @@
 #ifndef CGI___CGIAPP__HPP
 #define CGI___CGIAPP__HPP
 
-/*  $Id: cgiapp.hpp 497377 2016-04-06 13:21:42Z ivanov $
+/*  $Id: cgiapp.hpp 497034 2016-04-04 12:46:26Z dicuccio $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/cgi/cgictx.hpp b/c++/include/cgi/cgictx.hpp
index fe6d312..8325ac1 100644
--- a/c++/include/cgi/cgictx.hpp
+++ b/c++/include/cgi/cgictx.hpp
@@ -1,7 +1,7 @@
 #ifndef NCBI_CGI_CTX__HPP
 #define NCBI_CGI_CTX__HPP
 
-/*  $Id: cgictx.hpp 433624 2014-04-28 15:39:19Z grichenk $
+/*  $Id: cgictx.hpp 500790 2016-05-09 11:30:33Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -203,7 +203,7 @@ public:
     ///   SCHEME://SERVER_NAME[:SERVER_PORT]/SCRIPT_NAME
     /// @deprecated The flag is ignored, use GetSelfURL(void).
     NCBI_DEPRECATED
-    const string& GetSelfURL(ESelfUrlPort use_port) const
+    const string& GetSelfURL(ESelfUrlPort /*use_port*/) const
         { return GetSelfURL(); }
 
     /// Using HTTP environment variables, compose the CGI's own URL as:
diff --git a/c++/include/cgi/error_codes.hpp b/c++/include/cgi/error_codes.hpp
index 2bc5509..c8d0ef6 100644
--- a/c++/include/cgi/error_codes.hpp
+++ b/c++/include/cgi/error_codes.hpp
@@ -1,7 +1,7 @@
 #ifndef CGI___ERROR_CODES__HPP
 #define CGI___ERROR_CODES__HPP
 
-/*  $Id: error_codes.hpp 492269 2016-02-16 15:24:58Z ivanov $
+/*  $Id: error_codes.hpp 491685 2016-02-08 18:39:43Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/cgi/ncbicgi.hpp b/c++/include/cgi/ncbicgi.hpp
index fe18bbd..a262af4 100644
--- a/c++/include/cgi/ncbicgi.hpp
+++ b/c++/include/cgi/ncbicgi.hpp
@@ -1,7 +1,7 @@
 #ifndef CGI___NCBICGI__HPP
 #define CGI___NCBICGI__HPP
 
-/*  $Id: ncbicgi.hpp 497377 2016-04-06 13:21:42Z ivanov $
+/*  $Id: ncbicgi.hpp 497034 2016-04-04 12:46:26Z dicuccio $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/cgi/ncbicgir.hpp b/c++/include/cgi/ncbicgir.hpp
index ce94d9e..54c85f9 100644
--- a/c++/include/cgi/ncbicgir.hpp
+++ b/c++/include/cgi/ncbicgir.hpp
@@ -1,7 +1,7 @@
 #ifndef CGI___NCBICGIR__HPP
 #define CGI___NCBICGIR__HPP
 
-/*  $Id: ncbicgir.hpp 492270 2016-02-16 15:25:22Z ivanov $
+/*  $Id: ncbicgir.hpp 500790 2016-05-09 11:30:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -348,7 +348,7 @@ inline void CCgiResponse::SetLocation(const CUrl&        url,
                                       const IUrlEncoder* encoder)
 {
     SetHeaderValue(sm_LocationName,
-                   url.ComposeUrl(CCgiArgs::eAmp_Char, encoder));
+                   url.ComposeUrl(CUrlArgs::eAmp_Char, encoder));
 }
 
 inline void CCgiResponse::SetMultipartMode(EMultipartMode mode)
@@ -363,7 +363,7 @@ inline CCgiResponse::EMultipartMode CCgiResponse::GetMultipartMode(void)
 }
 
 inline void CCgiResponse::BeginPart(const string& name, const string& type,
-                                    size_t size)
+                                    size_t /*size*/)
 {
     BeginPart(name, type, out());
 }
diff --git a/c++/include/cgi/user_agent.hpp b/c++/include/cgi/user_agent.hpp
index aee40b1..d10ed17 100644
--- a/c++/include/cgi/user_agent.hpp
+++ b/c++/include/cgi/user_agent.hpp
@@ -1,7 +1,7 @@
 #ifndef CGI___USER_AGENT__HPP
 #define CGI___USER_AGENT__HPP
 
-/*  $Id: user_agent.hpp 466541 2015-05-04 14:38:31Z ivanov $
+/*  $Id: user_agent.hpp 514810 2016-09-26 15:28:00Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -97,7 +97,9 @@ public:
         eLynx,                  ///< Lynx       (lynx.browser.org)
         eNetscape,              ///< Netscape (Navigator), versions >=6 are Gecko-based (www.netscape.com)
         eOpera,                 ///< Opera      (www.opera.com)
-        eOregano,               ///< Oregano    (www.castle.org.uk/oregano/)
+        eOregano,               ///< Oregano    (www.castle.org.uk/oregano)
+        ePapers,                ///< Papers     (papersapp.com)
+        eUCBrowser,             ///< UC Browser (www.ucweb.com/ucbrowser)
         eW3m,                   ///< w3m        (www.w3m.org)
         eNagios,                ///< check_http/nagios-plugins (nagiosplugins.org)
 
diff --git a/c++/include/common/config/ncbiconf_msvc_site.h b/c++/include/common/config/ncbiconf_msvc_site.h
deleted file mode 100644
index c9d5e76..0000000
--- a/c++/include/common/config/ncbiconf_msvc_site.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* $Id: ncbiconf_msvc_site.h 125306 2008-04-22 13:29:11Z gouriano $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's official duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-* Author:  Andrei Gourianov
-*
-* File Description:
-*
-*   This file is a PLACEHOLDER ONLY
-*
-*   REAL file with the same name is generated by
-*   project_tree_builder.exe when configuring the toolkit.
-*
-*/
diff --git a/c++/include/common/config/ncbiconf_universal.h b/c++/include/common/config/ncbiconf_universal.h
index e901d26..a92303c 100644
--- a/c++/include/common/config/ncbiconf_universal.h
+++ b/c++/include/common/config/ncbiconf_universal.h
@@ -1,7 +1,7 @@
 #ifndef NCBICONF_UNIVERSAL_H
 #define NCBICONF_UNIVERSAL_H
 
-/*  $Id: ncbiconf_universal.h 487459 2015-12-17 18:57:21Z ucko $
+/*  $Id: ncbiconf_universal.h 509096 2016-08-03 11:33:41Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,7 +31,8 @@
  */
 
 /** @file ncbiconf_universal.h
- ** Architecture-specific settings for universal builds.
+ ** Architecture-specific settings for Xcode builds
+ ** (and, historically, universal builds).
  **/
 
 #ifdef NCBI_OS_DARWIN
diff --git a/c++/include/common/config/ncbiconf_xcode.h b/c++/include/common/config/ncbiconf_xcode.h
index 3252246..857a259 100644
--- a/c++/include/common/config/ncbiconf_xcode.h
+++ b/c++/include/common/config/ncbiconf_xcode.h
@@ -1,4 +1,4 @@
-/* $Id: ncbiconf_xcode.h 487685 2015-12-19 23:48:10Z ucko $
+/* $Id: ncbiconf_xcode.h 509096 2016-08-03 11:33:41Z ivanov $
  * By Vlad Lebedev, NCBI (lebedev at ncbi.nlm.nih.gov)
  *
  * Mac OS X - xCode Build
@@ -110,6 +110,9 @@
 /* Define to 1 if necessary to get FIONBIO (e.g., on Solaris) */
 /* #undef BSD_COMP */
 
+/* Define to 1 if you have the <Accelerate/Accelerate.h> header file. */
+#define HAVE_ACCELERATE_ACCELERATE_H 1
+
 /* Define to 1 if you have the `alarm' function. */
 #define HAVE_ALARM 1
 
@@ -147,6 +150,9 @@
 /* Define to 1 if the `Boost.Threads' library is available. */
 /* #undef HAVE_BOOST_THREAD */
 
+/* Define to 1 if you have the <clapack.h> header file. */
+/* #undef HAVE_CLAPACK_H */
+
 /* Define to 1 if the preprocessor supports GNU-style variadic macros. */
 #define HAVE_CPP_GNU_VARARGS 1
 
@@ -270,6 +276,12 @@
 /* Define to 1 if you have `ios(_base)::register_callback'. */
 #define HAVE_IOS_REGISTER_CALLBACK 1
 
+/* Define to 1 if you have the <lapacke.h> header file. */
+/* #undef HAVE_LAPACKE_H */
+
+/* Define to 1 if you have the <lapacke/lapacke.h> header file. */
+/* #undef HAVE_LAPACKE_LAPACKE_H */
+
 /* Define to 1 if you have the `lchown' function. */
 /* #undef HAVE_LCHOWN */
 
@@ -314,6 +326,9 @@
    the standard libraries. */
 /* #undef HAVE_LIBKSTAT */
 
+/* Define to 1 if liblapack is available. */
+#define HAVE_LIBLAPACK 1
+
 /* Define to 1 if liblzo2 is available. */
 /* #undef HAVE_LIBLZO */
 
@@ -643,6 +658,9 @@
 /* Define to 1 if wxWidgets is available. */
 /* #undef HAVE_WXWIDGETS */
 
+/* Define to 1 if the system has the type `__CLPK_integer'. */
+#define HAVE___CLPK_INTEGER 1
+
 /* Define as const if the declaration of iconv() needs const. */
 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 /* MAC_OS_X_VERSION_10_5 */
 #  define ICONV_CONST
@@ -702,11 +720,6 @@
    variables, or leave undefined if it doesn't. */
 /* #undef NCBI_TLS_VAR */
 
-/* Define to 1 if building universal (multi-architecture) binaries. */
-/* (Not necessarily the case, but we shouldn't hardcode anything
- *  PowerPC-specific either.) */
-#define NCBI_UNIVERSAL_BUILD 1
-
 /* Define to 1 if prototypes can use exception specifications. */
 #define NCBI_USE_THROW_SPEC 1
 
@@ -754,3 +767,6 @@
  *  Site localization
  */
 #include <common/config/ncbiconf_xcode_site.h>
+
+/* Architecture specifics */
+#include <common/config/ncbiconf_universal.h>
diff --git a/c++/include/common/config/ncbiconf_xcode_site.h b/c++/include/common/config/ncbiconf_xcode_site.h
deleted file mode 100644
index eb054bf..0000000
--- a/c++/include/common/config/ncbiconf_xcode_site.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* $Id: ncbiconf_xcode_site.h 381201 2012-11-20 14:30:39Z ucko $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's official duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-* Author:  Andrei Gourianov
-*
-* File Description:
-*
-*   Mac OS X - xCode Build
-*
-*   When configuring the toolkit, project_tree_builder application
-*   generates another file with the same name
-*
-*/
-
-/* Define to 1 if NCBI C++ API for BerkeleyDB is available. */
-#define HAVE_BDB 1
-
-/* Define to 1 if NCBI C++ API for BerkeleyDB based data cache is available.
-   */
-#define HAVE_BDB_CACHE 1
-
-/* Define to 1 if Berkeley DB libraries are available. */
-#define HAVE_BERKELEY_DB 1
-
-/* Define to 1 if the `Boost.Test' libraries are available. */
-/* #undef HAVE_BOOST_TEST */
-
-/* Define to 1 if CPPUNIT libraries are available. */
-/* #undef HAVE_CPPUNIT */
-
-/* Define to 1 if you have the `FCGX_Accept_r' function. */
-/* #undef HAVE_FCGX_ACCEPT_R */
-
-/* Define to 1 if ICU libraries are available. */
-/* #undef HAVE_ICU */
-
-/* Define to 1 if non-public CONNECT extensions are available. */
-/* #undef HAVE_LIBCONNEXT */
-
-/* Define to 1 if FastCGI libraries are available. */
-/* #undef HAVE_LIBFASTCGI */
-
-/* Define to 1 if libgif is available. */
-//#define HAVE_LIBGIF 1
-
-/* Define to 1 if libjpeg is available. */
-#define HAVE_LIBJPEG 1
-
-/* Define to 1 if liblzo is available. */
-/* #undef HAVE_LIBLZO */
-
-/* Define to 1 if libssl is available. */
-/* #undef HAVE_LIBOPENSSL */
-
-/* Define to 1 if libpng is available. */
-#define HAVE_LIBPNG 1
-
-/* Define to 1 if libsqlite3 is available. */
-/* #undef HAVE_LIBSQLITE3 */
-
-/* Define to 1 if SYBASE libraries are available. */
-/* #undef HAVE_LIBSYBASE */
-
-/* Define to 1 if libtiff is available. */
-#define HAVE_LIBTIFF 1
-
-/* Define to 1 if libxml2 is available. */
-/* #undef HAVE_LIBXML */
-
-/* Define to 1 if libxslt is available. */
-/* #undef HAVE_LIBXSLT */
-
-/* Define to 1 if MySQL is available. */
-/* #undef HAVE_MYSQL */
-
-/* Define to 1 if ODBC libraries are available. */
-/* #undef HAVE_ODBC */
-
-/* Define to 1 if you have the <odbcss.h> header file. */
-/* #undef HAVE_ODBCSS_H */
-
-/* Define to 1 if you have OpenGL (-lGL). */
-#define HAVE_OPENGL 1
-
-/* Define to 1 if the PUBSEQ service is available. */
-/* #undef HAVE_PUBSEQ_OS */
-
-/* Define to 1 if Python libraries are available. */
-/* #undef HAVE_PYTHON */
-
-/* Define to 1 if Xalan-C++ is available. */
-/* #undef HAVE_XALAN */
-
-/* Define to 1 if Xerces-C++ is available. */
-/* #undef HAVE_XERCES */
-
-/* Define to 1 if using a local copy of bzlib. */
-/* #undef USE_LOCAL_BZLIB */
-
-/* Define to 1 if using a local copy of PCRE. */
-#define USE_LOCAL_PCRE 1
diff --git a/c++/include/common/ncbi_build_ver.h.in b/c++/include/common/ncbi_build_ver.h.in
new file mode 100644
index 0000000..c986400
--- /dev/null
+++ b/c++/include/common/ncbi_build_ver.h.in
@@ -0,0 +1,37 @@
+/*  $Id: ncbi_build_ver.h.in 513308 2016-09-09 12:04:16Z ivanov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ */
+
+#if @NCBI_TEAMCITY_BUILD_NUMBER@ != 0
+#  define NCBI_TEAMCITY_BUILD_NUMBER @NCBI_TEAMCITY_BUILD_NUMBER@
+#endif
+
+#if @NCBI_SUBVERSION_REVISION@ != 0
+#  define NCBI_SUBVERSION_REVISION @NCBI_SUBVERSION_REVISION@
+#endif
+
+#if @NCBI_SC_VERSION@ != 0
+#  define NCBI_SC_VERSION @NCBI_SC_VERSION@
+#endif
diff --git a/c++/include/common/ncbi_export.h b/c++/include/common/ncbi_export.h
index f4cc8b3..97ab0d7 100644
--- a/c++/include/common/ncbi_export.h
+++ b/c++/include/common/ncbi_export.h
@@ -1,7 +1,7 @@
 #ifndef COMMON___NCBI_EXPORT__H
 #define COMMON___NCBI_EXPORT__H
 
-/*  $Id: ncbi_export.h 480275 2015-09-29 15:35:34Z vasilche $
+/*  $Id: ncbi_export.h 498832 2016-04-19 21:18:13Z vasilche $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1445,6 +1445,23 @@
 #endif
 
 
+/* Export specifier for library ncbi_xloader_snp
+ */
+#ifdef NCBI_XLOADER_SNP_EXPORTS
+#  define NCBI_XLOADER_SNP_EXPORT NCBI_DLL_EXPORT
+#else
+#  define NCBI_XLOADER_SNP_EXPORT NCBI_DLL_IMPORT
+#endif
+
+
+/* Export specifier for library ncbi_id2proc_snp
+ */
+#ifdef NCBI_ID2PROC_SNP_EXPORTS
+#  define NCBI_ID2PROC_SNP_EXPORT NCBI_DLL_EXPORT
+#else
+#  define NCBI_ID2PROC_SNP_EXPORT NCBI_DLL_IMPORT
+#endif
+
 
 /* STATIC LIBRARIES SECTION */
 /* This section is for static-only libraries */
diff --git a/c++/include/common/ncbi_package_ver.h b/c++/include/common/ncbi_package_ver.h
index ef342a3..c4b937c 100644
--- a/c++/include/common/ncbi_package_ver.h
+++ b/c++/include/common/ncbi_package_ver.h
@@ -7,7 +7,7 @@
 #define NCBI_PACKAGE                       1
 #define NCBI_PACKAGE_NAME                  "blast"
 #define NCBI_PACKAGE_VERSION_MAJOR         2
-#define NCBI_PACKAGE_VERSION_MINOR         4
+#define NCBI_PACKAGE_VERSION_MINOR         6
 #define NCBI_PACKAGE_VERSION_PATCH         0
 #define NCBI_PACKAGE_CONFIG                ""
 
diff --git a/c++/include/common/ncbi_source_ver.h b/c++/include/common/ncbi_source_ver.h
index c0b214e..0c86e10 100644
--- a/c++/include/common/ncbi_source_ver.h
+++ b/c++/include/common/ncbi_source_ver.h
@@ -1,4 +1,4 @@
-/*  $Id: ncbi_source_ver.h 498533 2016-04-16 04:03:05Z syncbot $
+/*  $Id: ncbi_source_ver.h 510638 2016-08-14 02:48:40Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -24,5 +24,11 @@
  * ===========================================================================
  */
 
-#define NCBI_PRODUCTION_VER 20160416
-#define NCBI_DEVELOPMENT_VER 20160127
+#include <ncbiconf.h>
+
+#define NCBI_PRODUCTION_VER 20160806
+#define NCBI_DEVELOPMENT_VER 20160726
+
+#ifdef HAVE_COMMON_NCBI_BUILD_VER_H
+#  include <common/ncbi_build_ver.h>
+#endif
diff --git a/c++/include/common/ncbiconf_impl.h b/c++/include/common/ncbiconf_impl.h
index bdd3d14..e7a0f9d 100644
--- a/c++/include/common/ncbiconf_impl.h
+++ b/c++/include/common/ncbiconf_impl.h
@@ -1,7 +1,7 @@
 #ifndef COMMON___NCBICONF_IMPL__H
 #define COMMON___NCBICONF_IMPL__H
 
-/* $Id: ncbiconf_impl.h 469886 2015-06-09 18:23:33Z ucko $
+/* $Id: ncbiconf_impl.h 491618 2016-02-08 14:08:15Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/connect/impl/server_connection.hpp b/c++/include/connect/impl/server_connection.hpp
index a8920d6..de4bcdf 100644
--- a/c++/include/connect/impl/server_connection.hpp
+++ b/c++/include/connect/impl/server_connection.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT___SERVER_CONNECTION__HPP
 #define CONNECT___SERVER_CONNECTION__HPP
 
-/* $Id: server_connection.hpp 462064 2015-03-16 14:27:31Z satskyse $
+/* $Id: server_connection.hpp 506707 2016-07-11 15:26:50Z satskyse $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -139,6 +139,7 @@ public:
         }
     }
     virtual void Passivate(void) { Close(); }
+    unsigned short GetPort(void) const { return m_Port; }
 private:
     friend class CAcceptRequest;
     auto_ptr<IServer_ConnectionFactory> m_Factory;
diff --git a/c++/include/connect/impl/thread_pool_for_server.hpp b/c++/include/connect/impl/thread_pool_for_server.hpp
index fa7039f..709b8d5 100644
--- a/c++/include/connect/impl/thread_pool_for_server.hpp
+++ b/c++/include/connect/impl/thread_pool_for_server.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT__IMPL__THREAD_POOL_FOR_SERVER__HPP
 #define CONNECT__IMPL__THREAD_POOL_FOR_SERVER__HPP
 
-/*  $Id: thread_pool_for_server.hpp 387666 2013-01-31 14:49:08Z ucko $
+/*  $Id: thread_pool_for_server.hpp 503649 2016-06-06 22:11:35Z satskyse $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -50,7 +50,7 @@ public:
     CQueueItemBase_ForServer(void) 
         : m_Status(CQueueItemBase::ePending)
     {}
-    
+
     const EStatus&   GetStatus(void) const       { return m_Status; }
 
     void MarkAsComplete(void)        { x_SetStatus(CQueueItemBase::eComplete); }
@@ -126,24 +126,25 @@ public:
             CQueueItemBase_ForServer::x_SetStatus(new_status);
             m_Request->OnStatusChange(old_status, new_status);
         }
-        
+
     private:
         friend class CBlockingQueue_ForServer;
 
         TRequest  m_Request;
     };
-    
+
 protected:
     /// The type of the queue
     typedef deque<TItemHandle> TRealQueue;
 
     // Derived classes should take care to use these members properly.
-    TRealQueue m_Queue;     ///< The queue
-#ifdef NCBI_HAVE_CONDITIONAL_VARIABLE
+    TRealQueue          m_Queue;     ///< The queue
+
+    #ifdef NCBI_HAVE_CONDITIONAL_VARIABLE
     CConditionVariable  m_GetCond;
-#else
+    #else
     CSemaphore          m_GetSem;    ///< Raised if the queue contains data
-#endif
+    #endif
     mutable CMutex      m_Mutex;     ///< Guards access to queue
 
 private:
@@ -283,9 +284,8 @@ private:
     CAtomicCounter          m_ThreadCount;
     /// The guard for m_MaxThreads and m_MaxUrgentThreads
     CMutex                  m_Mutex;
-    CAtomicCounter          m_PutQueueNum;
-    CAtomicCounter          m_GetQueueNum;
-    TQueue**                m_Queues;
+
+    TQueue                  m_Queue;
     string                  m_ThrSuffix;
 
     typedef list<CRef<TThread> > TThreads;
diff --git a/c++/include/connect/ncbi_base64.h b/c++/include/connect/ncbi_base64.h
index 6a5917c..4dd7187 100644
--- a/c++/include/connect/ncbi_base64.h
+++ b/c++/include/connect/ncbi_base64.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_BASE64__H
 #define CONNECT___NCBI_BASE64__H
 
-/* $Id: ncbi_base64.h 394629 2013-04-04 15:51:49Z kazimird $
+/* $Id: ncbi_base64.h 501318 2016-05-13 15:59:32Z vakatov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -97,9 +97,9 @@ extern NCBI_XCONNECT_EXPORT int/*bool*/ BASE64_Decode
  * was successful.
  */
 typedef enum {
-    eBase64_OK,             /** Transcoded successfully. */
-    eBase64_BufferTooSmall, /** The output buffer is too small. */
-    eBase64_InvalidInput    /** Input contains characters outside alphabet. */
+    eBase64_OK,             /**< Transcoded successfully. */
+    eBase64_BufferTooSmall, /**< The output buffer is too small. */
+    eBase64_InvalidInput    /**< Input contains characters outside alphabet. */
 } EBase64_Result;
 
 
diff --git a/c++/include/connect/ncbi_buffer.h b/c++/include/connect/ncbi_buffer.h
index d9443a1..cde5d8f 100644
--- a/c++/include/connect/ncbi_buffer.h
+++ b/c++/include/connect/ncbi_buffer.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_BUFFER__H
 #define CONNECT___NCBI_BUFFER__H
 
-/* $Id: ncbi_buffer.h 482179 2015-10-21 15:02:35Z lavr $
+/* $Id: ncbi_buffer.h 491234 2016-02-03 16:17:23Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -201,7 +201,8 @@ extern NCBI_XCONNECT_EXPORT size_t BUF_PeekAt
  * at position "pos"), in chunks.  Pass "cbdata" as an opaque parameter to the
  * "callback".  Processing stops when all buffer bytes (but no more than
  * "size" bytes) have been visited by the "callback", or when the "callback"
- * returns a value less than its passed "size" argument.
+ * returns a value less than its passed "size" argument (the "callback" may
+ * _not_ return a value greater than its "size" argument!).
  * Return the # of processed bytes (can be less than "size").
  * Return zero and do nothing if "buf" is NULL or "pos" >= BUF_Size(buf).
  * Do nothing and return min(BUF_Size(buf)-pos, size) if "callback" is NULL.
diff --git a/c++/include/connect/ncbi_connector.h b/c++/include/connect/ncbi_connector.h
index a73793a..b9f3ac3 100644
--- a/c++/include/connect/ncbi_connector.h
+++ b/c++/include/connect/ncbi_connector.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_CONNECTOR__H
 #define CONNECT___NCBI_CONNECTOR__H
 
-/* $Id: ncbi_connector.h 362749 2012-05-10 17:16:55Z lavr $
+/* $Id: ncbi_connector.h 513293 2016-09-09 11:36:15Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -83,7 +83,7 @@ typedef       char* (*FConnectorDescr)
 /** Open connection.  Used to setup all related data structures,
  * but not necessarily has to actually open the data channel.
  * @note  Regardless of the returned status, the connection is considered open
- *        (so this call does not get repeated) when the call returns.
+ *        (so this call doesn't get re-issued) after this call returns.
  */
 typedef EIO_Status (*FConnectorOpen)
 (CONNECTOR       connector,
@@ -107,7 +107,7 @@ typedef EIO_Status (*FConnectorWait)
 /** Write to connector.
  * The passed "n_written" is always non-NULL, and "*n_written" is always zero.
  * The number of bytes actually written gets returned in "*n_written".
- * It may not return "eIO_Success" if no data at all have been written.
+ * It may not return eIO_Success if no data at all have been written.
  * @note  FConnectorWrite() is guaranteed to be called after FConnectorOpen(),
  *        and only if the latter succeeded (returned eIO_Success).
  */
@@ -164,6 +164,7 @@ typedef EIO_Status (*FConnectorStatus)
  *        and only if the latter succeeded (returned eIO_Success).
  * @note  FConnectorFlush() gets called before FConnectorClose() automatically.
  * @note  It may return eIO_Closed to indicate an unusual close condition.
+ * @note  The same connector may now be either re-opened / re-used or recylced.
  */
 typedef EIO_Status (*FConnectorClose)
 (CONNECTOR       connector,
@@ -192,12 +193,12 @@ typedef struct {
 } SMetaConnector;
 
 
-#define CONN_TWO2ONE(a, b)   a##b
+#define _CONN_TWO2ONE(a, b)   a##b
 
 #define CONN_SET_METHOD(meta, method, function, connector) \
     do {                                                   \
-        meta->method                  = function;          \
-        meta->CONN_TWO2ONE(c_,method) = connector;         \
+        meta->method                   = function;         \
+        meta->_CONN_TWO2ONE(c_,method) = connector;        \
     } while (0)
 
 
@@ -214,7 +215,7 @@ typedef struct {
 /** Insert a connector in the beginning of the connection's list of connectors.
  * Calls connector's FSetupVTable, which must be defined.
  */
-extern NCBI_XCONNECT_EXPORT EIO_Status METACONN_Add
+extern NCBI_XCONNECT_EXPORT EIO_Status METACONN_Insert
 (SMetaConnector* meta,
  CONNECTOR       connector
  );
@@ -231,6 +232,7 @@ extern NCBI_XCONNECT_EXPORT EIO_Status METACONN_Remove
 
 
 /** Upcall on request to setup virtual function table (called from connection).
+ * NB:  May not detect any failures (follow up in Open to fail if necessary).
  */
 typedef void (*FSetupVTable)
 (CONNECTOR       connector
diff --git a/c++/include/connect/ncbi_connutil.h b/c++/include/connect/ncbi_connutil.h
index 5ad9a00..02835c7 100644
--- a/c++/include/connect/ncbi_connutil.h
+++ b/c++/include/connect/ncbi_connutil.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_CONNUTIL__H
 #define CONNECT___NCBI_CONNUTIL__H
 
-/* $Id: ncbi_connutil.h 500351 2016-05-04 09:45:13Z ivanov $
+/* $Id: ncbi_connutil.h 513929 2016-09-16 15:08:30Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -150,7 +150,7 @@ typedef enum {
 typedef unsigned EBDebugPrintout;
 
 
-/* Network connection related configurable info struct.
+/* Network connection-related configurable informational structure.
  * ATTENTION:  Do NOT fill out this structure (SConnNetInfo) "from scratch"!
  *             Instead, use ConnNetInfo_Create() described below to create
  *             it, and then fix (hard-code) some fields, if really necessary.
@@ -166,19 +166,20 @@ typedef struct {  /* NCBI_FAKE_WARNING: ICC */
     EBURLScheme     scheme:3;         /* only pre-defined types (limited)    */
     TReqMethod      req_method:5;     /* method to use in the request (HTTP) */
     unsigned        version:1;        /* HTTP/1.v (or selected by req_method)*/
+    unsigned        external:1;       /* mark service request as external    */
     EBFWMode        firewall:2;       /* to use firewall (relay otherwise)   */
     unsigned        stateless:1;      /* to connect in HTTP-like fashion only*/
     unsigned        lb_disable:1;     /* to disable local load-balancing     */
     EBDebugPrintout debug_printout:2; /* switch to printout some debug info  */
     unsigned        http_push_auth:1; /* push authorize tags even w/o 401/407*/
     unsigned        http_proxy_leak:1;/* non-zero when can fallback to direct*/
-    unsigned        reserved:15;      /* MBZ */
-    char            user[64];         /* username (if specified)             */
-    char            pass[64];         /* password (if any)                   */
+    unsigned        reserved:14;      /* MBZ                                 */
+    char            user[64];         /* username (if specified or required) */
+    char            pass[64];         /* password (if any for non-empty user)*/
     char            host[256];        /* host to connect to                  */
     unsigned short  port;             /* port to connect to, host byte order */
-    char            path[1024];       /* path (e.g. to  a CGI script or page)*/
-    char            args[1024];       /* args (e.g. for a CGI script)        */
+    char            path[2048];       /* path (e.g. to  a CGI script or page)*/
+    char            args[2048];       /* args (e.g. for a CGI script)        */
     char            http_proxy_host[256]; /* hostname of HTTP proxy server   */
     unsigned short  http_proxy_port;      /* port #   of HTTP proxy server   */
     char            http_proxy_user[64];  /* http proxy username (if req'd)  */
@@ -189,7 +190,8 @@ typedef struct {  /* NCBI_FAKE_WARNING: ICC */
     const char*     http_referer;     /* default referrer (when not spec'd)  */
     NCBI_CRED       credentials;      /* connection credentials (optional)   */
 
-    /* the following field(s) are for the internal use only -- don't touch!  */
+    /* the following field(s) are for internal use only -- do not touch!     */
+    unsigned int    magic;            /* to detect version skew              */
     STimeout        tmo;              /* default storage for finite timeout  */
     const char      svc[1];           /* service which this info created for */
 } SConnNetInfo;
@@ -244,6 +246,9 @@ typedef struct {  /* NCBI_FAKE_WARNING: ICC */
 #define REG_CONN_MAX_TRY          "MAX_TRY"
 #define DEF_CONN_MAX_TRY          3
 
+#define REG_CONN_EXTERNAL         "EXTERNAL"
+#define DEF_CONN_EXTERNAL         ""
+
 #define REG_CONN_FIREWALL         "FIREWALL"
 #define DEF_CONN_FIREWALL         ""
 
@@ -285,13 +290,14 @@ typedef struct {  /* NCBI_FAKE_WARNING: ICC */
  * 4. Registry key "param" (with "CONN_", if there was any, stripped)
  *    in the section "[CONN]".
  * Steps 1 & 2 skipped for "service" passed as NULL or empty ("").
- * Steps 3 & 4 skipped for non-empty "service" and "param" already beginning
- * with "CONN_".
- * If the found match's value has enveloping quotes (single '', or double "")
- * then they are stripped from the result (which may then become empty).
+ * Steps 3 & 4 skipped for non-empty "service" and the "param" that already
+ * begins with "CONN_".
+ * If the found match's value has enveloping quotes (either single '' or
+ * double ""), then they are stripped from the result, which can then become
+ * empty.
  * The first "value_size" bytes (including the terminating '\0') of the result
- * get copied to the "value" buffer (which may cause truncation!), and
- * the passed "value" address gets returned.
+ * get copied to the "value" buffer (which may cause truncation!), and the
+ * passed "value" address gets returned.
  * When no match is found, the "value" gets filled with "def_value" (or an
  * empty string), which then gets returned.  Return 0 only on out of memory.
  */
@@ -332,6 +338,7 @@ extern NCBI_XCONNECT_EXPORT int/*bool*/ ConnNetInfo_Boolean
  *  http_push_auth    HTTP_PUSH_AUTH    Send credentials pre-emptively
  *  timeout           TIMEOUT           "<sec>.<usec>": "3.00005", "infinite"
  *  max_try           MAX_TRY  
+ *  external          EXTERNAL
  *  firewall          FIREWALL
  *  stateless         STATELESS
  *  lb_disable        LB_DISABLE        obsolete
diff --git a/c++/include/connect/ncbi_core.h b/c++/include/connect/ncbi_core.h
index 0579d60..14caa80 100644
--- a/c++/include/connect/ncbi_core.h
+++ b/c++/include/connect/ncbi_core.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_CORE__H
 #define CONNECT___NCBI_CORE__H
 
-/* $Id: ncbi_core.h 424634 2014-01-17 18:57:34Z lavr $
+/* $Id: ncbi_core.h 505000 2016-06-21 16:48:46Z vakatov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -283,6 +283,7 @@ typedef struct LOG_tag* LOG;
 typedef enum {
     eLOG_Trace = 0,
     eLOG_Note,
+    eLOG_Info = eLOG_Note,  /**< In C++ Toolkit "Info" is used, not "Note" */
     eLOG_Warning,
     eLOG_Error,
     eLOG_Critical,
diff --git a/c++/include/connect/ncbi_core_cxx.hpp b/c++/include/connect/ncbi_core_cxx.hpp
index 026ad45..baf48bb 100644
--- a/c++/include/connect/ncbi_core_cxx.hpp
+++ b/c++/include/connect/ncbi_core_cxx.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_CORE_CXX__H
 #define CONNECT___NCBI_CORE_CXX__H
 
-/* $Id: ncbi_core_cxx.hpp 470048 2015-06-10 19:03:03Z lavr $
+/* $Id: ncbi_core_cxx.hpp 507476 2016-07-19 17:46:14Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -90,13 +90,14 @@ extern NCBI_XCONNECT_EXPORT MT_LOCK MT_LOCK_cxx2c
  );
 
 
-/// CONNECT_Init flags:  which parameters to own.
+/// CONNECT_Init flags:  which parameters to own / initialize.
 /// @sa
 ///  CONNECT_Init
 enum EConnectInitFlag {
     eConnectInit_OwnNothing  = 0,  ///< Original ownership gets retained
     eConnectInit_OwnRegistry = 1,  ///< Registry ownership gets passed
-    eConnectInit_OwnLock     = 2   ///< Lock ownership gets passed
+    eConnectInit_OwnLock     = 2,  ///< Lock ownership gets passed
+    eConnectInit_NoSSL       = 4   ///< Do not init secure socket layer (SSL)
 };
 typedef unsigned int TConnectInitFlags;  ///< Bitwise OR of EConnectInitFlag
 
diff --git a/c++/include/connect/ncbi_gnutls.h b/c++/include/connect/ncbi_gnutls.h
index 120a071..c9a40d0 100644
--- a/c++/include/connect/ncbi_gnutls.h
+++ b/c++/include/connect/ncbi_gnutls.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_GNUTLS__H
 #define CONNECT___NCBI_GNUTLS__H
 
-/* $Id: ncbi_gnutls.h 422344 2013-12-19 19:33:02Z lavr $
+/* $Id: ncbi_gnutls.h 507002 2016-07-13 21:10:28Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -47,10 +47,12 @@ extern "C" {
 #endif
 
 
-extern SOCKSSL NcbiSetupGnuTls(void);
+extern NCBI_XCONNECT_EXPORT
+SOCKSSL NcbiSetupGnuTls(void);
 
 
-extern NCBI_CRED NcbiCredGnuTls(void* xcred);
+extern NCBI_XCONNECT_EXPORT
+NCBI_CRED NcbiCredGnuTls(void* xcred);
 
 
 #ifdef __cplusplus
diff --git a/c++/include/connect/ncbi_http_connector.h b/c++/include/connect/ncbi_http_connector.h
index 1464cae..93d53ee 100644
--- a/c++/include/connect/ncbi_http_connector.h
+++ b/c++/include/connect/ncbi_http_connector.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___HTTP_CONNECTOR__H
 #define CONNECT___HTTP_CONNECTOR__H
 
-/* $Id: ncbi_http_connector.h 500355 2016-05-04 09:47:56Z ivanov $
+/* $Id: ncbi_http_connector.h 507766 2016-07-21 16:32:56Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -104,7 +104,7 @@ extern "C" {
  * @var fHTTP_NoAutoRetry
  *       Do not attempt any auto-retries in case of failing connections
  *       (this flag effectively means having SConnNetInfo::max_try set to 1).
-
+ *
  * @var fHTTP_UnsafeRedirects
  *       For security reasons the following redirects comprise security risk,
  *       and thus, are prohibited:  switching from https to http, and/or
@@ -285,6 +285,8 @@ typedef void        (*FHTTP_Cleanup)
  *  When fHTTP_WriteThru is set with HTTP/1.1, writing to the connector begins
  *  upon any write operations, and reading from the connector causes the
  *  request body to finalize and response to be fetched from the server.
+ *  Request method must be explicitly specified with fHTTP_WriteThru, "ANY"
+ *  does not get accepted (the eIO_NotSupported error returned).
  *
  *  @note
  *     If "fHTTP_AutoReconnect" is set in "flags", then the connector makes an
@@ -312,7 +314,8 @@ extern NCBI_XCONNECT_EXPORT CONNECTOR HTTP_CreateConnectorEx
  * located at "net_info->http_proxy_host:net_info->http_proxy_port".  Return
  * the tunnel as a socket via the last parameter.  For compatibility with
  * future API extensions, please make sure *sock is NULL when making the call.
- * If "net_info->scheme == eURL_Https", the returned socket is secure.
+ * The proxy gets contacted via HTTPS if "net_info->scheme == eURL_Https", and
+ * the resultant socket is returned secure (with the SSL session still active).
  * @note
  *  "net_info" can be passed as NULL to be constructed from the environment.
  * @note
diff --git a/c++/include/connect/ncbi_http_session.hpp b/c++/include/connect/ncbi_http_session.hpp
index bbd6cc5..666b9cd 100644
--- a/c++/include/connect/ncbi_http_session.hpp
+++ b/c++/include/connect/ncbi_http_session.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_HTTP_SESSION__HPP
 #define CONNECT___NCBI_HTTP_SESSION__HPP
 
-/* $Id: ncbi_http_session.hpp 492271 2016-02-16 15:25:30Z ivanov $
+/* $Id: ncbi_http_session.hpp 519414 2016-11-15 18:23:40Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -219,7 +219,7 @@ private:
     CHttpHeaders& operator=(const CHttpHeaders&);
 
     // Check if the name is a reserved one (NCBI-SID, NCBI-PHID).
-    // If yes, log error and _ASSERT(0) - these headers must be set in
+    // If yes, log error - these headers must be set in
     // CRequestContext, not directly.
     // Return 'false' if the header name is not reserved and a value can
     // be set safely.
@@ -489,6 +489,24 @@ public:
     /// value is used ($CONN_MAX_TRY - 1).
     void SetRetries(THttpRetries retries) { m_Retries = retries; }
 
+    /// Get current deadline for Execute().
+    /// For now, effective only for if waiting for actual response
+    /// (as opposed to a recognized 'retry later' response), infinite by default.
+    /// @sa Execute() GetRetryProcessing()
+    const CTimeout& GetDeadline() const { return m_Deadline; }
+    /// Set new deadline for Execute().
+    /// @sa Execute() SetRetryProcessing()
+    CHttpRequest& SetDeadline(const CTimeout& deadline);
+
+    /// Return whether Execute() will wait for actual response.
+    /// If on, will wait for deadline expired or actual response
+    /// (as opposed to a recognized 'retry later' response), off by default.
+    /// @sa Execute() GetDeadline()
+    ESwitch GetRetryProcessing() const { return m_RetryProcessing; }
+    /// Set whether Execute() should wait for actual response.
+    /// @sa Execute() SetDeadline()
+    CHttpRequest& SetRetryProcessing(ESwitch on_off);
+
 private:
     friend class CHttpSession;
 
@@ -523,6 +541,8 @@ private:
     CRef<CHttpResponse> m_Response; // current response or null
     CTimeout            m_Timeout;
     THttpRetries        m_Retries;
+    CTimeout            m_Deadline;
+    ESwitch             m_RetryProcessing;
 };
 
 
diff --git a/c++/include/connect/ncbi_lbos.hpp b/c++/include/connect/ncbi_lbos.hpp
old mode 100755
new mode 100644
index 060b443..12f8cda
--- a/c++/include/connect/ncbi_lbos.hpp
+++ b/c++/include/connect/ncbi_lbos.hpp
@@ -26,88 +26,199 @@
 * ===========================================================================
 *
 * Authors:  Dmitriy Elisov
+* Credits:  Denis Vakatov
+*
 * @file
 * File Description:
 *   A client for service discovery API based on LBOS. 
-*   LBOS is a client for ZooKeeper cloud-based DB. 
+*   (LBOS is a client for ZooKeeper cloud-based DB.)
 *   LBOS allows to announce, deannounce and resolve services.
 */
 
 #include <corelib/ncbiexpt.hpp>
+#include <connect/ncbi_server_info.h>
+
 
 BEGIN_NCBI_SCOPE
 
+#define LBOS_METADATA
+
 
 class NCBI_XNCBI_EXPORT LBOS
 {
 public:
-    /** Announce server.
+#ifdef LBOS_METADATA
+    class NCBI_XNCBI_EXPORT CMetaData 
+    {
+    public:
+        /** Possible values for "type" meta parameter */
+        enum EHostType {
+            eNone,          /**< no "type" meta parameter */
+            eHTTP,          /**< "HTTP" */
+            eHTTP_GET,      /**< "HTTP_GET" */
+            eHTTP_POST,     /**< "HTTP_POST" */
+            eStandalone,    /**< "STANDALONE" */
+            eNCBID,         /**< "NCBID" */
+            eDNS,           /**< "DNS" */
+            eFirewall,      /**< "FIREWALL" */
+            eUnknown        /**< a value that has no corresponding enum,  
+                                 but still valid */
+        };
+
+        CMetaData();
+        /** Get any meta parameter, including "known types" which can also be
+         * obtained via their corresponding individual functions */
+        string Get(const string& name) const;
+        /** Set any metadata, including "known types" - "type", "rate", "extra",
+         *  which can also be set by corresponding special functions. 
+         *  "" to unset the value
+         * @parameter[in] name
+         *  Case-insensitive name of meta parameter (will be converted
+         *  to lower case)
+         * @parameter[in] val
+         *  Value to announce. "" to unset the value. Any string value will be
+         *  accepted. If name is "extra", whitespace characters are forbidden
+         *  in val. If name is "type", val is converted to upper case.  */
+        void Set(const CTempString name, const CTempString val);
+        /** Get names of all meta parameters in this CMetaData instance */
+        void GetNames(vector<string>& cont);
+        /** Get names of all meta parameters in this CMetaData instance */
+        void GetNames(list<string>& cont);
+        /** Get "rate" parameter as double. Returns 0 if value is 
+         *  not set */
+        double GetRate() const;
+        /** Set "rate" meta parameter.
+         * @parameter[in] rate
+         *  Rate to announce. "" to unset the value */
+        void SetRate (const string& rate);
+        /** Set "rate" meta parameter.
+         * @parameter[in] rate
+         *  Rate to announce. 0 to unset the value */
+        void SetRate (double rate);
+        /** Get "server type" meta parameter. Returns upper-cased string value
+         *  of the "type" meta parameter.
+         * @param[in] bool_fake_param
+         *  To distinguish between EHostType and string return types */
+        string GetType(bool) const;
+        /** Set "type" meta parameter. 
+         * @parameter[in] host_type
+         *  Host type to announce. EHostType has most popular options. 
+         *  LBOS::CMetaData::eNone to clear */
+        void SetType (EHostType host_type);
+        /** Set "type" meta parameter using ncbi_server_info.h enums
+         * @parameter[in] host_type
+         *  Host type to announce. Only values from ESERV_Type are valid. */
+        void SetType (ESERV_Type host_type);
+        /** Set "type" meta parameter. 
+         * @parameter[in] host_type
+         *  Host type to announce. Integer equivalents of EHostType. 0 to clear
+         *  the value               */
+        void SetType (int host_type);
+        /** Set "type" meta parameter.
+         * @parameter[in] host_type
+         *  Host type to announce. Any string value will be accepted. 
+         *  "" to unset the value.
+         * @note
+         *  host_type will be converted to upper case.    */
+        void SetType (const string& host_type);
+        /** Get "extra" meta parameter */
+        string GetExtra() const;
+        /** Set "extra" meta parameter. Usually used to store a URL path to the
+         *  HTTP server.
+         * @parameter[in] extra
+         *  Extra to announce. Any string value will be accepted. 
+         *  "" to unset the value    */
+        void SetExtra(const string& extra);
+        /** Get "server type" meta parameter. Returns a corresponding enumerator
+         *  if "type" meta parameter is set and equal to any of HTTP, HTTP_POST,
+         *  DNS, STANDALONE or NCBID (case-insensitively). 
+         *  If "type is unset - returns eNone. 
+         *  Otherwise, returns eUnknown and actual value can be obtained with 
+         *  GetType(bool()); */
+        LBOS::CMetaData::EHostType GetType() const;
+        /** Get a string with all parameters ready to put it into URL */
+        string GetMetaString() const;
+        bool operator==(const CMetaData& other) const;
+    private:
+        map<string, string> m_Meta;
+    };
+
+#endif /* LBOS_METADATA */
+   /** Announce server.
     *
     * @param [in] service
-    *  Name of service as it will appear in ZK. For services this means that the
-    *  name should start with '/'.
+    *  Name of service as it will appear in ZK. For services this means that
+    *  the name should start with '/'.
     * @param [in] version
     *  Any non-null non-empty string that will help to identify the version
     *  of service. A good idea is to use [semantic versioning]
     *  (http://semver.org/) like "4.7.2"
     * @param [in] host
-    *  Optional parameter. Set to "" (empty string) to use host from 
-    *  healthcheck_url to make sure that server and healthcheck actually reside 
+    *  Optional parameter. Set it to "" (empty string) to use host from 
+    *  "healthcheck_url" to make sure that server and healthcheck do reside
     *  on the same machine (it can be important when you specify hostname that 
     *  can be resolved to multiple IPs, and LBOS ends up registering server 
     *  on one host and healthcheck on another)
     * @param [in] port
-    *  Port for the service. Can differ from healthcheck port.
+    *  Port for the service. Can differ from the healthcheck port.
     * @param [in] healthcheck_url
     *  Full absolute URL starting with "http://" or "https://". Must include 
     *  hostname or IP (and port, if necessary)
+    * @param [in] metadata
+    *  Additional meta parameters that will be displayed in  "meta" section in 
+    *  service discovery
     * @note
     *  If you want to announce a server that is on the same machine that
     *  announces it (i.e., if server announces itself), you can write
     *  "0.0.0.0" for IP in both "host" and "healthcheck_url". You still have to
     *  provide port, even if you write "0.0.0.0".
-    * @return
-    *  Returns nothing if announcement was successful. Otherwise, throws an
-    *  exception.
     * @exception CLBOSException
     * @sa AnnounceFromRegistry(), Deannounce(), DeannounceAll(), CLBOSException
     */
-    static void 
-        Announce(const string&   service,
-                 const string&   version,
-                 const string&   host,
-                 unsigned short  port,
-                 const string&   healthcheck_url);
-                                  
+    static void Announce(const string&    service,
+                         const string&    version,
+                         const string&    host,
+                         unsigned short   port,
+                         const string&    healthcheck_url,
+                         const CMetaData& metadata);
 
-   /** Modification of Announce() that gets all the needed parameters from 
-    * registry.
+    /** @copydoc LBOS::Announce() */
+    static void Announce(const string&    service,
+                         const string&    version,
+                         const string&    host,
+                         unsigned short   port,
+                         const string&    healthcheck_url,
+                         const string&    metadata = string());
+
+
+   /** A variant of Announce() that gets all the needed parameters from 
+    *  registry.
     *
     * @param [in] registry_section
-    *  Name of section in registry where to look for 
+    *  Name of section in registry where to look for the
     *  announcement parameters. Please check documentation for Announce() to
-    *  to see requirements for the arguments.
+    *  see requirements for the arguments.
     *  Parameters are:
     *  service, version, host, port, health
-    *  Example:
-    *  --------------
+    * @example
+    *  In configuration file:
     *  [LBOS_ANNOUNCEMENT]
     *  service=MYSERVICE
     *  version=1.0.0
     *  host=0.0.0.0
     *  port=8080
     *  health=http://0.0.0.0:8080/health
+    *  extra=http://myserver.com/index.cgi?param=val&param2=val2
+    *  type=HTTP
+    *  rate=100
     *
-    * @return
-    *  Returns nothing if announcement was successful. Otherwise, throws an
-    *  exception.
     * @exception CLBOSException
     * @sa Announce(), Deannounce(), DeannounceAll(), CLBOSException
     */
-    static void AnnounceFromRegistry(string  registry_section);
+    static void AnnounceFromRegistry(const string& registry_section);
 
 
-    /** Deannounce service.
+   /** Deannounce service.
     * @param [in] service
     *  Name of service to be de-announced.
     * @param [in] version
@@ -117,9 +228,6 @@ public:
     *  (NOT "0.0.0.0") to use local host address.
     * @param [in] port
     *  Port of service to be de-announced.
-    * @return
-    *  Returns nothing if de-announcement was successful. Otherwise, throws an
-    *  exception.
     * @exception CLBOSException
     * @sa Announce(), DeannounceAll(), CLBOSException
     */
@@ -129,65 +237,27 @@ public:
                            unsigned short port);
 
 
-    /** Deannounce all servers that were announced during runtime.
+   /** Deannounce all servers that were announced during runtime.
     * @note
     *  There is no guarantee that all servers were de-announced successfully
     *  after this function returned. There is a guarantee that de-announcement
     *  request was sent to LBOS for each server that was announced by the 
     *  running application during runtime.
-    * @return
-    *  Returns nothing, never throws.
+    * @note
+    *  Never throws. You have no guarantee that it ran successfully.
     * @sa Announce(), Deannounce()
     */
     static void DeannounceAll(void);
+};
 
 
-    /** Show default version of a service in ZooKeeper configuration. 
-    *  Does no change anything in ZooKeeper or LBOS configuration.
-    * @param service[in]
-    *  Name of service for which to ask default version.
-    * @return
-    *  Current default version.
-    * @exception CLBOSException
-    *  If no record for the service was found, the exception will contain 
-    *  e_LBOSNotFound code.
-    */
-    static
-    string ServiceVersionGet(const string&  service,
-                             bool* existed = NULL);
-
-
-    /** Set default version for a service in ZooKeeper configuration.
-    * @param[in] service
-    *  Name of service for which to change the default version.
-    * @param new_version[out]
-    *  Version that will be used by default for specified service.
-    * @return
-    *  Version before request.
-    */
-    static
-    string ServiceVersionSet(const string&  service,
-                             const string&  new_version,
-                             bool* existed = NULL);
-
-
-    /** Remove service from ZooKeeper configuration. Default
-    *   version will be empty.
-    * @param[in] service
-    *  Name of service to delete from ZooKeeper configuration.
-    * @return
-    *  Version before request 
-    */
-    static
-    string ServiceVersionDelete(const string&  service,
-                                bool* existed = NULL);
-};
+ostream& operator<<(ostream& os, const LBOS::CMetaData& metadata);
 
 
 /** CLBOSException is thrown if a request to LBOS fails for any
  * reason. CLBOSException has overloaded "what()" method that returns
  * message from LBOS (if there is one), which should contain status code and 
- * status message. If announcement failed not because of LBOS, but because of 
+ * status message. If announcement failed not because of LBOS but because of 
  * bad arguments, memory error, etc., status code is a non-HTTP status code. 
  * To get its meaning you can call CLBOSException::GetErrCodeString(void) to 
  * see human language description of the exception.
@@ -197,61 +267,64 @@ class NCBI_XNCBI_EXPORT CLBOSException : public CException
 public:
     typedef int TErrCode;
     enum EErrCode {
-        e_LBOSNoLBOS          = 0,  /**< LBOS was not found                  */
-        e_LBOSDNSResolveError = 1,  /**< Local address not resolved          */
-        e_LBOSInvalidArgs     = 2,  /**< Arguments not valid                 */
-        e_LBOSNotFound        = 3,  /**< For de-announcement only. Did not
-                                         find such server to deannounce      */
-        e_LBOSOff             = 4,  /**< LBOS client is off for any of the 
-                                         two reasons: either it is not 
-                                         enabled in registry, or no LBOS 
-                                         working LBOS instance was found at
-                                         initialization                      */
-        e_LBOSMemAllocError   = 5,  /**< Memory allocation error             */
-        e_LBOSCorruptOutput   = 6,  /**< LBOS returned unexpected output     */
-        e_LBOSBadRequest      = 7,  /**< LBOS returned "400 Bad Request"     */
-        e_LBOSUnknown         = 8,  /**< No information about this error
-                                         code meaning                        */
-        e_LBOSServerError     = 9   /**< LBOS returned "500 Internal Server 
-                                         Error"                              */
+        eLbosNotFound,  /**< LBOS server was not found           */
+        eDNSResolve,    /**< Local address not resolved          */
+        eInvalidArgs,   /**< Arguments not valid                 */
+        eNotFound,      /**< For de-announcement only. Did not
+                             find such server to deannounce      */
+        eDisabled,      /**< LBOS client is off for any of the two reasons:
+                             either it is not enabled in registry, or no
+                             working LBOS instance was found at
+                             initialization                      */
+        eMemAlloc,      /**< Memory allocation error             */
+        eProtocol,      /**< LBOS server returned unexpected data     */
+        eBadVersion,    /**< DTab contains empty(!) version for the service */
+        eBadRequest,    /**< LBOS server returned "400 Bad Request"   */
+        eUnknown,       /**< Unknown or unclassified error */
+        eServer         /**< LBOS server returned "500 InternalServerError" */
     };
 
-    CLBOSException(const CDiagCompileInfo& info,
-                   const CException* prev_exception, EErrCode err_code,
-                   const string& message, unsigned short status_code,
-                   EDiagSev severity = eDiag_Error);
+    CLBOSException(const CDiagCompileInfo&  info,
+                   const CException*        prev_exception,
+                   EErrCode                 err_code,
+                   const string&            message,
+                   unsigned short           status_code,
+                   EDiagSev                 severity = eDiag_Error);
 
-    CLBOSException(const CDiagCompileInfo& info, 
-                   const CException* prev_exception, 
+    CLBOSException(const CDiagCompileInfo&         info,
+                   const CException*               prev_exception,
                    const CExceptionArgs<EErrCode>& args, 
-                   const string& message,
-                   unsigned short status_code);
+                   const string&                   message,
+                   unsigned short                  status_code);
+
     virtual ~CLBOSException(void) throw();
     
     /** Get original status code and status message from LBOS in a string */
     virtual const char* what() const throw();
 
     /** Translate from the error code value to its string representation
-    *  (only for internal errors; real LBOS
-    *  errors will not be processed) */
+     *  (only for internal errors; real LBOS
+     *  errors will not be processed) */
     virtual const char* GetErrCodeString(void) const;
 
-    /** Translate from numerical HTTP status code to LBOS-specific
-     * error code */
+    /** Translate from numerical HTTP status code to LBOS-specific err code */
     static EErrCode s_HTTPCodeToEnum(unsigned short http_code);
 
     unsigned short GetStatusCode(void) const;
     virtual const char* GetType(void) const;
     TErrCode GetErrCode(void) const;
     NCBI_EXCEPTION_DEFAULT_THROW(CLBOSException)
+
 protected:
     CLBOSException(void);
     virtual const CException* x_Clone(void) const;
+
 private:
     unsigned short m_StatusCode;
-    string m_Message;
+    string         m_Message;
 };
 
+
 END_NCBI_SCOPE
 
 #endif /* CONNECT___NCBI_LBOS__HPP */
diff --git a/c++/include/connect/ncbi_monkey.hpp b/c++/include/connect/ncbi_monkey.hpp
new file mode 100644
index 0000000..709014d
--- /dev/null
+++ b/c++/include/connect/ncbi_monkey.hpp
@@ -0,0 +1,405 @@
+/* $Id: ncbi_monkey.hpp 505633 2016-06-27 19:28:13Z elisovdn $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's official duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* Author:  Dmitriy Elisov
+*
+* File Description:
+*   Chaos Monkey - a library that is hooked with ncbi_socket.c and introduces
+*   problems in network connectivity - losses, bad data, delays.
+*   difficulties
+*
+*/
+
+#ifndef CONNECT___NCBI_MONKEY__HPP
+#define CONNECT___NCBI_MONKEY__HPP
+
+#include "../src/connect/ncbi_priv.h"
+
+#ifdef NCBI_MONKEY
+#   define NCBI_MONKEY_TESTS /* For Unit Testing */
+
+#   include <corelib/ncbithr.hpp>
+#   include <corelib/ncbiexpt.hpp>
+#   include <corelib/ncbiapp.hpp>
+#   include <util/random_gen.hpp>
+#   include "ncbi_socket.h"
+#   include "../src/connect/ncbi_socketp.h"
+#   include "ncbi_socket.hpp"
+#   include <corelib/ncbistr.hpp>
+
+#   include <vector>
+#   include <string>
+#   include <sstream>
+
+
+BEGIN_NCBI_SCOPE
+
+using namespace std;
+
+enum EMonkeyActionType {
+    eMonkey_Recv,
+    eMonkey_Send,
+    eMonkey_Poll,
+    eMonkey_Connect
+};
+
+
+class NCBI_XNCBI_EXPORT CMonkeyException : public CException
+{
+public:
+    enum EErrCode {
+        e_MonkeyInvalidArgs = 0   /**< Incorrect arguments                 */
+       ,e_MonkeyUnknown     = 1   /**< Not classified as anything above    */
+    };
+
+    /** Get original status code and status message from LBOS in a string */
+    virtual const char* what(void)  const throw();
+
+private:
+    unsigned short m_StatusCode;
+    string         m_Message;
+
+    NCBI_EXCEPTION_DEFAULT(CMonkeyException, CException);
+};
+
+
+/** A special class which opens access to Monkey Seed 
+ *  (only for Monkey rules and plans) */
+class CMonkeySeedKey
+{
+    friend class CMonkeySeedAccessor;
+    CMonkeySeedKey() = default;
+    ~CMonkeySeedKey() = default;
+    /* No copying allowed */
+    CMonkeySeedKey(const CMonkeySeedKey&) = delete;
+    CMonkeySeedKey& operator=(const CMonkeySeedKey&) = delete;
+};
+
+
+/** Base class for Monkey methods that are allowed to write to MonkeyLog */
+class CMonkeySeedAccessor
+{
+protected: 
+    static const CMonkeySeedKey& Key(void);
+};
+
+
+/** Common functionality for all rule types:
+ *  - Runs order (vector<double> m_Runs)
+ *  - How to repeat runs order (ERepeatType m_RepeatType) 
+ *  - After how many runs repeat order (size_t m_RunsSize) 
+ */
+class CMonkeyRuleBase : public CMonkeySeedAccessor
+{
+public:
+    enum ERepeatType {
+        eMonkey_RepeatAgain,
+        eMonkey_RepeatLast,
+        eMonkey_RepeatNone
+    };
+    enum ERunMode {
+        eMonkey_RunProbability,
+        eMonkey_RunNumber
+    };
+    enum ERunFormat {
+        eMonkey_RunSequence,
+        eMonkey_RunRanges
+    };
+
+    /** Add socket */
+    void AddSocket(MONKEY_SOCKTYPE sock) ;
+
+    /** Check that this rule will trigger on this run (host and port have 
+     * already been successfully matched if this check is run) */
+    bool CheckRun(MONKEY_SOCKTYPE sock,
+                  unsigned short  probability_left = 100) const;
+
+    /** Get probability that the rule will run next time */
+    unsigned short GetProbability(MONKEY_SOCKTYPE sock) const;
+protected:
+    CMonkeyRuleBase(EMonkeyActionType     action_type,
+                    const vector<string>& name_value);
+    int /* EIO_Status or -1 */ GetReturnStatus(void) const;
+    unsigned long  GetDelay(void) const;
+
+    /* Iterate m_Runs */
+    void IterateRun(MONKEY_SOCKTYPE sock);
+private:
+    void           x_ReadRuns     (const string& runs);
+    void           x_ReadEIOStatus(const string& eIOStatus_str);
+    int                          m_ReturnStatus;
+    ERepeatType                  m_RepeatType;
+    unsigned long                m_Delay;
+    vector<double>               m_Runs;
+    EMonkeyActionType            m_ActionType;
+    map<MONKEY_SOCKTYPE, size_t> m_RunPos;
+    /** If there are no-interception runs before repeating the cycle,
+     * we know that from m_RunsSize */
+    size_t         m_RunsSize;
+    /** Whether trigger settings are stored as probabilities for each run, 
+        or as numbers of runs when the rule should trigger */
+    ERunMode       m_RunMode;
+};
+
+
+/** Common functionality for CMonkeyWriteRule and CMonkeyReadRule:
+ *  - Predefined text or random garbage? (bool m_Garbage)
+ *  - Predefined text (string m_Text)
+ *  - Text length (unsigned int m_TextLength)
+ *  - How to fill response with text if text predefined (EFillType m_FillType)
+ *  - What EIO_Status to return (EIO_Status m_ReturnStatus)
+ */
+class CMonkeyRWRuleBase : public CMonkeyRuleBase
+{
+public:
+    enum EFillType {
+        eMonkey_FillRepeat,
+        eMonkey_FillLastLetter
+    };
+protected:
+    CMonkeyRWRuleBase(EMonkeyActionType           action_type, 
+                      const vector<string>& name_value);
+    string    GetText     (void) const;
+    size_t    GetTextLength(void) const;
+    bool      GetGarbage   (void) const;
+    EFillType GetFillType   (void) const;
+private:
+    void      x_ReadFill(const string& fill_str);
+    string    m_Text;
+    size_t    m_TextLength;
+    bool      m_Garbage;
+    EFillType m_FillType;
+};
+
+
+class CMonkeyWriteRule : public CMonkeyRWRuleBase
+{
+public:
+    CMonkeyWriteRule(const vector<string>& name_value);
+
+    MONKEY_RETTYPE  Run(MONKEY_SOCKTYPE        sock,
+                        const MONKEY_DATATYPE  data,
+                        MONKEY_LENTYPE         size,
+                        int                    flags,
+                        SOCK*                  sock_ptr);
+};
+
+
+class CMonkeyReadRule : public CMonkeyRWRuleBase
+{
+public:
+    CMonkeyReadRule(const vector<string>& name_value);
+
+    MONKEY_RETTYPE Run(MONKEY_SOCKTYPE sock,
+                       MONKEY_DATATYPE buf,
+                       MONKEY_LENTYPE  size,
+                       int             flags, 
+                       SOCK*           sock_ptr);
+private:
+    /* A socket that gets timeouts*/
+    SOCK m_TimeoutingSocket;
+};
+
+
+class CMonkeyConnectRule : public CMonkeyRuleBase
+{
+public:
+    CMonkeyConnectRule(const vector<string>& name_value);
+    
+    int Run(MONKEY_SOCKTYPE        sock,
+            const struct sockaddr* name,
+            MONKEY_SOCKLENTYPE     namelen);
+private:
+    bool m_Allow;
+};
+
+
+class CMonkeyPollRule : public CMonkeyRuleBase
+{
+public:
+    CMonkeyPollRule(const vector<string>& name_value);
+    
+    bool  Run(size_t*     n,
+              SOCK*       sock,
+              EIO_Status* return_status);
+private:
+    map<SOCK, struct timeval> x_Delays;
+    bool m_Ignore;
+};
+
+
+class CMonkeyPlan : public CMonkeySeedAccessor
+{
+public:
+/* 
+ * write1=text=garbage;return_status=eIO_Closed;text_length=500;runs=100%,0%,50.5%,100%,repeat
+ * write2=text='garbage';text_length=500;fill=last_letter;runs=0%,50%,25%,100%,32%,...
+ * read=text='read_garbage';text_length=500;fill=repeat;runs=50%;return_status=eIO_Closed
+ * connect=allow=no;runs=1,2,3,4,100
+ * poll=delay=2000;ignore=yes,runs=1
+ */
+    CMonkeyPlan(const string& section);
+
+    bool Match (const string&  host, 
+                unsigned short port, 
+                const string&  url,
+                unsigned short probability_left = 100);
+    /** Guarantees to have not run send() if returned false. Returning true
+        can mean either that send() was run or that send() was simulated to be 
+        unsuccessful */
+    bool WriteRule     (MONKEY_SOCKTYPE        sock,
+                        const MONKEY_DATATYPE  data,
+                        MONKEY_LENTYPE         size,
+                        int                    flags,
+                        MONKEY_RETTYPE*        bytes_written,
+                        SOCK*                  sock_ptr);
+
+    bool ReadRule      (MONKEY_SOCKTYPE        sock,
+                        MONKEY_DATATYPE        buf,
+                        MONKEY_LENTYPE         size,
+                        int                    flags,
+                        MONKEY_RETTYPE*        bytes_read,
+                        SOCK*                  sock_ptr);
+
+    bool ConnectRule   (MONKEY_SOCKTYPE        sock,
+                        const struct sockaddr* name,
+                        MONKEY_SOCKLENTYPE     namelen,
+                        int*                   result);
+
+    bool PollRule      (size_t*                n,
+                        SOCK*                  sock,
+                        EIO_Status*            return_status);
+
+    unsigned short GetProbabilty(void);
+private:
+    /**  */
+    template<class Rule_Ty>
+    void x_LoadRules(const string&    section,
+                     const string&    rule_type_str, 
+                     vector<Rule_Ty>& container);
+
+
+    void                           x_ReadPortRange(const string&    conf);
+    unsigned short                 m_Probability;
+    string                         m_HostRegex;
+    /** Port ranges are stored in pairs.
+     * odd item - from, even - till (both - inclusive). So for one element
+     * in range "from" and "till" are the same. Example:
+     * for range "8080-8085, 8089"
+     * m_PortRanges = { 8080, 8085, 8089, 8089 } */
+    vector<unsigned short>         m_PortRanges;
+    vector<CMonkeyWriteRule>       m_WriteRules;
+    vector<CMonkeyReadRule>        m_ReadRules;
+    vector<CMonkeyConnectRule>     m_ConnectRules;
+    vector<CMonkeyPollRule>        m_PollRules;
+    /** Only for debugging purposes */
+    string                         m_Name;
+};
+
+
+enum EMonkeyHookSwitch {
+    eMonkeyHookSwitch_Disabled = 0,
+    eMonkeyHookSwitch_Enabled  = 1
+};
+
+
+typedef void (*FMonkeyHookSwitch)(EMonkeyHookSwitch hook_switch);
+
+
+class CMonkey : public CMonkeySeedAccessor
+{
+public:
+    /** This method is not for public use.
+     * CMonkeySeedLogKey is a special class that allows only some certain 
+     * class to call this method */
+    int GetRand(const CMonkeySeedKey& /* key */);
+
+    /** To be able to reproduce Chaos Monkey behavior, you need to tag each
+    * thread with a unique token. Then you can ask Chaos Monkey to reproduce
+    * behavior from a previous run, if Monkey saved what it did to a file */
+    bool RegisterThread(int token);
+
+    int GetSeed(void);
+    void SetSeed(int seed);
+    static CMonkey* Instance(void);
+    void ReloadConfig(const string& config = "");
+    bool IsEnabled(void);
+
+    MONKEY_RETTYPE Send(MONKEY_SOCKTYPE        sock,
+                        const MONKEY_DATATYPE  data,
+                        MONKEY_LENTYPE         size,
+                        int                    flags,
+                        SOCK*                  sock_ptr);
+
+    MONKEY_RETTYPE Recv(MONKEY_SOCKTYPE        sock,
+                        MONKEY_DATATYPE        buf,
+                        MONKEY_LENTYPE         size,
+                        int                    flags,
+                        SOCK*                  sock_ptr);
+
+    int Connect(MONKEY_SOCKTYPE        sock,
+                const struct sockaddr* name,
+                MONKEY_SOCKLENTYPE     namelen);
+
+    bool Poll(size_t*      n,
+              SSOCK_Poll** polls,
+              EIO_Status*  return_status);
+    /* Not a real Chaos Monkey interceptor, just a function to remove the socket 
+     * that was closed from m_KnownSockets */
+    void Close(MONKEY_SOCKTYPE sock);
+
+    static void MonkeyHookSwitchSet(FMonkeyHookSwitch hook_switch_func);
+private:
+    /* No one can create a separate instance of CMonkey*/
+    CMonkey(void);
+    /** Return plan for the socket, new or already assigned one. If the socket
+     *  is ignored by Chaos Monkey, NULL is returned. 
+     * @param[in] match_host 
+     *  Tell whether host has to be matched, too. In case of poll() on 
+     *  listening socket it is impossible to know host before accept(), so 
+     *  the check is omitted. */
+    CMonkeyPlan* x_FindPlan(MONKEY_SOCKTYPE sock,  const string& hostname,
+                            const string& host_IP, unsigned short port);
+    /** Sockets that are already assigned to a plan (or known to be ignored) */
+    map<SOCKET, CMonkeyPlan*> m_KnownSockets;
+    static CMonkey*           sm_Instance;
+    vector<CMonkeyPlan>       m_Plans;
+    double                    m_Probability;
+    bool                      m_Enabled;
+    static FMonkeyHookSwitch  sm_HookSwitch;
+    CRef<CTls<int>>           m_TlsToken;
+    CRef<CTls<vector<int> > > m_TlsRandList;
+    CRef<CTls<int> >          m_TlsRandListPos;
+    unsigned int              m_Seed;
+    /** Remember registered tokens for threads to avoid collisions */
+    set<int>                  m_RegisteredTokens;
+};
+
+
+END_NCBI_SCOPE
+
+#endif /* #ifdef NCBI_MONKEY */
+
+#endif /* CONNECT___NCBI_MONKEY__HPP */
\ No newline at end of file
diff --git a/c++/include/connect/ncbi_server_info.h b/c++/include/connect/ncbi_server_info.h
index 05a15c5..c120c76 100644
--- a/c++/include/connect/ncbi_server_info.h
+++ b/c++/include/connect/ncbi_server_info.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_SERVER_INFO__H
 #define CONNECT___NCBI_SERVER_INFO__H
 
-/* $Id: ncbi_server_info.h 451391 2014-11-06 15:31:05Z lavr $
+/* $Id: ncbi_server_info.h 494171 2016-03-04 01:46:23Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -83,9 +83,6 @@ typedef enum {
     eSERV_Blast        = 1,  /* Server is tied up to an instant host load */
     eSERV_RegularInter = 2,  /* Regular server shared between LBSM zones  */
     eSERV_BlastInter   = 3,  /* ... same for Blast-type server            */
-    /* compatibility only, deprecated */
-    fSERV_Regular      = eSERV_Regular,
-    fSERV_Blast        = eSERV_Blast
 } ESERV_Flag;
 
 
diff --git a/c++/include/connect/ncbi_service.h b/c++/include/connect/ncbi_service.h
index e7df611..48024c6 100644
--- a/c++/include/connect/ncbi_service.h
+++ b/c++/include/connect/ncbi_service.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_SERVICE__H
 #define CONNECT___NCBI_SERVICE__H
 
-/* $Id: ncbi_service.h 472260 2015-07-08 16:43:43Z elisovdn $
+/* $Id: ncbi_service.h 513292 2016-09-09 11:35:38Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -43,9 +43,9 @@
  * @{
  */
 
-/** Revision 6.270 */
-#define SERV_CLIENT_REVISION_MAJOR  6
-#define SERV_CLIENT_REVISION_MINOR  270
+/** Revision 7.0 */
+#define SERV_CLIENT_REVISION_MAJOR  7
+#define SERV_CLIENT_REVISION_MINOR  0
 
 /** Special values for the "preferred_host" parameter.
  * @sa
@@ -85,8 +85,8 @@ enum ESERV_TypeSpecial {
     fSERV_IncludeDown       = 0x08000000,
     fSERV_IncludeStandby    = 0x10000000,
     fSERV_IncludeReserved   = 0x20000000,  /**< @note Not yet implemented */
-    fSERV_IncludePenalized  = 0x40000000,
-    fSERV_IncludeSuppressed = 0x70000000,
+    fSERV_IncludeSuppressed = 0x40000000,
+    fSERV_IncludeInactive   = 0x70000000,
     fSERV_Promiscuous       = 0x78000000
 };
 typedef unsigned int   TSERV_Type;      /**<Bitwise OR of ESERV_Type[Special]*/
@@ -125,12 +125,12 @@ typedef unsigned short TSERV_TypeOnly;  /**<Server type only, w/o specials   */
  *  not to return from the search (whose server-infos match the would-be
  *  result).
  * @note However, special additional rules apply to the "skip" elements when
- *       the fSERV_ReverseDns bit is set in the "types":  the result-to-be is
- *       not considered if either
- *    1. There is an fSERV_Dns type entry found in "skip" that matches
- *       host[:port] (any port if 0); or
- *    2. The reverse lookup of the host:port turns up an fSERV_Dns type server
- *       whose name matches an fSERV_Dns type server from "skip".
+ *       the fSERV_ReverseDns bit is set in the "types" parameter:  the
+ *       result-to-be is not considered if either
+ *    1. There is an entry of the fSERV_Dns type found in "skip" array that
+ *       matches the host[:port] (any port if port is 0); or
+ *    2. The reverse lookup of the host:port turns up an fSERV_Dns-type server
+ *       whose name matches an fSERV_Dns-type server in "skip".
  * @param n_skip
  *  Number of entries in the "skip" array.
  * @return
@@ -202,13 +202,15 @@ extern NCBI_XCONNECT_EXPORT SERV_ITER SERV_OpenSimple
  *       may contain 0 in the host field to denote that the name exists but the
  *       service is currently not serving (down / unavailable).
  * @note Only when completing successfully, i.e. returning a non-NULL info,
- *       this call can also provide the host information as follows: if
+ *       this call can also provide host information as the following:  if
  *       "host_info" parameter is passed as a non-NULL pointer, then a copy of
- *       the host information is allocated, and the handle is stored at
- *       "*host_info".  Using this handle, various host parameters like load,
- *       host environment, number of CPUs can be retrieved
- *       (see ncbi_host_info.h).  The returned host information handle has to
- *       be explicitly free()'d when no longer needed.
+ *       host information may be allocated, and the handle is then stored at
+ *       "*host_info" when the host information is available for the host.
+ *       Otherwise, the pointer is updated with a NULL value stored.  Using the
+ *       non-NULL handle returned, various parameters like load, environment,
+ *       number of CPUs, etc can be retrieved (see ncbi_host_info.h).  The
+ *       returned host information handle has to be explicitly free()'d when
+ *       no longer needed.
  * @sa
  *  SERV_Reset, SERV_Close, SERV_GetInfoEx, ncbi_host_info.h
  */
@@ -231,8 +233,8 @@ extern NCBI_XCONNECT_EXPORT SSERV_InfoCPtr SERV_GetNextInfo
  * However, this call is optimized for an application, which only needs
  * a single entry (the first one), and which is not interested in iterating
  * over all available instances.  Both the returned server-info and host
- * information have to be explicitly free()'d by the application when no
- * longer needed.
+ * information (if any) have to be explicitly free()'d by the application when
+ * no longer needed.
  * @param service
  *  A service name (may not be NULL or empty).
  * @param types
@@ -277,7 +279,10 @@ extern NCBI_XCONNECT_EXPORT SSERV_Info* SERV_GetInfo
  const SConnNetInfo*  net_info
  );
 
-/** Same as "SERV_GetInfo(., fSERV_Any, SERV_ANYHOST, ConnNetInfo_Create(service))".
+/** Equivalent to "SERV_GetInfo(., fSERV_Any, SERV_ANYHOST,
+ *                              ConnNetInfo_Create(service))",
+ * but it takes care not to leak its last "net_info" parameter, which it builds
+ * on the fly.
  * @sa
  *  SERV_GetInfo, SERV_OpenSimple
  */
diff --git a/c++/include/connect/ncbi_socket.h b/c++/include/connect/ncbi_socket.h
index e542e12..ad0bc74 100644
--- a/c++/include/connect/ncbi_socket.h
+++ b/c++/include/connect/ncbi_socket.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_SOCKET__H
 #define CONNECT___NCBI_SOCKET__H
 
-/* $Id: ncbi_socket.h 482179 2015-10-21 15:02:35Z lavr $
+/* $Id: ncbi_socket.h 501319 2016-05-13 15:59:52Z vakatov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -297,9 +297,9 @@ extern NCBI_XCONNECT_EXPORT const STimeout*SOCK_SetSelectInternalRestartTimeout
  *  SOCK_SetIOWaitSysAPI
  */
 typedef enum {
-    eSOCK_IOWaitSysAPIAuto,   /** default; use some euristics to choose API */
-    eSOCK_IOWaitSysAPIPoll,   /** always use poll()                         */
-    eSOCK_IOWaitSysAPISelect  /** always use select()                       */
+    eSOCK_IOWaitSysAPIAuto,   /**< default; use some euristics to choose API */
+    eSOCK_IOWaitSysAPIPoll,   /**< always use poll()                         */
+    eSOCK_IOWaitSysAPISelect  /**< always use select()                       */
 } ESOCK_IOWaitSysAPI;
 
 /** This is a helper call that can improve I/O behavior (ignored for Windows).
@@ -1103,16 +1103,16 @@ extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_Status
  *  [in]  eIO_WritePlain | eIO_WritePersist
  * @return
  *  In "*n_written", return the number of bytes actually written.
- *  eIO_WritePlain   --  write as many bytes as possible at once and return
+ *  eIO_WritePlain   -- write as many bytes as possible at once and return
  *                      immediately; if no bytes can be written then wait
  *                      at most WRITE timeout, try again and return.
- *  eIO_WritePersist --  write all data (doing an internal retry loop
+ *  eIO_WritePersist -- write all data (doing an internal retry loop
  *                      if necessary); if any single write attempt times out
  *                      or fails then stop writing and return (error code).
  *  Return status: eIO_Success -- some bytes were written successfully  [Plain]
- *                            -- all bytes were written successfully [Persist]
- *                other code denotes an error, but some bytes might have
- *                been sent nevertheless (always check *n_written to know).
+ *                             -- all bytes were written successfully [Persist]
+ *                 other code denotes an error, but some bytes might have
+ *                 been sent nevertheless (always check *n_written to know).
  *
  * @note  With eIO_WritePlain the call returns eIO_Success if and only if
  *        some data were actually written to the socket.  If no data could
@@ -1142,7 +1142,7 @@ extern NCBI_XCONNECT_EXPORT EIO_Status SOCK_Write
  * This call is available for stream sockets only.
  * @note  Even though the underlying OS socket handle may have been marked for
  *        preservation via fSOCK_KeepOnClose, this call always and
- *        unconditially closes and destroys the actual OS handle.
+ *        unconditionally closes and destroys the actual OS handle.
  * @param sock
  *  [in] socket handle
  */
@@ -1251,9 +1251,9 @@ extern NCBI_XCONNECT_EXPORT unsigned short SOCK_GetRemotePort
  *  On success, return its "buf" argument; return 0 on error.
  */
 typedef enum {
-    eSAF_Full = 0,  /** address in full, native form                      */
-    eSAF_Port,      /** only numeric port if INET socket, empty otherwise */
-    eSAF_IP         /** only numeric IP if INET socket,   empty otherwise */
+    eSAF_Full = 0,  /**< address in full, native form                      */
+    eSAF_Port,      /**< only numeric port if INET socket, empty otherwise */
+    eSAF_IP         /**< only numeric IP if INET socket,   empty otherwise */
 } ESOCK_AddressFormat;
 
 extern NCBI_XCONNECT_EXPORT char* SOCK_GetPeerAddressStringEx
diff --git a/c++/include/connect/ncbi_types.h b/c++/include/connect/ncbi_types.h
index 80e4853..0b2cb80 100644
--- a/c++/include/connect/ncbi_types.h
+++ b/c++/include/connect/ncbi_types.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_TYPES__H
 #define CONNECT___NCBI_TYPES__H
 
-/* $Id: ncbi_types.h 445734 2014-09-08 13:43:28Z lavr $
+/* $Id: ncbi_types.h 501321 2016-05-13 16:00:05Z vakatov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -132,8 +132,8 @@ typedef enum ENcbiSwitch {
  * For example, specify if a CSocket object owns its underlying SOCK object.
  */
 typedef enum ENcbiOwnership {
-    eNoOwnership,       /** No ownership is assumed                 */
-    eTakeOwnership      /** An object can take ownership of another */
+    eNoOwnership,       /**< No ownership is assumed                 */
+    eTakeOwnership      /**< An object can take ownership of another */
 } EOwnership;
 
 #endif /*!NCBI_EOWNERSHIP_DEFINED*/
diff --git a/c++/include/connect/server.hpp b/c++/include/connect/server.hpp
index 008ce9d..96d601b 100644
--- a/c++/include/connect/server.hpp
+++ b/c++/include/connect/server.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT___SERVER__HPP
 #define CONNECT___SERVER__HPP
 
-/* $Id: server.hpp 384345 2012-12-26 15:51:40Z satskyse $
+/* $Id: server.hpp 506707 2016-07-11 15:26:50Z satskyse $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -103,6 +103,14 @@ public:
     void AddListener(IServer_ConnectionFactory* factory,
                      unsigned short             port);
 
+    /// Removes a listener
+    /// @param port
+    ///  the listener on the port will be removed
+    /// @return
+    ///  true if the listener has been removed, false if the server does not
+    ///  listen on the port.
+    bool RemoveListener(unsigned short  port);
+
     /// 
     void SetParameters(const SServer_Parameters& new_params);
 
@@ -152,11 +160,16 @@ public:
     void SetCustomThreadSuffix(const string& suffix)
     { m_ThreadSuffix = suffix; }
 
+    /// Provides a list of ports on which the server is listening
+    /// @return
+    ///  currently listened ports
+    vector<unsigned short>  GetListenerPorts(void);
+
 protected:
     /// Initialize the server
     ///
     /// Called by Run method before poll cycle.
-    virtual void Init();
+    virtual void Init() {}
 
     /// Cleanup the server
     ///
@@ -164,12 +177,12 @@ protected:
     /// are stopped, but before releasing listening ports. Here you're still
     /// guaranteed that another instance running on the same set of ports will
     /// fail at StartListening point.
-    virtual void Exit();
+    virtual void Exit() {}
 
     /// Runs synchronously when no socket activity has occurred in a
     /// while (as determined by m_AcceptTimeout).
     /// @sa m_Parameters->accept_timeout
-    virtual void ProcessTimeout(void) { }
+    virtual void ProcessTimeout(void) {}
 
     /// Runs synchronously between iterations.
     /// @return
@@ -177,7 +190,6 @@ protected:
     virtual bool ShutdownRequested(void) { return false; }
 
 private:
-    void x_AddRequests(const vector<CRef<CStdRequest> >& reqs);
     void x_DoRun(void);
 
     friend class CNetCacheServer;
@@ -274,6 +286,9 @@ public:
     // See comment for CAcceptRequest::Process and CServer::CreateRequest
     virtual void OnOverflow(EOverflowReason) { }
 
+    /// Runs when a socket error is detected
+    virtual void OnError(const string &  /*err_message*/) { }
+
     /// Get underlying socket
     CSocket& GetSocket(void) { return *m_Socket; }
 
diff --git a/c++/include/connect/services/grid_client.hpp b/c++/include/connect/services/grid_client.hpp
index 2f0b11f..4ca9e87 100644
--- a/c++/include/connect/services/grid_client.hpp
+++ b/c++/include/connect/services/grid_client.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES_GRID__GRID_CLIENT__HPP
 #define CONNECT_SERVICES_GRID__GRID_CLIENT__HPP
 
-/*  $Id: grid_client.hpp 492603 2016-02-18 19:27:56Z ivanov $
+/*  $Id: grid_client.hpp 492431 2016-02-17 17:05:04Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/connect/services/grid_worker.hpp b/c++/include/connect/services/grid_worker.hpp
index f70b9f9..6d099c2 100644
--- a/c++/include/connect/services/grid_worker.hpp
+++ b/c++/include/connect/services/grid_worker.hpp
@@ -2,7 +2,7 @@
 #define CONNECT_SERVICES__GRID_WORKER_HPP
 
 
-/*  $Id: grid_worker.hpp 492323 2016-02-16 19:37:01Z ivanov $
+/*  $Id: grid_worker.hpp 491853 2016-02-09 18:08:45Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/connect/services/grid_worker_app.hpp b/c++/include/connect/services/grid_worker_app.hpp
index 1ccaac1..b8d8bc2 100644
--- a/c++/include/connect/services/grid_worker_app.hpp
+++ b/c++/include/connect/services/grid_worker_app.hpp
@@ -2,7 +2,7 @@
 #define CONNECT_SERVICES__GRID_WORKER_APP_HPP
 
 
-/*  $Id: grid_worker_app.hpp 492325 2016-02-16 19:37:51Z ivanov $
+/*  $Id: grid_worker_app.hpp 491945 2016-02-10 18:01:31Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/connect/services/impl/neticache_client_int.hpp b/c++/include/connect/services/impl/neticache_client_int.hpp
index bbadd85..40133a5 100644
--- a/c++/include/connect/services/impl/neticache_client_int.hpp
+++ b/c++/include/connect/services/impl/neticache_client_int.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES_IMPL__NETICACHE_CLIENT_INT__HPP
 #define CONNECT_SERVICES_IMPL__NETICACHE_CLIENT_INT__HPP
 
-/*  $Id: neticache_client_int.hpp 498373 2016-04-15 17:20:10Z ivanov $
+/*  $Id: neticache_client_int.hpp 498257 2016-04-14 16:43:26Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/connect/services/impl/netschedule_api_int.hpp b/c++/include/connect/services/impl/netschedule_api_int.hpp
index 5fd4ab4..e4604f5 100644
--- a/c++/include/connect/services/impl/netschedule_api_int.hpp
+++ b/c++/include/connect/services/impl/netschedule_api_int.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES_IMPL__NETSCHEDULE_API_INT__HPP
 #define CONNECT_SERVICES_IMPL__NETSCHEDULE_API_INT__HPP
 
-/*  $Id: netschedule_api_int.hpp 492596 2016-02-18 19:25:31Z ivanov $
+/*  $Id: netschedule_api_int.hpp 491948 2016-02-10 18:22:43Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/connect/services/impl/netstorage_impl.hpp b/c++/include/connect/services/impl/netstorage_impl.hpp
index c36c070..0362c2c 100644
--- a/c++/include/connect/services/impl/netstorage_impl.hpp
+++ b/c++/include/connect/services/impl/netstorage_impl.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES_IMPL__NETSTORAGE_IMPL__HPP
 #define CONNECT_SERVICES_IMPL__NETSTORAGE_IMPL__HPP
 
-/*  $Id: netstorage_impl.hpp 499844 2016-04-28 16:13:26Z ivanov $
+/*  $Id: netstorage_impl.hpp 505978 2016-06-30 15:57:38Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -215,10 +215,10 @@ struct NCBI_XCONNECT_EXPORT SNetStorageImpl : public CObject
 {
     typedef SNetStorage::SConfig TConfig;
 
-    virtual CNetStorageObject Create(TNetStorageFlags flags = 0) = 0;
+    virtual CNetStorageObject Create(TNetStorageFlags flags) = 0;
     virtual CNetStorageObject Open(const string& object_loc) = 0;
     virtual string Relocate(const string& object_loc,
-            TNetStorageFlags flags) = 0;
+            TNetStorageFlags flags, TNetStorageProgressCb cb) = 0;
     virtual bool Exists(const string& object_loc) = 0;
     virtual ENetStorageRemoveResult Remove(const string& object_loc) = 0;
 #ifdef NCBI_GRID_XSITE_CONN_SUPPORT
@@ -232,12 +232,13 @@ struct NCBI_XCONNECT_EXPORT SNetStorageByKeyImpl : public CObject
     typedef SNetStorage::SConfig TConfig;
 
     virtual CNetStorageObject Open(const string& unique_key,
-            TNetStorageFlags flags = 0) = 0;
+            TNetStorageFlags flags) = 0;
     virtual string Relocate(const string& unique_key,
-            TNetStorageFlags flags, TNetStorageFlags old_flags = 0) = 0;
-    virtual bool Exists(const string& key, TNetStorageFlags flags = 0) = 0;
+            TNetStorageFlags flags, TNetStorageFlags old_flags,
+            TNetStorageProgressCb cb) = 0;
+    virtual bool Exists(const string& key, TNetStorageFlags flags) = 0;
     virtual ENetStorageRemoveResult Remove(const string& key,
-            TNetStorageFlags flags = 0) = 0;
+            TNetStorageFlags flags) = 0;
 #ifdef NCBI_GRID_XSITE_CONN_SUPPORT
     virtual void AllowXSiteConnections() {}
 #endif
diff --git a/c++/include/connect/services/impl/netstorage_int.hpp b/c++/include/connect/services/impl/netstorage_int.hpp
index c06cc35..e754b99 100644
--- a/c++/include/connect/services/impl/netstorage_int.hpp
+++ b/c++/include/connect/services/impl/netstorage_int.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES_IMPL__NETSTORAGE_INT__HPP
 #define CONNECT_SERVICES_IMPL__NETSTORAGE_INT__HPP
 
-/*  $Id: netstorage_int.hpp 499028 2016-04-21 15:25:58Z ivanov $
+/*  $Id: netstorage_int.hpp 498620 2016-04-18 16:34:28Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/connect/services/json_over_uttp.hpp b/c++/include/connect/services/json_over_uttp.hpp
index ca96bd8..a3350d4 100644
--- a/c++/include/connect/services/json_over_uttp.hpp
+++ b/c++/include/connect/services/json_over_uttp.hpp
@@ -1,7 +1,7 @@
 #ifndef JSON_OVER_UTTP__HPP
 #define JSON_OVER_UTTP__HPP
 
-/*  $Id: json_over_uttp.hpp 495785 2016-03-21 16:50:59Z ivanov $
+/*  $Id: json_over_uttp.hpp 502215 2016-05-23 15:27:45Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -278,6 +278,10 @@ class NCBI_XCONNECT_EXPORT CJsonNode
 
     /// Return a string representation of this node.
     string Repr(TReprFlags flags = 0) const;
+
+    static CJsonNode ParseObject(const string& json);
+    static CJsonNode ParseArray(const string& json);
+    static CJsonNode ParseJSON(const string& json);
 };
 
 /// Iterator for JSON arrays and objects.
diff --git a/c++/include/connect/services/netcache_api_expt.hpp b/c++/include/connect/services/netcache_api_expt.hpp
index d51e58a..0a9cc19 100644
--- a/c++/include/connect/services/netcache_api_expt.hpp
+++ b/c++/include/connect/services/netcache_api_expt.hpp
@@ -1,7 +1,7 @@
 #ifndef CONN___NETCACHE_API_EXPT__HPP
 #define CONN___NETCACHE_API_EXPT__HPP
 
-/*  $Id: netcache_api_expt.hpp 490874 2016-01-29 14:28:07Z ivanov $
+/*  $Id: netcache_api_expt.hpp 490771 2016-01-28 17:36:51Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/connect/services/netcache_search.hpp b/c++/include/connect/services/netcache_search.hpp
new file mode 100644
index 0000000..fd525cb
--- /dev/null
+++ b/c++/include/connect/services/netcache_search.hpp
@@ -0,0 +1,169 @@
+#ifndef CONNECT_SERVICES___NETCACHE_SEARCH__HPP
+#define CONNECT_SERVICES___NETCACHE_SEARCH__HPP
+
+/*  $Id: netcache_search.hpp 520438 2016-11-28 18:35:31Z ivanov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author: Rafael Sadyrov
+ *
+ */
+
+
+#include <connect/connect_export.h>
+#include <memory>
+#include <chrono>
+
+
+namespace ncbi {
+namespace grid {
+namespace netcache {
+namespace search {
+
+
+/// @internal
+/// @{
+
+struct SExpressionImpl;
+struct SBlobInfoImpl;
+struct SExpression { shared_ptr<SExpressionImpl> impl; ~SExpression(); };
+struct SBlobInfo   { shared_ptr<SBlobInfoImpl>   impl; ~SBlobInfo();   };
+
+/// @}
+
+
+using time_point = chrono::system_clock::time_point;
+using duration = chrono::system_clock::duration;
+
+
+/// @defgroup NetCacheSearch
+/// @{
+
+
+/// Search and output fields
+namespace fields {
+
+const struct KEY             {KEY(){}}              key;
+const struct SUBKEY          {SUBKEY(){}}           subkey;
+const struct CREATED         {CREATED(){}}          created;
+const struct EXPIRES         {EXPIRES(){}}          expires;
+const struct VERSION_EXPIRES {VERSION_EXPIRES(){}}  version_expires;
+const struct SIZE            {SIZE(){}}             size;
+
+}
+
+
+using namespace fields;
+
+/// Search operators
+/// @{
+
+struct NCBI_XCONNECT_EXPORT CExpression { SExpression base; };
+
+NCBI_XCONNECT_EXPORT CExpression operator==(KEY,             string);
+NCBI_XCONNECT_EXPORT CExpression operator==(string,          KEY);
+
+NCBI_XCONNECT_EXPORT CExpression operator>=(CREATED,         time_point);
+NCBI_XCONNECT_EXPORT CExpression operator< (CREATED,         time_point);
+NCBI_XCONNECT_EXPORT CExpression operator<=(time_point,      CREATED);
+NCBI_XCONNECT_EXPORT CExpression operator> (time_point,      CREATED);
+
+NCBI_XCONNECT_EXPORT CExpression operator>=(CREATED,         duration);
+NCBI_XCONNECT_EXPORT CExpression operator< (CREATED,         duration);
+NCBI_XCONNECT_EXPORT CExpression operator<=(duration,        CREATED);
+NCBI_XCONNECT_EXPORT CExpression operator> (duration,        CREATED);
+
+NCBI_XCONNECT_EXPORT CExpression operator>=(EXPIRES,         time_point);
+NCBI_XCONNECT_EXPORT CExpression operator< (EXPIRES,         time_point);
+NCBI_XCONNECT_EXPORT CExpression operator<=(time_point,      EXPIRES);
+NCBI_XCONNECT_EXPORT CExpression operator> (time_point,      EXPIRES);
+
+NCBI_XCONNECT_EXPORT CExpression operator>=(EXPIRES,         duration);
+NCBI_XCONNECT_EXPORT CExpression operator< (EXPIRES,         duration);
+NCBI_XCONNECT_EXPORT CExpression operator<=(duration,        EXPIRES);
+NCBI_XCONNECT_EXPORT CExpression operator> (duration,        EXPIRES);
+
+NCBI_XCONNECT_EXPORT CExpression operator>=(VERSION_EXPIRES, time_point);
+NCBI_XCONNECT_EXPORT CExpression operator< (VERSION_EXPIRES, time_point);
+NCBI_XCONNECT_EXPORT CExpression operator<=(time_point,      VERSION_EXPIRES);
+NCBI_XCONNECT_EXPORT CExpression operator> (time_point,      VERSION_EXPIRES);
+
+NCBI_XCONNECT_EXPORT CExpression operator>=(VERSION_EXPIRES, duration);
+NCBI_XCONNECT_EXPORT CExpression operator< (VERSION_EXPIRES, duration);
+NCBI_XCONNECT_EXPORT CExpression operator<=(duration,        VERSION_EXPIRES);
+NCBI_XCONNECT_EXPORT CExpression operator> (duration,        VERSION_EXPIRES);
+
+NCBI_XCONNECT_EXPORT CExpression operator>=(SIZE,            size_t);
+NCBI_XCONNECT_EXPORT CExpression operator< (SIZE,            size_t);
+NCBI_XCONNECT_EXPORT CExpression operator<=(size_t,          SIZE);
+NCBI_XCONNECT_EXPORT CExpression operator> (size_t,          SIZE);
+
+NCBI_XCONNECT_EXPORT CExpression operator&&(CExpression,     CExpression);
+
+/// @}
+
+
+/// Output fields specification
+/// @{
+
+struct NCBI_XCONNECT_EXPORT CFields
+{
+    SExpression base;
+
+    CFields();
+    CFields(CREATED);
+    CFields(EXPIRES);
+    CFields(VERSION_EXPIRES);
+    CFields(SIZE);
+};
+
+NCBI_XCONNECT_EXPORT CFields operator|(CFields, CFields);
+
+/// @}
+
+
+/// Blob info
+struct NCBI_XCONNECT_EXPORT CBlobInfo
+{
+    SBlobInfo base;
+
+    string     operator[](KEY)             const;
+    string     operator[](SUBKEY)          const;
+    time_point operator[](CREATED)         const;
+    time_point operator[](EXPIRES)         const;
+    time_point operator[](VERSION_EXPIRES) const;
+    size_t     operator[](SIZE)            const;
+};
+
+
+/// @}
+
+
+}
+}
+}
+}
+
+
+#endif
diff --git a/c++/include/connect/services/netcomponent.hpp b/c++/include/connect/services/netcomponent.hpp
index cab81b6..24f5840 100644
--- a/c++/include/connect/services/netcomponent.hpp
+++ b/c++/include/connect/services/netcomponent.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES__NET_OBJECT_HPP
 #define CONNECT_SERVICES__NET_OBJECT_HPP
 
-/*  $Id: netcomponent.hpp 485042 2015-11-18 14:41:49Z sadyrovr $
+/*  $Id: netcomponent.hpp 501217 2016-05-12 14:34:55Z vasilche $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -71,6 +71,13 @@ public:
         CObjectCounterLocker::UnlockRelease(
             reinterpret_cast<const CObject*>(object));
     }
+
+    void TransferLock(const S* object,
+                      const CNetComponentCounterLocker& old_locker) const
+    {
+        CObjectCounterLocker::TransferLock(
+            reinterpret_cast<const CObject*>(object), old_locker);
+    }
 };
 
 #define NCBI_NET_COMPONENT_DEF(Class, Impl)                                 \
diff --git a/c++/include/connect/services/neticache_client.hpp b/c++/include/connect/services/neticache_client.hpp
index ec135b7..3573590 100644
--- a/c++/include/connect/services/neticache_client.hpp
+++ b/c++/include/connect/services/neticache_client.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES___NETICACHE_CLIENT__HPP
 #define CONNECT_SERVICES___NETICACHE_CLIENT__HPP
 
-/*  $Id: neticache_client.hpp 486447 2015-12-04 15:37:50Z sadyrovr $
+/*  $Id: neticache_client.hpp 520437 2016-11-28 18:35:09Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -38,6 +38,7 @@
 ///
 
 #include "netcache_api.hpp"
+#include "netcache_search.hpp"
 
 #include <list>
 
@@ -150,6 +151,25 @@ class NCBI_NET_CACHE_EXPORT CNetICacheClient : public ICache
     ///
     list<string> GetSubkeyList(const string& key);
 
+    typedef grid::netcache::search::CBlobInfo CBlobInfo;
+    typedef grid::netcache::search::CExpression CExpression;
+    typedef grid::netcache::search::CFields CFields;
+
+    /// Returns information for all blobs matching provided search expression.
+    /// @see NetCacheSearch for complete list of classes and operators.
+    ///
+    /// @param expression
+    ///    Search expression,
+    ///    e.g. 'created < hours(1) && size >= 1024'
+    /// @param fields
+    ///    Additional output fields requested in blob info,
+    ///    e.g. 'expires | version_expires'
+    /// @return
+    ///    Blob info consisting of key, subkey, fields from provided search
+    ///    expression and output fields for all blobs matched the expression
+    ///
+    vector<CBlobInfo> Search(CExpression expression, CFields fields = CFields());
+
     /// @warning
     ///    This method DOES NOT follow ICache::Read() interface
     ///    on returning values/throwing exceptions.
diff --git a/c++/include/connect/services/netschedule_api.hpp b/c++/include/connect/services/netschedule_api.hpp
index 300402f..efb08ae 100644
--- a/c++/include/connect/services/netschedule_api.hpp
+++ b/c++/include/connect/services/netschedule_api.hpp
@@ -1,7 +1,7 @@
 #ifndef CONN___NETSCHEDULE_API__HPP
 #define CONN___NETSCHEDULE_API__HPP
 
-/*  $Id: netschedule_api.hpp 492595 2016-02-18 19:25:07Z ivanov $
+/*  $Id: netschedule_api.hpp 507304 2016-07-18 16:15:49Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -296,19 +296,17 @@ class NCBI_XCONNECT_EXPORT CNetScheduleAPI
 };
 
 
-////////////////////////////////////////////////////////////////////////////////
-////
-/// Job description
+/// New job description
 ///
-struct CNetScheduleJob
+
+struct CNetScheduleNewJob
 {
-    explicit CNetScheduleJob(const string& _input = kEmptyStr,
+    explicit CNetScheduleNewJob(const string& _input = kEmptyStr,
             const string& _affinity = kEmptyStr,
             CNetScheduleAPI::TJobMask _mask = CNetScheduleAPI::eEmptyMask) :
         input(_input),
         affinity(_affinity),
-        mask(_mask),
-        ret_code(0)
+        mask(_mask)
     {
     }
 
@@ -316,20 +314,10 @@ struct CNetScheduleJob
     {
         input.erase();
         affinity.erase();
-        client_ip.erase();
-        session_id.erase();
-        page_hit_id.erase();
         mask = CNetScheduleAPI::eEmptyMask;
         job_id.erase();
-        ret_code = 0;
-        output.erase();
-        error_msg.erase();
-        progress_msg.erase();
         group.erase();
-        auth_token.erase();
-        server = NULL;
     }
-    // input parameters
 
     /// Input data. Arbitrary string that contains input data
     /// for the job. It is suggested to use NetCache to keep
@@ -338,14 +326,46 @@ struct CNetScheduleJob
 
     string affinity;
 
-    string client_ip;
-    string session_id;
-    string page_hit_id;
+    string group;
 
     CNetScheduleAPI::TJobMask  mask;
 
-    /// Job key.
+    /// Output job key.
     string job_id;
+};
+
+
+/// Job description
+///
+
+struct CNetScheduleJob : CNetScheduleNewJob
+{
+    explicit CNetScheduleJob(const string& _input = kEmptyStr,
+            const string& _affinity = kEmptyStr,
+            CNetScheduleAPI::TJobMask _mask = CNetScheduleAPI::eEmptyMask) :
+        CNetScheduleNewJob(_input, _affinity, _mask),
+        ret_code(0)
+    {
+    }
+
+    void Reset()
+    {
+        CNetScheduleNewJob::Reset();
+        client_ip.erase();
+        session_id.erase();
+        page_hit_id.erase();
+        ret_code = 0;
+        output.erase();
+        error_msg.erase();
+        progress_msg.erase();
+        auth_token.erase();
+        server = NULL;
+    }
+
+    string client_ip;
+    string session_id;
+    string page_hit_id;
+
     /// Job return code.
     int ret_code;
     /// Job result data.
@@ -353,8 +373,6 @@ struct CNetScheduleJob
     string error_msg;
     string progress_msg;
 
-    string group;
-
     string auth_token;
 
     /// The server the job belongs to.
@@ -375,7 +393,7 @@ class NCBI_XCONNECT_EXPORT CNetScheduleSubmitter
 
     /// Submit job.
     /// @note on success job.job_id will be set.
-    string SubmitJob(CNetScheduleJob& job);
+    string SubmitJob(CNetScheduleNewJob& job);
 
     /// Submit job batch.
     /// Method automatically splits the submission into reasonable sized
diff --git a/c++/include/connect/services/netstorage.hpp b/c++/include/connect/services/netstorage.hpp
index d6ee656..889bde9 100644
--- a/c++/include/connect/services/netstorage.hpp
+++ b/c++/include/connect/services/netstorage.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES__NETSTORAGE__HPP
 #define CONNECT_SERVICES__NETSTORAGE__HPP
 
-/*  $Id: netstorage.hpp 494456 2016-03-07 17:46:55Z ivanov $
+/*  $Id: netstorage.hpp 505855 2016-06-29 16:17:14Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -42,6 +42,8 @@
 
 #include <corelib/ncbitime.hpp>
 
+#include <functional>
+
 
 BEGIN_NCBI_SCOPE
 
@@ -73,6 +75,7 @@ public:
         eTimeout,       ///< Timeout encountered while performing an op
         eExpired,       ///< Object has expired on server
         eNotSupported,  ///< Feature is not supported
+        eInterrupted,   ///< Operation has been interrupted
         eUnknown        ///< Unknown error
     };
     virtual const char* GetErrCodeString() const;
@@ -328,6 +331,14 @@ class NCBI_XCONNECT_EXPORT CNetStorageObject
 };
 
 
+/// Progress callback
+///
+/// @param CJsonNode
+///  progress info (depends on operation)
+///
+typedef function<void(CJsonNode)> TNetStorageProgressCb;
+
+
 /// Result returned by Remove() methods
 ///
 /// @see CNetStorage::Remove(), CNetStorageByKey::Remove()
@@ -411,13 +422,17 @@ class NCBI_XCONNECT_EXPORT CNetStorage
     ///  An existing object to relocate
     /// @param flags
     ///  Combination of flags that defines the new object location (storage)
-    ///
+    /// @param cb
+    ///  Relocation progress callback (@see TNetStorageProgressCb).
+    ///  CJsonNode input argument (object) will contain two subnodes:
+    ///  number 'BytesRelocated' and string 'Message'
     /// @return
     ///  New object ID that fully reflects the new object location.
     ///  If possible, this new ID should be used for further access to the
     ///  object. Note however that its original ID still can be used as well.
     ///
-    string Relocate(const string& object_loc, TNetStorageFlags flags);
+    string Relocate(const string& object_loc, TNetStorageFlags flags,
+            TNetStorageProgressCb cb = TNetStorageProgressCb());
 
     /// Check if the object addressed by 'object_loc' exists.
     ///
@@ -497,6 +512,10 @@ class NCBI_XCONNECT_EXPORT CNetStorageByKey
     ///  Combination of flags that defines the new object location
     /// @param old_flags
     ///  Combination of flags that defines the current object location
+    /// @param cb
+    ///  Relocation progress callback (@see TNetStorageProgressCb).
+    ///  CJsonNode input argument (object) will contain two subnodes:
+    ///  number 'BytesRelocated' and string 'Message'
     /// @return
     ///  A unique full object ID that reflects the new object location (storage)
     ///  and which can be used with CNetStorage::Open(). Note however that the
@@ -504,7 +523,8 @@ class NCBI_XCONNECT_EXPORT CNetStorageByKey
     ///
     string Relocate(const string&    unique_key,
                     TNetStorageFlags flags,
-                    TNetStorageFlags old_flags = 0);
+                    TNetStorageFlags old_flags = 0,
+                    TNetStorageProgressCb cb = TNetStorageProgressCb());
 
     /// Check if a object with the specified key exists in the storage
     /// hinted by 'flags'
diff --git a/c++/include/connect/services/netstorage_ft.hpp b/c++/include/connect/services/netstorage_ft.hpp
index dd077bc..a668545 100644
--- a/c++/include/connect/services/netstorage_ft.hpp
+++ b/c++/include/connect/services/netstorage_ft.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES__NETSTORAGE_FT__HPP
 #define CONNECT_SERVICES__NETSTORAGE_FT__HPP
 
-/*  $Id: netstorage_ft.hpp 493320 2016-02-25 19:43:11Z ivanov $
+/*  $Id: netstorage_ft.hpp 493146 2016-02-24 17:38:53Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/connect/services/ns_output_parser.hpp b/c++/include/connect/services/ns_output_parser.hpp
index 4635ce1..e88ad44 100644
--- a/c++/include/connect/services/ns_output_parser.hpp
+++ b/c++/include/connect/services/ns_output_parser.hpp
@@ -1,4 +1,4 @@
-/*  $Id: ns_output_parser.hpp 479861 2015-09-23 21:07:21Z sadyrovr $
+/*  $Id: ns_output_parser.hpp 502472 2016-05-24 21:38:49Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -37,47 +37,25 @@
 
 BEGIN_NCBI_SCOPE
 
-class NCBI_XCONNECT_EXPORT CNetScheduleStructuredOutputParser
+
+// Deprecated, use corresponding static method of CJsonNode instead
+class NCBI_DEPRECATED NCBI_XCONNECT_EXPORT CNetScheduleStructuredOutputParser
 {
 public:
     CJsonNode ParseObject(const string& ns_output)
     {
-        m_Ch = (m_NSOutput = ns_output).c_str();
-
-        return ParseObject('\0');
+        return CJsonNode::ParseObject(ns_output);
     }
 
     CJsonNode ParseArray(const string& ns_output)
     {
-        m_Ch = (m_NSOutput = ns_output).c_str();
-
-        return ParseArray('\0');
+        return CJsonNode::ParseArray(ns_output);
     }
 
-    CJsonNode ParseJSON(const string& json);
-
-private:
-    size_t GetRemainder() const
+    CJsonNode ParseJSON(const string& json)
     {
-        return m_NSOutput.length() - (m_Ch - m_NSOutput.data());
+        return CJsonNode::ParseJSON(json);
     }
-
-    size_t GetPosition() const
-    {
-        return m_Ch - m_NSOutput.data() + 1;
-    }
-
-    string ParseString(size_t max_len);
-    Int8 ParseInt(size_t len);
-    double ParseDouble(size_t len);
-    bool MoreNodes();
-
-    CJsonNode ParseObject(char closing_char);
-    CJsonNode ParseArray(char closing_char);
-    CJsonNode ParseValue();
-
-    string m_NSOutput;
-    const char* m_Ch;
 };
 
 class NCBI_XCONNECT_EXPORT CAttrListParser
diff --git a/c++/include/corelib/ddumpable.hpp b/c++/include/corelib/ddumpable.hpp
index 9b43b9f..e1c8714 100644
--- a/c++/include/corelib/ddumpable.hpp
+++ b/c++/include/corelib/ddumpable.hpp
@@ -1,7 +1,7 @@
 #ifndef DDUMPABLE__HPP
 #define DDUMPABLE__HPP
 
-/*  $Id: ddumpable.hpp 493118 2016-02-24 15:43:33Z ivanov $
+/*  $Id: ddumpable.hpp 493042 2016-02-23 19:38:23Z gouriano $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/corelib/hash_impl/_hash_map.h b/c++/include/corelib/hash_impl/_hash_map.h
index d3d3ea5..fb67209 100644
--- a/c++/include/corelib/hash_impl/_hash_map.h
+++ b/c++/include/corelib/hash_impl/_hash_map.h
@@ -83,71 +83,88 @@ public:
 private:
   _Ht _M_ht;
 public:
-  hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
-  explicit hash_map(size_type __n)
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED explicit hash_map(size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
-  hash_map(size_type __n, const hasher& __hf)
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(size_type __n, const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
-  hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
            const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a) {}
 
 #ifdef _STLP_MEMBER_TEMPLATES
   template <class _InputIterator>
-  hash_map(_InputIterator __f, _InputIterator __l)
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(_InputIterator __f, _InputIterator __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
   template <class _InputIterator>
-  hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
   template <class _InputIterator>
-  hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
            const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
 # ifdef _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS
   template <class _InputIterator>
-  hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
            const hasher& __hf, const key_equal& __eql)
     : _M_ht(__n, __hf, __eql, allocator_type())
     { _M_ht.insert_unique(__f, __l); }
 # endif
   template <class _InputIterator>
-  hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
            const hasher& __hf, const key_equal& __eql,
            const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL)
     : _M_ht(__n, __hf, __eql, __a)
     { _M_ht.insert_unique(__f, __l); }
 
 #else
-  hash_map(const value_type* __f, const value_type* __l)
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(const value_type* __f, const value_type* __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
-  hash_map(const value_type* __f, const value_type* __l, size_type __n)
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(const value_type* __f, const value_type* __l, size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
-  hash_map(const value_type* __f, const value_type* __l, size_type __n,
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(const value_type* __f, const value_type* __l, size_type __n,
            const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
-  hash_map(const value_type* __f, const value_type* __l, size_type __n,
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(const value_type* __f, const value_type* __l, size_type __n,
            const hasher& __hf, const key_equal& __eql,
            const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a)
     { _M_ht.insert_unique(__f, __l); }
 
-  hash_map(const_iterator __f, const_iterator __l)
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(const_iterator __f, const_iterator __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
-  hash_map(const_iterator __f, const_iterator __l, size_type __n)
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(const_iterator __f, const_iterator __l, size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
-  hash_map(const_iterator __f, const_iterator __l, size_type __n,
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(const_iterator __f, const_iterator __l, size_type __n,
            const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
-  hash_map(const_iterator __f, const_iterator __l, size_type __n,
+  /// @deprecated Use std::unordered_map
+  NCBI_DEPRECATED hash_map(const_iterator __f, const_iterator __l, size_type __n,
            const hasher& __hf, const key_equal& __eql,
            const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a)
@@ -250,71 +267,88 @@ public:
 private:
   _Ht _M_ht;
 public:
-  hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
-  explicit hash_multimap(size_type __n)
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED explicit hash_multimap(size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
-  hash_multimap(size_type __n, const hasher& __hf)
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(size_type __n, const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
-  hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
                 const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a) {}
 
 #ifdef _STLP_MEMBER_TEMPLATES
   template <class _InputIterator>
-  hash_multimap(_InputIterator __f, _InputIterator __l)
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(_InputIterator __f, _InputIterator __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
   template <class _InputIterator>
-  hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
   template <class _InputIterator>
-  hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
                 const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
 # ifdef _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS
   template <class _InputIterator>
-  hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
                 const hasher& __hf, const key_equal& __eql)
     : _M_ht(__n, __hf, __eql, allocator_type())
     { _M_ht.insert_equal(__f, __l); }
 #  endif
   template <class _InputIterator>
-  hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
                 const hasher& __hf, const key_equal& __eql,
                 const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL)
     : _M_ht(__n, __hf, __eql, __a)
     { _M_ht.insert_equal(__f, __l); }
 
 #else
-  hash_multimap(const value_type* __f, const value_type* __l)
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(const value_type* __f, const value_type* __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
-  hash_multimap(const value_type* __f, const value_type* __l, size_type __n)
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(const value_type* __f, const value_type* __l, size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
-  hash_multimap(const value_type* __f, const value_type* __l, size_type __n,
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(const value_type* __f, const value_type* __l, size_type __n,
                 const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
-  hash_multimap(const value_type* __f, const value_type* __l, size_type __n,
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(const value_type* __f, const value_type* __l, size_type __n,
                 const hasher& __hf, const key_equal& __eql,
                 const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a)
     { _M_ht.insert_equal(__f, __l); }
 
-  hash_multimap(const_iterator __f, const_iterator __l)
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(const_iterator __f, const_iterator __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
-  hash_multimap(const_iterator __f, const_iterator __l, size_type __n)
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(const_iterator __f, const_iterator __l, size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
-  hash_multimap(const_iterator __f, const_iterator __l, size_type __n,
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(const_iterator __f, const_iterator __l, size_type __n,
                 const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
-  hash_multimap(const_iterator __f, const_iterator __l, size_type __n,
+  /// @deprecated Use std::unordered_multimap
+  NCBI_DEPRECATED hash_multimap(const_iterator __f, const_iterator __l, size_type __n,
                 const hasher& __hf, const key_equal& __eql,
                 const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a)
diff --git a/c++/include/corelib/hash_impl/_hash_set.h b/c++/include/corelib/hash_impl/_hash_set.h
index 9b5629d..6c46a8f 100644
--- a/c++/include/corelib/hash_impl/_hash_set.h
+++ b/c++/include/corelib/hash_impl/_hash_set.h
@@ -79,72 +79,89 @@ private:
   _Ht _M_ht;
 
 public:
-  hash_set()
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set()
     : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
-  explicit hash_set(size_type __n)
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED explicit hash_set(size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
-  hash_set(size_type __n, const hasher& __hf)
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(size_type __n, const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
-  hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
            const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a) {}
 
 #ifdef _STLP_MEMBER_TEMPLATES
   template <class _InputIterator>
-  hash_set(_InputIterator __f, _InputIterator __l)
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(_InputIterator __f, _InputIterator __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
   template <class _InputIterator>
-  hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
   template <class _InputIterator>
-  hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
            const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
 # ifdef _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS
   template <class _InputIterator>
-  hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
            const hasher& __hf, const key_equal& __eql)
     : _M_ht(__n, __hf, __eql, allocator_type())
     { _M_ht.insert_unique(__f, __l); }
 #  endif
   template <class _InputIterator>
-  hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
            const hasher& __hf, const key_equal& __eql,
            const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL)
     : _M_ht(__n, __hf, __eql, __a)
     { _M_ht.insert_unique(__f, __l); }
 #else
 
-  hash_set(const value_type* __f, const value_type* __l)
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(const value_type* __f, const value_type* __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
-  hash_set(const value_type* __f, const value_type* __l, size_type __n)
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(const value_type* __f, const value_type* __l, size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
-  hash_set(const value_type* __f, const value_type* __l, size_type __n,
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(const value_type* __f, const value_type* __l, size_type __n,
            const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
-  hash_set(const value_type* __f, const value_type* __l, size_type __n,
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(const value_type* __f, const value_type* __l, size_type __n,
            const hasher& __hf, const key_equal& __eql,
            const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a)
     { _M_ht.insert_unique(__f, __l); }
 
-  hash_set(const_iterator __f, const_iterator __l)
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(const_iterator __f, const_iterator __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
-  hash_set(const_iterator __f, const_iterator __l, size_type __n)
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(const_iterator __f, const_iterator __l, size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
-  hash_set(const_iterator __f, const_iterator __l, size_type __n,
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(const_iterator __f, const_iterator __l, size_type __n,
            const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type())
     { _M_ht.insert_unique(__f, __l); }
-  hash_set(const_iterator __f, const_iterator __l, size_type __n,
+  /// @deprecated Use std::unordered_set
+  NCBI_DEPRECATED hash_set(const_iterator __f, const_iterator __l, size_type __n,
            const hasher& __hf, const key_equal& __eql,
            const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a)
@@ -251,75 +268,93 @@ private:
   _Ht _M_ht;
 
 public:
-  hash_multiset()
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset()
     : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
-  explicit hash_multiset(size_type __n)
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED explicit hash_multiset(size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
-  hash_multiset(size_type __n, const hasher& __hf)
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(size_type __n, const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
-  hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql)
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql)
     : _M_ht(__n, __hf, __eql, allocator_type()) {}
-  hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
                 const allocator_type& __a)
     : _M_ht(__n, __hf, __eql, __a) {}
 
 #ifdef _STLP_MEMBER_TEMPLATES
   template <class _InputIterator>
-  hash_multiset(_InputIterator __f, _InputIterator __l)
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(_InputIterator __f, _InputIterator __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
   template <class _InputIterator>
-  hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
   template <class _InputIterator>
-  hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
                 const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
 
 # ifdef _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS
   template <class _InputIterator>
-  hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
                 const hasher& __hf, const key_equal& __eql)
     : _M_ht(__n, __hf, __eql, allocator_type())
     { _M_ht.insert_equal(__f, __l); }
 # endif
   template <class _InputIterator>
-  hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
                 const hasher& __hf, const key_equal& __eql,
                 const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL)
     : _M_ht(__n, __hf, __eql, __a)
     { _M_ht.insert_equal(__f, __l); }
 #else
 
-  hash_multiset(const value_type* __f, const value_type* __l)
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(const value_type* __f, const value_type* __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
-  hash_multiset(const value_type* __f, const value_type* __l, size_type __n)
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(const value_type* __f, const value_type* __l, size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
-  hash_multiset(const value_type* __f, const value_type* __l, size_type __n,
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(const value_type* __f, const value_type* __l, size_type __n,
                 const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
-  hash_multiset(const value_type* __f, const value_type* __l, size_type __n,
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(const value_type* __f, const value_type* __l, size_type __n,
                 const hasher& __hf, const key_equal& __eql,
                 const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a)
     { _M_ht.insert_equal(__f, __l); }
 
-  hash_multiset(const_iterator __f, const_iterator __l)
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(const_iterator __f, const_iterator __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
-  hash_multiset(const_iterator __f, const_iterator __l, size_type __n)
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(const_iterator __f, const_iterator __l, size_type __n)
     : _M_ht(__n, hasher(), key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
-  hash_multiset(const_iterator __f, const_iterator __l, size_type __n,
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(const_iterator __f, const_iterator __l, size_type __n,
                 const hasher& __hf)
     : _M_ht(__n, __hf, key_equal(), allocator_type())
     { _M_ht.insert_equal(__f, __l); }
-  hash_multiset(const_iterator __f, const_iterator __l, size_type __n,
+  /// @deprecated Use std::unordered_multiset
+  NCBI_DEPRECATED hash_multiset(const_iterator __f, const_iterator __l, size_type __n,
                 const hasher& __hf, const key_equal& __eql,
                 const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a)
diff --git a/c++/include/corelib/impl/ncbi_atomic_defs.h b/c++/include/corelib/impl/ncbi_atomic_defs.h
index ae46601..64b817a 100644
--- a/c++/include/corelib/impl/ncbi_atomic_defs.h
+++ b/c++/include/corelib/impl/ncbi_atomic_defs.h
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBI_ATOMIC_DEFS__HPP
 #define CORELIB___NCBI_ATOMIC_DEFS__HPP
 
-/*  $Id: ncbi_atomic_defs.h 471651 2015-06-30 12:52:35Z vasilche $
+/*  $Id: ncbi_atomic_defs.h 503972 2016-06-09 18:47:13Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -90,7 +90,7 @@ extern "C" {
 #  define NCBI_SWAP_POINTERS_EXTERN 1
 #endif
 
-#if defined(NCBI_HAVE_CXX11)
+#if defined(NCBI_HAVE_CXX11) && !defined(NCBI_COMPILER_MSVC)
 #  include <atomic>
 #endif
 
@@ -130,7 +130,7 @@ extern "C" {
 #  if defined(__sparc)  &&  !defined(__sparcv9)
 #    define NCBI_COUNTER_RESERVED_VALUE 0x3FFFFFFF
 #  endif
-#elif defined(NCBI_HAVE_CXX11) && !defined(NCBI_OS_MSWIN)
+#elif defined(NCBI_HAVE_CXX11) && !defined(NCBI_COMPILER_MSVC)
    /* std::atomic<> in MSVC has non-default constructor so
       static CAtomicCounter couldn't be initialized in MT-safe manner */
     typedef size_t TNCBIAtomicValue;
diff --git a/c++/include/corelib/impl/ncbi_dbsvcmapper.hpp b/c++/include/corelib/impl/ncbi_dbsvcmapper.hpp
index 0ecbbbd..d4b0a2c 100644
--- a/c++/include/corelib/impl/ncbi_dbsvcmapper.hpp
+++ b/c++/include/corelib/impl/ncbi_dbsvcmapper.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___DB_SERVICE_MAPPER__HPP
 #define CORELIB___DB_SERVICE_MAPPER__HPP
 
-/*  $Id: ncbi_dbsvcmapper.hpp 414127 2013-09-20 16:02:32Z ucko $
+/*  $Id: ncbi_dbsvcmapper.hpp 501812 2016-05-18 22:51:45Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -37,16 +37,54 @@
 #include <corelib/ncbistd.hpp>
 #include <corelib/ncbiobj.hpp>
 
+#ifdef NCBI_OS_MSWIN
+#  include <winsock2.h>
+#endif
 
 BEGIN_NCBI_SCOPE
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Forward declaration
+/// Forward declarations
 ///
 
+class CDBServer;
+class IDBServiceMapper;
 class IRegistry;
 
 ///////////////////////////////////////////////////////////////////////////////
+/// I_ConnectionExtra
+///
+
+class I_ConnectionExtra
+{
+public:
+    virtual ~I_ConnectionExtra(void) { }
+
+#ifdef NCBI_OS_MSWIN
+    typedef SOCKET  TSockHandle;
+#else
+    typedef int     TSockHandle;
+#endif
+
+    /// Get OS handle of the socket represented by the connection
+    virtual TSockHandle GetLowLevelHandle(void) const = 0;
+
+    virtual void SetUserData(CObject* data) = 0;
+    template<typename T> T* GetUserData(void)
+    { return dynamic_cast<T*>(x_GetUserData()); }
+    template<typename T> const T* GetUserData(void) const
+    { return dynamic_cast<T*>(x_GetUserData()); }
+
+protected:
+    virtual CObject* x_GetUserData(void) const = 0;
+    virtual void     x_RecordServer(const CDBServer& server) { }
+
+private:
+    friend class IDBServiceMapper;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
 /// IDBServiceMapper
 ///
 
@@ -127,6 +165,18 @@ public:
     virtual void    SetPreference(const string&    service,
                                   const TSvrRef&   preferred_server,
                                   double           preference = 100) = 0;
+
+    /// Given a connection that succeeded even though this service
+    /// mapper was unable to identify a good server beforehand, try to
+    /// determine which server it actually reached on the basis of its
+    /// low-level handle (if available); on success, pass the result
+    /// to its x_RecordServer method to inform subsequent logging.
+    /// @return true if successful, false otherwise.
+    virtual bool RecordServer(I_ConnectionExtra& extra) const { return false; }
+
+protected:
+    static void x_RecordServer(I_ConnectionExtra& extra, CDBServer& server)
+        { extra.x_RecordServer(server); }
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/c++/include/corelib/ncbi_base64.h b/c++/include/corelib/ncbi_base64.h
index f0bbf95..7d0ef1b 100644
--- a/c++/include/corelib/ncbi_base64.h
+++ b/c++/include/corelib/ncbi_base64.h
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBI_BASE64__H
 #define CORELIB___NCBI_BASE64__H
 
-/* $Id: ncbi_base64.h 394628 2013-04-04 15:46:39Z kazimird $
+/* $Id: ncbi_base64.h 501322 2016-05-13 16:01:34Z vakatov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -90,9 +90,9 @@ extern NCBI_XNCBI_EXPORT int/*bool*/ BASE64_Decode
  * was successful.
  */
 typedef enum {
-    eBase64_OK,             /** Transcoded successfully. */
-    eBase64_BufferTooSmall, /** The output buffer is too small. */
-    eBase64_InvalidInput    /** Input contains characters outside alphabet. */
+    eBase64_OK,             /**< Transcoded successfully. */
+    eBase64_BufferTooSmall, /**< The output buffer is too small. */
+    eBase64_InvalidInput    /**< Input contains characters outside alphabet. */
 } EBase64_Result;
 
 
diff --git a/c++/include/corelib/ncbi_config.hpp b/c++/include/corelib/ncbi_config.hpp
index 9260ffa..a036639 100644
--- a/c++/include/corelib/ncbi_config.hpp
+++ b/c++/include/corelib/ncbi_config.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBI_CONFIG__HPP
 #define CORELIB___NCBI_CONFIG__HPP
 
-/*  $Id: ncbi_config.hpp 492407 2016-02-17 15:08:33Z ivanov $
+/*  $Id: ncbi_config.hpp 492280 2016-02-16 16:42:42Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/corelib/ncbi_cookies.hpp b/c++/include/corelib/ncbi_cookies.hpp
index e7b73fc..e703916 100644
--- a/c++/include/corelib/ncbi_cookies.hpp
+++ b/c++/include/corelib/ncbi_cookies.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBI_COOKIES__HPP
 #define CORELIB___NCBI_COOKIES__HPP
 
-/*  $Id: ncbi_cookies.hpp 458676 2015-02-09 12:35:49Z lavr $
+/*  $Id: ncbi_cookies.hpp 517040 2016-10-20 11:22:39Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -107,9 +107,10 @@ public:
     /// encoded - the caller is responsible for providing a valid value.
     /// @sa AsString()
     void SetValue(const CTempString& value);
-    /// Set cookie's domain. No validation is performed immediately, but
-    /// if the value is invalid CHttpCookieExcepion will be thrown on
-    /// an attempt to get the cookie as a string.
+    /// Set cookie's domain. The value is converted to lower case and
+    /// the leading '.' is trimmed (if any). No other validation is performed
+    /// immediately, but if the value is invalid CHttpCookieExcepion will be
+    /// thrown on an attempt to get the cookie as a string.
     /// @sa AsString()
     void SetDomain(const CTempString& domain);
     /// Set host-only flag. If the flag is true, the domain must be identical
@@ -472,6 +473,10 @@ inline void CHttpCookie::SetValue(const CTempString& value)
 inline void CHttpCookie::SetDomain(const CTempString& domain)
 {
     m_Domain = domain;
+    if (m_Domain.empty()) return;
+    // Ignore leading '.'
+    if (m_Domain[0] == '.') m_Domain = m_Domain.substr(1);
+    NStr::ToLower(m_Domain);
 }
 
 inline void CHttpCookie::SetPath(const CTempString& path)
diff --git a/c++/include/corelib/ncbi_param.hpp b/c++/include/corelib/ncbi_param.hpp
index 9ad97ac..0759bd9 100644
--- a/c++/include/corelib/ncbi_param.hpp
+++ b/c++/include/corelib/ncbi_param.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBI_PARAM__HPP
 #define CORELIB___NCBI_PARAM__HPP
 
-/*  $Id: ncbi_param.hpp 445853 2014-09-09 13:27:06Z grichenk $
+/*  $Id: ncbi_param.hpp 505730 2016-06-28 15:29:57Z elisovdn $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -235,7 +235,7 @@ double NCBI_XNCBI_EXPORT g_GetConfigDouble(const char* section,
                   const TParamDesc& descr)                                  \
     { return CEnumParser< type, ptype >::EnumToString(val, descr); }
 
-// Defenition of SNcbiParamDesc_XXXX static members common for normal
+// Definition of SNcbiParamDesc_XXXX static members common for normal
 // and enum parameters.
 #define X_NCBI_PARAM_STATIC_DEF(descname, defval)                           \
     descname::TStaticValue descname::sm_Default = defval;                   \
@@ -268,6 +268,11 @@ double NCBI_XNCBI_EXPORT g_GetConfigDouble(const char* section,
 /// Enum parameter declaration. In addition to NCBI_PARAM_DECL also
 /// specializes CParamParser<type, ptype> to convert between strings and
 /// enum values.
+/// @attention 
+/// Only use this macro in the global or "ncbi" namespace, otherwise you will
+/// get compilation errors. Using this macro in the said namespaces will not 
+/// affect usability of a created CParamParser<type, ptype> specialization
+/// from other namespaces.
 /// @sa NCBI_PARAM_ENUM_ARRAY
 /// @sa NCBI_PARAM_ENUM_DEF
 #define NCBI_PARAM_ENUM_DECL(type, section, name)                             \
@@ -279,6 +284,11 @@ double NCBI_XNCBI_EXPORT g_GetConfigDouble(const char* section,
 
 
 /// Same as NCBI_PARAM_ENUM_DECL but with export specifier (e.g. NCBI_XNCBI_EXPORT)
+/// @attention 
+/// Only use this macro in the global or "ncbi" namespace, otherwise you will
+/// get compilation errors. Using this macro in the said namespaces will not 
+/// affect usability of a created CParamParser<type, ptype> specialization
+/// from other namespaces.
 /// @sa NCBI_PARAM_ENUM_DECL
 #define NCBI_PARAM_ENUM_DECL_EXPORT(expname, type, section, name)             \
     struct expname X_NCBI_PARAM_DECLNAME(section, name);                      \
diff --git a/c++/include/corelib/ncbi_stack.hpp b/c++/include/corelib/ncbi_stack.hpp
index c5d73d4..b9ed26c 100644
--- a/c++/include/corelib/ncbi_stack.hpp
+++ b/c++/include/corelib/ncbi_stack.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBI_STACK__HPP
 #define CORELIB___NCBI_STACK__HPP
 
-/*  $Id: ncbi_stack.hpp 379373 2012-10-31 15:06:17Z grichenk $
+/*  $Id: ncbi_stack.hpp 500861 2016-05-09 16:32:20Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -52,17 +52,22 @@ public:
         string func;
         string file;
         string module;
+        const void* addr;
         size_t offs;
         size_t line;
 
-        SStackFrameInfo()
-            : offs(0), line(0) {}
+        SStackFrameInfo(void)
+            : addr(0), offs(0), line(0) {}
+
+        SStackFrameInfo(const void* address)
+            : addr(address), offs(0), line(0) {}
 
         bool operator ==(const SStackFrameInfo& other) const
         {
             return func == other.func  &&
                 file == other.file  &&
                 module == other.module  &&
+                addr == other.addr  &&
                 offs == other.offs  &&
                 line == other.line;
         }
diff --git a/c++/include/corelib/ncbi_xstr.hpp b/c++/include/corelib/ncbi_xstr.hpp
index 25de3b2..a12deae 100644
--- a/c++/include/corelib/ncbi_xstr.hpp
+++ b/c++/include/corelib/ncbi_xstr.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBI_XSTR__HPP
 #define CORELIB___NCBI_XSTR__HPP
 
-/*  $Id: ncbi_xstr.hpp 372736 2012-08-22 13:12:59Z gouriano $
+/*  $Id: ncbi_xstr.hpp 500405 2016-05-04 15:18:35Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -76,18 +76,18 @@ public:
         : m_Data(str), m_Length(NPOS)
     {
     }
-    CTempXStr(const _TChar* str, size_t length)
-        : m_Data(str), m_Length(length)
+    CTempXStr(const _TChar* str, size_t len)
+        : m_Data(str), m_Length(len)
     {
     }
-    CTempXStr(const _TChar* str, size_t pos, size_t length)
+    CTempXStr(const _TChar* str, size_t pos, size_t len)
     {
         if (pos == x_npos()) {
             m_Data = str;
             m_Length = 0;    
         } else {
             m_Data = str+pos;
-            m_Length = length;
+            m_Length = len;
         }
     }
 
@@ -96,22 +96,22 @@ public:
         : m_Data(str.data()), m_Length(str.length())
     {
     }
-    CTempXStr(const basic_string<_TChar>& str, size_t length)
-        : m_Data(str.data()), m_Length(length)
+    CTempXStr(const basic_string<_TChar>& str, size_t len)
+        : m_Data(str.data()), m_Length(len)
     {
     }
-    CTempXStr(const basic_string<_TChar>& str, size_t pos, size_t length)
-        : m_Data(str.data()+pos), m_Length(length)
+    CTempXStr(const basic_string<_TChar>& str, size_t pos, size_t len)
+        : m_Data(str.data()+pos), m_Length(len)
     {
         if (pos == x_npos()) {
             m_Data = str.data();
             m_Length = 0;
         } else {
             m_Data = str.data()+pos;
-            if (length == x_npos()) {
+            if (len == x_npos()) {
                 m_Length = str.length() - pos;
             } else {
-                m_Length = length;
+                m_Length = len;
                 if (m_Length + pos > str.length()) {
                     m_Length = str.length() - pos;
                 }
diff --git a/c++/include/corelib/ncbiapp.hpp b/c++/include/corelib/ncbiapp.hpp
index 8d86fa4..a7d49ac 100644
--- a/c++/include/corelib/ncbiapp.hpp
+++ b/c++/include/corelib/ncbiapp.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBIAPP__HPP
 #define CORELIB___NCBIAPP__HPP
 
-/*  $Id: ncbiapp.hpp 497376 2016-04-06 13:21:22Z ivanov $
+/*  $Id: ncbiapp.hpp 518670 2016-11-07 15:25:48Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -431,6 +431,7 @@ protected:
     /// @sa GetVersion
     void SetVersion(const CVersionInfo& version);
     void SetVersion(const CVersionInfo& version, const SBuildInfo& build_info);
+    void SetVersionByBuild(int major);
 
     /// Set version data for the program.
     ///
@@ -559,6 +560,13 @@ private:
     ///   Registry to read from. If NULL, use the current registry setting.
     void x_HonorStandardSettings(IRegistry* reg = 0);
 
+    /// Read switches that are stored in m_LogOptions from registry and 
+    /// environment
+    void x_ReadLogOptions();
+
+    /// Log environment, registry, command arguments, path
+    void x_LogOptions(int event);
+    
     /// Setup C++ standard I/O streams' behaviour.
     ///
     /// Called from AppMain() to do compiler-specific optimization
@@ -602,6 +610,7 @@ private:
     string                     m_DefaultConfig; ///< conf parameter to AppMain
     bool                       m_ConfigLoaded;  ///< Finished loading config
     const char*                m_LogFile;     ///< Logfile if set in the command line
+    int                        m_LogOptions; ///<  logging of env, reg, args, path
 };
 
 
diff --git a/c++/include/corelib/ncbiargs.hpp b/c++/include/corelib/ncbiargs.hpp
index 144403f..b21ea09 100644
--- a/c++/include/corelib/ncbiargs.hpp
+++ b/c++/include/corelib/ncbiargs.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBIARGS__HPP
 #define CORELIB___NCBIARGS__HPP
 
-/*  $Id: ncbiargs.hpp 491416 2016-02-04 17:55:07Z ivanov $
+/*  $Id: ncbiargs.hpp 497224 2016-04-05 12:11:44Z gouriano $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -104,6 +104,7 @@ BEGIN_NCBI_SCOPE
 class CNcbiArguments;
 class CArgAllow;
 class CDir;
+class CArgDependencyGroup;
 
 
 /////////////////////////////////////////////////////////////////////////////
@@ -874,6 +875,16 @@ public:
                              const string& arg_name,
                              const string& comment = kEmptyStr);
 
+    /// Add a dependency group.
+    /// The argument constraints specified by the dependency group(s)
+    /// will be processed only after all regular dependencies for arguments and
+    /// dependency groups have been processed.
+    /// @attention
+    ///  The "dep_group" will be added by reference, and its lifetime will then
+    ///  be managed according to the usual CObject/CRef rules.
+    /// @sa SetDependency()
+    void AddDependencyGroup(CArgDependencyGroup* dep_group);
+
     /// Flag to invert constraint logically
     enum EConstraintNegate {
         eConstraintInvert,  ///< Logical NOT
@@ -1069,6 +1080,7 @@ private:
     EArgPositionalMode m_PositionalMode; ///< Processing of positional args
     TDependencies      m_Dependencies;   ///< Arguments' dependencies
     TMiscFlags   m_MiscFlags;    ///< Flags for USAGE, error handling etc.
+    set< CConstRef<CArgDependencyGroup> > m_DependencyGroups;
 
     // Extra USAGE info
 protected:
@@ -1179,6 +1191,7 @@ protected:
         ~CPrintUsageXml();
         void PrintArguments(const CArgDescriptions& desc) const;
     private:
+        const CArgDescriptions& m_desc;
         CNcbiOstream& m_out;
     };
 
@@ -1799,6 +1812,90 @@ private:
     string m_Comment;   ///< Argument description
 };
 
+/////////////////////////////////////////////////////////////////////////////
+
+class NCBI_XNCBI_EXPORT CArgDependencyGroup : public CObject
+{
+public:
+    /// Create new dependency group.
+    /// @param name
+    ///  Name of the group 
+    /// @param description
+    ///  User-provided description of the dependency group (for Usage).
+    ///  A generated description will be added to it.
+    static CRef<CArgDependencyGroup> Create(
+        const string& name, const string& description = kEmptyStr);
+
+    virtual ~CArgDependencyGroup(void);
+
+    /// @param min_members
+    ///  Mark this group as "set" (in the context of
+    ///  CArgDescriptions::EDependency) if at least "min_members" of its
+    ///  members (args or groups listed in this group) are set.
+    /// @note This condition can be weakened by "eInstantSet" mechanism.
+    /// @sa EInstantSet
+    /// @return "*this"
+    CArgDependencyGroup& SetMinMembers(size_t min_members);
+
+    /// @param max_members
+    ///  No more than "max_members" of members (args or immediate groups
+    ///  listed in this group) are allowed to be in the "set" state.
+    ///  If this condition is not met, then this group will be marked
+    ///  as "not set".
+    /// @return "*this"
+    CArgDependencyGroup& SetMaxMembers(size_t max_members);
+
+    /// Control whether the "setting" of this particular member marks the
+    /// whole group as "set" regardless of the value passed to  SetMinMembers()
+    /// @sa SetMinMembers(), Add()
+    enum EInstantSet {
+        eNoInstantSet,
+        eInstantSet
+    };
+
+    /// Make a regular argument a member of this dependency group.
+    /// An argument with this name will need to be added separately using
+    /// CArgDescriptions::AddXXX().
+    /// @param arg_name
+    ///  Name of the argument, as specified in CArgDescriptions::AddXXX()
+    /// @param instant_set
+    ///  "eInstantSet" means that if the added argument ("arg_name") is
+    ///  set, then the SetMinMembers() condition doesn't apply anymore.
+    /// @return  "*this"
+    CArgDependencyGroup& Add(const string& arg_name,
+                             EInstantSet  instant_set = eNoInstantSet);
+
+    /// Make another dependency group a member of this dependency group.
+    /// @attention
+    ///  The "dep_group" will be added by reference, and its lifetime will
+    ///  be managed according to the usual CObject/CRef rules.
+    /// @param instant_set
+    ///  "eInstantSet" means that if the added group ("dep_group") is
+    ///  set, then the SetMinMembers() condition doesn't apply anymore.
+    /// @return  "*this"
+    CArgDependencyGroup& Add(CArgDependencyGroup* dep_group,
+                             EInstantSet instant_set = eNoInstantSet);
+
+private:
+    bool x_Evaluate( const CArgs& args, string* arg_set, string* arg_unset) const;
+
+    string m_Name;
+    string m_Description;
+    size_t m_MinMembers, m_MaxMembers;
+    map<string,                         EInstantSet> m_Arguments;
+    map<CConstRef<CArgDependencyGroup>, EInstantSet> m_Groups;
+
+    // prohibit unwanted ctors and assignments
+    CArgDependencyGroup(void);
+    CArgDependencyGroup( const CArgDependencyGroup& dep_group);
+    CArgDependencyGroup& operator= (const CArgDependencyGroup&);
+
+public:
+    void PrintUsage(list<string>& arr, size_t offset) const;
+    void PrintUsageXml(CNcbiOstream& out) const;
+    void Evaluate( const CArgs& args) const;
+};
+
 END_NCBI_SCOPE
 
 
diff --git a/c++/include/corelib/ncbiatomic.h b/c++/include/corelib/ncbiatomic.h
index 2b6fd70..24d8245 100644
--- a/c++/include/corelib/ncbiatomic.h
+++ b/c++/include/corelib/ncbiatomic.h
@@ -1,7 +1,7 @@
 #ifndef NCBIATOMIC__H
 #define NCBIATOMIC__H
 
-/*  $Id: ncbiatomic.h 434180 2014-05-05 14:10:19Z ucko $
+/*  $Id: ncbiatomic.h 503985 2016-06-09 20:21:58Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -68,7 +68,7 @@ void* NCBI_SwapPointers(void * volatile * location, void* new_value)
 #else
 {
     void** nv_loc = (void**) location;
-#  ifdef NCBI_HAVE_CXX11
+#  if defined(NCBI_HAVE_CXX11) && !defined(NCBI_COMPILER_MSVC)
     if (sizeof(std::atomic<void*>) == sizeof(void*)) {
         std::atomic<void*>& a = *(std::atomic<void*>*)nv_loc;
         return a.exchange(new_value);
diff --git a/c++/include/corelib/ncbictype.hpp b/c++/include/corelib/ncbictype.hpp
index f93c447..c0409cb 100644
--- a/c++/include/corelib/ncbictype.hpp
+++ b/c++/include/corelib/ncbictype.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBICTYPE__HPP
 #define CORELIB___NCBICTYPE__HPP
 
-/*  $Id: ncbictype.hpp 453380 2014-12-03 14:39:19Z ucko $
+/*  $Id: ncbictype.hpp 500405 2016-05-04 15:18:35Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -49,11 +49,14 @@
 
 BEGIN_STD_NAMESPACE;
 
-#define NCBI_DEFINE_CTYPE_FUNC(name)                                    \
-    inline int name(Uchar c) { return name(int(c)); }                   \
-    inline int name(char c) { return name(Uchar(c)); }                  \
-    template<class C> inline int name(C c)                              \
-    { return See_the_standard_on_proper_argument_type_for_ctype_functions(c); }
+#define NCBI_DEFINE_CTYPE_FUNC(name)                    \
+    inline int name(Uchar c) { return name(int(c)); }   \
+    inline int name(char c) { return name(Uchar(c)); }  \
+    template<class C> inline int name(C c)              \
+    { \
+        return See_the_standard_on_proper_argument_type_for_ctype_functions(c); \
+        return 0; /* to avoid a compilation warning */ \
+    } 
 
 NCBI_DEFINE_CTYPE_FUNC(isalpha)
 NCBI_DEFINE_CTYPE_FUNC(isalnum)
diff --git a/c++/include/corelib/ncbidbg.hpp b/c++/include/corelib/ncbidbg.hpp
index d8f2920..361ee9b 100644
--- a/c++/include/corelib/ncbidbg.hpp
+++ b/c++/include/corelib/ncbidbg.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBIDBG__HPP
 #define CORELIB___NCBIDBG__HPP
 
-/*  $Id: ncbidbg.hpp 491449 2016-02-04 19:41:49Z ivanov $
+/*  $Id: ncbidbg.hpp 491415 2016-02-04 17:54:53Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/corelib/ncbidiag.hpp b/c++/include/corelib/ncbidiag.hpp
index 12ce548..ec5fe11 100644
--- a/c++/include/corelib/ncbidiag.hpp
+++ b/c++/include/corelib/ncbidiag.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBIDIAG__HPP
 #define CORELIB___NCBIDIAG__HPP
 
-/*  $Id: ncbidiag.hpp 500364 2016-05-04 12:04:46Z ivanov $
+/*  $Id: ncbidiag.hpp 514369 2016-09-21 15:22:25Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -36,7 +36,7 @@
 ///   Defines NCBI C++ diagnostic APIs, classes, and macros.
 ///
 ///   More elaborate documentation could be found in:
-///     http://www.ncbi.nlm.nih.gov/toolkit/doc/book/ch_core/#ch_core.diag
+///     http://ncbi.github.io/cxx-toolkit/pages/ch_log.html
 
 
 #include <corelib/ncbi_stack.hpp>
@@ -189,6 +189,12 @@ NCBI_XNCBI_EXPORT const char* g_DiagUnknownFunction(void);
 
 // When printing a message in 'old' (human readable) format LOG_POST skips
 // all fields except the message.
+/// This macro is deprecated and it's strongly recomended to move
+/// in all projects (except tests) to macro LOG_POST_X to make possible more
+/// flexible error statistics and logging.
+///
+/// @sa
+///   LOG_POST_EX, LOG_POST_X
 #define LOG_POST(message)                                               \
     ( NCBI_NS_NCBI::CNcbiDiag(DIAG_COMPILE_INFO,                        \
       NCBI_NS_NCBI::eDiag_Error,                                        \
@@ -274,7 +280,7 @@ NCBI_XNCBI_EXPORT const char* g_DiagUnknownFunction(void);
             };                                                  \
         };                                                      \
     }                                                           \
-    extern void err_code_x__dummy_for_semicolon(void)
+    NCBI_EAT_SEMICOLON(err_code)
 
 /// Define maximum value of subcode for the error code currently in use.
 /// Currently used error code is defined by macro NCBI_USE_ERRCODE_X. This
@@ -400,7 +406,7 @@ struct WRONG_USAGE_OF_DEFINE_ERR_SUBCODE_MACRO<errorCode, false> {
         NCBI_NS_NCBI::WRONG_USAGE_OF_DEFINE_ERR_SUBCODE_MACRO <     \
               NCBI_ERRCODE_X_NAME(name),                            \
               NCBI_NS_NCBI::err_code_x::eErrCodeX_Max_##name != 0>  \
-                                                   err_subcode)     \
+                                               /*err_subcode*/)     \
     {}
 
 
@@ -505,10 +511,10 @@ struct WRONG_USAGE_OF_DEFINE_ERR_SUBCODE_MACRO<errorCode, true> {
 /// All calls to ERR_POST_X under the same default error code
 /// MUST be with deferent error subcodes to make possible more
 /// flexible error statistics and logging.
-/// If using of macro leads to compile errors containing in message strings
-/// like "err_code_x" or "ErrCodeX" then you didn't defined error code name
-/// with NCBI_DEFINE_ERRCODE_X macro or didn't selected current default
-/// error code with valid NCBI_USE_ERRCODE_X definition.
+/// If using the macro leads to compile errors containing strings
+/// like "err_code_x" or "ErrCodeX" in messages, it means you didn't define 
+/// error code name with NCBI_DEFINE_ERRCODE_X macro or didn't select current 
+/// default error code with valid NCBI_USE_ERRCODE_X definition.
 /// This macro allows the use of only constant error subcodes
 /// (integer literals or enum constants). If you need to make variable error
 /// subcode you need to use macro ERR_POST_EX as follows:
@@ -1777,6 +1783,7 @@ enum EPostNumberIncrement {
 
 struct SRequestCtxWrapper;
 class CRequestContext;
+class CSharedHitId;
 class CRequestRateControl;
 class CEncodedString;
 
@@ -2221,7 +2228,7 @@ public:
     /// or Log.Http_Hit_Id/Log.Hit_Id values in the INI file. The Http-value
     /// has higher priority. If none of the values is set, the default hit id
     /// is generated automatically.
-    string GetDefaultHitID(void) const { return x_GetDefaultHitID(eHitID_Create); }
+    string GetDefaultHitID(void) const;
 
     /// Set new global default hit id. This value is used only if the per-request
     /// hit id is not set.
@@ -2338,7 +2345,8 @@ private:
     // Check if current state is 'PB/P/PE'.
     bool x_DiagAtApplicationLevel(void) const;
     bool x_IsSetDefaultHitID(void) const;
-    string x_GetDefaultHitID(EDefaultHitIDFlags flag) const;
+    CSharedHitId x_GetDefaultHitID(EDefaultHitIDFlags flag) const;
+    string x_GetNextHitID(bool is_default) const;
     void x_LogHitID(void) const;
     void x_LogHitID_WithLock(void) const; // Same as above but with mutex lock.
 
@@ -2349,21 +2357,21 @@ private:
     static TPID                         sm_PID;
 
     mutable TUID                        m_UID;
-    mutable unique_ptr<CEncodedString>    m_Host;
+    mutable unique_ptr<CEncodedString>  m_Host;
     string                              m_HostIP;
-    unique_ptr<CEncodedString>            m_Username;
-    unique_ptr<CEncodedString>            m_AppName;
+    unique_ptr<CEncodedString>          m_Username;
+    unique_ptr<CEncodedString>          m_AppName;
     mutable bool                        m_AppNameSet;
-    mutable unique_ptr<CEncodedString>    m_DefaultSessionId;
-    mutable unique_ptr<string>            m_DefaultHitId;
+    mutable unique_ptr<CEncodedString>  m_DefaultSessionId;
+    mutable unique_ptr<CSharedHitId>    m_DefaultHitId;
     mutable bool                        m_LoggedHitId;
     int                                 m_ExitCode;
     bool                                m_ExitCodeSet;
     int                                 m_ExitSig;
     EDiagAppState                       m_AppState;
     TProperties                         m_Properties;
-    unique_ptr<CStopWatch>                m_StopWatch;
-    unique_ptr<TMessages>                 m_Messages;
+    unique_ptr<CStopWatch>              m_StopWatch;
+    unique_ptr<TMessages>               m_Messages;
     size_t                              m_MaxMessages;
     static CDiagContext*                sm_Instance;
 
@@ -2371,9 +2379,9 @@ private:
     static bool                         sm_ApplogSeverityLocked;
 
     // Rate control
-    unique_ptr<CRequestRateControl>       m_AppLogRC;
-    unique_ptr<CRequestRateControl>       m_ErrLogRC;
-    unique_ptr<CRequestRateControl>       m_TraceLogRC;
+    unique_ptr<CRequestRateControl>     m_AppLogRC;
+    unique_ptr<CRequestRateControl>     m_ErrLogRC;
+    unique_ptr<CRequestRateControl>     m_TraceLogRC;
     bool                                m_AppLogSuspended;
     bool                                m_ErrLogSuspended;
     bool                                m_TraceLogSuspended;
@@ -2453,7 +2461,8 @@ extern void SetDiagHandler(CDiagHandler* handler,
 
 /// Get the currently set diagnostic handler class.
 NCBI_XNCBI_EXPORT
-extern CDiagHandler* GetDiagHandler(bool take_ownership = false);
+extern CDiagHandler* GetDiagHandler(bool take_ownership = false,
+                                    bool* current_ownership = 0);
 
 /// Set the diagnostic handler using the specified diagnostic handler
 /// and cleanup functions.
diff --git a/c++/include/corelib/ncbidiag.inl b/c++/include/corelib/ncbidiag.inl
index a8a781d..a185e00 100644
--- a/c++/include/corelib/ncbidiag.inl
+++ b/c++/include/corelib/ncbidiag.inl
@@ -1,7 +1,7 @@
 #if defined(CORELIB___NCBIDIAG__HPP)  &&  !defined(CORELIB___NCBIDIAG__INL)
 #define CORELIB___NCBIDIAG__INL
 
-/*  $Id: ncbidiag.inl 461881 2015-03-13 13:39:13Z vasilche $
+/*  $Id: ncbidiag.inl 503553 2016-06-06 15:54:54Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -100,7 +100,8 @@ class CDiagBuffer
     // Handler
     NCBI_XNCBI_EXPORT friend void
     SetDiagHandler(CDiagHandler* handler, bool can_delete);
-    NCBI_XNCBI_EXPORT friend CDiagHandler* GetDiagHandler(bool take_ownership);
+    NCBI_XNCBI_EXPORT friend CDiagHandler* GetDiagHandler(bool take_ownership,
+                                                          bool* current_ownership);
     NCBI_XNCBI_EXPORT friend bool IsSetDiagHandler(void);
 
     // Error code information
diff --git a/c++/include/corelib/ncbierror.hpp b/c++/include/corelib/ncbierror.hpp
index b780f4b..45313c9 100644
--- a/c++/include/corelib/ncbierror.hpp
+++ b/c++/include/corelib/ncbierror.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBIERROR__HPP
 #define CORELIB___NCBIERROR__HPP
 
-/*  $Id: ncbierror.hpp 458676 2015-02-09 12:35:49Z lavr $
+/*  $Id: ncbierror.hpp 511430 2016-08-22 15:25:37Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -169,17 +169,20 @@ public:
 
     /// Copy constructor
     CNcbiError(const CNcbiError& err)
-        : m_Code(err.m_Code), m_Category(err.m_Category)
-        , m_Native(err.m_Native), m_Extra(err.m_Extra) {}
+        : m_Code(err.m_Code), 
+          m_Category(err.m_Category),
+          m_Native(err.m_Native),
+          m_Extra(err.m_Extra) 
+    {}
 
-    ~CNcbiError(void){}
+    ~CNcbiError(void) {}
 
     /// Assignment.
     CNcbiError& operator= (const CNcbiError& err) {
-        m_Code    = err.m_Code;
-        m_Category= err.m_Category;
-        m_Native  = err.m_Native;
-        m_Extra   = err.m_Extra;
+        m_Code     = err.m_Code;
+        m_Category = err.m_Category;
+        m_Native   = err.m_Native;
+        m_Extra    = err.m_Extra;
         return *this;
     }
 
@@ -202,7 +205,15 @@ public:
     ///   Error code
     /// @param extra
     ///   Additional information
-    static void Set(ECode code, const CTempString& extra = CTempString());
+    static void Set(ECode code);
+    /// @copydoc CNcbiError::Set(ECode)
+    static void Set(ECode code, const CTempString extra);
+    /// @copydoc CNcbiError::Set(ECode)
+    static void Set(ECode code, const char* extra);
+    /// @copydoc CNcbiError::Set(ECode)
+    static void Set(ECode code, const string& extra);
+    /// @copydoc CNcbiError::Set(ECode)
+    static void Set(ECode code, string&& extra);
 
     /// Set last error using errno code
     ///
@@ -210,14 +221,29 @@ public:
     ///   "errno" code
     /// @param extra
     ///   Additional information
-    static void SetErrno(int                errno_code,
-                         const CTempString& extra = CTempString());
+    static void SetErrno(int errno_code);
+    /// @copydoc CNcbiError::SetErrno(int)
+    static void SetErrno(int errno_code, const CTempString extra);
+    /// @copydoc CNcbiError::SetErrno(int)
+    static void SetErrno(int errno_code, const string& extra);
+    /// @copydoc CNcbiError::SetErrno(int)
+    static void SetErrno(int errno_code, const char* extra);
+    /// @copydoc CNcbiError::SetErrno(int)
+    static void SetErrno(int errno_code, string&& extra);
 
     /// Set last error using current "errno" code
     ///
     /// @param extra
     ///   Additional information
-    static void SetFromErrno(const CTempString& extra = CTempString());
+    static void SetFromErrno(void);
+    /// @copydoc CNcbiError::SetFromErrno(void)
+    static void SetFromErrno(const CTempString extra);
+    /// @copydoc CNcbiError::SetFromErrno(void)
+    static void SetFromErrno(const string& extra);
+    /// @copydoc CNcbiError::SetFromErrno(void)
+    static void SetFromErrno(const char* extra);
+    /// @copydoc CNcbiError::SetFromErrno(void)
+    static void SetFromErrno(string&& extra);
 
 #if defined(NCBI_OS_MSWIN)
     /// Set last error using Windows-specific error code
@@ -229,8 +255,15 @@ public:
     /// @note
     ///   Not all Windows errors can be translated into ECode enum.
     ///   In this case, Code() will return 'eUnknown'
-    static void SetWindowsError(int                native_err_code,
-                                const CTempString& extra = CTempString());
+    static void SetWindowsError(int native_err_code);
+    /// @copydoc CNcbiError::SetWindowsError(int)
+    static void SetWindowsError(int native_err_code, const CTempString extra);
+    /// @copydoc CNcbiError::SetWindowsError(int)
+    static void SetWindowsError(int native_err_code, const string& extra);
+    /// @copydoc CNcbiError::SetWindowsError(int)
+    static void SetWindowsError(int native_err_code, const char* extra);
+    /// @copydoc CNcbiError::SetWindowsError(int)
+    static void SetWindowsError(int native_err_code, string&& extra);
 
     /// Set last error on MS Windows using GetLastError()
     ///
@@ -239,7 +272,15 @@ public:
     /// @note
     ///   Not all Windows errors can be translated into ECode enum.
     ///   In this case, Code() will return 'eUnknown'
-    static void SetFromWindowsError(const CTempString& extra = CTempString());
+    static void SetFromWindowsError(void);
+    /// @copydoc CNcbiError::SetFromWindowsError(void)
+    static void SetFromWindowsError(const CTempString extra);
+    /// @copydoc CNcbiError::SetFromWindowsError(void)
+    static void SetFromWindowsError(const string& extra);
+    /// @copydoc CNcbiError::SetFromWindowsError(void)
+    static void SetFromWindowsError(const char* extra);
+    /// @copydoc CNcbiError::SetFromWindowsError(void)
+    static void SetFromWindowsError(string&& extra);
 #endif  /* NCBI_OS_MSWIN */
 
 protected:
@@ -247,6 +288,14 @@ protected:
     CNcbiError(void);
 
 private:
+    static CNcbiError* x_Init(int err_code);
+    template<class Ty>
+    static CNcbiError* x_Init(int err_code, Ty extra);
+#ifdef NCBI_OS_MSWIN
+    static void x_SetWindowsCodeCategory(CNcbiError* e);
+#endif
+
+private:
     mutable ECode m_Code;
     ECategory     m_Category;
     int           m_Native;
diff --git a/c++/include/corelib/ncbifile.hpp b/c++/include/corelib/ncbifile.hpp
index b320749..bc218b5 100644
--- a/c++/include/corelib/ncbifile.hpp
+++ b/c++/include/corelib/ncbifile.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBIFILE__HPP
 #define CORELIB___NCBIFILE__HPP
 
-/*  $Id: ncbifile.hpp 497376 2016-04-06 13:21:22Z ivanov $
+/*  $Id: ncbifile.hpp 515654 2016-10-04 18:38:59Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -391,7 +391,8 @@ public:
     /// How to interpret relative paths.
     /// @sa CreateAbsolutePath
     enum ERelativeToWhat {
-        eRelativeToCwd, ///< Relative to the current working directory
+        /// Relative to the current working directory.
+        eRelativeToCwd, 
         /// Relative to the executable's location.  If the executable was
         /// invoked via a symlink, search the directory containing the symlink
         /// before the directory (if different) containing the actual binary.
@@ -409,10 +410,24 @@ public:
     ///   Corresponding absolute path.  May be the original string (if already
     ///   absolute) or the starting point indicated by rtw (if the input was
     ///   empty or ".").
-    /// @sa ERelativeToWhat
+    /// @sa ERelativeToWhat, CreateAbsolutePath
     static string CreateAbsolutePath(const string& path,
                                      ERelativeToWhat rtw = eRelativeToCwd);
 
+    /// Get an absolute path from some, possibly relative, path.
+    ///
+    /// @param path 
+    ///   Path to resolve, in native syntax; returned as is if absolute.
+    /// @param rtw
+    ///   Starting point for relative path resolution. Used as base path
+    ///   for "path" if the latter have an relative form. 
+    ///   Must be an absolute.
+    /// @return
+    ///   Corresponding absolute path.  May be the original string (if already
+    ///   absolute) or concatenation of rtw and path.
+    /// @sa CreateAbsolutePath
+    static string CreateAbsolutePath(const string& path, const string& rtw);
+
     /// Concatenate two parts of the path for the current OS.
     ///
     /// Note that the arguments must be OS-specific.
@@ -1619,8 +1634,24 @@ public:
     static string GetHome(void);
 
     /// Get temporary directory.
+    ///
+    /// Return temporary directory name specified by OS via environment variables.
+    /// @sa GetAppTmpDir
     static string GetTmpDir(void);
 
+    /// Get temporary directory name for application.
+    ///
+    /// Return temporary directory name specified in the application's registry file or via environment.
+    /// Registry file:
+    ///     [NCBI]
+    ///     TmpDir = ...
+    /// Environment variable:
+    ///     NCBI_CONFIG__NCBI__TmpDir
+    ///
+    /// If not specified, return GetTmpDir().
+    /// @sa GetTmpDir
+    static string GetAppTmpDir(void);
+
     /// Get the current working directory.
     static string GetCwd(void);
 
@@ -2118,12 +2149,8 @@ public:
 ///
 /// Define a list of dir entries for deletion.
 ///
-/// Each Object of this class maintains a list of names of dir entries
-/// that will be deleted from the file system when the object
-/// goes out of scope.
-///
-/// Note: Directories will be removed recursively, symbolic links -- 
-/// without dir entries which they points to.
+/// Each object of this class maintains a list of paths that will be deleted
+/// from the file system when the object goes out of scope.
 
 class NCBI_XNCBI_EXPORT CFileDeleteList : public CObject
 {
@@ -2131,17 +2158,25 @@ public:
     /// Destructor removes all dir entries on list.
     ~CFileDeleteList();
 
-    typedef list<string> TNames;
+    typedef list<string> TList;
+
+    /// Add a path for later deletion.
+    /// @param path
+    ///   String that specifies the file system entry to delete.
+    ///   It will be stored as the absolute normalized path, so relative names
+    ///   are safe to use.
+    /// @note
+    ///   Directories will be removed recursively.
+    ///   Symbolic links -- without dir entries which they points to.
+    void Add(const string& path);
 
-    /// Add a dir entry for later deletion.
-    void Add(const string& entryname);
     /// Get the underlying list.
-    const TNames& GetNames() const;
+    const TList& GetList() const;
     /// Set the underlying list.
-    void SetNames(TNames& names);
+    void SetList(TList& list);
 
 private:
-    TNames  m_Names;   ///< List of dir entries for deletion
+    TList  m_Paths;  ///< List of dir entries for deletion
 };
 
 
@@ -2156,7 +2191,7 @@ class NCBI_XNCBI_EXPORT CFileDeleteAtExit
 {
 public:
     /// Add the name of a dir entry; it will be deleted on (normal) exit
-    static void Add(const string& entryname);
+    static void Add(const string& path);
 
     /// Get underlying static CFileDeleteList object
     static const CFileDeleteList& GetDeleteList();
@@ -2259,6 +2294,8 @@ struct SMemoryFileAttrs;
 class NCBI_XNCBI_EXPORT CMemoryFile_Base
 {
 public:
+    typedef Int8 TOffsetType; // signed for POSIX compatibility
+
     /// Which operations are permitted in memory map file.
     typedef enum {
         eMMP_Read,        ///< Data can be read
@@ -2360,7 +2397,7 @@ public:
     ///   EMemMapProtect, EMemMapShare, GetPtr, GetSize, GetOffset
     CMemoryFileSegment(SMemoryFileHandle& handle,
                        SMemoryFileAttrs&  attrs,
-                       off_t              offset,
+                       TOffsetType        offset,
                        size_t             length);
 
     /// Destructor.
@@ -2381,7 +2418,7 @@ public:
     ///   Offset in bytes of mapped area from beginning of the file.
     ///   Always return value passed in constructor even if data
     ///   was not successfully mapped.
-    off_t GetOffset(void) const;
+    TOffsetType GetOffset(void) const;
 
     /// Get length of the mapped area.
     ///
@@ -2412,7 +2449,7 @@ public:
     ///   Always return adjusted value even if data was not successfully mapped.
     /// @sa
     ///    GetRealPtr, GetRealSize, GetOffset 
-    off_t GetRealOffset(void) const;
+    TOffsetType GetRealOffset(void) const;
 
     /// Get real length of the mapped area.
     ///
@@ -2460,14 +2497,14 @@ private:
     // Values for user
     void*   m_DataPtr;     ///< Pointer to the beginning of the mapped area.
                            ///> The user seen this one.
-    off_t   m_Offset;      ///< Requested starting offset of the
+    TOffsetType   m_Offset;      ///< Requested starting offset of the
                            ///< mapped area from beginning of file.
     size_t  m_Length;      ///< Requested length of the mapped area.
 
     // Internal real values
     void*   m_DataPtrReal; ///< Real pointer to the beginning of the mapped
                            ///< area which should be fried later.
-    off_t   m_OffsetReal;  ///< Corrected starting offset of the
+    TOffsetType   m_OffsetReal;  ///< Corrected starting offset of the
                            ///< mapped area from beginning of file.
     size_t  m_LengthReal;  ///< Corrected length of the mapped area.
 
@@ -2555,7 +2592,7 @@ public:
     ///   MS Windows: If file is open in eMMP_Read mode with eMMS_Private
     ///   protection, that memory pages will be mapped in exclusive mode,
     ///   and any other process cannot access the same file for writing.
-    void* Map(off_t offset, size_t length);
+    void* Map(TOffsetType offset, size_t length);
 
     /// Unmap file segment.
     ///
@@ -2582,7 +2619,7 @@ public:
     ///   Offset in bytes of mapped segment from beginning of the file.
     ///   Returned value is a value of "offset" parameter passed
     ///   to Map() method for specified "ptr".
-    off_t GetOffset(void* ptr) const;
+    TOffsetType GetOffset(void* ptr) const;
 
     /// Get length of the mapped segment.
     ///
@@ -2714,7 +2751,7 @@ public:
     CMemoryFile(const string&  file_name,
                 EMemMapProtect protect_attr = eMMP_Read,
                 EMemMapShare   share_attr   = eMMS_Shared,
-                off_t          offset       = 0,
+                TOffsetType    offset       = 0,
                 size_t         lendth       = 0,
                 EOpenMode      mode         = eDefault,
                 Uint8          max_file_len = 0);
@@ -2739,7 +2776,7 @@ public:
     ///   - NULL if mapped to a file of zero length, or if not mapped.
     /// @sa
     ///   Unmap, GetPtr, GetOffset, GetSize, Extend
-    void* Map(off_t offset = 0, size_t length = 0);
+    void* Map(TOffsetType offset = 0, size_t length = 0);
 
     /// Unmap file if mapped.
     ///
@@ -2777,7 +2814,7 @@ public:
     ///
     /// @return
     ///   Offset in bytes of mapped area from beginning of the file.
-    off_t GetOffset(void) const;
+    TOffsetType GetOffset(void) const;
 
     /// Get length of the mapped region.
     ///
@@ -3540,6 +3577,8 @@ private:
 class NCBI_XNCBI_EXPORT CFileLock
 {
 public:
+    typedef Int8 TOffsetType; // signed for POSIX compatibility
+
     /// Type of file lock.
     ///
     /// Shared lock allows all processes to read from the locked portion
@@ -3578,12 +3617,12 @@ public:
     CFileLock(const string& filename,
               TFlags flags  = fDefault,
               EType  type   = eShared,
-              off_t  offset = 0,
+              TOffsetType offset = 0,
               size_t length = 0);
     CFileLock(const char* filename,
               TFlags flags  = fDefault,
               EType  type   = eShared,
-              off_t  offset = 0,
+              TOffsetType offset = 0,
               size_t length = 0);
 
     /// Construct CFileLock for locking file by system file handle 'handle'.
@@ -3593,7 +3632,7 @@ public:
     CFileLock(TFileHandle handle,
               TFlags flags  = fDefault,
               EType  type   = eShared,
-              off_t  offset = 0,
+              TOffsetType offset = 0,
               size_t length = 0);
 
     /// Destruct the CFileLock, close file and remove all locks if necessary.
@@ -3614,7 +3653,7 @@ public:
     ///   Number of bytes to lock.
     ///   The value 0 means that whole file will be locked.
     /// @sa Unlock
-    void Lock(EType type, off_t offset = 0, size_t length = 0);
+    void Lock(EType type, TOffsetType offset = 0, size_t length = 0);
 
     /// Unlock file.
     ///
@@ -3636,7 +3675,7 @@ public:
 
 protected:
     /// Auxiliary method for constructors.
-    void x_Init(const char* filename, EType type, off_t offset, size_t length);
+    void x_Init(const char* filename, EType type, TOffsetType offset, size_t length);
 
 private:
     TFileHandle    m_Handle;      ///< System file handle.
@@ -3906,21 +3945,22 @@ bool CSymLink::Exists(void) const
 // CFileDelete*
 
 inline
-void CFileDeleteList::Add(const string& entryname)
+void CFileDeleteList::Add(const string& path)
 {
-    m_Names.push_back(entryname);
+    string p = CDirEntry::NormalizePath(CDirEntry::CreateAbsolutePath(path));
+    m_Paths.push_back(p);
 }
 
 inline
-const CFileDeleteList::TNames& CFileDeleteList::GetNames(void) const
+const CFileDeleteList::TList& CFileDeleteList::GetList(void) const
 {
-    return m_Names;
+    return m_Paths;
 }
 
 inline
-void CFileDeleteList::SetNames(CFileDeleteList::TNames& names)
+void CFileDeleteList::SetList(CFileDeleteList::TList& list)
 {
-    m_Names = names;
+    m_Paths = list;
 }
 
 
@@ -3950,7 +3990,7 @@ size_t CMemoryFileSegment::GetSize(void) const
 
 
 inline
-off_t CMemoryFileSegment::GetOffset(void) const
+CMemoryFileSegment::TOffsetType CMemoryFileSegment::GetOffset(void) const
 {
     return m_Offset;
 }
@@ -3969,7 +4009,7 @@ size_t CMemoryFileSegment::GetRealSize(void) const
 
 
 inline
-off_t CMemoryFileSegment::GetRealOffset(void) const
+CMemoryFileSegment::TOffsetType CMemoryFileSegment::GetRealOffset(void) const
 {
     return m_OffsetReal;
 }
@@ -3993,7 +4033,7 @@ CMemoryFileMap::GetMemoryFileSegment(void* ptr) const
 }
 
 inline
-off_t CMemoryFileMap::GetOffset(void* ptr) const
+CMemoryFileMap::TOffsetType CMemoryFileMap::GetOffset(void* ptr) const
 {
     return GetMemoryFileSegment(ptr)->GetOffset();
 }
@@ -4038,7 +4078,7 @@ size_t CMemoryFile::GetSize(void) const
 }
 
 inline
-off_t CMemoryFile::GetOffset(void) const
+CMemoryFile::TOffsetType CMemoryFile::GetOffset(void) const
 {
     x_Verify();
     return CMemoryFileMap::GetOffset(m_Ptr);
diff --git a/c++/include/corelib/ncbimisc.hpp b/c++/include/corelib/ncbimisc.hpp
index c7a48cf..7aa3167 100644
--- a/c++/include/corelib/ncbimisc.hpp
+++ b/c++/include/corelib/ncbimisc.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBIMISC__HPP
 #define CORELIB___NCBIMISC__HPP
 
-/*  $Id: ncbimisc.hpp 494187 2016-03-04 12:23:11Z ivanov $
+/*  $Id: ncbimisc.hpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -973,6 +973,7 @@ typedef int TTaxId;
 
 //#define NCBI_STRICT_GI
 //#define NCBI_INT8_GI
+//#define NCBI_STRICT_ENTREZ_ID
 
 #ifdef NCBI_STRICT_GI
 # define NCBI_INT8_GI
@@ -988,41 +989,41 @@ typedef Uint8 TUintId;
 
 // Strict mode can be enabled only for Int8 GIs.
 
-class CStrictGi
+class CStrictId64
 {
 public:
-    CStrictGi(void) : m_Gi(0) {}
+    CStrictId64(void) : m_Gi(0) {}
 
-    bool operator==(const CStrictGi& gi) const { return m_Gi == gi.m_Gi; }
-    bool operator!=(const CStrictGi& gi) const { return m_Gi != gi.m_Gi; }
-    bool operator<(const CStrictGi& gi) const { return m_Gi < gi.m_Gi; }
-    bool operator<=(const CStrictGi& gi) const { return m_Gi <= gi.m_Gi; }
-    bool operator>(const CStrictGi& gi) const { return m_Gi > gi.m_Gi; }
-    bool operator>=(const CStrictGi& gi) const { return m_Gi >= gi.m_Gi; }
+    bool operator==(const CStrictId64& gi) const { return m_Gi == gi.m_Gi; }
+    bool operator!=(const CStrictId64& gi) const { return m_Gi != gi.m_Gi; }
+    bool operator<(const CStrictId64& gi) const { return m_Gi < gi.m_Gi; }
+    bool operator<=(const CStrictId64& gi) const { return m_Gi <= gi.m_Gi; }
+    bool operator>(const CStrictId64& gi) const { return m_Gi > gi.m_Gi; }
+    bool operator>=(const CStrictId64& gi) const { return m_Gi >= gi.m_Gi; }
 
-    CStrictGi& operator++(void) { m_Gi++; return *this; }
-    CStrictGi operator++(int) { CStrictGi tmp = *this; m_Gi++; return tmp; }
-    CStrictGi& operator--(void) { m_Gi--; return *this; }
-    CStrictGi operator--(int) { CStrictGi tmp = *this; m_Gi--; return tmp; }
+    CStrictId64& operator++(void) { m_Gi++; return *this; }
+    CStrictId64 operator++(int) { CStrictId64 tmp = *this; m_Gi++; return tmp; }
+    CStrictId64& operator--(void) { m_Gi--; return *this; }
+    CStrictId64 operator--(int) { CStrictId64 tmp = *this; m_Gi--; return tmp; }
 
-    TIntId operator+(const CStrictGi& gi) const { return m_Gi + gi.m_Gi; }
-    TIntId operator-(const CStrictGi& gi) const { return m_Gi - gi.m_Gi; }
+    TIntId operator+(const CStrictId64& gi) const { return m_Gi + gi.m_Gi; }
+    TIntId operator-(const CStrictId64& gi) const { return m_Gi - gi.m_Gi; }
 
-    CStrictGi operator+(TIntId offset) const { return m_Gi + offset; }
-    CStrictGi operator-(TIntId offset) const { return m_Gi - offset; }
+    CStrictId64 operator+(TIntId offset) const { return m_Gi + offset; }
+    CStrictId64 operator-(TIntId offset) const { return m_Gi - offset; }
 #if defined(NCBI_INT8_GI)
-    CStrictGi operator+(Int4 offset) const { return m_Gi + offset; }
-    CStrictGi operator-(Int4 offset) const { return m_Gi - offset; }
+    CStrictId64 operator+(Int4 offset) const { return m_Gi + offset; }
+    CStrictId64 operator-(Int4 offset) const { return m_Gi - offset; }
 #endif
 
-    CStrictGi(TIntId value) : m_Gi(value) {}
-    CStrictGi& operator=(TIntId value) { m_Gi = value; return *this; }
+    CStrictId64(TIntId value) : m_Gi(value) {}
+    CStrictId64& operator=(TIntId value) { m_Gi = value; return *this; }
     operator TIntId(void) const { return m_Gi; }
     bool operator==(TIntId value) const { return m_Gi == value; }
 
 #if defined(NCBI_INT8_GI) && defined(NCBI_TEST_APPLICATION)
-    CStrictGi(Int4 value) : m_Gi(value) {}
-    CStrictGi& operator=(Int4 value) { m_Gi = value; return *this; }
+    CStrictId64(Int4 value) : m_Gi(value) {}
+    CStrictId64& operator=(Int4 value) { m_Gi = value; return *this; }
     bool operator==(Int4 value) const { return m_Gi == value; }
 #endif
 
@@ -1030,26 +1031,26 @@ public:
 
 private:
 #if defined(NCBI_INT8_GI) && !defined(NCBI_TEST_APPLICATION)
-    CStrictGi(Int4);
-    CStrictGi& operator=(Int4);
+    CStrictId64(Int4);
+    CStrictId64& operator=(Int4);
     operator Int4(void) const;
 #endif
-    CStrictGi(Int1);
-    CStrictGi(Uint1);
-    CStrictGi(Int2);
-    CStrictGi(Uint2);
-    CStrictGi(Uint4);
-    CStrictGi(Uint8);
-    CStrictGi(float);
-    CStrictGi(double);
-    CStrictGi& operator=(Int1);
-    CStrictGi& operator=(Uint1);
-    CStrictGi& operator=(Int2);
-    CStrictGi& operator=(Uint2);
-    CStrictGi& operator=(Uint4);
-    CStrictGi& operator=(Uint8);
-    CStrictGi& operator=(float);
-    CStrictGi& operator=(double);
+    CStrictId64(Int1);
+    CStrictId64(Uint1);
+    CStrictId64(Int2);
+    CStrictId64(Uint2);
+    CStrictId64(Uint4);
+    CStrictId64(Uint8);
+    CStrictId64(float);
+    CStrictId64(double);
+    CStrictId64& operator=(Int1);
+    CStrictId64& operator=(Uint1);
+    CStrictId64& operator=(Int2);
+    CStrictId64& operator=(Uint2);
+    CStrictId64& operator=(Uint4);
+    CStrictId64& operator=(Uint8);
+    CStrictId64& operator=(float);
+    CStrictId64& operator=(double);
     operator Int1(void) const;
     operator Uint1(void) const;
     operator Int2(void) const;
@@ -1063,14 +1064,26 @@ private:
     TIntId m_Gi;
 };
 
+/// @deprecated: Use CStrictId64 instead of CStrictGi, or TGi/TEntrezId typedefs.
+NCBI_DEPRECATED typedef CStrictId64 CStrictGi;
+
 
 inline
-CNcbiOstream& operator<<(CNcbiOstream& out, const CStrictGi& gi)
+CNcbiOstream& operator<<(CNcbiOstream& out, const CStrictId64& gi)
 {
     return out << TIntId(gi);
 }
 
-typedef CStrictGi TGi;
+inline
+CNcbiIstream& operator>>(CNcbiIstream& in, CStrictId64& gi)
+{
+    TIntId id;
+    in >> id;
+    gi = id;
+    return in;
+}
+
+typedef CStrictId64 TGi;
 
 #else // NCBI_STRICT_GI
 
@@ -1086,6 +1099,16 @@ typedef Uint4 TUintId;
 
 #endif
 
+/// TEntrezId type for entrez ids which require the same strictness as TGi.
+#ifdef NCBI_STRICT_ENTREZ_ID
+# ifndef NCBI_STRICT_GI
+#  undef NCBI_STRICT_ENTREZ_ID
+# endif
+typedef TGi TEntrezId;
+#else
+typedef TIntId TEntrezId;
+#endif
+
 /// a helper template to enforce constness of argument to GI_CONST macro
 template<TIntId gi>
 class CConstGIChecker {
@@ -1149,9 +1172,9 @@ template <size_t KEmbeddedSize, class TType = char>
 class CFastBuffer
 {
 public:
-    CFastBuffer(size_t size)
-        : m_Size(size),
-          m_Buffer(size <= KEmbeddedSize ? m_EmbeddedBuffer : new TType[size])
+    CFastBuffer(size_t buf_size)
+        : m_Size(buf_size),
+          m_Buffer(buf_size <= KEmbeddedSize ? m_EmbeddedBuffer : new TType[buf_size])
     {}
     ~CFastBuffer() { if (m_Buffer != m_EmbeddedBuffer) delete[] m_Buffer; }
 
@@ -1234,9 +1257,9 @@ size_t ArraySize(const Element (&)[Size])
 }
 
 #ifdef NCBI_STRICT_GI
-template <> struct hash<ncbi::CStrictGi>
+template <> struct hash<ncbi::CStrictId64>
 {
-    size_t operator()(const ncbi::CStrictGi & x) const
+    size_t operator()(const ncbi::CStrictId64 & x) const
     {
         return hash<ncbi::TIntId>()((ncbi::TIntId)x);
     }
diff --git a/c++/include/corelib/ncbiobj.hpp b/c++/include/corelib/ncbiobj.hpp
index d4e6fea..480f821 100644
--- a/c++/include/corelib/ncbiobj.hpp
+++ b/c++/include/corelib/ncbiobj.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBIOBJ__HPP
 #define CORELIB___NCBIOBJ__HPP
 
-/*  $Id: ncbiobj.hpp 463582 2015-03-30 18:03:40Z vasilche $
+/*  $Id: ncbiobj.hpp 502479 2016-05-24 22:41:09Z vasilche $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -662,6 +662,16 @@ public:
             }
         }
 
+    /// Copy constructor from an existing CRef object, 
+    CRef(TThisType&& ref)
+        : m_Data(ref.m_Data)
+        {
+            if ( TObjectType* ptr = ref.m_Data.second() ) {
+                m_Data.first().TransferLock(ptr, ref.m_Data.first());
+                ref.m_Data.second() = 0;
+            }
+        }
+
     /// Destructor.
     ~CRef(void)
         {
@@ -879,6 +889,29 @@ public:
             return *this;
         }
 
+    /// Assignment operator for references.
+    TThisType& operator=(TThisType&& ref)
+        {
+#ifdef NCBI_COMPILER_MSVC
+            // extra check on MSVC
+            if (this == &ref) {
+                // no-op
+                return *this;
+            }
+#endif
+            TObjectType* oldPtr = m_Data.second();
+            TObjectType* newPtr = ref.m_Data.second();
+            if ( newPtr ) {
+                m_Data.first().TransferLock(newPtr, ref.m_Data.first());
+                ref.m_Data.second() = 0;
+            }
+            m_Data.second() = newPtr;
+            if ( oldPtr ) {
+                m_Data.first().Unlock(oldPtr);
+            }
+            return *this;
+        }
+
     /// Assignment operator for references with right hand side set to
     /// a pointer.
     TThisType& operator=(TObjectType* ptr)
@@ -1205,6 +1238,16 @@ public:
             }
         }
 
+    /// Constructor from an existing CConstRef object, 
+    CConstRef(TThisType&& ref)
+        : m_Data(ref.m_Data)
+        {
+            if ( TObjectType* ptr = ref.m_Data.second() ) {
+                m_Data.first().TransferLock(ptr, ref.m_Data.first());
+                ref.m_Data.second() = 0;
+            }
+        }
+
     /// Constructor from an existing CRef object, 
     CConstRef(const CRef<C, Locker>& ref)
         : m_Data(ref.GetLocker(), 0)
@@ -1433,6 +1476,29 @@ public:
             return *this;
         }
 
+    /// Assignment operator for const references.
+    TThisType& operator=(TThisType&& ref)
+        {
+#ifdef NCBI_COMPILER_MSVC
+            // extra check on MSVC
+            if (this == &ref) {
+                // no-op
+                return *this;
+            }
+#endif
+            TObjectType* oldPtr = m_Data.second();
+            TObjectType* newPtr = ref.m_Data.second();
+            if ( newPtr ) {
+                m_Data.first().TransferLock(newPtr, ref.m_Data.first());
+                ref.m_Data.second() = 0;
+            }
+            m_Data.second() = newPtr;
+            if ( oldPtr ) {
+                m_Data.first().Unlock(oldPtr);
+            }
+            return *this;
+        }
+
     /// Assignment operator for assigning a reference to a const reference.
     TThisType& operator=(const CRef<C, Locker>& ref)
         {
diff --git a/c++/include/corelib/ncbireg.hpp b/c++/include/corelib/ncbireg.hpp
index 88786fd..dae0a6d 100644
--- a/c++/include/corelib/ncbireg.hpp
+++ b/c++/include/corelib/ncbireg.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBIREG__HPP
 #define CORELIB___NCBIREG__HPP
 
-/*  $Id: ncbireg.hpp 495404 2016-03-17 13:28:04Z ivanov $
+/*  $Id: ncbireg.hpp 506965 2016-07-13 16:55:04Z elisovdn $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -297,6 +297,14 @@ public:
     void WriteLock(void);
     void Unlock   (void);
 
+    /// Check if "str" consists of alphanumeric and '_' only
+    /// Treat the case of set fSectionlessEntries separately
+    static bool IsNameSection(const string& str, TFlags flags);
+
+    // Check if "str" consists of alphanumeric and '_' only
+    static bool IsNameEntry(const string& str, TFlags flags);
+
+
     /// Entry name for an in-section comment
     static const char* sm_InSectionCommentName;
 
diff --git a/c++/include/corelib/ncbistl.hpp b/c++/include/corelib/ncbistl.hpp
index c3916ed..b1d6b22 100644
--- a/c++/include/corelib/ncbistl.hpp
+++ b/c++/include/corelib/ncbistl.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBISTL__HPP
 #define CORELIB___NCBISTL__HPP
 
-/*  $Id: ncbistl.hpp 442488 2014-08-04 17:50:17Z vasilche $
+/*  $Id: ncbistl.hpp 504449 2016-06-15 15:52:43Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -217,6 +217,7 @@ END_NCBI_SCOPE
 #    include <ext/concurrence.h>
 #    ifdef _GLIBCXX_THROW_OR_ABORT /* using libstdc++ from GCC 4.8 or later */
 #      include <typeinfo>
+#      include <bits/alloc_traits.h>
 #      include <bits/unique_ptr.h>
 #      include <bits/shared_ptr.h>
 #    endif
diff --git a/c++/include/corelib/ncbistr.hpp b/c++/include/corelib/ncbistr.hpp
index 5cc1cc5..5cc0431 100644
--- a/c++/include/corelib/ncbistr.hpp
+++ b/c++/include/corelib/ncbistr.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBISTR__HPP
 #define CORELIB___NCBISTR__HPP
 
-/*  $Id: ncbistr.hpp 497430 2016-04-06 17:39:32Z ivanov $
+/*  $Id: ncbistr.hpp 511434 2016-08-22 15:26:41Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -232,23 +232,32 @@ enum class EEncoding {
 class NCBI_XNCBI_EXPORT NStr
 {
 public:
-    /// Convert string to non-negative integer value.
-    ///
-    /// @param str
-    ///   String containing only digits, representing non-negative 
-    ///   decimal value in the int range: [0..kMax_Int].
-    /// @return
-    ///   - If conversion succeeds, set errno to zero and return the
-    ///     converted value.
-    ///   - Otherwise, set errno to non-zero and return -1.
-    static int StringToNonNegativeInt(const string& str);
-
-    /// @deprecated
-    ///   Use template-based StringToNumeric<> or StringToNonNegativeInt() instead.
-    NCBI_DEPRECATED
-    static int StringToNumeric(const string& str) {
-        return StringToNonNegativeInt(str);
-    }
+    /// Common conversion flags.
+    enum EConvErrFlags {
+        /// Do not throw an exception on error.
+        /// Could be used with methods throwing an exception by default, ignored otherwise.
+        /// Just return zero and set errno to non-zero instead of throwing an exception.
+        /// We recommend the following technique to check against errors
+        /// with minimum overhead when this flag is used:
+        /// @code
+        ///     if (!retval  &&  errno != 0)
+        ///        ERROR;
+        /// @endcode
+        /// And for StringToDouble*() variants:
+        /// @code
+        ///     if (retval == HUGE_VAL  ||  retval == -HUGE_VAL  ||  
+        ///        !retval  &&  errno != 0)
+        ///        ERROR;
+        /// @endcode
+        fConvErr_NoThrow      = (1 <<  0),
+        /*
+        fConvErr_NoErrno      = (1 <<  1),  ///< Do not set errno at all.
+                                            ///< If used together with fConvErr_NoThrow flag
+                                            ///< returns 0 on error (-1 for StringToNonNegativeInt).
+        */
+        fConvErr_NoErrMessage = (1 <<  2)   ///< Set errno, but do not set CNcbiError message on error
+    };
+    typedef int TConvErrFlags;    ///< Bitwise OR of "EConvErrFlags"
 
     /// Number to string conversion flags.
     ///
@@ -256,12 +265,13 @@ public:
     ///   If specified base in the *ToString() methods is not default 10,
     ///   that some flags like fWithSign and fWithCommas will be ignored.
     enum ENumToStringFlags {
-        fWithSign        = (1 <<  6), ///< Prefix the output value with a sign
-        fWithCommas      = (1 <<  7), ///< Use commas as thousands separator
-        fDoubleFixed     = (1 <<  8), ///< Use n.nnnn format for double
-        fDoubleScientific= (1 <<  9), ///< Use scientific format for double
-        fDoublePosix     = (1 << 10), ///< Use C locale
-        fDoubleGeneral   = fDoubleFixed | fDoubleScientific,
+        fWithSign                = (1 <<  6),  ///< Prefix the output value with a sign
+        fWithCommas              = (1 <<  7),  ///< Use commas as thousands separator
+        fDoubleFixed             = (1 <<  8),  ///< Use n.nnnn format for double
+        fDoubleScientific        = (1 <<  9),  ///< Use scientific format for double
+        fDoublePosix             = (1 << 10),  ///< Use C locale
+        fDoubleGeneral           = fDoubleFixed | fDoubleScientific,
+        // Additional flags to convert "software" qualifiers (see UInt8ToString_DataSize)
         fDS_Binary               = (1 << 11),
         fDS_NoDecimalPoint       = (1 << 12),
         fDS_PutSpaceBeforeSuffix = (1 << 13),
@@ -272,39 +282,26 @@ public:
 
     /// String to number conversion flags.
     enum EStringToNumFlags {
-        fConvErr_NoThrow      = (1 << 16),   ///< On error, return zero and set
-        /// errno to non-zero instead of throwing an exception (the default).
-        /// We recommend the following technique to check against errors
-        /// with minimum overhead when this flag is used:
-        ///     if (!retval  &&  errno != 0)
-        ///        ERROR;
-        /// And for StringToDouble*() variants:
-        ///     if (retval == HUGE_VAL  ||  retval == -HUGE_VAL  ||  
-        ///        !retval  &&  errno != 0)
-        ///        ERROR;
-        
-        fMandatorySign        = (1 << 17),   ///< See 'fWithSign'
-        fAllowCommas          = (1 << 18),   ///< See 'fWithCommas'
-        fAllowLeadingSpaces   = (1 << 19),   ///< Can have leading spaces
-        fAllowLeadingSymbols  = (1 << 20) | fAllowLeadingSpaces,
-                                             ///< Can have leading non-nums
-        fAllowTrailingSpaces  = (1 << 21),   ///< Can have trailing spaces
-        fAllowTrailingSymbols = (1 << 22) | fAllowTrailingSpaces,
-                                             ///< Can have trailing non-nums
-        fDecimalPosix         = (1 << 23),   ///< For decimal point, use C locale
-        fDecimalPosixOrLocal  = (1 << 24),   ///< For decimal point, try both C and current locale
-        fDecimalPosixFinite   = (1 << 25),   ///< keep result finite and normalized
-        /// if DBL_MAX < result < INF,     result becomes DBL_MAX
-        /// if       0 < result < DBL_MIN, result becomes DBL_MIN
-
-        fDS_ForceBinary       = (1 << 26),
-        fDS_ProhibitFractions = (1 << 27),
+        fMandatorySign           = (1 << 17),  ///< See 'ENumToStringFlags::fWithSign'
+        fAllowCommas             = (1 << 18),  ///< See 'ENumToStringFlags::fWithCommas'
+        fAllowLeadingSpaces      = (1 << 19),  ///< Can have leading spaces
+        fAllowLeadingSymbols     = (1 << 20) | fAllowLeadingSpaces,
+                                               ///< Can have leading non-nums
+        fAllowTrailingSpaces     = (1 << 21),  ///< Can have trailing spaces
+        fAllowTrailingSymbols    = (1 << 22) | fAllowTrailingSpaces,
+                                               ///< Can have trailing non-nums
+        fDecimalPosix            = (1 << 23),  ///< For decimal point, use C locale
+        fDecimalPosixOrLocal     = (1 << 24),  ///< For decimal point, try both C and current locale
+        fDecimalPosixFinite      = (1 << 25),  ///< Keep result finite and normalized:
+                                               ///< if DBL_MAX < result < INF,     result becomes DBL_MAX
+                                               ///< if       0 < result < DBL_MIN, result becomes DBL_MIN
+        // Additional flags to convert "software" qualifiers (see StringToUInt8_DataSize)
+        fDS_ForceBinary          = (1 << 26),
+        fDS_ProhibitFractions    = (1 << 27),
         fDS_ProhibitSpaceBeforeSuffix = (1 << 28)
-
     };
     typedef int TStringToNumFlags;   ///< Bitwise OR of "EStringToNumFlags"
 
-
     /// Convert string to a numeric value.
     ///
     /// @param str
@@ -349,6 +346,27 @@ public:
                                 TStringToNumFlags flags = 0,
                                 int               base  = 10);
 
+    /// Convert string to non-negative integer value.
+    ///
+    /// @param str
+    ///   String containing only digits, representing non-negative 
+    ///   decimal value in the int range: [0..kMax_Int].
+    /// @param flags
+    ///   How to convert string to value.
+    ///   Only fConvErr_NoErrMessage flag is supported here.
+    /// @return
+    ///   - If conversion succeeds, set errno to zero and return the converted value.
+    ///   - Otherwise, set errno to non-zero and return -1.
+    static int StringToNonNegativeInt(const CTempString str, TConvErrFlags flags = 0);
+
+    /// @deprecated
+    ///   Use template-based StringToNumeric<> or StringToNonNegativeInt() instead.
+    NCBI_DEPRECATED
+    static int StringToNumeric(const string& str)
+    {
+        return StringToNonNegativeInt(str);
+    }
+
     /// Convert string to int.
     ///
     /// @param str
@@ -572,7 +590,7 @@ public:
     ///     converted value.
     ///   - Otherwise, if fConvErr_NoThrow is not set, throw an exception.
     ///   - Otherwise, set errno to non-zero and return zero.
-    /// @deprecated  Use StringToUInt8_DataSize(str,flags) instead.
+    /// @deprecated  Use StringToUInt8_DataSize(str, flags) instead.
     NCBI_DEPRECATED
     static Uint8 StringToUInt8_DataSize(const CTempString str,
                                         TStringToNumFlags flags,
@@ -601,12 +619,15 @@ public:
     ///
     /// @param str
     ///   String to be converted.
+    /// @param flags
+    ///   How to convert string to value.
+    ///   Only fConvErr_NoErrMessage flag is supported here.
     /// @return
     ///   Pointer value corresponding to its string representation.
     ///   - If conversion succeeds, set errno to zero and return the
     ///     converted value.
     ///   - Otherwise, set errno to non-zero and return NULL.
-    static const void* StringToPtr(const CTempStringEx str);
+    static const void* StringToPtr(const CTempStringEx str, TConvErrFlags flags = 0);
 
     /// Convert character to integer.
     ///
@@ -677,29 +698,6 @@ public:
     static string IntToString(unsigned int value, TNumToStringFlags flags = 0,
                               int base = 10);
 
-// +++ will be deleted soon
-//private:
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static string IntToString(long value, TNumToStringFlags flags = 0,
-                              int base = 10);
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static string IntToString(unsigned long value, TNumToStringFlags flags = 0,
-                              int base = 10);
-#if !NCBI_INT8_IS_LONG
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static string IntToString(Int8 value, TNumToStringFlags flags = 0,
-                              int base = 10);
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static string IntToString(Uint8 value, TNumToStringFlags flags = 0,
-                              int base = 10);
-#endif
-// --- will be deleted soon
-public:
-
     /// Convert int to string.
     ///
     /// @param out_str
@@ -724,33 +722,6 @@ public:
                             TNumToStringFlags flags = 0,
                             int               base  = 10);
 
-// +++ will be deleted soon
-//private:
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static void IntToString(string& out_str, long value, 
-                            TNumToStringFlags flags = 0,
-                            int               base  = 10);
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static void IntToString(string& out_str, unsigned long value, 
-                            TNumToStringFlags flags = 0,
-                            int               base  = 10);
-#if !NCBI_INT8_IS_LONG
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static void IntToString(string& out_str, Int8 value, 
-                            TNumToStringFlags flags = 0,
-                            int               base  = 10);
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static void IntToString(string& out_str, Uint8 value, 
-                            TNumToStringFlags flags = 0,
-                            int               base  = 10);
-#endif
-// --- will be deleted soon
-public:
-
     /// Convert UInt to string.
     ///
     /// @param value
@@ -773,33 +744,6 @@ public:
                                TNumToStringFlags flags = 0,
                                int               base  = 10);
 
-// +++ will be deleted soon
-//private:
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static string UIntToString(unsigned long     value,
-                               TNumToStringFlags flags = 0,
-                               int               base  = 10);
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static string UIntToString(long              value,
-                               TNumToStringFlags flags = 0,
-                               int               base  = 10);
-#if !NCBI_INT8_IS_LONG
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static string UIntToString(Int8              value,
-                               TNumToStringFlags flags = 0,
-                               int               base  = 10);
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static string UIntToString(Uint8             value,
-                               TNumToStringFlags flags = 0,
-                               int               base  = 10);
-#endif
-// --- will be deleted soon
-public:
-
     /// Convert UInt to string.
     ///
     /// @param out_str
@@ -824,33 +768,6 @@ public:
                              TNumToStringFlags flags = 0,
                              int               base  = 10);
 
-// +++ will be deleted soon
-//private:
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static void UIntToString(string& out_str, unsigned long value,
-                             TNumToStringFlags flags = 0,
-                             int               base  = 10);
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static void UIntToString(string& out_str, long value,
-                             TNumToStringFlags flags = 0,
-                             int               base  = 10);
-#if !NCBI_INT8_IS_LONG
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static void UIntToString(string& out_str, Int8 value, 
-                             TNumToStringFlags flags = 0,
-                             int               base  = 10);
-    /// @deprecated  Use NumericToString instead
-    NCBI_DEPRECATED
-    static void UIntToString(string& out_str, Uint8 value, 
-                             TNumToStringFlags flags = 0,
-                             int               base  = 10);
-#endif
-// --- will be deleted soon
-public:
-
     /// Convert Int to string.
     ///
     /// @param value
@@ -1983,8 +1900,8 @@ public:
     ///   NOTE:  When an occurrence is found the next occurrence will be
     ///          searched for starting right *after* the found pattern.
     /// @return
-    ///   - Start of the found pattern in the string.
-    ///   - NPOS if there is no occurrence of the pattern in the string.
+    ///   Start of the found pattern in the string.
+    ///   Or NPOS if there is no occurrence of the pattern in the string.
     static SIZE_TYPE Find(const CTempString str,
                           const CTempString pattern,
                           ECase             use_case   = eCase,
@@ -1998,11 +1915,11 @@ public:
     /// @param pattern
     ///   Pattern to search for in "str". 
     /// @param start
-    ///   Position in "str" to start search from -- default of 0 means start
-    ///   the search from the beginning of the string.
+    ///   Position in "str" to start search from.
+    ///   0 means start the search from the beginning of the string.
     /// @param end
-    ///   Position in "str" to perform search up to -- default of NPOS means
-    ///   to search to the end of the string.
+    ///   Position in "str" to perform search up to.
+    ///   NPOS means to search to the end of the string.
     /// @param which
     ///   When set to eFirst, this means to find the first occurrence of 
     ///   "pattern" in "str". When set to eLast, this means to find the last
@@ -2012,12 +1929,32 @@ public:
     ///   case-insensitive compare (eNocase) while searching for the pattern.
     /// @return
     ///   - The start of the first or last (depending on "which" parameter)
-    ///   occurrence of "pattern" in "str", within the string interval
-    ///   ["start", "end"], or
+    ///     occurrence of "pattern" in "str", within the string interval
+    ///     ["start", "end"], or
     ///   - NPOS if there is no occurrence of the pattern.
     /// @sa FindCase, FindNoCase, FindWord
+    ///
     /// @deprecated
-    ///   Use Find() method without [start:end] range.
+    ///   Use
+    ///   @code
+    ///       Find(str, pattern, [use_case], [direction], [occurrence])
+    ///   @endcode
+    ///   method instead.
+    ///   For example:
+    ///   @code
+    ///       Find(str, pattern, 0, NPOS, eLast, eCase)
+    ///   @endcode
+    ///   can be replaced by 
+    ///   @code
+    ///       Find(str, pattern, eCase, eReverseSearch, /* 0 */)
+    ///   @endcode
+    ///   If you doing a search on a substring of the 'str' and ["start", "end"] search
+    ///   interval is not a default [0, NPOS], that mean a whole 'str' string, you may
+    ///   need to pass a substring instead of 'str', like 
+    ///   @code
+    ///       Find(CTempString(str, start, len), pattern, ....)
+    ///   @endcode
+    ///  and after checking search result on NPOS, adjust it by 'start' yourself.
     NCBI_DEPRECATED
     static SIZE_TYPE Find(const CTempString str,
                           const CTempString pattern,
@@ -2027,8 +1964,7 @@ public:
 
     /// Wrapper for backward-compatibility
     inline
-    static SIZE_TYPE Find(const CTempString str, const CTempString pattern,
-                          SIZE_TYPE start)
+    static SIZE_TYPE Find(const CTempString str, const CTempString pattern, SIZE_TYPE start)
         { return FindCase(str, pattern, start); }
 
 
@@ -2051,12 +1987,38 @@ public:
     ///    occurrence of "pattern" in "str".
     /// @return
     ///   - The start of the first or last (depending on "which" parameter)
-    ///   occurrence of "pattern" in "str", within the string interval
-    ///   ["start", "end"], or
+    ///     occurrence of "pattern" in "str", within the string interval
+    ///     ["start", "end"], or
     ///   - NPOS if there is no occurrence of the pattern.
     /// @sa Find
+    ///
     /// @deprecated
     ///   Use Find() method without [start:end] range.
+    /// @deprecated
+    ///   Use one of the next methods instead:
+    ///   @code
+    ///       Find(str, pattern, [use_case], [direction], [occurrence])
+    ///       FindCase(str, pattern, [start])
+    ///   @endcode
+    ///   For example:
+    ///   @code
+    ///       FindCase(str, pattern, 0, NPOS, eLast)
+    ///   @endcode
+    ///   can be replaced by 
+    ///   @code
+    ///       Find(str, pattern, eCase, eReverseSearch, /* 0 */)
+    ///   @endcode
+    ///   For simpler cases without range, or with default [0, NPOS] please use 
+    ///   @code
+    ///       FindCase(str, pattern, [start])
+    ///   @endcode
+    ///   But if you doing a search on a substring of the 'str' and ["start", "end"] search
+    ///   interval is not a default [0, NPOS], that mean a whole 'str' string, you may
+    ///   need to pass a substring instead of 'str', like 
+    ///   @code
+    ///       FindCase(CTempString(str, start, len), pattern, ....)
+    ///   @endcode
+    ///  and after checking search result on NPOS, adjust it by 'start' yourself.
     NCBI_DEPRECATED
     static SIZE_TYPE FindCase(const CTempString str, 
                               const CTempString pattern,
@@ -2086,12 +2048,36 @@ public:
     ///    occurrence of "pattern" in "str".
     /// @return
     ///   - The start of the first or last (depending on "which" parameter)
-    ///   occurrence of "pattern" in "str", within the string interval
-    ///   ["start", "end"], or
+    ///     occurrence of "pattern" in "str", within the string interval
+    ///     ["start", "end"], or
     ///   - NPOS if there is no occurrence of the pattern.
     /// @sa Find
+    ///
     /// @deprecated
-    ///   Use Find() method without [start:end] range.
+    ///   Use one of the next methods instead:
+    ///   @code
+    ///       Find(str, pattern, [use_case], [direction], [occurrence])
+    ///       FindNoCase(str, pattern, [start])
+    ///   @endcode
+    ///   For example:
+    ///   @code
+    ///       FindNoCase(str, pattern, 0, NPOS, eLast)
+    ///   @endcode
+    ///   can be replaced by 
+    ///   @code
+    ///       Find(str, pattern, eNocase, eReverseSearch, /* 0 */)
+    ///   @endcode
+    ///   For simpler cases without range, or with default [0, NPOS] please use 
+    ///   @code
+    ///       FindNoCase(str, pattern, [start])
+    ///   @endcode
+    ///   But if you doing a search on a substring of the 'str' and ["start", "end"] search
+    ///   interval is not a default [0, NPOS], that mean a whole 'str' string, you may
+    ///   need to pass a substring instead of 'str', like 
+    ///   @code
+    ///       FindNoCase(CTempString(str, start, len), pattern, ....)
+    ///   @endcode
+    ///  and after checking search result on NPOS, adjust it by 'start' yourself.
     NCBI_DEPRECATED
     static SIZE_TYPE FindNoCase(const CTempString str,
                                 const CTempString pattern,
@@ -2170,7 +2156,10 @@ public:
     ///   - NPOS if there is no occurrence of the word.
     /// @sa Find
     /// @deprecated
-    ///   Use FindWord() variant with EDirection parameter.
+    ///   Use FindWord() variant with EDirection parameter:
+    ///   @code
+    ///       FindWord(str, word, [use_case], [direction])
+    ///   @endcode
     inline
     NCBI_DEPRECATED
     static SIZE_TYPE FindWord(const CTempString str,
@@ -2390,7 +2379,7 @@ public:
         fSplit_Truncate_End    = 1 << 2,  ///< Truncate trailing delimiters
         fSplit_Truncate        = fSplit_Truncate_Begin | fSplit_Truncate_End,
         fSplit_ByPattern       = 1 << 3,  ///< Require full delimiter strings
-        fSplit_CanEscape       = 1 << 4,  ///< Allow \... escaping
+        fSplit_CanEscape       = 1 << 4,  ///< Allow \\... escaping
         fSplit_CanSingleQuote  = 1 << 5,  ///< Allow '...' quoting
         fSplit_CanDoubleQuote  = 1 << 6,  ///< Allow "..." quoting
         fSplit_CanQuote        = fSplit_CanSingleQuote | fSplit_CanDoubleQuote,
@@ -2404,7 +2393,7 @@ public:
         /// Note that it truncates leading and trailing delimiters as well.
         /// Please use ESplitFlags instead.
         fSplit_MergeDelims = fSplit_MergeDelimiters | fSplit_Truncate,
-        /// Mo merge the delimiters.
+        /// Do not merge the delimiters.
         /// fSplit_NoMergeDelims can be temporary used for semantics
         /// purposes only, because we still have legacy Split() version
         /// without flags, that use fSplit_MergeDelims by default.
@@ -2488,19 +2477,19 @@ public:
 
     /// Variation of Split() wihout flags -- for backward compatibility only.
     /// @attention
-    ///   Automatically use flags: fSplit_MergeDelimiters | fSplit_Truncate
+    ///   Automatically use flags: fSplit_Tokenize
     /// @deprecated  Use Split() with TSplitFlags instead
     inline
     NCBI_DEPRECATED
     static list<string>& Split(const CTempString    str,
                                const CTempString    delim,
                                list<string>&        arr) {
-        return Split(str, delim, arr, fSplit_MergeDelimiters | fSplit_Truncate);
+        return Split(str, delim, arr, fSplit_Tokenize);
     }
 
     /// Variation of Split() wihout flags -- for backward compatibility only.
     /// @attention
-    ///   Automatically use flags: fSplit_MergeDelimiters | fSplit_Truncate
+    ///   Automatically use flags: fSplit_Tokenize
     /// @deprecated  Use Split() with TSplitFlags instead
     inline
     NCBI_DEPRECATED
@@ -2508,7 +2497,7 @@ public:
                                 const CTempString    str,
                                 const CTempString    delim,
                                 list<CTempStringEx>& arr) {
-        return Split(str, delim, arr, fSplit_MergeDelimiters | fSplit_Truncate);
+        return Split(str, delim, arr, fSplit_Tokenize);
     }
 
     /// @deprecated  Use Split() with TSplitFlags instead
@@ -2754,7 +2743,7 @@ public:
     /// Get a printable version of the specified string. 
     ///
     /// All non-printable characters will be represented as "\r", "\n", "\v",
-    /// "\t", "\"", "\\", etc, or "\ooo" where 'ooo' is an octal code of the
+    /// "\t", "\"", "\\\\", etc, or "\\ooo" where 'ooo' is an octal code of the
     /// character.  The resultant string is a well-formed C string literal,
     /// which, without alterations, can be compiled by a C/C++ compiler.
     /// In many instances, octal representations of non-printable characters
@@ -3078,42 +3067,43 @@ public:
     ///   first line.
     /// @return
     ///   Return "arr", the list of wrapped lines.
-	template<typename _D>
-	static void WrapIt(const string& str, SIZE_TYPE width,
-		_D& dest, TWrapFlags flags = 0,
-		const string* prefix = 0,
-		const string* prefix1 = 0);
-
-	class IWrapDest
-	{
-	public:
-		virtual void Append(const string& s) = 0;
-		virtual void Append(const CTempString& s) = 0;
-	};
-
-	class CWrapDestStringList : public IWrapDest
-	{
-	protected:
-		list<string>& m_list;
-	public:
-		CWrapDestStringList(list<string>& l) : m_list(l) {};
-		virtual void Append(const string& s)
-		{
-			m_list.push_back(s);
-		}
-		virtual void Append(const CTempString& s)
-		{
+    template<typename _D>
+    static void WrapIt(const string& str, SIZE_TYPE width,
+        _D& dest, TWrapFlags flags = 0,
+        const string* prefix = 0,
+        const string* prefix1 = 0);
+
+    class IWrapDest
+    {
+    public:
+        virtual ~IWrapDest() {}
+        virtual void Append(const string& s) = 0;
+        virtual void Append(const CTempString& s) = 0;
+    };
+
+    class CWrapDestStringList : public IWrapDest
+    {
+    protected:
+        list<string>& m_list;
+    public:
+        CWrapDestStringList(list<string>& l) : m_list(l) {};
+        virtual void Append(const string& s)
+        {
+            m_list.push_back(s);
+        }
+        virtual void Append(const CTempString& s)
+        {
             m_list.push_back(NcbiEmptyString);
             m_list.back().assign(s.data(), s.length());
-		}
-	};
+        }
+    };
 
-	static void Wrap(const string& str, SIZE_TYPE width,
-							  IWrapDest& dest, TWrapFlags flags,
-							  const string* prefix,
-							  const string* prefix1);
+    static void Wrap(const string& str, SIZE_TYPE width,
+                              IWrapDest& dest, TWrapFlags flags,
+                              const string* prefix,
+                              const string* prefix1);
 
-	static list<string>& Wrap(const string& str, SIZE_TYPE width,
+    static list<string>& Wrap(const string& str, SIZE_TYPE width,
                               list<string>& arr, TWrapFlags flags = 0,
                               const string* prefix = 0,
                               const string* prefix1 = 0);
@@ -4441,7 +4431,13 @@ char NStr::StringToNumeric(const CTempString str,
     int n = StringToInt(str, flags, base);
     if (n < numeric_limits<char>::min()  ||  n > numeric_limits<char>::max()) {
         if (flags & NStr::fConvErr_NoThrow) {
-            CNcbiError::SetErrno(errno = ERANGE, str);
+//            if ((flags & fConvErr_NoErrno) == 0) {
+                if (flags & fConvErr_NoErrMessage) {
+                    CNcbiError::SetErrno(errno = ERANGE);
+                } else {
+                    CNcbiError::SetErrno(errno = ERANGE, str);
+                }
+//            }
             return 0;
         } else {
             NCBI_THROW2(CStringException, eConvert, 
@@ -4458,7 +4454,13 @@ unsigned char NStr::StringToNumeric(const CTempString str,
     unsigned int n = StringToUInt(str, flags, base);
     if (n > numeric_limits<unsigned char>::max()) {
         if (flags & NStr::fConvErr_NoThrow) {
-            CNcbiError::SetErrno(errno = ERANGE,str);
+//            if ((flags & fConvErr_NoErrno) == 0) {
+                if (flags & fConvErr_NoErrMessage) {
+                    CNcbiError::SetErrno(errno = ERANGE);
+                } else {
+                    CNcbiError::SetErrno(errno = ERANGE, str);
+                }
+//            }
             return 0;
         } else {
             NCBI_THROW2(CStringException, eConvert, 
@@ -4479,7 +4481,13 @@ bool NStr::StringToNumeric(const CTempString str,
     }
     if (n < numeric_limits<char>::min()  ||  n > numeric_limits<char>::max()) {
         if (flags & NStr::fConvErr_NoThrow) {
-            CNcbiError::SetErrno(errno = ERANGE, str);
+//            if ((flags & fConvErr_NoErrno) == 0) {
+                if (flags & fConvErr_NoErrMessage) {
+                    CNcbiError::SetErrno(errno = ERANGE);
+                } else {
+                    CNcbiError::SetErrno(errno = ERANGE, str);
+                }
+//            }
             return false;
         } else {
             NCBI_THROW2(CStringException, eConvert, 
@@ -4501,7 +4509,13 @@ bool NStr::StringToNumeric(const CTempString str,
     }
     if (n > numeric_limits<unsigned char>::max()) {
         if (flags & NStr::fConvErr_NoThrow) {
-            CNcbiError::SetErrno(errno = ERANGE,str);
+//            if ((flags & fConvErr_NoErrno) == 0) {
+                if (flags & fConvErr_NoErrMessage) {
+                    CNcbiError::SetErrno(errno = ERANGE);
+                } else {
+                    CNcbiError::SetErrno(errno = ERANGE, str);
+                }
+//            }
             return false;
         } else {
             NCBI_THROW2(CStringException, eConvert, 
@@ -4535,7 +4549,13 @@ wchar_t NStr::StringToNumeric(const CTempString str,
     int n = StringToInt(str, flags, base);
     if (n < numeric_limits<wchar_t>::min()  ||  n > numeric_limits<wchar_t>::max()) {
         if (flags & NStr::fConvErr_NoThrow) {
-            CNcbiError::SetErrno(errno = ERANGE, str);;
+//            if ((flags & fConvErr_NoErrno) == 0) {
+                if (flags & fConvErr_NoErrMessage) {
+                    CNcbiError::SetErrno(errno = ERANGE);
+                } else {
+                    CNcbiError::SetErrno(errno = ERANGE, str);
+                }
+//            }
             return 0;
         } else {
             NCBI_THROW2(CStringException, eConvert, 
@@ -4556,7 +4576,13 @@ bool NStr::StringToNumeric(const CTempString str,
     }
     if (n < numeric_limits<wchar_t>::min()  ||  n > numeric_limits<wchar_t>::max()) {
         if (flags & NStr::fConvErr_NoThrow) {
-            CNcbiError::SetErrno(errno = ERANGE, str);
+//            if ((flags & fConvErr_NoErrno) == 0) {
+                if (flags & fConvErr_NoErrMessage) {
+                    CNcbiError::SetErrno(errno = ERANGE);
+                } else {
+                    CNcbiError::SetErrno(errno = ERANGE, str);
+                }
+//            }
             return false;
         } else {
             NCBI_THROW2(CStringException, eConvert, 
@@ -4604,7 +4630,13 @@ short NStr::StringToNumeric(const CTempString str,
     int n = StringToInt(str, flags, base);
     if (n < numeric_limits<short>::min()  ||  n > numeric_limits<short>::max()) {
         if (flags & NStr::fConvErr_NoThrow) {
-            CNcbiError::SetErrno(errno = ERANGE, str);
+//            if ((flags & fConvErr_NoErrno) == 0) {
+                if (flags & fConvErr_NoErrMessage) {
+                    CNcbiError::SetErrno(errno = ERANGE);
+                } else {
+                    CNcbiError::SetErrno(errno = ERANGE, str);
+                }
+//            }
             return 0;
         } else {
             NCBI_THROW2(CStringException, eConvert, 
@@ -4621,7 +4653,13 @@ unsigned short NStr::StringToNumeric(const CTempString str,
     unsigned int n = StringToUInt(str, flags, base);
     if (n > numeric_limits<unsigned short>::max()) {
         if (flags & NStr::fConvErr_NoThrow) {
-            CNcbiError::SetErrno(errno = ERANGE, str);
+//            if ((flags & fConvErr_NoErrno) == 0) {
+                if (flags & fConvErr_NoErrMessage) {
+                    CNcbiError::SetErrno(errno = ERANGE);
+                } else {
+                    CNcbiError::SetErrno(errno = ERANGE, str);
+                }
+//            }
             return 0;
         } else {
             NCBI_THROW2(CStringException, eConvert, 
@@ -4642,7 +4680,13 @@ bool NStr::StringToNumeric(const CTempString str,
     }
     if (n < numeric_limits<short>::min()  ||  n > numeric_limits<short>::max()) {
         if (flags & NStr::fConvErr_NoThrow) {
-            CNcbiError::SetErrno(errno = ERANGE, str);
+//            if ((flags & fConvErr_NoErrno) == 0) {
+                if (flags & fConvErr_NoErrMessage) {
+                    CNcbiError::SetErrno(errno = ERANGE);
+                } else {
+                    CNcbiError::SetErrno(errno = ERANGE, str);
+                }
+//            }
             return false;
         } else {
             NCBI_THROW2(CStringException, eConvert, 
@@ -4664,7 +4708,13 @@ bool NStr::StringToNumeric(const CTempString str,
     }
     if (n > numeric_limits<unsigned short>::max()) {
         if (flags & NStr::fConvErr_NoThrow) {
-            CNcbiError::SetErrno(errno = ERANGE, str);
+//            if ((flags & fConvErr_NoErrno) == 0) {
+                if (flags & fConvErr_NoErrMessage) {
+                    CNcbiError::SetErrno(errno = ERANGE);
+                } else {
+                    CNcbiError::SetErrno(errno = ERANGE, str);
+                }
+//            }
             return false;
         } else {
             NCBI_THROW2(CStringException, eConvert, 
@@ -4941,7 +4991,13 @@ float NStr::StringToNumeric(const CTempString str,
     // dont use ::min() for float types, it returns positive value
     if (n < -numeric_limits<float>::max()  ||  n > numeric_limits<float>::max()) {
         if (flags & NStr::fConvErr_NoThrow) {
-            CNcbiError::SetErrno(errno = ERANGE, str);
+//            if ((flags & fConvErr_NoErrno) == 0) {
+                if (flags & fConvErr_NoErrMessage) {
+                    CNcbiError::SetErrno(errno = ERANGE);
+                } else {
+                    CNcbiError::SetErrno(errno = ERANGE, str);
+                }
+//            }
             return 0;
         } else {
             NCBI_THROW2(CStringException, eConvert, 
@@ -4963,7 +5019,13 @@ bool NStr::StringToNumeric(const CTempString str,
     // dont use ::min() for float types, it returns positive value
     if (n < -numeric_limits<float>::max() || n > numeric_limits<float>::max()) {
         if (flags & NStr::fConvErr_NoThrow) {
-            CNcbiError::SetErrno(errno = ERANGE, str);
+//            if ((flags & fConvErr_NoErrno) == 0) {
+                if (flags & fConvErr_NoErrMessage) {
+                    CNcbiError::SetErrno(errno = ERANGE);
+                } else {
+                    CNcbiError::SetErrno(errno = ERANGE, str);
+                }
+//            }
             return false;
         } else {
             NCBI_THROW2(CStringException, eConvert, 
@@ -5060,44 +5122,6 @@ string NStr::IntToString(unsigned int value,
 }
 
 inline
-string NStr::IntToString(long value,
-                         TNumToStringFlags flags, int base)
-{
-    string ret;
-    LongToString(ret, value, flags, base);
-    return ret;
-}
-
-inline
-string NStr::IntToString(unsigned long value,
-                         TNumToStringFlags flags, int base)
-{
-    string ret;
-    LongToString(ret, value, flags, base);
-    return ret;
-}
-
-#if !NCBI_INT8_IS_LONG
-inline
-string NStr::IntToString(Int8 value,
-                         TNumToStringFlags flags, int base)
-{
-    string ret;
-    Int8ToString(ret, value, flags, base);
-    return ret;
-}
-
-inline
-string NStr::IntToString(Uint8 value,
-                         TNumToStringFlags flags, int base)
-{
-    string ret;
-    Int8ToString(ret, (Int8)value, flags, base);
-    return ret;
-}
-#endif
-
-inline
 void NStr::IntToString(string& out_str, unsigned int value, 
                        TNumToStringFlags flags, int base)
 {
@@ -5105,36 +5129,6 @@ void NStr::IntToString(string& out_str, unsigned int value,
 }
 
 inline
-void NStr::IntToString(string& out_str, long value, 
-                       TNumToStringFlags flags, int base)
-{
-    LongToString(out_str, value, flags, base);
-}
-
-inline
-void NStr::IntToString(string& out_str, unsigned long value, 
-                       TNumToStringFlags flags, int base)
-{
-    LongToString(out_str, value, flags, base);
-}
-
-#if !NCBI_INT8_IS_LONG
-inline
-void NStr::IntToString(string& out_str, Int8 value, 
-                       TNumToStringFlags flags, int base)
-{
-    Int8ToString(out_str, value, flags, base);
-}
-
-inline
-void NStr::IntToString(string& out_str, Uint8 value, 
-                       TNumToStringFlags flags, int base)
-{
-    Int8ToString(out_str, (Int8)value, flags, base);
-}
-#endif
-
-inline
 string NStr::UIntToString(unsigned int value,
                           TNumToStringFlags flags, int base)
 {
@@ -5153,44 +5147,6 @@ string NStr::UIntToString(int value,
 }
 
 inline
-string NStr::UIntToString(unsigned long value,
-                          TNumToStringFlags flags, int base)
-{
-    string ret;
-    ULongToString(ret, value, flags, base);
-    return ret;
-}
-
-inline
-string NStr::UIntToString(long value,
-                          TNumToStringFlags flags, int base)
-{
-    string ret;
-    ULongToString(ret, (unsigned long)value, flags, base);
-    return ret;
-}
-
-#if !NCBI_INT8_IS_LONG
-inline
-string NStr::UIntToString(Int8 value,
-                          TNumToStringFlags flags, int base)
-{
-    string ret;
-    UInt8ToString(ret, (Uint8)value, flags, base);
-    return ret;
-}
-
-inline
-string NStr::UIntToString(Uint8 value,
-                          TNumToStringFlags flags, int base)
-{
-    string ret;
-    UInt8ToString(ret, value, flags, base);
-    return ret;
-}
-#endif
-
-inline
 void NStr::UIntToString(string& out_str, unsigned int value,
                         TNumToStringFlags flags, int base)
 {
@@ -5205,36 +5161,6 @@ void NStr::UIntToString(string& out_str, int value,
 }
 
 inline
-void NStr::UIntToString(string& out_str, unsigned long value,
-                        TNumToStringFlags flags, int base)
-{
-    ULongToString(out_str, value, flags, base);
-}
-
-inline
-void NStr::UIntToString(string& out_str, long value,
-                        TNumToStringFlags flags, int base)
-{
-    ULongToString(out_str, (unsigned long)value, flags, base);
-}
-
-#if !NCBI_INT8_IS_LONG
-inline
-void NStr::UIntToString(string& out_str, Int8 value,
-                        TNumToStringFlags flags, int base)
-{
-    UInt8ToString(out_str, (Uint8)value, flags, base);
-}
-
-inline
-void NStr::UIntToString(string& out_str, Uint8 value,
-                        TNumToStringFlags flags, int base)
-{
-    UInt8ToString(out_str, value, flags, base);
-}
-#endif
-
-inline
 string NStr::LongToString(long value,
                           TNumToStringFlags flags, int base)
 {
@@ -6065,7 +5991,6 @@ bool PNocase_Conditional_Generic<T>::operator()(const T& s1, const T& s2) const
 }
 
 
-
 END_NCBI_NAMESPACE;
 
 #endif  /* CORELIB___NCBISTR__HPP */
diff --git a/c++/include/corelib/request_ctx.hpp b/c++/include/corelib/request_ctx.hpp
index 999efb9..29fc93f 100644
--- a/c++/include/corelib/request_ctx.hpp
+++ b/c++/include/corelib/request_ctx.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___REQUEST_CTX__HPP
 #define CORELIB___REQUEST_CTX__HPP
 
-/*  $Id: request_ctx.hpp 489237 2016-01-11 17:27:20Z grichenk $
+/*  $Id: request_ctx.hpp 508071 2016-07-25 16:13:27Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -58,6 +58,63 @@ BEGIN_NCBI_SCOPE
 // Forward declarations
 class CRequestContext_PassThrough;
 
+
+/// Helper class to hold hit id and sub-hit counter which can be shared
+/// between multiple request contexts.
+class NCBI_XNCBI_EXPORT CSharedHitId
+{
+public:
+    explicit CSharedHitId(const string& hit) : m_HitId(hit), m_SubHitId(0) {}
+    CSharedHitId(void) : m_SubHitId(0) {}
+    ~CSharedHitId(void) {}
+
+    bool Empty(void) const { return m_HitId.empty(); }
+
+    /// Mark this hit id as a shared one and start using shared counter.
+    void SetShared(void) const
+    {
+        if ( IsShared() ) return; // Already shared.
+        m_SharedSubHitId.Reset(new TSharedCounter());
+        m_SharedSubHitId->GetData().Set(m_SubHitId);
+    }
+
+    /// Check if shared counter is used.
+    bool IsShared(void) const { return m_SharedSubHitId; }
+
+    /// Get hit id value.
+    const string& GetHitId(void) const { return m_HitId; }
+
+    /// Set new hit id value. This resets sub-hit counter and makes it non-shared.
+    void SetHitId(const string& hit_id)
+    {
+        m_SharedSubHitId.Reset();
+        m_SubHitId = 0;
+        m_HitId = hit_id;
+    }
+
+    typedef unsigned int TSubHitId;
+
+    /// Get current sub-hit id value.
+    TSubHitId GetCurrentSubHitId(void) const
+    {
+        return IsShared() ? (TSubHitId)m_SharedSubHitId->GetData().Get() : m_SubHitId;
+    }
+
+    /// Get next sub-hit id value.
+    TSubHitId GetNextSubHitId(void)
+    {
+        return IsShared() ? (TSubHitId)m_SharedSubHitId->GetData().Add(1) : ++m_SubHitId;
+    }
+
+private:
+    typedef CObjectFor<CAtomicCounter> TSharedCounter;
+
+    string m_HitId;
+    TSubHitId m_SubHitId;
+    mutable CRef<TSharedCounter> m_SharedSubHitId;
+};
+
+
 class NCBI_XNCBI_EXPORT CRequestContext : public CObject
 {
 public:
@@ -150,10 +207,9 @@ public:
     /// the hit id value.
     const string& SetHitID(void);
     /// Get current hit id appended with auto-incremented sub-hit id.
-    /// If hit id is not set, return empty string.
-    const string& GetNextSubHitID(void);
+    const string& GetNextSubHitID(CTempString prefix = CTempString());
     /// Get the last generated sub-hit id.
-    const string& GetCurrentSubHitID(void);
+    const string& GetCurrentSubHitID(CTempString prefix = CTempString());
 
     /// Dtab
     bool IsSetDtab(void) const;
@@ -299,9 +355,10 @@ private:
     // If 'ignore_app_state' is set, log any available hit id anyway.
     void x_LogHitID(bool ignore_app_state = false) const;
 
+    void x_SetHitID(const CSharedHitId& hit_id);
     string x_GetHitID(CDiagContext::EDefaultHitIDFlags flag) const;
 
-    void x_UpdateSubHitID(bool increment);
+    void x_UpdateSubHitID(bool increment, CTempString prefix);
 
     static bool& sx_GetDefaultAutoIncRequestIDOnPost(void);
 
@@ -319,10 +376,9 @@ private:
     EDiagAppState  m_AppState;
     string         m_ClientIP;
     CEncodedString m_SessionID;
-    string         m_HitID;
+    CSharedHitId   m_HitID;
     string         m_Dtab;
     mutable bool   m_LoggedHitID;
-    int            m_SubHitID;
     int            m_ReqStatus;
     CStopWatch     m_ReqTimer;
     Int8           m_BytesRd;
@@ -533,25 +589,24 @@ inline
 void CRequestContext::UnsetHitID(void)
 {
     x_UnsetProp(eProp_HitID);
-    m_HitID.clear();
+    m_HitID.SetHitId(kEmptyStr);
     m_LoggedHitID = false;
-    m_SubHitID = 0;
     m_SubHitIDCache.clear();
 }
 
 
 inline
-const string& CRequestContext::GetNextSubHitID(void)
+const string& CRequestContext::GetNextSubHitID(CTempString prefix)
 {
-    x_UpdateSubHitID(true);
+    x_UpdateSubHitID(true, prefix);
     return m_SubHitIDCache;
 }
 
 
 inline
-const string& CRequestContext::GetCurrentSubHitID(void)
+const string& CRequestContext::GetCurrentSubHitID(CTempString prefix)
 {
-    x_UpdateSubHitID(false);
+    x_UpdateSubHitID(false, prefix);
     return m_SubHitIDCache;
 }
 
diff --git a/c++/include/corelib/rwstream.hpp b/c++/include/corelib/rwstream.hpp
index 3e87967..fb49dd5 100644
--- a/c++/include/corelib/rwstream.hpp
+++ b/c++/include/corelib/rwstream.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___RWSTREAM__HPP
 #define CORELIB___RWSTREAM__HPP
 
-/*  $Id: rwstream.hpp 426324 2014-02-07 17:28:45Z lavr $
+/*  $Id: rwstream.hpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -94,7 +94,7 @@ BEGIN_NCBI_SCOPE
 ///     may specify the buffer location (if 0, an internal storage gets
 ///     allocated and later freed upon stream destruction).
 ///
-/// @param flags
+/// @param stm_flags
 ///     controls whether IReader is destroyed upon stream destruction,
 ///     whether exceptions get logged (or leaked, or caught silently), etc.
 ///
@@ -106,10 +106,10 @@ class NCBI_XNCBI_EXPORT CRStream : public CNcbiIstream
 {
 public:
     CRStream(IReader*             r,
-             streamsize           buf_size = 0,
-             CT_CHAR_TYPE*        buf      = 0,
-             CRWStreambuf::TFlags flags    = 0)
-        : CNcbiIstream(0), m_Sb(r, 0, buf_size, buf, flags)
+             streamsize           buf_size  = 0,
+             CT_CHAR_TYPE*        buf       = 0,
+             CRWStreambuf::TFlags stm_flags = 0)
+        : CNcbiIstream(0), m_Sb(r, 0, buf_size, buf, stm_flags)
     {
         init(r ? &m_Sb : 0);
     }
@@ -131,7 +131,7 @@ private:
 ///     may specify the buffer location (if 0, an internal storage gets
 ///     allocated and later freed upon stream destruction).
 ///
-/// @param flags
+/// @param stm_flags
 ///     controls whether IWriter is destroyed upon stream destruction,
 ///     whether exceptions get logged (or leaked, or caught silently), etc.
 ///
@@ -143,10 +143,10 @@ class NCBI_XNCBI_EXPORT CWStream : public CNcbiOstream
 {
 public:
     CWStream(IWriter*             w,
-             streamsize           buf_size = 0,
-             CT_CHAR_TYPE*        buf      = 0,
-             CRWStreambuf::TFlags flags    = 0)
-        : CNcbiOstream(0), m_Sb(0, w, buf_size, buf, flags)
+             streamsize           buf_size  = 0,
+             CT_CHAR_TYPE*        buf       = 0,
+             CRWStreambuf::TFlags stm_flags = 0)
+        : CNcbiOstream(0), m_Sb(0, w, buf_size, buf, stm_flags)
     {
         init(w ? &m_Sb : 0);
     }
@@ -169,7 +169,7 @@ private:
 ///     may specify the buffer location (if 0, an internal storage gets
 ///     allocated and later freed upon stream destruction).
 ///
-/// @param flags
+/// @param stm_flags
 ///     controls whether IReaderWriter is destroyed upon stream destruction,
 ///     whether exceptions get logged (or leaked, or caught silently), etc.
 ///
@@ -181,20 +181,20 @@ class NCBI_XNCBI_EXPORT CRWStream : public CNcbiIostream
 {
 public:
     CRWStream(IReaderWriter*       rw,
-              streamsize           buf_size = 0,
-              CT_CHAR_TYPE*        buf      = 0,
-              CRWStreambuf::TFlags flags    = 0)
-        : CNcbiIostream(0), m_Sb(rw, buf_size, buf, flags)
+              streamsize           buf_size  = 0,
+              CT_CHAR_TYPE*        buf       = 0,
+              CRWStreambuf::TFlags stm_flags = 0)
+        : CNcbiIostream(0), m_Sb(rw, buf_size, buf, stm_flags)
     {
         init(rw ? &m_Sb : 0);
     }
 
     CRWStream(IReader*             r,
               IWriter*             w,
-              streamsize           buf_size = 0,
-              CT_CHAR_TYPE*        buf      = 0,
-              CRWStreambuf::TFlags flags    = 0)
-        : CNcbiIostream(0), m_Sb(r, w, buf_size, buf, flags)
+              streamsize           buf_size  = 0,
+              CT_CHAR_TYPE*        buf       = 0,
+              CRWStreambuf::TFlags stm_flags = 0)
+        : CNcbiIostream(0), m_Sb(r, w, buf_size, buf, stm_flags)
     {
         init(r  ||  w ? &m_Sb : 0);
     }
diff --git a/c++/include/corelib/version.hpp b/c++/include/corelib/version.hpp
index 18ee5c2..eaaf946 100644
--- a/c++/include/corelib/version.hpp
+++ b/c++/include/corelib/version.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___VERSION__HPP
 #define CORELIB___VERSION__HPP
 
-/*  $Id: version.hpp 492326 2016-02-16 19:38:11Z ivanov $
+/*  $Id: version.hpp 508153 2016-07-26 15:24:18Z elisovdn $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -286,6 +286,7 @@ public:
         fPackageFull    = 0x08,  ///< Print package info, if available
         fBuildInfo      = 0x10,  ///< Print build info (date and tag)
         fBuildSignature = 0x20,  ///< Print build signature, if available
+        fTCBuildNumber  = 0x40,  ///< Print TeamCity build number, if available
         fPrintAll       = 0xFF   ///< Print all version data
     };
     typedef int TPrintFlags;  ///< Binary OR of EPrintFlags
diff --git a/c++/include/dbapi/dbapi.hpp b/c++/include/dbapi/dbapi.hpp
index 62649cd..b66c713 100644
--- a/c++/include/dbapi/dbapi.hpp
+++ b/c++/include/dbapi/dbapi.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI___DBAPI__HPP
 #define DBAPI___DBAPI__HPP
 
-/* $Id: dbapi.hpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: dbapi.hpp 501456 2016-05-16 15:12:46Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -906,7 +906,7 @@ public:
     virtual void SetTimeout(size_t nof_secs) = 0;
 
     /// Set timeout for command cancellation and connection closing
-    virtual void SetCancelTimeout(size_t nof_secs) {}
+    virtual void SetCancelTimeout(size_t /*nof_secs*/) {}
 
     /// Get connection timeout.
     virtual size_t GetTimeout(void) const;
diff --git a/c++/include/dbapi/driver/dbapi_driver_conn_mgr.hpp b/c++/include/dbapi/driver/dbapi_driver_conn_mgr.hpp
index 4a1854a..ef54d13 100644
--- a/c++/include/dbapi/driver/dbapi_driver_conn_mgr.hpp
+++ b/c++/include/dbapi/driver/dbapi_driver_conn_mgr.hpp
@@ -2,7 +2,7 @@
 #define DBAPI_DRIVER_CONN_MGR_HPP
 
 
-/* $Id: dbapi_driver_conn_mgr.hpp 494592 2016-03-08 17:55:58Z ivanov $
+/* $Id: dbapi_driver_conn_mgr.hpp 494417 2016-03-07 15:06:35Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/dbapi/driver/dbapi_driver_convert.hpp b/c++/include/dbapi/driver/dbapi_driver_convert.hpp
index 1d7b7d2..d152b0b 100644
--- a/c++/include/dbapi/driver/dbapi_driver_convert.hpp
+++ b/c++/include/dbapi/driver/dbapi_driver_convert.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_DRIVER___DBAPI_DRIVER_CONVERT__HPP
 #define DBAPI_DRIVER___DBAPI_DRIVER_CONVERT__HPP
 
-/* $Id: dbapi_driver_convert.hpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: dbapi_driver_convert.hpp 498292 2016-04-14 19:07:55Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NTOICE
diff --git a/c++/include/dbapi/driver/dbapi_object_convert.hpp b/c++/include/dbapi/driver/dbapi_object_convert.hpp
index 0ecbb71..2afb24b 100644
--- a/c++/include/dbapi/driver/dbapi_object_convert.hpp
+++ b/c++/include/dbapi/driver/dbapi_object_convert.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_DRIVER___DBAPI_OBJECT_CONVERT__HPP
 #define DBAPI_DRIVER___DBAPI_OBJECT_CONVERT__HPP
 
-/* $Id: dbapi_object_convert.hpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: dbapi_object_convert.hpp 498292 2016-04-14 19:07:55Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NTOICE
diff --git a/c++/include/dbapi/driver/dbapi_svc_mapper.hpp b/c++/include/dbapi/driver/dbapi_svc_mapper.hpp
index 5e9a689..628c1f3 100644
--- a/c++/include/dbapi/driver/dbapi_svc_mapper.hpp
+++ b/c++/include/dbapi/driver/dbapi_svc_mapper.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_SVC_MAPPER_HPP
 #define DBAPI_SVC_MAPPER_HPP
 
-/*  $Id: dbapi_svc_mapper.hpp 494592 2016-03-08 17:55:58Z ivanov $
+/*  $Id: dbapi_svc_mapper.hpp 506715 2016-07-11 16:01:42Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -98,6 +98,7 @@ public:
                                   double           preference = 100.0);
     virtual void    GetServersList(const string& service,
                                    list<string>* serv_list) const;
+    virtual bool    RecordServer(I_ConnectionExtra& extra) const;
 
     void Push(const CRef<IDBServiceMapper>& mapper);
     void Pop(void);
@@ -203,6 +204,7 @@ private:
     TLBNameMap          m_LBNameMap;
     TServiceMap         m_ServerMap;
     TServiceUsageMap    m_ServiceUsageMap;
+    TServiceUsageMap    m_OrigServiceUsageMap;
 };
 
 class NCBI_DBAPIDRIVER_EXPORT CDBUniversalMapper : public CDBServiceMapperCoR
diff --git a/c++/include/dbapi/driver/exception.hpp b/c++/include/dbapi/driver/exception.hpp
index c7e3bdb..27b6cc0 100644
--- a/c++/include/dbapi/driver/exception.hpp
+++ b/c++/include/dbapi/driver/exception.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_DRIVER___EXCEPTION__HPP
 #define DBAPI_DRIVER___EXCEPTION__HPP
 
-/* $Id: exception.hpp 440575 2014-07-15 13:59:14Z ivanov $
+/* $Id: exception.hpp 501456 2016-05-16 15:12:46Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -156,8 +156,8 @@ public:
     };
 
     struct NCBI_DBAPIDRIVER_EXPORT SMessageInContext {
-        SMessageInContext(const string& msg, const SContext& context)
-            :  message(msg), context(&context)
+        SMessageInContext(const string& msg, const SContext& ctx)
+            :  message(msg), context(&ctx)
             { }
         SMessageInContext(const string& msg = kEmptyStr)
             : message(msg)
@@ -166,7 +166,7 @@ public:
             : message(msg)
             { }
 
-        SMessageInContext operator+(const SContext& context) const;
+        SMessageInContext operator+(const SContext& ctx) const;
 
         string              message;
         CConstRef<SContext> context;
@@ -210,8 +210,8 @@ public:
         { return m_Context->database_name; }
 
     const SContext& GetContext(void) const { return *m_Context; }
-    void ApplyContext(const SContext& context)
-        { x_SetContext().UpdateFrom(context); }
+    void ApplyContext(const SContext& ctx)
+        { x_SetContext().UpdateFrom(ctx); }
     void SetFromConnection(const impl::CConnection& connection);
 
     void SetExtraMsg(const string& msg)   { x_SetContext().extra_msg = msg; }
diff --git a/c++/include/dbapi/driver/impl/dbapi_driver_utils.hpp b/c++/include/dbapi/driver/impl/dbapi_driver_utils.hpp
index 2f7474e..dd49808 100644
--- a/c++/include/dbapi/driver/impl/dbapi_driver_utils.hpp
+++ b/c++/include/dbapi/driver/impl/dbapi_driver_utils.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_DRIVER_IMPL___DBAPI_DRIVER_UTILS__HPP
 #define DBAPI_DRIVER_IMPL___DBAPI_DRIVER_UTILS__HPP
 
-/* $Id: dbapi_driver_utils.hpp 450609 2014-10-28 18:46:14Z ucko $
+/* $Id: dbapi_driver_utils.hpp 503691 2016-06-07 15:44:43Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -259,6 +259,19 @@ string ConvertN2A(Uint4 host);
 NCBI_DBAPIDRIVER_EXPORT
 SIZE_TYPE GetValidUTF8Len(const CTempString& ts);
 
+enum EBinaryToHexFlags
+{
+    fB2H_NoFinalNul = 0x1,
+    fB2H_NoPrefix   = 0x2
+};
+typedef int TBinaryToHexFlags;
+// Returns the number of bytes used in buffer, NOT counting the final
+// NUL (if it wasn't suppressed).
+NCBI_DBAPIDRIVER_EXPORT
+size_t binary_to_hex_string(char* buffer, size_t buffer_size,
+                            const void* value, size_t value_size,
+                            TBinaryToHexFlags flags = 0);
+    
 /////////////////////////////////////////////////////////////////////////////
 inline
 void
diff --git a/c++/include/dbapi/driver/impl/dbapi_impl_cmd.hpp b/c++/include/dbapi/driver/impl/dbapi_impl_cmd.hpp
index d136f9f..6d1b6a6 100644
--- a/c++/include/dbapi/driver/impl/dbapi_impl_cmd.hpp
+++ b/c++/include/dbapi/driver/impl/dbapi_impl_cmd.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_DRIVER_IMPL___DBAPI_IMPL_CMD__HPP
 #define DBAPI_DRIVER_IMPL___DBAPI_IMPL_CMD__HPP
 
-/* $Id: dbapi_impl_cmd.hpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: dbapi_impl_cmd.hpp 497635 2016-04-08 13:52:30Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/dbapi/driver/impl/dbapi_impl_connection.hpp b/c++/include/dbapi/driver/impl/dbapi_impl_connection.hpp
index 293bb01..bd8f131 100644
--- a/c++/include/dbapi/driver/impl/dbapi_impl_connection.hpp
+++ b/c++/include/dbapi/driver/impl/dbapi_impl_connection.hpp
@@ -2,7 +2,7 @@
 #define DBAPI_DRIVER_IMPL___DBAPI_IMPL_CONNECTION__HPP
 
 
-/* $Id: dbapi_impl_connection.hpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: dbapi_impl_connection.hpp 510689 2016-08-15 15:29:39Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -120,6 +120,11 @@ public:
         return *m_ExceptionContext;
     }
 
+    const string& GetRequestedServer(void) const
+    {
+        return m_RequestedServer;
+    }
+
 public:
     /// Check out if connection is alive (this function doesn't ping the server,
     /// it just checks the status of connection which was set by the last
@@ -312,6 +317,8 @@ protected:
         return const_cast<CObject*>(m_UserData.GetPointerOrNull());
     }
 
+    void x_RecordServer(const CDBServer& server);
+
 private:
     typedef deque<impl::CCommand*>  TCommandList;
 
@@ -326,8 +333,9 @@ private:
     CDBConnParams::EServerType      m_ServerType;
     bool                            m_ServerTypeIsKnown;
 
-    const Uint4    m_Host;
-    const Uint2    m_Port;
+    const string   m_RequestedServer;
+    Uint4          m_Host;
+    Uint2          m_Port;
     const string   m_Passwd;
     const string   m_Pool;
     unsigned int   m_PoolMinSize;
diff --git a/c++/include/dbapi/driver/impl/dbapi_impl_context.hpp b/c++/include/dbapi/driver/impl/dbapi_impl_context.hpp
index 7db2608..a80db1c 100644
--- a/c++/include/dbapi/driver/impl/dbapi_impl_context.hpp
+++ b/c++/include/dbapi/driver/impl/dbapi_impl_context.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_DRIVER_IMPL___DBAPI_IMPL_CONTEXT__HPP
 #define DBAPI_DRIVER_IMPL___DBAPI_IMPL_CONTEXT__HPP
 
-/* $Id: dbapi_impl_context.hpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: dbapi_impl_context.hpp 516380 2016-10-13 11:32:10Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -76,7 +76,8 @@ struct NCBI_DBAPIDRIVER_EXPORT SDBConfParams
         fPasswordKeySet  = 0x4000,
         fPoolIdleTimeSet = 0x8000,
         fPoolWaitTimeSet = 0x10000,
-        fPoolAllowTempSet= 0x20000
+        fPoolAllowTempSet= 0x20000,
+        fContRaiserrorSet= 0x40000
     };
     typedef unsigned int  TFlags;
 
@@ -99,6 +100,7 @@ struct NCBI_DBAPIDRIVER_EXPORT SDBConfParams
     string  pool_idle_time;
     string  pool_wait_time;
     string  pool_allow_temp_overflow;
+    string  continue_after_raiserror;
     string  args;
 
 
@@ -122,6 +124,8 @@ struct NCBI_DBAPIDRIVER_EXPORT SDBConfParams
     bool IsPoolWaitTimeSet(void) { return IsFlagSet(fPoolWaitTimeSet);  }
     bool IsPoolAllowTempOverflowSet(void)
                                  { return IsFlagSet(fPoolAllowTempSet); }
+    bool IsContinueAfterRaiserrorSet(void)
+                                 { return IsFlagSet(fContRaiserrorSet); }
     bool IsArgsSet(void)         { return IsFlagSet(fArgsSet);          }
 
     void Clear(void);
@@ -267,11 +271,10 @@ protected:
 
 private:
     mutable CMutex  m_DefaultCtxMtx;
-#ifdef NCBI_THREADS
+    mutable CMutex  m_PoolMutex; //< for m_PoolSem* and m_(Not)InUse
     CSemaphore      m_PoolSem;
     string          m_PoolSemSubject;
     CConnection*    m_PoolSemConn;
-#endif
 
     unsigned int    m_LoginTimeout; //< Login timeout.
     unsigned int    m_Timeout;      //< Connection timeout.
diff --git a/c++/include/dbapi/driver/impl/dbapi_impl_result.hpp b/c++/include/dbapi/driver/impl/dbapi_impl_result.hpp
index a1fefb6..07d31c9 100644
--- a/c++/include/dbapi/driver/impl/dbapi_impl_result.hpp
+++ b/c++/include/dbapi/driver/impl/dbapi_impl_result.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_DRIVER_IMPL___DBAPI_IMPL_RESULT__HPP
 #define DBAPI_DRIVER_IMPL___DBAPI_IMPL_RESULT__HPP
 
-/* $Id: dbapi_impl_result.hpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: dbapi_impl_result.hpp 497635 2016-04-08 13:52:30Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/dbapi/driver/interfaces.hpp b/c++/include/dbapi/driver/interfaces.hpp
index ee04b3c..a39cafa 100644
--- a/c++/include/dbapi/driver/interfaces.hpp
+++ b/c++/include/dbapi/driver/interfaces.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_DRIVER___INTERFACES__HPP
 #define DBAPI_DRIVER___INTERFACES__HPP
 
-/* $Id: interfaces.hpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: interfaces.hpp 501812 2016-05-18 22:51:45Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -38,9 +38,7 @@
 #include <dbapi/driver/types.hpp>
 #include <dbapi/driver/exception.hpp>
 
-#ifdef NCBI_OS_MSWIN
-#  include <winsock2.h>
-#else // NCBI_OS_UNIX
+#ifdef NCBI_OS_UNIX
 #  include <unistd.h>
 #endif
 
@@ -1128,8 +1126,6 @@ private:
 
 
 
-class I_ConnectionExtra;
-
 /////////////////////////////////////////////////////////////////////////////
 ///
 ///  I_Connection::
@@ -1385,31 +1381,6 @@ public:
 };
 
 
-class NCBI_DBAPIDRIVER_EXPORT I_ConnectionExtra
-{
-public:
-    virtual ~I_ConnectionExtra(void);
-
-#ifdef NCBI_OS_MSWIN
-    typedef SOCKET  TSockHandle;
-#else
-    typedef int     TSockHandle;
-#endif
-
-    /// Get OS handle of the socket represented by the connection
-    virtual TSockHandle GetLowLevelHandle(void) const = 0;
-
-    virtual void SetUserData(CObject* data) = 0;
-    template<typename T> T* GetUserData(void)
-    { return dynamic_cast<T*>(x_GetUserData()); }
-    template<typename T> const T* GetUserData(void) const
-    { return dynamic_cast<T*>(x_GetUserData()); }
-
-protected:
-    virtual CObject* x_GetUserData(void) const = 0;
-};
-
-
 END_NCBI_SCOPE
 
 
diff --git a/c++/include/dbapi/driver/odbc/interfaces.hpp b/c++/include/dbapi/driver/odbc/interfaces.hpp
index 90e15f3..bcd65f5 100644
--- a/c++/include/dbapi/driver/odbc/interfaces.hpp
+++ b/c++/include/dbapi/driver/odbc/interfaces.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_DRIVER_ODBC___INTERFACES__HPP
 #define DBAPI_DRIVER_ODBC___INTERFACES__HPP
 
-/* $Id: interfaces.hpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: interfaces.hpp 497635 2016-04-08 13:52:30Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/dbapi/driver/public.hpp b/c++/include/dbapi/driver/public.hpp
index a3ef0a9..6eb1c52 100644
--- a/c++/include/dbapi/driver/public.hpp
+++ b/c++/include/dbapi/driver/public.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_DRIVER___PUBLIC__HPP
 #define DBAPI_DRIVER___PUBLIC__HPP
 
-/* $Id: public.hpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: public.hpp 498292 2016-04-14 19:07:55Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/dbapi/driver/types.hpp b/c++/include/dbapi/driver/types.hpp
index 8f2a9c7..939d7a3 100644
--- a/c++/include/dbapi/driver/types.hpp
+++ b/c++/include/dbapi/driver/types.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_DRIVER___TYPES__HPP
 #define DBAPI_DRIVER___TYPES__HPP
 
-/* $Id: types.hpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: types.hpp 498292 2016-04-14 19:07:55Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/dbapi/driver/util/blobstore.hpp b/c++/include/dbapi/driver/util/blobstore.hpp
index 91f7bd4..2bd6aeb 100644
--- a/c++/include/dbapi/driver/util/blobstore.hpp
+++ b/c++/include/dbapi/driver/util/blobstore.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_UTILS___BLOBSTORE__HPP
 #define DBAPI_UTILS___BLOBSTORE__HPP
 
-/* $Id: blobstore.hpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: blobstore.hpp 497635 2016-04-08 13:52:30Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/dbapi/error_codes.hpp b/c++/include/dbapi/error_codes.hpp
index f51400b..745ae4b 100644
--- a/c++/include/dbapi/error_codes.hpp
+++ b/c++/include/dbapi/error_codes.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI___ERROR_CODES__HPP
 #define DBAPI___ERROR_CODES__HPP
 
-/*  $Id: error_codes.hpp 495422 2016-03-17 13:33:23Z ivanov $
+/*  $Id: error_codes.hpp 516380 2016-10-13 11:32:10Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/dbapi/variant.hpp b/c++/include/dbapi/variant.hpp
index 8b4de10..13eae80 100644
--- a/c++/include/dbapi/variant.hpp
+++ b/c++/include/dbapi/variant.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI___VARIANT__HPP
 #define DBAPI___VARIANT__HPP
 
-/* $Id: variant.hpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: variant.hpp 498292 2016-04-14 19:07:55Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/html/htmlhelper.hpp b/c++/include/html/htmlhelper.hpp
index 7fdcc3c..03fa5eb 100644
--- a/c++/include/html/htmlhelper.hpp
+++ b/c++/include/html/htmlhelper.hpp
@@ -1,7 +1,7 @@
 #ifndef HTML___HTMLHELPER__HPP
 #define HTML___HTMLHELPER__HPP
 
-/*  $Id: htmlhelper.hpp 460167 2015-02-25 15:39:05Z ivanov $
+/*  $Id: htmlhelper.hpp 501456 2016-05-16 15:12:46Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -212,11 +212,11 @@ void CIDs::Decode(const string& str)
         pos = 1;        // start of number
     }
 
-    SIZE_TYPE end;      // end of number
-    while ( (end = str.find_first_of(" +_,", pos)) != NPOS ) {
-        id = AddID(cmd, id, GetNumber(str.substr(pos, end - pos)));
-        cmd = str[end];
-        pos = end + 1;
+    SIZE_TYPE end_pos;  // end of number
+    while ( (end_pos = str.find_first_of(" +_,", pos)) != NPOS ) {
+        id = AddID(cmd, id, GetNumber(str.substr(pos, end_pos - pos)));
+        cmd = str[end_pos];
+        pos = end_pos + 1;
     }
     AddID(cmd, id, GetNumber(str.substr(pos)));
 }
diff --git a/c++/include/html/nodemap.hpp b/c++/include/html/nodemap.hpp
index fc3e75a..ed8446b 100644
--- a/c++/include/html/nodemap.hpp
+++ b/c++/include/html/nodemap.hpp
@@ -1,7 +1,7 @@
 #ifndef HTML___NODEMAP__HPP
 #define HTML___NODEMAP__HPP
 
-/*  $Id: nodemap.hpp 103491 2007-05-04 17:18:18Z kazimird $
+/*  $Id: nodemap.hpp 501456 2016-05-16 15:12:46Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -186,7 +186,7 @@ struct TagMapper : public BaseTagMapper
     TagMapper(CNCBINode* (C::*method)(void))
         : m_Method(method)
         { return; }
-    virtual CNCBINode* MapTag(CNCBINode* _this, const string& name) const
+    virtual CNCBINode* MapTag(CNCBINode* _this, const string& /*name*/) const
         { return (dynamic_cast<C*>(_this)->*m_Method)(); }
 private:
     CNCBINode* (C::*m_Method)(void);
diff --git a/c++/include/misc/error_codes.hpp b/c++/include/misc/error_codes.hpp
new file mode 100644
index 0000000..10b42c3
--- /dev/null
+++ b/c++/include/misc/error_codes.hpp
@@ -0,0 +1,52 @@
+#ifndef MISC___ERROR_CODES__HPP
+#define MISC___ERROR_CODES__HPP
+
+/*  $Id: error_codes.hpp 467460 2015-05-13 18:25:03Z grichenk $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Authors:  Pavel Ivanov
+ *
+ */
+
+/// @file error_codes.hpp
+/// Definition of all error codes used in misc libraries
+/// (xcgi_redirect.lib, xgridcgi.lib).
+///
+
+
+#include <corelib/ncbidiag.hpp>
+
+
+BEGIN_NCBI_SCOPE
+
+
+NCBI_DEFINE_ERRCODE_X(Misc_CgiRedirect, 701,  2);
+NCBI_DEFINE_ERRCODE_X(Misc_GridCgi,     702,  3);
+NCBI_DEFINE_ERRCODE_X(Misc_EutilsClient, 703, 6);
+
+END_NCBI_SCOPE
+
+
+#endif  /* MISC___ERROR_CODES__HPP */
diff --git a/c++/include/ncbi_pch.hpp b/c++/include/ncbi_pch.hpp
index d7b2df2..5f36f13 100644
--- a/c++/include/ncbi_pch.hpp
+++ b/c++/include/ncbi_pch.hpp
@@ -1,5 +1,5 @@
 #if defined(NCBI_USE_PCH)  &&  !defined(NCBI_PCH__HPP)
-/*  $Id: ncbi_pch.hpp 500618 2016-05-05 19:15:27Z blastadm $
+/*  $Id: ncbi_pch.hpp 521318 2016-12-07 19:37:59Z blastadm $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/ncbi_source_ver.h b/c++/include/ncbi_source_ver.h
index 53cda90..291450b 100644
--- a/c++/include/ncbi_source_ver.h
+++ b/c++/include/ncbi_source_ver.h
@@ -1,4 +1,4 @@
-/*  $Id: ncbi_source_ver.h 500618 2016-05-05 19:15:27Z blastadm $
+/*  $Id: ncbi_source_ver.h 521318 2016-12-07 19:37:59Z blastadm $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/ncbiconf.h b/c++/include/ncbiconf.h
index 8434a4c..87a6e18 100644
--- a/c++/include/ncbiconf.h
+++ b/c++/include/ncbiconf.h
@@ -1,7 +1,7 @@
 #ifndef FORWARDING_NCBICONF_H
 #define FORWARDING_NCBICONF_H
 
-/*  $Id: ncbiconf.h 500618 2016-05-05 19:15:27Z blastadm $
+/*  $Id: ncbiconf.h 521318 2016-12-07 19:37:59Z blastadm $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objects/biblio/MedlineUID.hpp b/c++/include/objects/biblio/MedlineUID.hpp
new file mode 100644
index 0000000..2e67f4a
--- /dev/null
+++ b/c++/include/objects/biblio/MedlineUID.hpp
@@ -0,0 +1,76 @@
+/* $Id: MedlineUID.hpp 498065 2016-04-12 22:14:52Z vasilche $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ */
+
+/// @file MedlineUID.hpp
+/// User-defined methods of the data storage class.
+///
+/// This file was originally generated by application DATATOOL
+/// using the following specifications:
+/// 'biblio.asn'.
+///
+/// New methods or data members can be added to it if needed.
+/// See also: MedlineUID_.hpp
+
+
+#ifndef OBJECTS_BIBLIO_MEDLINEUID_HPP
+#define OBJECTS_BIBLIO_MEDLINEUID_HPP
+
+
+// generated includes
+#include <objects/biblio/MedlineUID_.hpp>
+
+// generated classes
+
+BEGIN_NCBI_SCOPE
+
+BEGIN_objects_SCOPE // namespace ncbi::objects::
+
+/////////////////////////////////////////////////////////////////////////////
+class NCBI_BIBLIO_EXPORT CMedlineUID : public CMedlineUID_Base
+{
+    typedef CMedlineUID_Base Tparent;
+public:
+    CMedlineUID(void) {}
+
+    /// Explicit constructor from the primitive type.
+    explicit CMedlineUID(const ncbi::TEntrezId& data)
+        : Tparent(data) {}
+
+#ifdef NCBI_STRICT_ENTREZ_ID
+    /// Explicit constructor from zero.
+    explicit CMedlineUID(std::nullptr_t zero)
+        : Tparent((TIntId)0) {}
+#endif
+};
+
+END_objects_SCOPE // namespace ncbi::objects::
+
+END_NCBI_SCOPE
+
+
+#endif // OBJECTS_BIBLIO_MEDLINEUID_HPP
+/* Original file checksum: lines: 70, chars: 2190, CRC32: 8a1e1a16 */
diff --git a/c++/include/objects/biblio/PmcID.hpp b/c++/include/objects/biblio/PmcID.hpp
new file mode 100644
index 0000000..e533028
--- /dev/null
+++ b/c++/include/objects/biblio/PmcID.hpp
@@ -0,0 +1,76 @@
+/* $Id: PmcID.hpp 498065 2016-04-12 22:14:52Z vasilche $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ */
+
+/// @file PmcID.hpp
+/// User-defined methods of the data storage class.
+///
+/// This file was originally generated by application DATATOOL
+/// using the following specifications:
+/// 'biblio.asn'.
+///
+/// New methods or data members can be added to it if needed.
+/// See also: PmcID_.hpp
+
+
+#ifndef OBJECTS_BIBLIO_PMCID_HPP
+#define OBJECTS_BIBLIO_PMCID_HPP
+
+
+// generated includes
+#include <objects/biblio/PmcID_.hpp>
+
+// generated classes
+
+BEGIN_NCBI_SCOPE
+
+BEGIN_objects_SCOPE // namespace ncbi::objects::
+
+/////////////////////////////////////////////////////////////////////////////
+class NCBI_BIBLIO_EXPORT CPmcID : public CPmcID_Base
+{
+    typedef CPmcID_Base Tparent;
+public:
+    CPmcID(void) {}
+
+    /// Explicit constructor from the primitive type.
+    explicit CPmcID(const ncbi::TEntrezId& data)
+        : Tparent(data) {}
+
+#ifdef NCBI_STRICT_ENTREZ_ID
+    /// Explicit constructor from zero.
+    explicit CPmcID(std::nullptr_t zero)
+        : Tparent((TIntId)0) {}
+#endif
+};
+
+END_objects_SCOPE // namespace ncbi::objects::
+
+END_NCBI_SCOPE
+
+
+#endif // OBJECTS_BIBLIO_PMCID_HPP
+/* Original file checksum: lines: 70, chars: 2135, CRC32: dbe555d8 */
diff --git a/c++/include/objects/biblio/PubMedId.hpp b/c++/include/objects/biblio/PubMedId.hpp
new file mode 100644
index 0000000..3108b5c
--- /dev/null
+++ b/c++/include/objects/biblio/PubMedId.hpp
@@ -0,0 +1,76 @@
+/* $Id: PubMedId.hpp 498065 2016-04-12 22:14:52Z vasilche $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ */
+
+/// @file PubMedId.hpp
+/// User-defined methods of the data storage class.
+///
+/// This file was originally generated by application DATATOOL
+/// using the following specifications:
+/// 'biblio.asn'.
+///
+/// New methods or data members can be added to it if needed.
+/// See also: PubMedId_.hpp
+
+
+#ifndef OBJECTS_BIBLIO_PUBMEDID_HPP
+#define OBJECTS_BIBLIO_PUBMEDID_HPP
+
+
+// generated includes
+#include <objects/biblio/PubMedId_.hpp>
+
+// generated classes
+
+BEGIN_NCBI_SCOPE
+
+BEGIN_objects_SCOPE // namespace ncbi::objects::
+
+/////////////////////////////////////////////////////////////////////////////
+class NCBI_BIBLIO_EXPORT CPubMedId : public CPubMedId_Base
+{
+    typedef CPubMedId_Base Tparent;
+public:
+    CPubMedId(void) {}
+
+    /// Explicit constructor from the primitive type.
+    explicit CPubMedId(const ncbi::TEntrezId& data)
+        : Tparent(data) {}
+
+#ifdef NCBI_STRICT_ENTREZ_ID
+    /// Explicit constructor from zero.
+    explicit CPubMedId(std::nullptr_t zero)
+        : Tparent((TIntId)0) {}
+#endif
+};
+
+END_objects_SCOPE // namespace ncbi::objects::
+
+END_NCBI_SCOPE
+
+
+#endif // OBJECTS_BIBLIO_PUBMEDID_HPP
+/* Original file checksum: lines: 70, chars: 2168, CRC32: 981284c0 */
diff --git a/c++/include/objects/general/Dbtag.hpp b/c++/include/objects/general/Dbtag.hpp
index 456af1f..7140c1b 100644
--- a/c++/include/objects/general/Dbtag.hpp
+++ b/c++/include/objects/general/Dbtag.hpp
@@ -1,4 +1,4 @@
-/* $Id: Dbtag.hpp 496201 2016-03-24 15:11:44Z ivanov $
+/* $Id: Dbtag.hpp 509625 2016-08-08 14:26:35Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -212,7 +212,9 @@ public:
         eDbtagType_ERIC,
         eDbtagType_I5KNAL,
         eDbtagType_VISTA,
-        eDbtagType_BEI
+        eDbtagType_BEI,
+        eDbtagType_Araport,
+        eDbtagType_VGNC
     };
 
     enum EDbtagGroup {
diff --git a/c++/include/objects/general/Name_std.hpp b/c++/include/objects/general/Name_std.hpp
index be5e199..36757ec 100644
--- a/c++/include/objects/general/Name_std.hpp
+++ b/c++/include/objects/general/Name_std.hpp
@@ -1,4 +1,4 @@
-/* $Id: Name_std.hpp 103491 2007-05-04 17:18:18Z kazimird $
+/* $Id: Name_std.hpp 509242 2016-08-04 14:12:34Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -66,6 +66,9 @@ public:
 
     /// Get a list of NCBI's standard suffixes.
     static const TSuffixes& GetStandardSuffixes(void);
+    static void FixSuffix(string& suffix);
+
+    bool ExtractSuffixFromLastName();
 
 private:
     // Prohibit copy constructor and assignment operator
diff --git a/c++/include/objects/general/User_object.hpp b/c++/include/objects/general/User_object.hpp
index 7e78bf9..06e68b1 100644
--- a/c++/include/objects/general/User_object.hpp
+++ b/c++/include/objects/general/User_object.hpp
@@ -1,4 +1,4 @@
-/* $Id: User_object.hpp 490266 2016-01-22 16:40:57Z kornbluh $
+/* $Id: User_object.hpp 501123 2016-05-11 17:29:51Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -166,7 +166,8 @@ public:
         eObjectType_Unverified,
         eObjectType_ValidationSuppression,
         eObjectType_Cleanup,
-        eObjectType_AutodefOptions
+        eObjectType_AutodefOptions,
+        eObjectType_FileTrack
     };
 
     EObjectType GetObjectType() const;
@@ -185,6 +186,10 @@ public:
 
     void UpdateNcbiCleanup(int version);
 
+    // Set FileTrack URL
+    void SetFileTrackURL(const string& url);
+    void SetFileTrackUploadId(const string& upload_id);
+
 private:
     /// Prohibit copy constructor and assignment operator
     CUser_object(const CUser_object& value);
diff --git a/c++/include/objects/genomecoll/GCClient_GetAssemblyBySequ.hpp b/c++/include/objects/genomecoll/GCClient_GetAssemblyBySequ.hpp
new file mode 100644
index 0000000..fc7dcb6
--- /dev/null
+++ b/c++/include/objects/genomecoll/GCClient_GetAssemblyBySequ.hpp
@@ -0,0 +1,89 @@
+/* $Id: GCClient_GetAssemblyBySequ.hpp 500855 2016-05-09 16:12:34Z zherikov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ */
+
+/// @file GCClient_GetAssemblyBySequ.hpp
+/// User-defined methods of the data storage class.
+///
+/// This file was originally generated by application DATATOOL
+/// using the following specifications:
+/// 'gencoll_client.asn'.
+///
+/// New methods or data members can be added to it if needed.
+/// See also: GCClient_GetAssemblyBySequ_.hpp
+
+
+#ifndef OBJECTS_GENOMECOLL_GCCLIENT_GETASSEMBLYBYSEQU_HPP
+#define OBJECTS_GENOMECOLL_GCCLIENT_GETASSEMBLYBYSEQU_HPP
+
+
+// generated includes
+#include <objects/genomecoll/GCClient_GetAssemblyBySequ_.hpp>
+
+// generated classes
+
+BEGIN_NCBI_SCOPE
+
+BEGIN_objects_SCOPE // namespace ncbi::objects::
+
+/////////////////////////////////////////////////////////////////////////////
+class CGCClient_GetAssemblyBySequenceRequest : public CGCClient_GetAssemblyBySequenceRequest_Base
+{
+    typedef CGCClient_GetAssemblyBySequenceRequest_Base Tparent;
+public:
+    // constructor
+    CGCClient_GetAssemblyBySequenceRequest(void);
+    // destructor
+    ~CGCClient_GetAssemblyBySequenceRequest(void);
+
+    static string GetFilterDisplayName(int filter);
+
+private:
+    // Prohibit copy constructor and assignment operator
+    CGCClient_GetAssemblyBySequenceRequest(const CGCClient_GetAssemblyBySequenceRequest& value);
+    CGCClient_GetAssemblyBySequenceRequest& operator=(const CGCClient_GetAssemblyBySequenceRequest& value);
+
+};
+
+/////////////////// CGCClient_GetAssemblyBySequenceRequest inline methods
+
+// constructor
+inline
+CGCClient_GetAssemblyBySequenceRequest::CGCClient_GetAssemblyBySequenceRequest(void)
+{
+}
+
+
+/////////////////// end of CGCClient_GetAssemblyBySequenceRequest inline methods
+
+
+END_objects_SCOPE // namespace ncbi::objects::
+
+END_NCBI_SCOPE
+
+
+#endif // OBJECTS_GENOMECOLL_GCCLIENT_GETASSEMBLYBYSEQU_HPP
+/* Original file checksum: lines: 86, chars: 2881, CRC32: 175ce2d7 */
diff --git a/c++/include/objects/genomecoll/GC_Assembly.hpp b/c++/include/objects/genomecoll/GC_Assembly.hpp
index 00ac70b..7066c75 100644
--- a/c++/include/objects/genomecoll/GC_Assembly.hpp
+++ b/c++/include/objects/genomecoll/GC_Assembly.hpp
@@ -1,4 +1,4 @@
-/* $Id: GC_Assembly.hpp 467805 2015-05-18 12:53:53Z zherikov $
+/* $Id: GC_Assembly.hpp 504372 2016-06-14 18:01:03Z shchekot $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -79,6 +79,9 @@ public:
     /// Retrieve the accession for this assembly
     string GetAccession() const;
 
+    /// Either accession or submitter-provided id
+    string GetBestIdentifier() const;
+
     /// Retrieve the full set of assembly descriptors
     const CGC_AssemblyDesc& GetDesc() const;
 
@@ -159,6 +162,9 @@ private:
                  CGC_TaggedSequences::TState relation);
 
     void x_Index(CGC_Assembly& root);
+
+    const list< CRef< CDbtag > >& x_GetId() const;
+    string x_GetSubmitterId() const;
 };
 
 /////////////////// CGC_Assembly inline methods
diff --git a/c++/include/objects/genomecoll/cached_assembly.hpp b/c++/include/objects/genomecoll/cached_assembly.hpp
index dbec443..e6d8110 100644
--- a/c++/include/objects/genomecoll/cached_assembly.hpp
+++ b/c++/include/objects/genomecoll/cached_assembly.hpp
@@ -41,10 +41,14 @@ public:
     CCachedAssembly(const vector<char>& blob);
 
     CRef<objects::CGC_Assembly> Assembly();
+    //@deprecated, Blob() will be used in the next release(SC18). This one will be removed in SC19.
     const string& Blob(CCompressStream::EMethod neededCompression);
+    //New assemblies are compressed with CCompressStream::eZip, existing returned as is.
+    const string& Blob();
 
 public:
     static bool ValidBlob(int blobSize);
+    static CCompressStream::EMethod Compression(const string& blob);
 
 private:
     CRef<objects::CGC_Assembly> m_assembly;
diff --git a/c++/include/objects/genomecoll/genomic_collections_cli.hpp b/c++/include/objects/genomecoll/genomic_collections_cli.hpp
index 8ce6e05..557746f 100644
--- a/c++/include/objects/genomecoll/genomic_collections_cli.hpp
+++ b/c++/include/objects/genomecoll/genomic_collections_cli.hpp
@@ -1,4 +1,4 @@
-/* $Id: genomic_collections_cli.hpp 499302 2016-04-25 15:35:38Z ivanov $
+/* $Id: genomic_collections_cli.hpp 517367 2016-10-24 17:52:09Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -45,6 +45,7 @@
 #include <objects/genomecoll/GCClient_AttributeFlags.hpp>
 #include <objects/genomecoll/GCClient_GetAssemblyReques.hpp>
 #include <objects/genomecoll/GCClient_FindBestAssemblyR.hpp>
+#include <objects/genomecoll/GCClient_GetAssemblyBySequ.hpp>
 #include <objects/genomecoll/cached_assembly.hpp>
 // generated classes
 
@@ -118,6 +119,11 @@ public:
         // pseudo scaffolds are reported as unlocalized/unplaced, as needed for analysis
         static string kScaffoldsWithAlignments()  {return "ScaffoldsWithAlignments";};
 
+        // Scaffolds
+        // No alignment data
+        // pseudo scaffolds reported as submitted.
+        static string kEntrezIndexing()  {return "EntrezIndexing";};
+
         // Almost maximum contents:
         // all sequences down to contigs
         // No statistics
@@ -135,22 +141,119 @@ public:
 
     string ValidateChrType(const string& chrType, const string& chrLoc);
 
+    NCBI_DEPRECATED  // Use FindOneAssemblyBySequences
     CRef<CGCClient_AssemblyInfo> FindBestAssembly
         (const string& seq_id,
          int filter_type,
          int sort_type = eGCClient_FindBestAssemblySort_default);
 
+    NCBI_DEPRECATED  // Use FindOneAssemblyBySequences
     CRef<CGCClient_AssemblySequenceInfo> FindBestAssembly
         (const list<string>& seq_id,
          int filter_type,
          int sort_type = eGCClient_FindBestAssemblySort_default);
 
+    NCBI_DEPRECATED  // Use FindAssembliesBySequences
     CRef<CGCClient_AssembliesForSequences> FindAllAssemblies
         (const list<string>& seq_id,
          int filter_type,
          int sort_type = eGCClient_FindBestAssemblySort_default);
 
 
+    /// Find assembly by sequence accession
+    ///
+    /// @param sequence_acc
+    ///     Sequence accession in ACC.VER format
+    /// @param filter
+    ///     Bitfield, OR-ed combination of eGCClient_GetAssemblyBySequenceFilter_* values:
+    ///         eGCClient_GetAssemblyBySequenceFilter_all     - do not filter out anything
+    ///         eGCClient_GetAssemblyBySequenceFilter_latest  - look up for latest releases only
+    ///         eGCClient_GetAssemblyBySequenceFilter_major   - look up for major releases only
+    ///         eGCClient_GetAssemblyBySequenceFilter_genbank - look up for GenBank releases only
+    ///         eGCClient_GetAssemblyBySequenceFilter_refseq  - look up for RefSeq releases only
+    ///     If none of genbank of refseq filters are specified then both GenBank and RefSeq releases will be returned
+    /// @param sort
+    ///     Assembly ordering:
+    ///         CGCClient_GetAssemblyBySequenceRequest::eSort_default - sort by number of sequences found in assembly, then by reference/representative/other, then by modification date
+    ///         CGCClient_GetAssemblyBySequenceRequest::eSort_latest  - sort by number of sequences found in assembly, then latest first, then by reference/representative/other, then by modification date
+    ///         CGCClient_GetAssemblyBySequenceRequest::eSort_major   - sort by number of sequences found in assembly, then major first, then by reference/representative/other, then by modification date
+    /// @return Assembly if found, NULL otherwise.
+    CRef<CGCClient_AssemblyInfo> FindOneAssemblyBySequences
+        (const string& sequence_acc,
+         int filter,
+         CGCClient_GetAssemblyBySequenceRequest::ESort sort = CGCClient_GetAssemblyBySequenceRequest::eSort_default);
+
+    /// Find assembly by sequence accessions
+    ///
+    /// @param sequence_acc
+    ///     Sequence accessions in ACC.VER format
+    /// @param filter
+    ///     Bitfield, OR-ed combination of eGCClient_GetAssemblyBySequenceFilter_* values:
+    ///         eGCClient_GetAssemblyBySequenceFilter_all     - do not filter out anything
+    ///         eGCClient_GetAssemblyBySequenceFilter_latest  - look up for latest releases only
+    ///         eGCClient_GetAssemblyBySequenceFilter_major   - look up for major releases only
+    ///         eGCClient_GetAssemblyBySequenceFilter_genbank - look up for GenBank releases only
+    ///         eGCClient_GetAssemblyBySequenceFilter_refseq  - look up for RefSeq releases only
+    ///     If none of genbank of refseq filters are specified then both GenBank and RefSeq releases will be returned
+    /// @param sort
+    ///     Assembly ordering:
+    ///         CGCClient_GetAssemblyBySequenceRequest::eSort_default - sort by number of sequences found in assembly, then by reference/representative/other, then by modification date
+    ///         CGCClient_GetAssemblyBySequenceRequest::eSort_latest  - sort by number of sequences found in assembly, then latest first, then by reference/representative/other, then by modification date
+    ///         CGCClient_GetAssemblyBySequenceRequest::eSort_major   - sort by number of sequences found in assembly, then major first, then by reference/representative/other, then by modification date
+    /// @return If assembly is found then return it with list of related sequences. NULL otherwise.
+    CRef<CGCClient_AssemblySequenceInfo> FindOneAssemblyBySequences
+        (const list<string>& sequence_acc,
+         int filter,
+         CGCClient_GetAssemblyBySequenceRequest::ESort sort = CGCClient_GetAssemblyBySequenceRequest::eSort_default);
+
+    /// Find assemblies by sequence accession
+    ///
+    /// @param sequence_acc
+    ///     Sequence accession in ACC.VER format
+    /// @param filter
+    ///     Bitfield, OR-ed combination of eGCClient_GetAssemblyBySequenceFilter_* values:
+    ///         eGCClient_GetAssemblyBySequenceFilter_all     - do not filter out anything
+    ///         eGCClient_GetAssemblyBySequenceFilter_latest  - look up for latest releases only
+    ///         eGCClient_GetAssemblyBySequenceFilter_major   - look up for major releases only
+    ///         eGCClient_GetAssemblyBySequenceFilter_genbank - look up for GenBank releases only
+    ///         eGCClient_GetAssemblyBySequenceFilter_refseq  - look up for RefSeq releases only
+    ///     If none of genbank of refseq filters are specified then both GenBank and RefSeq releases will be returned
+    /// @param sort
+    ///     Assembly ordering:
+    ///         CGCClient_GetAssemblyBySequenceRequest::eSort_default - sort by number of sequences found in assembly, then by reference/representative/other, then by modification date
+    ///         CGCClient_GetAssemblyBySequenceRequest::eSort_latest  - sort by number of sequences found in assembly, then latest first, then by reference/representative/other, then by modification date
+    ///         CGCClient_GetAssemblyBySequenceRequest::eSort_major   - sort by number of sequences found in assembly, then major first, then by reference/representative/other, then by modification date
+    /// @return List of found assemblies with related sequences.
+    CRef<CGCClient_AssembliesForSequences> FindAssembliesBySequences
+        (const string& sequence_acc,
+         int filter,
+         CGCClient_GetAssemblyBySequenceRequest::ESort sort = CGCClient_GetAssemblyBySequenceRequest::eSort_default);
+
+    /// Find assemblies by sequence accessions
+    ///
+    /// @param sequence_acc
+    ///     Sequence accessions in ACC.VER format
+    /// @param filter
+    ///     Bitfield, OR-ed combination of eGCClient_GetAssemblyBySequenceFilter_* values:
+    ///         eGCClient_GetAssemblyBySequenceFilter_all     - do not filter out anything
+    ///         eGCClient_GetAssemblyBySequenceFilter_latest  - look up for latest releases only
+    ///         eGCClient_GetAssemblyBySequenceFilter_major   - look up for major releases only
+    ///         eGCClient_GetAssemblyBySequenceFilter_genbank - look up for GenBank releases only
+    ///         eGCClient_GetAssemblyBySequenceFilter_refseq  - look up for RefSeq releases only
+    ///     If none of genbank of refseq filters are specified then both GenBank and RefSeq releases will be returned
+    /// @param sort
+    ///     Assembly ordering:
+    ///         CGCClient_GetAssemblyBySequenceRequest::eSort_default - sort by number of sequences found in assembly, then by reference/representative/other, then by modification date
+    ///         CGCClient_GetAssemblyBySequenceRequest::eSort_latest  - sort by number of sequences found in assembly, then latest first, then by reference/representative/other, then by modification date
+    ///         CGCClient_GetAssemblyBySequenceRequest::eSort_major   - sort by number of sequences found in assembly, then major first, then by reference/representative/other, then by modification date
+    /// @return List of found assemblies with related sequences.
+    CRef<CGCClient_AssembliesForSequences> FindAssembliesBySequences
+        (const list<string>& sequence_acc,
+         int filter,
+         CGCClient_GetAssemblyBySequenceRequest::ESort sort = CGCClient_GetAssemblyBySequenceRequest::eSort_default);
+
+
+
     CRef<CGCClient_EquivalentAssemblies> GetEquivalentAssemblies(const string& acc,
                                                                  int equivalency); // see CGCClient_GetEquivalentAssembliesRequest_::EEquivalency
 
@@ -159,6 +262,7 @@ private:
     CGenomicCollectionsService(const CGenomicCollectionsService& value);
     CGenomicCollectionsService& operator=(const CGenomicCollectionsService& value);
 
+    CRef<CGCClient_AssembliesForSequences> FindAssembliesBySequences(const list<string>& sequence_acc, int filter, CGCClient_GetAssemblyBySequenceRequest::ESort sort, bool top_only);
 };
 
 END_objects_SCOPE
diff --git a/c++/include/objects/id2/id2processor.hpp b/c++/include/objects/id2/id2processor.hpp
index fc9177e..c01d990 100644
--- a/c++/include/objects/id2/id2processor.hpp
+++ b/c++/include/objects/id2/id2processor.hpp
@@ -1,6 +1,6 @@
 #ifndef OBJECTS_ID2_ID2PROCESSOR_HPP
 #define OBJECTS_ID2_ID2PROCESSOR_HPP
-/*  $Id: id2processor.hpp 486265 2015-12-02 19:22:44Z vasilche $
+/*  $Id: id2processor.hpp 504899 2016-06-20 17:49:29Z vasilche $
 * ===========================================================================
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
@@ -50,8 +50,12 @@ public:
     virtual ~CID2ProcessorResolver(void);
 
     typedef vector<CConstRef<CSeq_id> > TIds;
+    typedef vector<CRef<CID2_Reply> > TReplies;
 
     virtual TIds GetIds(const CSeq_id& id) = 0;
+
+    virtual void ProcessPacket(TReplies& replies,
+                               CID2_Request_Packet& packet) = 0;
 };
 
 
diff --git a/c++/include/objects/macro/String_constraint.hpp b/c++/include/objects/macro/String_constraint.hpp
index 414e0f6..c16c724 100644
--- a/c++/include/objects/macro/String_constraint.hpp
+++ b/c++/include/objects/macro/String_constraint.hpp
@@ -1,4 +1,4 @@
-/* $Id: String_constraint.hpp 494819 2016-03-10 18:53:49Z ivanov $
+/* $Id: String_constraint.hpp 494536 2016-03-08 14:06:47Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objects/macro/Suspect_rule.hpp b/c++/include/objects/macro/Suspect_rule.hpp
index c419cbc..5baa8cc 100644
--- a/c++/include/objects/macro/Suspect_rule.hpp
+++ b/c++/include/objects/macro/Suspect_rule.hpp
@@ -1,4 +1,4 @@
-/* $Id: Suspect_rule.hpp 436428 2014-05-28 13:28:28Z chenj $
+/* $Id: Suspect_rule.hpp 514101 2016-09-19 15:56:13Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -48,9 +48,20 @@
 // generated classes
 
 BEGIN_NCBI_SCOPE
-
 BEGIN_objects_SCOPE // namespace ncbi::objects::
 
+// forward declarations
+class CConstraint_choice;
+class CConstraint_choice_set;
+class CField_constraint;
+class CField_type;
+class CLocation_constraint;
+class CLocation_pos_constraint;
+class CReplace_rule;
+class CSearch_func;
+class CSource_constraint;
+class CString_constraint;
+
 /////////////////////////////////////////////////////////////////////////////
 class CSuspect_rule : public CSuspect_rule_Base
 {
@@ -66,10 +77,25 @@ public:
 
     bool ApplyToString(string& val) const;
 
+    string GetRuleTypeName(void) const;
+    string SummarizeRule(void) const;
+    bool IsFatal(void) const { return GetFatal() || GetRule_type() == eFix_type_remove_organism_name || GetRule_type() == eFix_type_inappropriate_symbol;}
+
 private:
     // Prohibit copy constructor and assignment operator
     CSuspect_rule(const CSuspect_rule& value);
     CSuspect_rule& operator=(const CSuspect_rule& value);
+
+    string SummarizeSearchFunc(const CSearch_func&) const;
+    string SummarizeReplaceRule(const CReplace_rule&) const;
+    string SummarizeStringConstraint(const CString_constraint&) const;
+    string SummarizeConstraintSet(const CConstraint_choice_set&) const;
+    string SummarizeConstraint(const CConstraint_choice&) const;
+    string SummarizeLocationConstraint(const CLocation_constraint&) const;
+    string SummarizeEndDistance(const CLocation_pos_constraint&) const;
+    string SummarizeSourceConstraint(const CSource_constraint&) const;
+    string SummarizeFieldConstraint(const CField_constraint&) const;
+    string SummarizeFieldType(const CField_type&) const;
 };
 
 /////////////////// CSuspect_rule inline methods
diff --git a/c++/include/objects/seq/Seq_gap.hpp b/c++/include/objects/seq/Seq_gap.hpp
index de9b2df..86a69e2 100644
--- a/c++/include/objects/seq/Seq_gap.hpp
+++ b/c++/include/objects/seq/Seq_gap.hpp
@@ -1,4 +1,4 @@
-/* $Id: Seq_gap.hpp 499433 2016-04-26 14:13:30Z ivanov $
+/* $Id: Seq_gap.hpp 494120 2016-03-03 18:29:40Z gotvyans $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objects/seq/Seq_inst.hpp b/c++/include/objects/seq/Seq_inst.hpp
index 49f2191..d10cc3e 100644
--- a/c++/include/objects/seq/Seq_inst.hpp
+++ b/c++/include/objects/seq/Seq_inst.hpp
@@ -1,4 +1,4 @@
-/* $Id: Seq_inst.hpp 488736 2016-01-05 15:02:56Z choi $
+/* $Id: Seq_inst.hpp 518949 2016-11-09 16:44:19Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -66,6 +66,8 @@ public:
     // translate EMol to string
     static string GetMoleculeClass(EMol mol);
 
+    bool ConvertDeltaToRaw();
+
 private:
     // Prohibit copy constructor and assignment operator
     CSeq_inst(const CSeq_inst& value);
diff --git a/c++/include/objects/seq/Seq_literal.hpp b/c++/include/objects/seq/Seq_literal.hpp
index 7df80f8..8eee459 100644
--- a/c++/include/objects/seq/Seq_literal.hpp
+++ b/c++/include/objects/seq/Seq_literal.hpp
@@ -1,4 +1,4 @@
-/* $Id: Seq_literal.hpp 429786 2014-03-19 15:22:12Z mozese2 $
+/* $Id: Seq_literal.hpp 497282 2016-04-05 18:01:48Z kiryutin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -62,7 +62,10 @@ public:
     enum EBridgeableStatus { e_NotAGap, e_Bridgeable,
                              e_NotBridgeable, e_MaybeBridgeable };
 
-    EBridgeableStatus IsBridgeable() const;
+    EBridgeableStatus GetBridgeability() const;
+
+    // change the method name to GetBridgeability to make it clear
+    NCBI_DEPRECATED EBridgeableStatus IsBridgeable() const { return GetBridgeability(); }
 
 private:
     // Prohibit copy constructor and assignment operator
diff --git a/c++/include/objects/seq/seq_loc_mapper_base.hpp b/c++/include/objects/seq/seq_loc_mapper_base.hpp
index 058f4c3..73c0be7 100644
--- a/c++/include/objects/seq/seq_loc_mapper_base.hpp
+++ b/c++/include/objects/seq/seq_loc_mapper_base.hpp
@@ -1,7 +1,7 @@
 #ifndef SEQ_LOC_MAPPER_BASE__HPP
 #define SEQ_LOC_MAPPER_BASE__HPP
 
-/*  $Id: seq_loc_mapper_base.hpp 493266 2016-02-25 16:13:50Z ivanov $
+/*  $Id: seq_loc_mapper_base.hpp 505917 2016-06-29 20:22:14Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -82,9 +82,8 @@ public:
                   ENa_strand        dst_strand,
                   bool              ext_to = false,
                   int               frame = 0,
-                  TSeqPos           dst_total_len = kInvalidSeqPos,
                   TSeqPos           src_bioseq_len = kInvalidSeqPos,
-                  TSeqPos           dst_len = kInvalidSeqPos );
+                  TSeqPos           dst_len = kInvalidSeqPos);
 
     /// Check if the id is on the source sequence.
     bool GoodSrcId(const CSeq_id& id) const;
@@ -145,9 +144,6 @@ private:
     bool                m_ExtTo;
     // Holds the frame shift (0 if none) of the underlying CDS (if any).
     int                 m_Frame;
-    // Holds the complete length of the destination.  This is needed
-    // to detect whether or not fuzzy edges should be extended to the end.
-    TSeqPos             m_Dst_total_len;
     // This holds the complete length of the original source bioseq.
     // Needed to detect whether or not fuzzy edges should be extended to the end.
     TSeqPos             m_Src_bioseq_len;
@@ -278,6 +274,65 @@ private:
 
 /////////////////////////////////////////////////////////////////////////////
 ///
+///  CSeq_loc_Mapper_Options --
+///
+///  Options passed to CSeq_loc_Mapper[_Base] constructor.
+///
+
+class NCBI_SEQ_EXPORT CSeq_loc_Mapper_Options
+{
+public:
+    typedef int TMapOptions;
+
+    CSeq_loc_Mapper_Options(void);
+    CSeq_loc_Mapper_Options(IMapper_Sequence_Info* seq_info,
+                            TMapOptions opts = 0);
+    CSeq_loc_Mapper_Options(TMapOptions opts);
+
+    ///  Sequence type, length etc. provider. If any ids from the mapping
+    ///  ranges are not available through this object, they should be
+    ///  registered using CSeq_loc_Mapper_Base::SetSeqTypeById().
+    IMapper_Sequence_Info* GetMapperSequenceInfo(void) const;
+    CSeq_loc_Mapper_Options& SetMapperSequenceInfo(IMapper_Sequence_Info* seq_info);
+
+    /// Dense-seg mapping option.
+    /// @sa CSeq_loc_Mapper_Base::fAlign_Dense_seg_TotalRange
+    bool GetAlign_Dense_seg_TotalRange(void) const;
+    CSeq_loc_Mapper_Options& SetAlign_Dense_seg_TotalRange(bool value = true);
+
+    /// Mapping direction when mapping through a sparse-seg.
+    /// @sa CSeq_loc_Mapper_Base::fAlign_Sparse_ToFirst
+    /// @sa CSeq_loc_Mapper_Base::fAlign_Sparse_ToSecond
+    bool GetAlign_Sparse_ToFirst(void) const;
+    bool GetAlign_Sparse_ToSecond(void) const;
+    CSeq_loc_Mapper_Options& SetAlign_Sparse_ToFirst(bool value = true);
+    CSeq_loc_Mapper_Options& SetAlign_Sparse_ToSecond(bool value = true);
+
+    /// Mapping depth when using a seq-map, a bioseq or a GC-assembly.
+    /// @sa CSeq_loc_Mapper_Base::fMapSingleLevel
+    bool GetMapSingleLevel(void) const;
+    CSeq_loc_Mapper_Options& SetMapSingleLevel(bool value = true);
+
+    /// Mapped location trimming at sequence end. Off by default.
+    /// @sa CSeq_loc_Mapper_Base::fTrimMappedLocation
+    bool GetTrimMappedLocation(void) const;
+    CSeq_loc_Mapper_Options& SetTrimMappedLocation(bool value = true);
+
+private:
+    friend class CSeq_loc_Mapper_Base;
+
+    IMapper_Sequence_Info& GetSeqInfo(void) const;
+
+    bool x_IsSetOption(int opt) const;
+    void x_SetOption(int opt, bool enable);
+
+    mutable CRef<IMapper_Sequence_Info> m_SeqInfo;
+    TMapOptions m_Options;
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+///
 ///  CSeq_loc_Mapper_Base --
 ///
 ///  Mapping locations and alignments between bioseqs through seq-locs,
@@ -296,12 +351,12 @@ public:
     enum EMapOptions {
         /// Ignore internal dense-seg structure - map each
         /// dense-seg according to the total ranges involved
-        fAlign_Dense_seg_TotalRange = 0x01,
+        fAlign_Dense_seg_TotalRange = 1 << 0,
 
         /// Flags used to indicate mapping direction when mapping
         /// through a sparse-seg.
-        fAlign_Sparse_ToFirst       = 0x00, ///< Map to first-id
-        fAlign_Sparse_ToSecond      = 0x02, ///< Map to second-id
+        fAlign_Sparse_ToFirst       = 0,      ///< Map to first-id
+        fAlign_Sparse_ToSecond      = 1 << 1, ///< Map to second-id
         
         /// Flag used when mapping through a seq-map (this includes
         /// mapping through a bioseq or a GC-assembly). If set, each
@@ -309,7 +364,12 @@ public:
         /// mode which maps from any level as far up/down as possible.
         /// The result of mapping can be mapped further by making another
         /// call to Map().
-        fMapSingleLevel             = 0x04
+        fMapSingleLevel             = 1 << 2,
+
+        /// Enable trimming of source/destination ranges at sequence end.
+        /// By default locations can stretch beyond sequence end. With trimming
+        /// enabled the mapper will truncate ranges to fit sequence lengths.
+        fTrimMappedLocation         = 1 << 3
     };
     typedef int TMapOptions;
 
@@ -337,40 +397,48 @@ public:
     ///  NOTE: If the mapper is used with mixed sequence types, the
     ///  ranges must use genomic coordinates (for ranges on proteins
     ///  multiply all coordinates by 3).
-    /// @param seq_info
-    ///  Sequence type, length etc. provider. If any ids from the mapping
-    ///  ranges are not available through this object, they must be
-    ///  registered using SetSeqTypeById.
-    /// @sa IMapper_Sequence_Info
-    /// @sa SetSeqTypeById
-    CSeq_loc_Mapper_Base(CMappingRanges*        mapping_ranges,
-                         IMapper_Sequence_Info* seq_info = 0);
+    /// @param options
+    ///  Mapping options which need to be set during mapper initialization.
+    /// @sa CSeq_loc_Mapper_Options
+    CSeq_loc_Mapper_Base(CMappingRanges*         mapping_ranges,
+                         CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
 
     /// Mapping through a feature, both location and product must be set.
-    CSeq_loc_Mapper_Base(const CSeq_feat&       map_feat,
-                         EFeatMapDirection      dir,
-                         IMapper_Sequence_Info* seq_info = 0);
+    CSeq_loc_Mapper_Base(const CSeq_feat&        map_feat,
+                         EFeatMapDirection       dir,
+                         CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
 
     /// Mapping between two seq_locs.
-    CSeq_loc_Mapper_Base(const CSeq_loc&        source,
-                         const CSeq_loc&        target,
-                         IMapper_Sequence_Info* seq_info = 0);
+    CSeq_loc_Mapper_Base(const CSeq_loc&         source,
+                         const CSeq_loc&         target,
+                         CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
 
     /// Mapping through an alignment. Need to specify target ID or
     /// target row of the alignment. Any other ID is mapped to the
     /// target one. Only the first row matching target ID is used,
     /// all other rows are considered source.
+    CSeq_loc_Mapper_Base(const CSeq_align&       map_align,
+                         const CSeq_id&          to_id,
+                         CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
+    /// @deprecated Use the version with CSeq_loc_Mapper_Options instead.
+    NCBI_DEPRECATED
     CSeq_loc_Mapper_Base(const CSeq_align&      map_align,
                          const CSeq_id&         to_id,
-                         TMapOptions            opts = 0,
-                         IMapper_Sequence_Info* seq_info = 0);
+                         TMapOptions            opts,
+                         IMapper_Sequence_Info* seq_info);
+
     /// Sparse alignments require special row indexing since each
     /// row contains two seq-ids. Use options to specify mapping
     /// direction.
+    CSeq_loc_Mapper_Base(const CSeq_align&       map_align,
+                         size_t                  to_row,
+                         CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
+    /// @deprecated Use the version with CSeq_loc_Mapper_Options instead.
+    NCBI_DEPRECATED
     CSeq_loc_Mapper_Base(const CSeq_align&      map_align,
                          size_t                 to_row,
-                         TMapOptions            opts = 0,
-                         IMapper_Sequence_Info* seq_info = 0);
+                         TMapOptions            opts,
+                         IMapper_Sequence_Info* seq_info);
 
     ~CSeq_loc_Mapper_Base(void);
 
@@ -568,7 +636,6 @@ protected:
                             const CInt_fuzz* fuzz_from = 0,
                             const CInt_fuzz* fuzz_to = 0,
                             int              frame = 0,
-                            TSeqPos          dst_total_len = kInvalidSeqPos,
                             TSeqPos          src_bioseq_len = kInvalidSeqPos);
 
     // Add new CMappingRange. This includes collecting all synonyms for the id,
@@ -583,7 +650,6 @@ protected:
                          TSeqPos        length,
                          bool           ext_right,
                          int            frame,
-                         TSeqPos        dst_total_len,
                          TSeqPos        src_bioseq_len,
                          TSeqPos        dst_length );
 
@@ -882,14 +948,11 @@ protected:
     // Control how fuzz is generated and propagated
     TFuzzOption          m_FuzzOption;
     // Misc mapping options
-    TMapOptions          m_MapOptions;
-
-    // Sequence info provider
-    mutable CRef<IMapper_Sequence_Info> m_SeqInfo;
+    CSeq_loc_Mapper_Options m_MapOptions;
 
 public:
     // Initialize the mapper with default values
-    CSeq_loc_Mapper_Base(IMapper_Sequence_Info* seqinfo = 0);
+    CSeq_loc_Mapper_Base(CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
 
     /// Methods for getting sequence types, use cached types (m_SeqTypes)
     /// if possible.
@@ -1249,6 +1312,122 @@ int CSeq_loc_Mapper_Base::GetWidthById(const CSeq_id& id) const
 }
 
 
+inline
+CSeq_loc_Mapper_Options::CSeq_loc_Mapper_Options(void)
+    : m_SeqInfo(0), m_Options(0) {}
+
+inline
+CSeq_loc_Mapper_Options::CSeq_loc_Mapper_Options(IMapper_Sequence_Info* seq_info,
+                                                 TMapOptions            opts)
+    : m_SeqInfo(seq_info), m_Options(opts) {}
+
+inline
+CSeq_loc_Mapper_Options::CSeq_loc_Mapper_Options(TMapOptions opts)
+    : m_SeqInfo(0), m_Options(opts) {}
+
+inline
+IMapper_Sequence_Info*
+CSeq_loc_Mapper_Options::GetMapperSequenceInfo(void) const
+{
+    return m_SeqInfo;
+}
+
+inline
+CSeq_loc_Mapper_Options&
+CSeq_loc_Mapper_Options::SetMapperSequenceInfo(IMapper_Sequence_Info* seq_info)
+{
+    m_SeqInfo = seq_info;
+    return *this;
+}
+
+inline
+bool CSeq_loc_Mapper_Options::GetAlign_Dense_seg_TotalRange(void) const
+{
+    return x_IsSetOption(CSeq_loc_Mapper_Base::fAlign_Dense_seg_TotalRange);
+}
+
+inline
+CSeq_loc_Mapper_Options&
+CSeq_loc_Mapper_Options::SetAlign_Dense_seg_TotalRange(bool value)
+{
+    x_SetOption(CSeq_loc_Mapper_Base::fAlign_Dense_seg_TotalRange, value);
+    return *this;
+}
+
+inline
+bool CSeq_loc_Mapper_Options::GetAlign_Sparse_ToFirst(void) const
+{
+    return !x_IsSetOption(CSeq_loc_Mapper_Base::fAlign_Sparse_ToSecond);
+}
+
+inline
+bool CSeq_loc_Mapper_Options::GetAlign_Sparse_ToSecond(void) const
+{
+    return x_IsSetOption(CSeq_loc_Mapper_Base::fAlign_Sparse_ToSecond);
+}
+
+inline
+CSeq_loc_Mapper_Options&
+CSeq_loc_Mapper_Options::SetAlign_Sparse_ToFirst(bool value)
+{
+    x_SetOption(CSeq_loc_Mapper_Base::fAlign_Sparse_ToSecond, !value);
+    return *this;
+}
+
+inline
+CSeq_loc_Mapper_Options&
+CSeq_loc_Mapper_Options::SetAlign_Sparse_ToSecond(bool value)
+{
+    x_SetOption(CSeq_loc_Mapper_Base::fAlign_Sparse_ToSecond, value);
+    return *this;
+}
+
+inline
+bool CSeq_loc_Mapper_Options::GetMapSingleLevel(void) const
+{
+    return x_IsSetOption(CSeq_loc_Mapper_Base::fMapSingleLevel);
+}
+
+inline
+CSeq_loc_Mapper_Options&
+CSeq_loc_Mapper_Options::SetMapSingleLevel(bool value)
+{
+    x_SetOption(CSeq_loc_Mapper_Base::fMapSingleLevel, value);
+    return *this;
+}
+
+inline
+bool CSeq_loc_Mapper_Options::GetTrimMappedLocation(void) const
+{
+    return x_IsSetOption(CSeq_loc_Mapper_Base::fTrimMappedLocation);
+}
+
+inline
+CSeq_loc_Mapper_Options&
+CSeq_loc_Mapper_Options::SetTrimMappedLocation(bool value)
+{
+    x_SetOption(CSeq_loc_Mapper_Base::fTrimMappedLocation, value);
+    return *this;
+}
+
+inline
+bool CSeq_loc_Mapper_Options::x_IsSetOption(int opt) const
+{
+    return (m_Options & opt) != 0;
+}
+
+inline
+void CSeq_loc_Mapper_Options::x_SetOption(int opt, bool enable)
+{
+    if ( enable ) {
+        m_Options |= opt;
+    }
+    else {
+        m_Options &= ~opt;
+    }
+}
+
+
 /* @} */
 
 
diff --git a/c++/include/objects/seq/sofa_map.hpp b/c++/include/objects/seq/sofa_map.hpp
index 1dbb5d2..08c7517 100644
--- a/c++/include/objects/seq/sofa_map.hpp
+++ b/c++/include/objects/seq/sofa_map.hpp
@@ -1,4 +1,4 @@
-/*  $Id: sofa_map.hpp 496057 2016-03-23 15:31:16Z ivanov $
+/*  $Id: sofa_map.hpp 493092 2016-02-24 12:36:34Z ludwigf $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objects/seqfeat/BioSource.hpp b/c++/include/objects/seqfeat/BioSource.hpp
index f283d15..4812637 100644
--- a/c++/include/objects/seqfeat/BioSource.hpp
+++ b/c++/include/objects/seqfeat/BioSource.hpp
@@ -1,4 +1,4 @@
-/* $Id: BioSource.hpp 488225 2015-12-28 20:52:28Z kans $
+/* $Id: BioSource.hpp 512289 2016-08-29 18:14:36Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -40,6 +40,7 @@
 
 // generated includes
 #include <objects/seqfeat/BioSource_.hpp>
+#include <objects/seqfeat/SubSource.hpp>
 
 // generated classes
 
@@ -49,6 +50,7 @@ BEGIN_objects_SCOPE // namespace ncbi::objects::
 
 class COrgName;
 class CFieldDiff;
+class CSubSource;
 
 typedef vector< CRef<CFieldDiff> > TFieldDiffList;
 
@@ -135,6 +137,40 @@ public:
     bool RemoveSubSource(int subtype);
     bool RemoveOrgMod(int subtype);
 
+    //If taxname starts with uncultured, set environmental-sample to true
+    //If metagenomic, set environmental_sample
+    //    Add environmental_sample to BioSource if BioSource.org.orgname.div == "ENV"
+    //    Add metagenomic(and environmental_sample) if BioSource.org.orgname.lineage contains "metagenomes"
+    //    Add metagenomic(and environmental_sample) if BioSource has / metagenome_source qualifier
+    // returns true if change was made
+    bool FixEnvironmentalSample();
+
+    // Remove null terms from SubSource values and OrgMod values
+    bool RemoveNullTerms();
+
+    // do not allow sex qualifier if virus, bacteria, Archaea, or fungus
+    static bool AllowSexQualifier(const string& lineage);
+    bool AllowSexQualifier() const;
+
+    // do not allow mating_type qualifier if animal, plant, or virus
+    static bool AllowMatingTypeQualifier(const string& lineage);
+    bool AllowMatingTypeQualifier() const;
+
+    //Remove /sex qualifier from virus, bacteria, archaea, fungus organisms
+    //Remove /mating_type qualifier from animal, plant, and virus organisms
+    //Move /mating_type qualifier that is valid /sex qualifier word to /sex qualifier
+    bool FixSexMatingTypeInconsistencies();
+
+    //Remove qualifiers not appropriate for virus organisms from Virus organisms
+    bool RemoveUnexpectedViralQualifiers();
+
+    bool FixGenomeForQualifiers();
+
+    static bool IsViral(const string& lineage);
+    bool IsViral() const;
+
+    bool HasSubtype(CSubSource::TSubtype subtype) const;
+
     CRef<CBioSource> MakeCommon( const CBioSource& other) const;
 
 private:
diff --git a/c++/include/objects/seqfeat/Delta_item.hpp b/c++/include/objects/seqfeat/Delta_item.hpp
new file mode 100644
index 0000000..d9ff406
--- /dev/null
+++ b/c++/include/objects/seqfeat/Delta_item.hpp
@@ -0,0 +1,94 @@
+/* $Id: Delta_item.hpp 492313 2016-02-16 18:52:15Z foleyjp $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ */
+
+/// @file Delta_item.hpp
+/// User-defined methods of the data storage class.
+///
+/// This file was originally generated by application DATATOOL
+/// using the following specifications:
+/// 'seqfeat.asn'.
+///
+/// New methods or data members can be added to it if needed.
+/// See also: Delta_item_.hpp
+
+
+#ifndef OBJECTS_SEQFEAT_DELTA_ITEM_HPP
+#define OBJECTS_SEQFEAT_DELTA_ITEM_HPP
+
+
+#include <objects/seq/IUPACna.hpp>
+
+// generated includes
+#include <objects/seqfeat/Delta_item_.hpp>
+
+// generated classes
+
+BEGIN_NCBI_SCOPE
+
+BEGIN_objects_SCOPE // namespace ncbi::objects::
+
+/////////////////////////////////////////////////////////////////////////////
+class NCBI_SEQFEAT_EXPORT CDelta_item : public CDelta_item_Base
+{
+    typedef CDelta_item_Base Tparent;
+public:
+    // constructor
+    CDelta_item(void);
+    // destructor
+    ~CDelta_item(void);
+
+    void SetDeletion(void);
+    void SetDuplication(void);
+    void SetInsertion(const CIUPACna& sequence,
+                      TSeqPos seq_length=0); 
+
+private:
+    // Prohibit copy constructor and assignment operator
+    CDelta_item(const CDelta_item& value);
+    CDelta_item& operator=(const CDelta_item& value);
+
+};
+
+/////////////////// CDelta_item inline methods
+
+// constructor
+inline
+CDelta_item::CDelta_item(void)
+{
+}
+
+
+/////////////////// end of CDelta_item inline methods
+
+
+END_objects_SCOPE // namespace ncbi::objects::
+
+END_NCBI_SCOPE
+
+
+#endif // OBJECTS_SEQFEAT_DELTA_ITEM_HPP
+/* Original file checksum: lines: 86, chars: 2435, CRC32: be4d21ba */
diff --git a/c++/include/objects/seqfeat/Gb_qual.hpp b/c++/include/objects/seqfeat/Gb_qual.hpp
index db820dc..fb5710a 100644
--- a/c++/include/objects/seqfeat/Gb_qual.hpp
+++ b/c++/include/objects/seqfeat/Gb_qual.hpp
@@ -1,4 +1,4 @@
-/* $Id: Gb_qual.hpp 493884 2016-03-02 14:18:51Z ivanov $
+/* $Id: Gb_qual.hpp 514391 2016-09-21 15:38:23Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -87,6 +87,10 @@ public:
     static const TLegalPseudogeneSet &GetSetOfLegalPseudogenes(void);
     static bool IsValidPseudogeneValue(const string& val);
 
+    // for misc_recomb qualifiers
+    typedef CStaticArraySet<const char *, PNocase_CStr> TLegalRecombinationClassSet;
+    static const TLegalRecombinationClassSet &GetSetOfLegalRecombinationClassValues(void);
+
     static bool IsLegalMobileElementValue(const string& val);
     static void GetMobileElementValueElements(const string& val, string& element_type, string& element_name);
 
diff --git a/c++/include/objects/seqfeat/OrgMod.hpp b/c++/include/objects/seqfeat/OrgMod.hpp
index db6460f..716a84b 100644
--- a/c++/include/objects/seqfeat/OrgMod.hpp
+++ b/c++/include/objects/seqfeat/OrgMod.hpp
@@ -1,4 +1,4 @@
-/* $Id: OrgMod.hpp 462584 2015-03-19 16:38:52Z kachalos $
+/* $Id: OrgMod.hpp 515540 2016-10-03 16:03:50Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -77,7 +77,7 @@ public:
     static bool IsValidSubtypeName(const string& str, 
                                    EVocabulary vocabulary = eVocabulary_raw);
 
-    static bool IsDiscouraged(const TSubtype stype);
+    static bool IsDiscouraged(const TSubtype stype, bool indexer=false);
     static bool IsMultipleValuesAllowed(TSubtype);
 
     /// This indicates if the given Org-mod subtype is supposed to hold an 
@@ -102,6 +102,7 @@ public:
 
     static string FixStrain( const string& strain);
     static bool FuzzyStrainMatch( const string& strain1, const string& strain2 );
+    static bool IsStrainValid(const string& strain);
 
     static string FixHost(const string& value);
     static string FixHostCapitalization(const string& value);
@@ -111,6 +112,14 @@ public:
     static string AutoFix(TSubtype subtype, const string& value);
     void AutoFix();
 
+    // Remove "subsp. " and "serovar " from start of strain
+    // Remove "subsp. " and "serovar " from start of serovar
+    // Remove "subsp. " from start of sub-species qualifier
+    bool RemoveAbbreviation();
+
+    static bool IsUnexpectedViralOrgModQualifier(TSubtype subtype);
+    bool IsUnexpectedViralOrgModQualifier() const;
+
     private:
     // Prohibit copy constructor and assignment operator
     COrgMod(const COrgMod& value);
diff --git a/c++/include/objects/seqfeat/SeqFeatData.hpp b/c++/include/objects/seqfeat/SeqFeatData.hpp
index ce4ff5d..96c85f9 100644
--- a/c++/include/objects/seqfeat/SeqFeatData.hpp
+++ b/c++/include/objects/seqfeat/SeqFeatData.hpp
@@ -1,4 +1,4 @@
-/* $Id: SeqFeatData.hpp 477822 2015-09-02 12:03:07Z bollin $
+/* $Id: SeqFeatData.hpp 514392 2016-09-21 15:38:46Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -230,7 +230,8 @@ public:
         eSubtype_telomere           = 101,
         eSubtype_assembly_gap       = 102,
         eSubtype_regulatory         = 103,
-        eSubtype_max                = 104,
+        eSubtype_propeptide         = 104,  // Prot-ref propeptide
+        eSubtype_max                = 105,
         eSubtype_any                = 255
     };
     ESubtype GetSubtype(void) const;
@@ -410,6 +411,7 @@ public:
         eQual_pseudo,
         eQual_pseudogene,
         eQual_rearranged,
+        eQual_recombination_class,
         eQual_region_name,
         eQual_regulatory_class,
         eQual_replace,
@@ -483,6 +485,7 @@ public:
     static bool IsRegulatory(ESubtype subtype);
     static const string & GetRegulatoryClass(ESubtype subtype);
     static ESubtype GetRegulatoryClass(const string & class_name );
+    static vector<string> GetRegulatoryClassList();
 
     static bool IsDiscouragedSubtype(ESubtype subtype);
     static bool IsDiscouragedQual(EQualifier qual);
@@ -503,6 +506,11 @@ public:
     static bool ShouldRepresentAsGbqual (CSeqFeatData::ESubtype feat_subtype, const CGb_qual& qual);
     static bool ShouldRepresentAsGbqual (CSeqFeatData::ESubtype feat_subtype, CSeqFeatData::EQualifier qual_type);
 
+    static void s_InitXrefAllowedSubtypesTable(void);
+    static void s_InitXrefProhibitedSubtypesTable(void);
+    static bool AllowXref(CSeqFeatData::ESubtype subtype1, CSeqFeatData::ESubtype subtype2);
+    static bool ProhibitXref(CSeqFeatData::ESubtype subtype1, CSeqFeatData::ESubtype subtype2);
+
     // Internal structure to hold additional info
     struct SFeatDataInfo
     {
diff --git a/c++/include/objects/seqfeat/Seq_feat.hpp b/c++/include/objects/seqfeat/Seq_feat.hpp
index 7e28ec5..1b27e25 100644
--- a/c++/include/objects/seqfeat/Seq_feat.hpp
+++ b/c++/include/objects/seqfeat/Seq_feat.hpp
@@ -1,4 +1,4 @@
-/* $Id: Seq_feat.hpp 490392 2016-01-25 17:20:58Z bollin $
+/* $Id: Seq_feat.hpp 518385 2016-11-02 17:27:05Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -45,6 +45,7 @@
 #include <objects/seqfeat/Prot_ref.hpp>
 #include <objects/seqfeat/SeqFeatData.hpp>
 #include <objects/seqloc/Seq_loc.hpp>
+#include <objects/seqfeat/SeqFeatXref.hpp>
 
 // generated classes
 
@@ -78,6 +79,9 @@ public:
     void SetProtXref(CProt_ref& value);
     CProt_ref& SetProtXref(void);
 
+    bool HasSeqFeatXref(const CSeqFeatXref::TId& id) const;
+    bool AddSeqFeatXref(const CSeqFeatXref::TId& id);
+
     /// Add a qualifier to this feature
     void AddQualifier(const string& qual_name, const string& qual_val);
 
diff --git a/c++/include/objects/seqfeat/SubSource.hpp b/c++/include/objects/seqfeat/SubSource.hpp
index 400dc71..3a3ce22 100644
--- a/c++/include/objects/seqfeat/SubSource.hpp
+++ b/c++/include/objects/seqfeat/SubSource.hpp
@@ -1,4 +1,4 @@
-/* $Id: SubSource.hpp 493853 2016-03-02 14:07:56Z ivanov $
+/* $Id: SubSource.hpp 502999 2016-05-31 15:35:13Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -208,6 +208,7 @@ public:
     static string AutoFix(TSubtype subtype, const string& value);
     void AutoFix();
 
+    static bool HasCultureNotes(const string& value);
     static void RemoveCultureNotes(string& value, bool is_species_level = true);
     void RemoveCultureNotes(bool is_species_level = true);
 
diff --git a/c++/include/objects/seqfeat/Trna_ext.hpp b/c++/include/objects/seqfeat/Trna_ext.hpp
index 3bd2dc0..b206bb5 100644
--- a/c++/include/objects/seqfeat/Trna_ext.hpp
+++ b/c++/include/objects/seqfeat/Trna_ext.hpp
@@ -1,4 +1,4 @@
-/* $Id: Trna_ext.hpp 500111 2016-05-02 15:51:42Z ivanov $
+/* $Id: Trna_ext.hpp 499339 2016-04-25 18:08:43Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objects/seqfeat/Variation_ref.hpp b/c++/include/objects/seqfeat/Variation_ref.hpp
index 877a242..8d0f673 100644
--- a/c++/include/objects/seqfeat/Variation_ref.hpp
+++ b/c++/include/objects/seqfeat/Variation_ref.hpp
@@ -1,4 +1,4 @@
-/* $Id: Variation_ref.hpp 341186 2011-10-17 21:23:07Z dicuccio $
+/* $Id: Variation_ref.hpp 492328 2016-02-16 19:46:22Z foleyjp $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -39,6 +39,9 @@
 #ifndef OBJECTS_SEQFEAT_VARIATION_REF_HPP
 #define OBJECTS_SEQFEAT_VARIATION_REF_HPP
 
+#include <objects/seq/Seq_data.hpp>
+#include <objects/seqfeat/Delta_item.hpp>
+#include <objects/seq/Seq_data.hpp>
 
 // generated includes
 #include <objects/seqfeat/Variation_ref_.hpp>
@@ -68,6 +71,23 @@ public:
     /// PostRead() hooks to establish correct, non-deprecated data layout
     void PostRead();
 
+
+    void SetSNV(const CSeq_data& nucleotide, 
+                CRef<CDelta_item> offset=null);
+
+    void SetMNP(const CSeq_data& nucleotide, 
+                TSeqPos length,
+                CRef<CDelta_item> offset=null);
+
+    void SetMissense(const CSeq_data& amino_acid);
+
+    void SetDuplication(CRef<CDelta_item> start_offset=null,
+                        CRef<CDelta_item> stop_offset=null);
+
+    void SetIdentity(CRef<CSeq_literal> seq_literal,
+                     CRef<CDelta_item> start_offset=null,
+                     CRef<CDelta_item> stop_offset=null);
+
     /// Set a standard single nucleotide variant.  The replaces set can include
     /// empty strings and/or '-' as a character to indicate a deletion.
     void SetSNV(const vector<string>& replaces,
diff --git a/c++/include/objects/seqloc/Seq_loc.hpp b/c++/include/objects/seqloc/Seq_loc.hpp
index 2e71381..b8c7d3e 100644
--- a/c++/include/objects/seqloc/Seq_loc.hpp
+++ b/c++/include/objects/seqloc/Seq_loc.hpp
@@ -1,4 +1,4 @@
-/* $Id: Seq_loc.hpp 496694 2016-03-30 14:14:36Z ivanov $
+/* $Id: Seq_loc.hpp 495960 2016-03-22 19:19:34Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -113,7 +113,7 @@ public:
     // destructor
     virtual ~CSeq_loc(void);
 
-    /// See related functions in util/sequence.hpp:
+    /// See related functions in objmgr/util/seq_loc_util.hpp:
     ///
     ///   TSeqPos GetLength(const CSeq_loc&, CScope*)
     ///   bool IsOneBioseq(const CSeq_loc&, CScope*)
@@ -127,7 +127,7 @@ public:
 
     TRange GetTotalRange(void) const;
     void InvalidateTotalRangeCache(void) const;
- 
+
     /// Check if strand is set for any/all part(s) of the seq-loc
     /// depending on the flag.
     bool IsSetStrand(EIsSetStrand flag = eIsSetStrand_Any) const;
@@ -259,7 +259,7 @@ public:
     /// Minus strand locations' order is reversed.
     /// Seq-ids are not checked in this method, unless you set
     /// filter, which will allow the user to pick which parts to skip.
-    int CompareSubLoc(const CSeq_loc& loc, ENa_strand strand, 
+    int CompareSubLoc(const CSeq_loc& loc, ENa_strand strand,
         const ISubLocFilter *filter = NULL) const;
 
     /// Simple adding of seq-locs.
@@ -530,7 +530,7 @@ public:
     /// or GetEmbeddingSeq_loc instead.
     NCBI_DEPRECATED const CSeq_loc& GetSeq_loc(void) const;
 
-    // Return null if non-fuzzy 
+    // Return null if non-fuzzy
     const CInt_fuzz* GetFuzzFrom(void) const;
     const CInt_fuzz* GetFuzzTo  (void) const;
 
@@ -765,7 +765,7 @@ public:
         /// C. the insertion point is in the middle of existing part
         /// then the existing part will be split at the insertion point
         /// and new element will be added to the second part after splitting.
-        /// 
+        ///
         /// The mode will switch to eEquiv_append after the insertion.
         eEquiv_new_part,
 
@@ -868,14 +868,14 @@ void CSeq_loc::InvalidateTotalRangeCache(void) const
 }
 
 
-inline 
+inline
 void CSeq_loc::InvalidateIdCache(void) const
 {
     m_IdCache = NULL;
 }
 
 
-inline 
+inline
 void CSeq_loc::InvalidateCache(void) const
 {
     InvalidateTotalRangeCache();
@@ -976,7 +976,7 @@ DEFINE_NCBI_SEQ_LOC_SETTERS(Feat)
 inline
 bool CSeq_loc::IsReverseStrand(void) const
 {
-    return IsReverse(GetStrand());    
+    return IsReverse(GetStrand());
 }
 
 
diff --git a/c++/include/objects/seqset/Bioseq_set.hpp b/c++/include/objects/seqset/Bioseq_set.hpp
index 867f666..c866e61 100644
--- a/c++/include/objects/seqset/Bioseq_set.hpp
+++ b/c++/include/objects/seqset/Bioseq_set.hpp
@@ -1,4 +1,4 @@
-/* $Id: Bioseq_set.hpp 132506 2008-06-30 18:09:32Z kans $
+/* $Id: Bioseq_set.hpp 519216 2016-11-14 16:06:08Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -86,6 +86,9 @@ public:
     const CBioseq& GetGenomicFromGenProdSet(void) const;
     const CBioseq& GetMasterFromSegSet(void) const;
 
+    bool NeedsDocsumTitle() const;
+    static bool NeedsDocsumTitle(EClass set_class);
+
 private:
     // Prohibit copy constructor & assignment operator
     CBioseq_set(const CBioseq_set&);
diff --git a/c++/include/objects/taxon1/Taxon2_data.hpp b/c++/include/objects/taxon1/Taxon2_data.hpp
index 465a50d..b08e8af 100644
--- a/c++/include/objects/taxon1/Taxon2_data.hpp
+++ b/c++/include/objects/taxon1/Taxon2_data.hpp
@@ -1,4 +1,4 @@
-/* $Id: Taxon2_data.hpp 454834 2014-12-18 16:56:57Z domrach $
+/* $Id: Taxon2_data.hpp 494538 2016-03-08 14:31:04Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objects/taxon1/taxon1.hpp b/c++/include/objects/taxon1/taxon1.hpp
index 03f9358..d985b61 100644
--- a/c++/include/objects/taxon1/taxon1.hpp
+++ b/c++/include/objects/taxon1/taxon1.hpp
@@ -1,7 +1,7 @@
 #ifndef NCBI_TAXON1_HPP
 #define NCBI_TAXON1_HPP
 
-/* $Id: taxon1.hpp 488663 2016-01-04 18:15:48Z domrach $
+/* $Id: taxon1.hpp 497983 2016-04-12 17:06:15Z domrach $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -607,6 +607,11 @@ public:
     //          false otherwise
     virtual bool             IsRoot() const = 0;
 
+    //-------------------------------------------------
+    // Returns: true if node is hidden in the GenBank lineage,
+    //          false otherwise
+    virtual bool             IsGenBankHidden() const = 0;
+   
 };
 
 //-------------------------------------------------
diff --git a/c++/include/objects/trackmgr/TMgr_ClientInfo.hpp b/c++/include/objects/trackmgr/TMgr_ClientInfo.hpp
index afe0b0f..5d0c88a 100644
--- a/c++/include/objects/trackmgr/TMgr_ClientInfo.hpp
+++ b/c++/include/objects/trackmgr/TMgr_ClientInfo.hpp
@@ -1,4 +1,4 @@
-/* $Id: TMgr_ClientInfo.hpp 441154 2014-07-21 19:21:04Z clausen $
+/* $Id: TMgr_ClientInfo.hpp 494538 2016-03-08 14:31:04Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objects/trackmgr/TMgr_DTrackId.hpp b/c++/include/objects/trackmgr/TMgr_DTrackId.hpp
index 89505e6..27b2902 100755
--- a/c++/include/objects/trackmgr/TMgr_DTrackId.hpp
+++ b/c++/include/objects/trackmgr/TMgr_DTrackId.hpp
@@ -1,4 +1,4 @@
-/* $Id: TMgr_DTrackId.hpp 414270 2013-09-23 13:00:48Z meric $
+/* $Id: TMgr_DTrackId.hpp 498695 2016-04-19 04:42:31Z meric $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -51,14 +51,17 @@ BEGIN_objects_SCOPE // namespace ncbi::objects::
 class NCBI_TRACKMGR_EXPORT CTMgr_DTrackId : public CTMgr_DTrackId_Base
 {
     typedef CTMgr_DTrackId_Base Tparent;
+
 public:
-    CTMgr_DTrackId(void) {}
+    CTMgr_DTrackId(void)
+    {
+    }
 
-    static CRef<CTMgr_DTrackId> FromTrackIdString(const string& track_id)
+    static CRef<CTMgr_DTrackId> FromTrackIdString(const string& track_id, const string& db = "TMS")
     {
-        CRef<CTMgr_DTrackId> id(new CTMgr_DTrackId());
+        auto id = Ref(new CTMgr_DTrackId());
         CDbtag& tag = id->Set();
-        tag.SetDb("TMS");
+        tag.SetDb(db);
         tag.SetTag().SetStr(track_id);
         return id;
     }
diff --git a/c++/include/objects/trackmgr/displaytrack_client.hpp b/c++/include/objects/trackmgr/displaytrack_client.hpp
index 82c04d3..ba092f1 100644
--- a/c++/include/objects/trackmgr/displaytrack_client.hpp
+++ b/c++/include/objects/trackmgr/displaytrack_client.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_TRACKMGR_GRIDCLI__DISPLAY_TRACK_CLIENT_HPP
 #define OBJECTS_TRACKMGR_GRIDCLI__DISPLAY_TRACK_CLIENT_HPP
 
-/* $Id: displaytrack_client.hpp 488465 2015-12-30 23:55:06Z meric $
+/* $Id: displaytrack_client.hpp 506052 2016-06-30 21:39:40Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -36,6 +36,8 @@
 /// NetSchedule grid client for TrackManager display-track request/reply
 
 #include <objects/trackmgr/gridrpcclient.hpp>
+#include <connect/ncbi_http_session.hpp>
+#include <serial/rpcbase.hpp>
 
 
 BEGIN_NCBI_SCOPE
@@ -49,13 +51,23 @@ END_SCOPE(objects)
 class CTMS_DisplayTrack_Client : private CGridRPCBaseClient<CAsnBinCompressed>
 {
 private:
-    typedef CGridRPCBaseClient<ncbi::CAsnBinCompressed> TBaseClient;
+    using TBaseClient = CGridRPCBaseClient<ncbi::CAsnBinCompressed>;
+
+    struct HttpService
+    {
+        explicit HttpService(const string& svc)
+            : service(svc)
+        {
+        }
+        string service;
+    };
+
 
 public:
-    typedef objects::CTMgr_DisplayTrackRequest TRequest;
-    typedef objects::CTMgr_DisplayTrackReply TReply;
-    typedef CConstRef<TRequest> TRequestCRef;
-    typedef CRef<TReply> TReplyRef;
+    using TRequest = objects::CTMgr_DisplayTrackRequest;
+    using TReply = objects::CTMgr_DisplayTrackReply;
+    using TRequestCRef = CConstRef<TRequest>;
+    using TReplyRef = CRef<TReply>;
 
 public:
     CTMS_DisplayTrack_Client(const string& NS_service,
@@ -67,10 +79,31 @@ public:
     CTMS_DisplayTrack_Client(const string& NS_registry_section = "netschedule_api",
                              const string& NC_registry_section = kEmptyStr
                             );
+    CTMS_DisplayTrack_Client(CTMS_DisplayTrack_Client&& c)
+        : TBaseClient(move(c)),
+          m_Http_svc(move(c.m_Http_svc)),
+          m_Http_session(move(c.m_Http_session)),
+          m_Rpc_client(move(c.m_Rpc_client))
+    {
+    }
+    virtual ~CTMS_DisplayTrack_Client() = default;
 
-    virtual ~CTMS_DisplayTrack_Client();
+    static CTMS_DisplayTrack_Client CreateServiceClient(const string& http_svc = "TMS_DisplayTracks");
 
     TReplyRef Fetch(const TRequest& request) const;
+    bool FetchRawStream(CNcbiIstream& requeststr, CNcbiOstream& replystr) const;
+
+protected:
+    CTMS_DisplayTrack_Client(CTMS_DisplayTrack_Client&) = delete;
+    CTMS_DisplayTrack_Client(const HttpService&& http_svc);
+    TReplyRef x_HttpFetch(const TRequest& request) const;
+
+
+protected:
+    CUrl m_Http_svc;
+    mutable CRef<CHttpSession> m_Http_session;
+    using TRPCBaseClient = CGridRPCHttpClient<TRequest, TReply>;
+    mutable CRef<TRPCBaseClient> m_Rpc_client;
 };
 
 
diff --git a/c++/include/objects/trackmgr/gridrpcclient.hpp b/c++/include/objects/trackmgr/gridrpcclient.hpp
index 2619a99..e2d4a0f 100644
--- a/c++/include/objects/trackmgr/gridrpcclient.hpp
+++ b/c++/include/objects/trackmgr/gridrpcclient.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_MISC_SERIAL___GRID_RPC_CLIENT__HPP
 #define OBJECTS_MISC_SERIAL___GRID_RPC_CLIENT__HPP
 
-/* $Id: gridrpcclient.hpp 489744 2016-01-15 16:50:24Z sadyrovr $
+/* $Id: gridrpcclient.hpp 514371 2016-09-21 15:22:54Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -38,6 +38,7 @@
 #include <serial/serial.hpp>
 #include <serial/objistr.hpp>
 #include <serial/objostr.hpp>
+#include <serial/rpcbase.hpp>
 #include <connect/services/grid_worker_app.hpp>
 #include <connect/services/grid_rw_impl.hpp>
 #include <connect/services/grid_client.hpp>
@@ -74,7 +75,7 @@ public:
 class CAsnBinCompressed : public CAsnBin
 {
 public:
-    typedef int TOwnership;
+    using TOwnership = int;
 
     struct SStreamProp
     {
@@ -93,17 +94,17 @@ public:
     ///   underlying output stream
     /// @return
     ///   object stream
-    static CObjectOStream*
+    static unique_ptr<CObjectOStream>
     GetOStream(CNcbiOstream& ostr, SStreamProp stream_prop = SStreamProp(CCompressStream::eZip))
     {
-        auto_ptr<CCompressionOStream> outstr_zip(
+        unique_ptr<CCompressionOStream> outstr_zip(
             new CCompressionOStream(
                 ostr,
                 CreateStreamCompressor(stream_prop),
                 CCompressionStream::fOwnProcessor
             )
         );
-        return CObjectOStream::Open(GetDataFormat(), *outstr_zip.release(), eTakeOwnership);
+        return unique_ptr<CObjectOStream>(CObjectOStream::Open(GetDataFormat(), *outstr_zip.release(), eTakeOwnership));
     }
 
     /// Return an object input stream (CObjectIStream)
@@ -112,43 +113,57 @@ public:
     ///   underlying input stream
     /// @return
     ///   object stream
-    static CObjectIStream*
+    static unique_ptr<CObjectIStream>
     GetIStream(CNcbiIstream& istr)
     {
         return GetIStream(istr, GetIStreamProperties(istr));
     }
 
-    static CObjectIStream*
+    static unique_ptr<CObjectIStream>
     GetIStream(const string& job_content, CNetCacheAPI& nc_api)
     {
         SStreamProp sp;
         return GetIStream(job_content, nc_api, sp);
     }
 
-    static CObjectIStream*
+    static unique_ptr<CObjectIStream>
     GetIStream(const string& job_content, CNetCacheAPI& nc_api, SStreamProp& streamprop)
     {
-        streamprop = GetJobStreamProperties(job_content, nc_api);
-        auto_ptr<CStringOrBlobStorageReader> reader(new CStringOrBlobStorageReader(job_content, nc_api));
-        auto_ptr<CRStream> rstr(new CRStream(reader.release(), CRWStreambuf::fOwnReader));
+        auto rstr = GetRawIStream(job_content, nc_api, streamprop);
         return GetIStream(*rstr.release(), streamprop, CCompressionStream::fOwnAll);
     }
 
+    static unique_ptr<CNcbiIstream>
+    GetRawIStream(const string& job_content, CNetCacheAPI& nc_api)
+    {
+        SStreamProp sp;
+        return GetRawIStream(job_content, nc_api, sp);
+    }
+
+    static unique_ptr<CNcbiIstream>
+    GetRawIStream(const string& job_content, CNetCacheAPI& nc_api, SStreamProp& streamprop)
+    {
+        streamprop = GetJobStreamProperties(job_content, nc_api);
+        unique_ptr<CStringOrBlobStorageReader> reader(new CStringOrBlobStorageReader(job_content, nc_api));
+        unique_ptr<CNcbiIstream> rstr(new CRStream(reader.release(), CRWStreambuf::fOwnReader));
+        return rstr;
+    }
+
 protected:
-    static CObjectIStream*
+    static unique_ptr<CObjectIStream>
     GetIStream(CNcbiIstream& istr,
                const SStreamProp& stream_prop,
                TOwnership ownership = CCompressionStream::fOwnProcessor
               )
     {
-        auto_ptr<CCompressionIStream> instr_zip(
+        unique_ptr<CCompressionIStream> instr_zip(
             new CCompressionIStream(
                 istr,
                 CreateStreamDecompressor(stream_prop),
                 ownership
             )
         );
-        return CObjectIStream::Open(GetDataFormat(), *instr_zip.release(), eTakeOwnership);
+        return unique_ptr<CObjectIStream>(CObjectIStream::Open(GetDataFormat(), *instr_zip.release(), eTakeOwnership));
     }
 
     static SStreamProp GetJobStreamProperties(const string& job_content, CNetCacheAPI& nc_api)
@@ -192,7 +207,7 @@ protected:
 
     static CCompressionStreamProcessor* CreateStreamCompressor(const SStreamProp& stream_prop)
     {
-        auto_ptr<CCompressionStreamProcessor> sp;
+        unique_ptr<CCompressionStreamProcessor> sp;
         if (stream_prop.compress_method == CCompressStream::eLZO) {
             sp.reset(new CLZOStreamCompressor());
         }
@@ -204,7 +219,7 @@ protected:
 
     static CCompressionStreamProcessor* CreateStreamDecompressor(const SStreamProp& stream_prop)
     {
-        auto_ptr<CCompressionStreamProcessor> sp;
+        unique_ptr<CCompressionStreamProcessor> sp;
         if (stream_prop.compress_method == CCompressStream::eLZO) {
             sp.reset(new CLZOStreamDecompressor());
         }
@@ -257,7 +272,7 @@ public:
 /// TConnectTraits template classes: CAsnBinCompressed
 ///
 template <typename TConnectTraits = CAsnBinCompressed, int DefaultTimeout = 20>
-class CGridRPCBaseClient : private TConnectTraits
+class CGridRPCBaseClient : protected TConnectTraits
 {
 public:
     CGridRPCBaseClient(const string& NS_service,
@@ -297,8 +312,65 @@ public:
         m_NC_api = CNetCacheAPI(CNetCacheAPI::eAppRegistry, NC_registry_section);
     }
 
-    virtual ~CGridRPCBaseClient()
+    virtual ~CGridRPCBaseClient() = default;
+
+    pair<CNetScheduleJob, bool> AskStream(CNcbiIstream& request, CNcbiOstream& reply) const
     {
+        CGridClient grid_cli(m_NS_api.GetSubmitter(),
+                             m_NC_api,
+                             CGridClient::eManualCleanup,
+                             CGridClient::eProgressMsgOn
+                            );
+        auto& job_in = grid_cli.GetOStream(); // job input stream
+        NcbiStreamCopy(job_in, request);
+        if (job_in.bad()) {
+            NCBI_THROW(CIOException, eWrite, "Error while writing request");
+        }
+        grid_cli.CloseStream();
+
+        CNetScheduleJob& job = grid_cli.GetJob();
+        bool timed_out = false;
+        x_PrepareJob(job);
+
+        try {
+            const CNetScheduleAPI::EJobStatus evt = grid_cli.SubmitAndWait(m_Timeout);
+            switch (evt) {
+            case CNetScheduleAPI::eDone:
+            {
+                m_NS_api.GetJobDetails(job);
+                auto instr = TConnectTraits::GetRawIStream(job.output, m_NC_api);
+                NcbiStreamCopy(reply, *instr);
+                break;
+            }
+            case CNetScheduleAPI::eFailed:
+                NCBI_THROW(CGridRPCBaseClientException, eUnexpectedFailure, "Job failed");
+
+            case CNetScheduleAPI::eCanceled:
+                NCBI_THROW(CGridRPCBaseClientException, eUnexpectedFailure, "Job canceled");
+
+            case CNetScheduleAPI::eRunning:
+                NCBI_THROW(CGridRPCBaseClientException, eUnexpectedFailure, "Job running");
+
+            default:
+                NCBI_THROW(CGridRPCBaseClientException,
+                           eWaitTimeout,
+                           "Unexpected status: " + CNetScheduleAPI::StatusToString(evt)
+                          );
+            }
+        }
+        catch (const CGridRPCBaseClientException& e) {
+            switch (e.GetErrCode()) {
+            case CGridRPCBaseClientException::eUnexpectedFailure:
+                timed_out = true;
+                break;
+
+            case CGridRPCBaseClientException::eWaitTimeout:
+            default:
+                break;
+            }
+            throw e;
+        }
+        return make_pair(job, timed_out);
     }
 
     template <class TRequest, class TReply>
@@ -309,8 +381,8 @@ public:
                              CGridClient::eManualCleanup,
                              CGridClient::eProgressMsgOn
                             );
-        CNcbiOstream& job_in = grid_cli.GetOStream(); // job input stream
-        auto_ptr<CObjectOStream> outstr(TConnectTraits::GetOStream(job_in));
+        auto& job_in = grid_cli.GetOStream(); // job input stream
+        auto outstr = TConnectTraits::GetOStream(job_in);
         *outstr << request;
         if (job_in.bad()) {
             NCBI_THROW(CIOException, eWrite, "Error while writing request");
@@ -328,7 +400,7 @@ public:
             case CNetScheduleAPI::eDone:
             {
                 m_NS_api.GetJobDetails(job);
-                auto_ptr<CObjectIStream> instr(TConnectTraits::GetIStream(job.output, m_NC_api));
+                auto instr = TConnectTraits::GetIStream(job.output, m_NC_api);
                 *instr >> reply;
                 break;
             }
@@ -364,7 +436,14 @@ public:
     }
 
 protected:
-    virtual void x_PrepareJob(CNetScheduleJob& job) const
+    CGridRPCBaseClient(const CGridRPCBaseClient&) = delete;
+    CGridRPCBaseClient(CGridRPCBaseClient&& c)
+        : m_NS_api(move(c.m_NS_api)), m_NC_api(move(c.m_NC_api)),
+          m_Timeout(c.m_Timeout)
+    {
+    }
+
+    virtual void x_PrepareJob(CNetScheduleJob& /*job*/) const
     {
     }
 
@@ -380,7 +459,7 @@ protected:
         case CNetScheduleAPI::eDone:
         {
             m_NS_api.GetJobDetails(job);
-            auto_ptr<CObjectIStream> instr(TConnectTraits::GetIStream(job.output, m_NC_api));
+            auto instr = TConnectTraits::GetIStream(job.output, m_NC_api);
             *instr >> reply;
             break;
         }
@@ -409,6 +488,30 @@ private:
 };
 
 
+template <typename TRequest, typename TReply>
+class CGridRPCHttpClient : public CRPCClient<TRequest, TReply>
+{
+protected:
+    using TParent = CRPCClient<TRequest, TReply>;
+
+public:
+    CGridRPCHttpClient(const string& http_service)
+        : TParent(http_service)
+    {
+    }
+
+    virtual ~CGridRPCHttpClient() = default;
+
+protected:
+    virtual void x_Connect() override
+    {
+        TParent::x_Connect();
+        TParent::m_In.reset(CAsnBinCompressed::GetIStream(*TParent::m_Stream).release());
+        TParent::m_Out.reset(CAsnBinCompressed::GetOStream(*TParent::m_Stream).release());
+    }
+};
+
+
 END_NCBI_SCOPE
 
 #endif // OBJECTS_MISC_SERIAL___GRID_RPC_CLIENT__HPP
diff --git a/c++/include/objects/valerr/ValidErrItem.hpp b/c++/include/objects/valerr/ValidErrItem.hpp
index 1254c40..73191d2 100644
--- a/c++/include/objects/valerr/ValidErrItem.hpp
+++ b/c++/include/objects/valerr/ValidErrItem.hpp
@@ -1,4 +1,4 @@
-/* $Id: ValidErrItem.hpp 473063 2015-07-15 23:22:36Z kans $
+/* $Id: ValidErrItem.hpp 519224 2016-11-14 16:08:42Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -251,6 +251,7 @@ enum EErrType {
     eErr_SEQ_DESCR_WrongBiomolForTechnique,
     eErr_SEQ_DESCR_WrongOrganismFor16SrRNA,
     eErr_SEQ_DESCR_InconsistentWGSFlags,
+    eErr_SEQ_DESCR_TitleNotAppropriateForSet,
     ERR_CODE_END(SEQ_DESCR),
 
 
@@ -275,6 +276,19 @@ enum EErrType {
     eErr_GENERIC_MissingVolumeEpub,
     eErr_GENERIC_MissingPages,
     eErr_GENERIC_MissingPagesEpub,
+    eErr_GENERIC_BarcodeTooShort,
+    eErr_GENERIC_BarcodeMissingPrimers,
+    eErr_GENERIC_BarcodeMissingCountry,
+    eErr_GENERIC_BarcodeMissingVoucher,
+    eErr_GENERIC_BarcodeTooManyNs,
+    eErr_GENERIC_BarcodeBadCollectionDate,
+    eErr_GENERIC_BarcodeMissingOrderAssignment,
+    eErr_GENERIC_BarcodeLowTrace,
+    eErr_GENERIC_BarcodeFrameShift,
+    eErr_GENERIC_BarcodeStructuredVoucher,
+    eErr_GENERIC_BarcodeTestFails,
+    eErr_GENERIC_BarcodeTestPasses,
+    eErr_GENERIC_InvalidAsn,
     ERR_CODE_END(GENERIC),
 
     ERR_CODE_BEGIN(SEQ_PKG) = 3000,
@@ -410,6 +424,7 @@ enum EErrType {
     eErr_SEQ_FEAT_BadFullLengthFeature,
     eErr_SEQ_FEAT_RedundantFields,
     eErr_SEQ_FEAT_CDSwithNoMRNAOverlap,
+    eErr_SEQ_FEAT_CDSwithNoMRNA,
     eErr_SEQ_FEAT_FeatureProductInconsistency,
     eErr_SEQ_FEAT_ImproperBondLocation,
     eErr_SEQ_FEAT_GeneXrefWithoutGene,
@@ -521,6 +536,9 @@ enum EErrType {
     eErr_SEQ_FEAT_InconsistentPseudogeneValue,
     eErr_SEQ_FEAT_MultiIntervalIntron,
     eErr_SEQ_FEAT_SeqLocTypeProblem,
+    eErr_SEQ_FEAT_RefSeqInText,
+    eErr_SEQ_FEAT_ColdShockProteinProblem,
+    eErr_SEQ_FEAT_BadLocation,
     ERR_CODE_END(SEQ_FEAT),
 
     ERR_CODE_BEGIN(SEQ_ALIGN) = 5000,
diff --git a/c++/include/objects/valerr/ValidError.hpp b/c++/include/objects/valerr/ValidError.hpp
index e13d4ce..70f0926 100644
--- a/c++/include/objects/valerr/ValidError.hpp
+++ b/c++/include/objects/valerr/ValidError.hpp
@@ -1,4 +1,4 @@
-/* $Id: ValidError.hpp 447658 2014-09-29 18:29:18Z bollin $
+/* $Id: ValidError.hpp 513779 2016-09-15 11:23:57Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -91,6 +91,10 @@ public:
                          const int            ver,     // version of object.
                          const int            seq_offset = 0);
 
+     void AddValidErrItem(EDiagSev            sev,     // severity
+                          unsigned int         ec,      // error code
+                          const string&        msg);     // specific error message
+
     // Statistics
     SIZE_TYPE TotalSize(void)    const;
     SIZE_TYPE Size(EDiagSev sev) const;
diff --git a/c++/include/objects/valid/Comment_rule.hpp b/c++/include/objects/valid/Comment_rule.hpp
index 000a88d..5573b0a 100644
--- a/c++/include/objects/valid/Comment_rule.hpp
+++ b/c++/include/objects/valid/Comment_rule.hpp
@@ -1,4 +1,4 @@
-/* $Id: Comment_rule.hpp 493827 2016-03-02 13:59:27Z ivanov $
+/* $Id: Comment_rule.hpp 491404 2016-02-04 17:37:54Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objects/varrep/AaInterval.hpp b/c++/include/objects/varrep/AaInterval.hpp
new file mode 100644
index 0000000..1d354d3
--- /dev/null
+++ b/c++/include/objects/varrep/AaInterval.hpp
@@ -0,0 +1,90 @@
+/* $Id: AaInterval.hpp 497242 2016-04-05 14:40:38Z foleyjp $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ */
+
+/// @file AaInterval.hpp
+/// User-defined methods of the data storage class.
+///
+/// This file was originally generated by application DATATOOL
+/// using the following specifications:
+/// 'variation_irep.asn'.
+///
+/// New methods or data members can be added to it if needed.
+/// See also: AaInterval_.hpp
+
+
+#ifndef OBJECTS_VARREP_AAINTERVAL_HPP
+#define OBJECTS_VARREP_AAINTERVAL_HPP
+
+
+// generated includes
+#include <objects/varrep/AaInterval_.hpp>
+
+// generated classes
+
+BEGIN_NCBI_SCOPE
+
+BEGIN_objects_SCOPE // namespace ncbi::objects::
+
+/////////////////////////////////////////////////////////////////////////////
+class CAaInterval : public CAaInterval_Base
+{
+    typedef CAaInterval_Base Tparent;
+public:
+    // constructor
+    CAaInterval(void);
+    // destructor
+    ~CAaInterval(void);
+
+    size_t size(void) const;
+    string GetString(void) const;
+
+private:
+    // Prohibit copy constructor and assignment operator
+    CAaInterval(const CAaInterval& value);
+    CAaInterval& operator=(const CAaInterval& value);
+
+};
+
+/////////////////// CAaInterval inline methods
+
+// constructor
+inline
+CAaInterval::CAaInterval(void)
+{
+}
+
+
+/////////////////// end of CAaInterval inline methods
+
+
+END_objects_SCOPE // namespace ncbi::objects::
+
+END_NCBI_SCOPE
+
+
+#endif // INTERNAL_VARIATION_EXCHANGE_OBJECTS_HGVS_PARSER_AAINTERVAL_HPP
+/* Original file checksum: lines: 86, chars: 2550, CRC32: d1dc9d82 */
diff --git a/c++/include/objects/varrep/AaLocation.hpp b/c++/include/objects/varrep/AaLocation.hpp
new file mode 100644
index 0000000..bdd75ec
--- /dev/null
+++ b/c++/include/objects/varrep/AaLocation.hpp
@@ -0,0 +1,90 @@
+/* $Id: AaLocation.hpp 497242 2016-04-05 14:40:38Z foleyjp $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ */
+
+/// @file AaLocation.hpp
+/// User-defined methods of the data storage class.
+///
+/// This file was originally generated by application DATATOOL
+/// using the following specifications:
+/// 'variation_irep.asn'.
+///
+/// New methods or data members can be added to it if needed.
+/// See also: AaLocation_.hpp
+
+
+#ifndef OBJECTS_VARREP_AALOCATION_HPP
+#define OBJECTS_VARREP_AALOCATION_HPP
+
+
+// generated includes
+#include <objects/varrep/AaLocation_.hpp>
+
+// generated classes
+
+BEGIN_NCBI_SCOPE
+
+BEGIN_objects_SCOPE // namespace ncbi::objects::
+
+/////////////////////////////////////////////////////////////////////////////
+class CAaLocation : public CAaLocation_Base
+{
+    typedef CAaLocation_Base Tparent;
+public:
+    // constructor
+    CAaLocation(void);
+    // destructor
+    ~CAaLocation(void);
+
+    size_t size(void) const;
+    string GetString(void) const;
+
+private:
+    // Prohibit copy constructor and assignment operator
+    CAaLocation(const CAaLocation& value);
+    CAaLocation& operator=(const CAaLocation& value);
+
+};
+
+/////////////////// CAaLocation inline methods
+
+// constructor
+inline
+CAaLocation::CAaLocation(void)
+{
+}
+
+
+/////////////////// end of CAaLocation inline methods
+
+
+END_objects_SCOPE // namespace ncbi::objects::
+
+END_NCBI_SCOPE
+
+
+#endif // INTERNAL_VARIATION_EXCHANGE_OBJECTS_HGVS_PARSER_AALOCATION_HPP
+/* Original file checksum: lines: 86, chars: 2550, CRC32: d954b9b7 */
diff --git a/c++/include/objmgr/annot_selector.hpp b/c++/include/objmgr/annot_selector.hpp
index 731ae35..b65edcc 100644
--- a/c++/include/objmgr/annot_selector.hpp
+++ b/c++/include/objmgr/annot_selector.hpp
@@ -1,7 +1,7 @@
 #ifndef ANNOT_SELECTOR__HPP
 #define ANNOT_SELECTOR__HPP
 
-/*  $Id: annot_selector.hpp 499042 2016-04-21 17:39:04Z ivanov $
+/*  $Id: annot_selector.hpp 519943 2016-11-21 15:34:20Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -466,6 +466,21 @@ struct NCBI_XOBJMGR_EXPORT SAnnotSelector : public SAnnotTypeSelector
             return *this;
         }
 
+    enum EMaxSearchSegmentsAction {
+        eMaxSearchSegmentsThrow, // default
+        eMaxSearchSegmentsLog,   // log error message, and stop searching
+        eMaxSearchSegmentsSilent // silently stop searching
+    };
+    EMaxSearchSegmentsAction GetMaxSearchSegmentsAction(void) const
+        {
+            return m_MaxSearchSegmentsAction;
+        }
+    SAnnotSelector& SetMaxSearchSegmentsAction(EMaxSearchSegmentsAction action)
+        {
+            m_MaxSearchSegmentsAction = action;
+            return *this;
+        }
+
     typedef float TMaxSearchTime;
     /// Get maximum time (in seconds) to search before giving up.
     TMaxSearchTime GetMaxSearchTime(void) const
@@ -726,6 +741,35 @@ struct NCBI_XOBJMGR_EXPORT SAnnotSelector : public SAnnotTypeSelector
         return m_IgnoreFarLocationsForSorting;
     }
 
+    /// Set bit filter for annotations that support it (SNP)
+    /// If filter is set then collect only annotations
+    /// that have masked (filter_mask) bits equal to the filter_bits
+    typedef Uint8 TBitFilter;
+    SAnnotSelector& SetBitFilter(TBitFilter filter_bits,
+                                 TBitFilter filter_mask = TBitFilter(-1))
+    {
+        m_FilterMask = filter_mask;
+        m_FilterBits = filter_bits & filter_mask;
+        return *this;
+    }
+    SAnnotSelector& ResetBitFilter(void)
+    {
+        m_FilterMask = m_FilterBits = 0;
+        return *this;
+    }
+    bool HasBitFilter(void) const
+    {
+        return m_FilterMask != 0;
+    }
+    TBitFilter GetFilterMask(void) const
+    {
+        return m_FilterMask;
+    }
+    TBitFilter GetFilterBits(void) const
+    {
+        return m_FilterBits;
+    }
+
 protected:
     friend class CAnnot_Collector;
 
@@ -760,6 +804,7 @@ protected:
     TAnnotsNames          m_IncludeAnnotsNames;
     TAnnotsNames          m_ExcludeAnnotsNames;
     AutoPtr<TNamedAnnotAccessions> m_NamedAnnotAccessions;
+    EMaxSearchSegmentsAction m_MaxSearchSegmentsAction;
     bool                  m_NoMapping;
     TAdaptiveDepthFlags   m_AdaptiveDepthFlags;
     bool                  m_ExactDepth;
@@ -773,6 +818,8 @@ protected:
     TAnnotTypesBitset     m_AnnotTypesBitset;
     AutoPtr<CHandleRangeMap> m_SourceLoc;
     CBioseq_Handle        m_IgnoreFarLocationsForSorting;
+    TBitFilter            m_FilterMask;
+    TBitFilter            m_FilterBits;
 };
 
 
diff --git a/c++/include/objmgr/annot_types_ci.hpp b/c++/include/objmgr/annot_types_ci.hpp
index dfba106..03e907c 100644
--- a/c++/include/objmgr/annot_types_ci.hpp
+++ b/c++/include/objmgr/annot_types_ci.hpp
@@ -1,7 +1,7 @@
 #ifndef ANNOT_TYPES_CI__HPP
 #define ANNOT_TYPES_CI__HPP
 
-/*  $Id: annot_types_ci.hpp 439336 2014-06-27 16:08:17Z vasilche $
+/*  $Id: annot_types_ci.hpp 519943 2016-11-21 15:34:20Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -92,6 +92,9 @@ public:
     // Get number of annotations
     size_t GetSize(void) const;
 
+    // check if empty segment limit is reached
+    bool MaxSearchSegmentsLimitIsReached(void) const;
+
     typedef vector<SAnnotTypeSelector> TAnnotTypes;
     // Get annot types
     const TAnnotTypes& GetAnnotTypes(void) const;
diff --git a/c++/include/objmgr/bioseq_handle.hpp b/c++/include/objmgr/bioseq_handle.hpp
index d3b6162..612eb79 100644
--- a/c++/include/objmgr/bioseq_handle.hpp
+++ b/c++/include/objmgr/bioseq_handle.hpp
@@ -1,7 +1,7 @@
 #ifndef BIOSEQ_HANDLE__HPP
 #define BIOSEQ_HANDLE__HPP
 
-/*  $Id: bioseq_handle.hpp 499042 2016-04-21 17:39:04Z ivanov $
+/*  $Id: bioseq_handle.hpp 496211 2016-03-24 15:33:11Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objmgr/data_loader.hpp b/c++/include/objmgr/data_loader.hpp
index f6d46f5..2838f42 100644
--- a/c++/include/objmgr/data_loader.hpp
+++ b/c++/include/objmgr/data_loader.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_OBJMGR___DATA_LOADER__HPP
 #define OBJECTS_OBJMGR___DATA_LOADER__HPP
 
-/*  $Id: data_loader.hpp 498421 2016-04-15 18:44:37Z ivanov $
+/*  $Id: data_loader.hpp 498345 2016-04-15 14:39:08Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objmgr/impl/annot_collector.hpp b/c++/include/objmgr/impl/annot_collector.hpp
index e2d249d..8c114f4 100644
--- a/c++/include/objmgr/impl/annot_collector.hpp
+++ b/c++/include/objmgr/impl/annot_collector.hpp
@@ -1,7 +1,7 @@
 #ifndef ANNOT_COLLECTOR__HPP
 #define ANNOT_COLLECTOR__HPP
 
-/*  $Id: annot_collector.hpp 493571 2016-02-29 19:45:30Z ivanov $
+/*  $Id: annot_collector.hpp 519943 2016-11-21 15:34:20Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -61,6 +61,8 @@ struct SAnnotObject_Index;
 class CSeq_entry_Info;
 class CSeq_annot_Info;
 class CSeq_annot_SNP_Info;
+class CSeq_annot_SortedIter;
+class CSeqTableInfo;
 struct SSNP_Info;
 struct SIdAnnotObjs;
 class CSeq_loc_Conversion;
@@ -177,9 +179,15 @@ class NCBI_XOBJMGR_EXPORT CAnnotObject_Ref
 public:
     typedef CRange<TSeqPos> TRange;
     typedef Int4           TAnnotIndex;
-    enum {
-        kSNPTableBit    = 0x80000000,
-        kAnnotIndexMask = 0x7fffffff
+    enum EAnnotType {
+        fAnnot_NoAnnotInfo    = 1<<0,
+        fAnnot_SNPTable       = 1<<1,
+        fAnnot_SeqTable       = 1<<2,
+
+        eAnnot_Regular        = 0,
+        eAnnot_SNPTable       = fAnnot_NoAnnotInfo | fAnnot_SNPTable,
+        eAnnot_SeqTable       = fAnnot_SeqTable,
+        eAnnot_SortedSeqTable = fAnnot_NoAnnotInfo | fAnnot_SeqTable,
     };
 
     CAnnotObject_Ref(void);
@@ -189,15 +197,34 @@ public:
                      const CSeq_annot_Handle& annot_handle,
                      const SSNP_Info& snp_info,
                      CSeq_loc_Conversion* cvt);
+    CAnnotObject_Ref(const CSeq_annot_Handle& annot_handle,
+                     const CSeq_annot_SortedIter& iter,
+                     CSeq_loc_Conversion* cvt);
 
+    // the annotation has CAnnotObject_Info object and entry in annot index
     bool HasAnnotObject_Info(void) const;
+    // the annotation has CSeq_feat, CAnnotObject_Info, and annot index
     bool IsPlainFeat(void) const;
-    bool IsSNPFeat(void) const;
-    bool IsTableFeat(void) const;
+
+    // the feature is from parsed SNP table (GenBank SNP external annotations)
+    // it doesn't have corresponding CAnnotObject_Info and entry in annot index
+    bool IsSNPTableFeat(void) const;
+    // the feature is from Seq-table
+    // it may or may not have corresponding CAnnotObject_Info and annot index
+    bool IsAnySeqTableFeat(void) const;
+    // the feature is from pre-sorted Seq-table
+    // it doesn't have corresponding CAnnotObject_Info and entry in annot index
+    bool IsSortedSeqTableFeat(void) const;
+
+    // replaced with IsSNPTableFeat() and IsSortedSeqTableFeat()
+    NCBI_DEPRECATED bool IsSNPFeat(void) const;
+    // replaced with IsAnySeqTableFeat() and IsSortedSeqTableFeat()
+    NCBI_DEPRECATED bool IsTableFeat(void) const;
 
     const CSeq_annot_Handle& GetSeq_annot_Handle(void) const;
     const CSeq_annot_Info& GetSeq_annot_Info(void) const;
     const CSeq_annot_SNP_Info& GetSeq_annot_SNP_Info(void) const;
+    const CSeqTableInfo& GetSeqTableInfo(void) const;
     TAnnotIndex GetAnnotIndex(void) const;
 
     const CAnnotObject_Info& GetAnnotObject_Info(void) const;
@@ -226,8 +253,12 @@ private:
     friend class CAnnot_Collector;
 
     CSeq_annot_Handle          m_Seq_annot;   //  4 or  8
+    mutable CAnnotMapping_Info m_MappingInfo; // 20 or 32
     TAnnotIndex                m_AnnotIndex;  //  4 or  4
-    mutable CAnnotMapping_Info m_MappingInfo; // 16 or 20
+    EAnnotType                 m_AnnotType;   //  4 or  4
+    // total size:
+    //   32 B on 32-bit system (can be packed into 28 B)
+    //   48 B on 64-bit system (can be packed into 40 B)
 };
 
 
@@ -459,6 +490,10 @@ private:
     const TAnnotNames& x_GetAnnotNames(void) const;
 
     void x_StopSearchLimits(void);
+    bool x_MaxSearchSegmentsLimitIsReached(void) const
+        {
+            return m_SearchSegments == 0;
+        }
 
     const SAnnotSelector*            m_Selector;
     CHeapScope                       m_Scope;
@@ -482,6 +517,7 @@ private:
     typedef SAnnotSelector::TMaxSearchSegments TMaxSearchSegments;
     CStopWatch              m_SearchTime;
     TMaxSearchSegments      m_SearchSegments;
+    SAnnotSelector::EMaxSearchSegmentsAction m_SearchSegmentsAction;
     bool                    m_FromOtherTSE;
 
     friend class CAnnotTypes_CI;
@@ -792,7 +828,7 @@ void CAnnotMapping_Info::Swap(CAnnotMapping_Info& info)
 
 inline
 CAnnotObject_Ref::CAnnotObject_Ref(void)
-    : m_AnnotIndex(0)
+    : m_AnnotIndex(0), m_AnnotType(eAnnot_Regular)
 {
 }
 
@@ -800,37 +836,56 @@ CAnnotObject_Ref::CAnnotObject_Ref(void)
 inline
 CAnnotObject_Ref::TAnnotIndex CAnnotObject_Ref::GetAnnotIndex(void) const
 {
-    return m_AnnotIndex & kAnnotIndexMask;
+    return m_AnnotIndex;
 }
 
 
 inline
 bool CAnnotObject_Ref::HasAnnotObject_Info(void) const
 {
-    return (m_AnnotIndex & kSNPTableBit) == 0;
+    return (m_AnnotType & fAnnot_NoAnnotInfo) == 0;
 }
 
 
 inline
 bool CAnnotObject_Ref::IsPlainFeat(void) const
 {
-    return (m_AnnotIndex & kSNPTableBit) == 0 &&
-        GetAnnotObject_Info().IsRegular();
+    return m_AnnotType == eAnnot_Regular;
+}
+
+
+inline
+bool CAnnotObject_Ref::IsSNPTableFeat(void) const
+{
+    return m_AnnotType == eAnnot_SNPTable;
+}
+
+
+inline
+bool CAnnotObject_Ref::IsSortedSeqTableFeat(void) const
+{
+    return m_AnnotType == eAnnot_SortedSeqTable;
+}
+
+
+inline
+bool CAnnotObject_Ref::IsAnySeqTableFeat(void) const
+{
+    return (m_AnnotType & fAnnot_SeqTable) != 0;
 }
 
 
 inline
 bool CAnnotObject_Ref::IsSNPFeat(void) const
 {
-    return (m_AnnotIndex & kSNPTableBit) != 0;
+    return IsSNPTableFeat();
 }
 
 
 inline
 bool CAnnotObject_Ref::IsTableFeat(void) const
 {
-    return (m_AnnotIndex & kSNPTableBit) == 0 &&
-        !GetAnnotObject_Info().IsRegular();
+    return IsAnySeqTableFeat();
 }
 
 
@@ -854,6 +909,9 @@ bool CAnnotObject_Ref::operator<(const CAnnotObject_Ref& ref) const
     if ( m_Seq_annot != ref.m_Seq_annot ) {
         return m_Seq_annot.OrderedBefore(ref.m_Seq_annot);
     }
+    if ( m_AnnotType != ref.m_AnnotType ) {
+        return m_AnnotType < ref.m_AnnotType;
+    }
     return m_AnnotIndex < ref.m_AnnotIndex;
 }
 
@@ -861,16 +919,16 @@ bool CAnnotObject_Ref::operator<(const CAnnotObject_Ref& ref) const
 inline
 bool CAnnotObject_Ref::operator==(const CAnnotObject_Ref& ref) const
 {
-    return (m_Seq_annot == ref.m_Seq_annot &&
-            m_AnnotIndex == ref.m_AnnotIndex);
+    return (m_AnnotIndex == ref.m_AnnotIndex &&
+            m_AnnotType == ref.m_AnnotType &&
+            m_Seq_annot == ref.m_Seq_annot);
 }
 
 
 inline
 bool CAnnotObject_Ref::operator!=(const CAnnotObject_Ref& ref) const
 {
-    return (m_Seq_annot != ref.m_Seq_annot ||
-            m_AnnotIndex != ref.m_AnnotIndex);
+    return !(*this == ref);
 }
 
 
@@ -927,6 +985,7 @@ void CAnnotObject_Ref::Swap(CAnnotObject_Ref& ref)
 {
     m_Seq_annot.Swap(ref.m_Seq_annot);
     swap(m_AnnotIndex, ref.m_AnnotIndex);
+    swap(m_AnnotType, ref.m_AnnotType);
     m_MappingInfo.Swap(ref.m_MappingInfo);
 }
 
diff --git a/c++/include/objmgr/impl/annot_object_index.hpp b/c++/include/objmgr/impl/annot_object_index.hpp
index 1767ac8..a4ac61c 100644
--- a/c++/include/objmgr/impl/annot_object_index.hpp
+++ b/c++/include/objmgr/impl/annot_object_index.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_OBJMGR_IMPL___ANNOT_OBJECT_INDEX__HPP
 #define OBJECTS_OBJMGR_IMPL___ANNOT_OBJECT_INDEX__HPP
 
-/*  $Id: annot_object_index.hpp 382134 2012-12-03 19:56:38Z vasilche $
+/*  $Id: annot_object_index.hpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -129,15 +129,15 @@ struct SAnnotObject_Index
         }
     void SetLocationIsPoint(void)
         {
-            m_Flags = (m_Flags & ~fSimpleLocation_Mask) | fLocation_Point;
+            m_Flags = TFlags((m_Flags & ~fSimpleLocation_Mask) | fLocation_Point);
         }
     void SetLocationIsInterval(void)
         {
-            m_Flags = (m_Flags & ~fSimpleLocation_Mask) | fLocation_Interval;
+            m_Flags = TFlags((m_Flags & ~fSimpleLocation_Mask) | fLocation_Interval);
         }
     void SetLocationIsWhole(void)
         {
-            m_Flags = (m_Flags & ~fSimpleLocation_Mask) | fLocation_Whole;
+            m_Flags = TFlags((m_Flags & ~fSimpleLocation_Mask) | fLocation_Whole);
         }
 
     CAnnotObject_Info*                  m_AnnotObject_Info;
diff --git a/c++/include/objmgr/impl/bioseq_base_info.hpp b/c++/include/objmgr/impl/bioseq_base_info.hpp
index 520ebcb..eb52c96 100644
--- a/c++/include/objmgr/impl/bioseq_base_info.hpp
+++ b/c++/include/objmgr/impl/bioseq_base_info.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_OBJMGR_IMPL___BIOSEQ_BASE_INFO__HPP
 #define OBJECTS_OBJMGR_IMPL___BIOSEQ_BASE_INFO__HPP
 
-/*  $Id: bioseq_base_info.hpp 465027 2015-04-16 13:18:40Z vasilche $
+/*  $Id: bioseq_base_info.hpp 507368 2016-07-18 21:33:41Z vasilche $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -111,6 +111,8 @@ public:
 
     const CSeqdesc* x_SearchFirstDesc(TDescTypeMask type) const;
 
+    TDescTypeMask x_GetExistingDescrMask(void) const;
+
     // annot
     typedef vector< CRef<CSeq_annot_Info> > TAnnot;
     typedef list< CRef<CSeq_annot> > TObjAnnot;
@@ -153,7 +155,7 @@ public:
     void x_DoUpdate(TNeedUpdateFlags flags);
     void x_SetNeedUpdateParent(TNeedUpdateFlags flags);
 
-private:
+protected:
     bool x_IsEndNextDesc(TDesc_CI iter) const; // internal inlined method
 
     friend class CAnnotTypes_CI;
diff --git a/c++/include/objmgr/impl/bioseq_info.hpp b/c++/include/objmgr/impl/bioseq_info.hpp
index 0c36a7f..20b770d 100644
--- a/c++/include/objmgr/impl/bioseq_info.hpp
+++ b/c++/include/objmgr/impl/bioseq_info.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_OBJMGR_IMPL___BIOSEQ_INFO__HPP
 #define OBJECTS_OBJMGR_IMPL___BIOSEQ_INFO__HPP
 
-/*  $Id: bioseq_info.hpp 499042 2016-04-21 17:39:04Z ivanov $
+/*  $Id: bioseq_info.hpp 496211 2016-03-24 15:33:11Z vasilche $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objmgr/impl/data_source.hpp b/c++/include/objmgr/impl/data_source.hpp
index 2357de3..070305d 100644
--- a/c++/include/objmgr/impl/data_source.hpp
+++ b/c++/include/objmgr/impl/data_source.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_OBJMGR_IMPL___DATA_SOURCE__HPP
 #define OBJECTS_OBJMGR_IMPL___DATA_SOURCE__HPP
 
-/*  $Id: data_source.hpp 494477 2016-03-07 19:25:35Z ivanov $
+/*  $Id: data_source.hpp 493168 2016-02-24 19:28:38Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objmgr/impl/scope_impl.hpp b/c++/include/objmgr/impl/scope_impl.hpp
index 380a11d..efa3893 100644
--- a/c++/include/objmgr/impl/scope_impl.hpp
+++ b/c++/include/objmgr/impl/scope_impl.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJMGR_IMPL_SCOPE_IMPL__HPP
 #define OBJMGR_IMPL_SCOPE_IMPL__HPP
 
-/*  $Id: scope_impl.hpp 496835 2016-03-31 15:49:15Z ivanov $
+/*  $Id: scope_impl.hpp 495071 2016-03-14 17:45:32Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objmgr/impl/seq_annot_info.hpp b/c++/include/objmgr/impl/seq_annot_info.hpp
index 8fc7729..3a22288 100644
--- a/c++/include/objmgr/impl/seq_annot_info.hpp
+++ b/c++/include/objmgr/impl/seq_annot_info.hpp
@@ -1,7 +1,7 @@
 #ifndef SEQ_ANNOT_INFO__HPP
 #define SEQ_ANNOT_INFO__HPP
 
-/*  $Id: seq_annot_info.hpp 496424 2016-03-28 15:16:13Z ivanov $
+/*  $Id: seq_annot_info.hpp 502681 2016-05-26 16:04:36Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -42,6 +42,7 @@
 #include <objmgr/annot_name.hpp>
 #include <objmgr/impl/annot_object.hpp>
 #include <objmgr/impl/annot_object_index.hpp>
+#include <objmgr/impl/seq_table_info.hpp>
 
 #include <vector>
 
@@ -61,6 +62,7 @@ class CSeqTableInfo;
 class CFeat_id;
 class CGene_ref;
 class CSeq_feat_Handle;
+class CSeq_annot_SortedIter;
 
 class NCBI_XOBJMGR_EXPORT CSeq_annot_Info : public CTSE_Info_Object
 {
@@ -73,7 +75,10 @@ public:
     typedef C_Data::TGraph      TGraph;
     typedef C_Data::TLocs       TLocs;
     typedef C_Data::TSeq_table  TSeq_table;
-    typedef Uint4               TAnnotIndex;
+    typedef Int4               TAnnotIndex;
+
+    // annotation index marking the Seq-annot as a whole
+    static const TAnnotIndex kWholeAnnotIndex = kMax_I4;
 
     explicit CSeq_annot_Info(CSeq_annot& annot, int chunk_id = 0);
     explicit CSeq_annot_Info(CSeq_annot_SNP_Info& snp_annot);
@@ -159,6 +164,10 @@ public:
     const CAnnotObject_Info& GetInfo(TAnnotIndex index) const;
 
     const CSeqTableInfo& GetTableInfo(void) const;
+    bool IsSortedTable(void) const;
+    CSeq_annot_SortedIter StartSortedIterator(CRange<TSeqPos> range) const;
+    bool MatchBitFilter(const SAnnotSelector& sel,
+                        const CSeq_annot_SortedIter& iter) const;
 
     void UpdateTableFeat(CRef<CSeq_feat>& seq_feat,
                          CRef<CSeq_point>& seq_point,
@@ -176,6 +185,10 @@ public:
 
     virtual string GetDescription(void) const;
 
+    // special access to SNP or sorted table features
+    bool TableFeat_HasLabel(TAnnotIndex index) const;
+    string TableFeat_GetLabel(TAnnotIndex index) const;
+
 protected:
     friend class CDataSource;
     friend class CTSE_Info;
@@ -260,6 +273,43 @@ private:
 };
 
 
+class NCBI_XOBJMGR_EXPORT CSeq_annot_SortedIter
+{
+public:
+
+    DECLARE_OPERATOR_BOOL(m_ObjectRow < m_NumRows);
+
+    CSeq_annot_SortedIter& operator++(void)
+        {
+            ++m_ObjectRow;
+            x_Settle();
+            return *this;
+        }
+
+    size_t GetRow(void) const
+        {
+            return m_ObjectRow;
+        }
+
+    const CRange<TSeqPos>& GetRange(void) const
+        {
+            return m_ObjectRange;
+        }
+
+protected:
+    void x_Settle(void);
+    bool x_Valid(void);
+
+private:
+    friend class CSeq_annot_Info;
+
+    CRange<TSeqPos> m_RequestRange;
+    CRef<CSeqTableInfo> m_Table_Info;
+    size_t m_ObjectRow, m_NumRows;
+    CRange<TSeqPos> m_ObjectRange;
+};
+
+
 /////////////////////////////////////////////////////////////////////
 //
 //  Inline methods
@@ -326,7 +376,7 @@ CConstRef<CSeq_annot> CSeq_annot_Info::GetSeq_annotSkeleton(void) const
 inline
 const CAnnotObject_Info& CSeq_annot_Info::GetInfo(TAnnotIndex index) const
 {
-    _ASSERT(index < GetAnnotObjectInfos().size());
+    _ASSERT(size_t(index) < GetAnnotObjectInfos().size());
     return GetAnnotObjectInfos()[index];
 }
 
diff --git a/c++/include/objmgr/impl/seq_entry_info.hpp b/c++/include/objmgr/impl/seq_entry_info.hpp
index c3d98e5..188c27c 100644
--- a/c++/include/objmgr/impl/seq_entry_info.hpp
+++ b/c++/include/objmgr/impl/seq_entry_info.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_OBJMGR_IMPL___SEQ_ENTRY_INFO__HPP
 #define OBJECTS_OBJMGR_IMPL___SEQ_ENTRY_INFO__HPP
 
-/*  $Id: seq_entry_info.hpp 203738 2010-09-01 19:02:10Z vasilche $
+/*  $Id: seq_entry_info.hpp 518178 2016-11-01 11:46:07Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -91,7 +91,7 @@ public:
 
     typedef CSeq_entry TObject;
 
-    bool HasSeq_entry(void) const;
+    bool HasNoSeq_entry(void) const;
     CConstRef<TObject> GetCompleteSeq_entry(void) const;
     CConstRef<TObject> GetSeq_entryCore(void) const;
     CConstRef<TObject> GetSeq_entrySkeleton(void) const;
@@ -215,6 +215,9 @@ protected:
 
     void x_UpdateAnnotIndexContents(CTSE_Info& tse);
 
+    void x_UpdateSkeleton() const;
+    void x_Update(TNeedUpdateFlags flags) const;
+
     void x_DoUpdate(TNeedUpdateFlags flags);
     void x_SetNeedUpdateContents(TNeedUpdateFlags flags);
 
@@ -241,43 +244,11 @@ protected:
 /////////////////////////////////////////////////////////////////////
 
 inline
-bool CSeq_entry_Info::HasSeq_entry(void) const
-{
-    return m_Object.NotEmpty();
-}
-
-
-inline
-CSeq_entry::E_Choice CSeq_entry_Info::Which(void) const
+bool CSeq_entry_Info::HasNoSeq_entry(void) const
 {
-    return m_Which;
+    return !m_Object;
 }
 
-inline 
-CConstRef<CSeq_entry> CSeq_entry_Info::GetSeq_entrySkeleton(void) const
-{
-    return m_Object;   
-}
-
-inline
-CSeq_entry& CSeq_entry_Info::x_GetObject(void)
-{
-    return *m_Object;
-}
-
-
-inline
-const CSeq_entry& CSeq_entry_Info::x_GetObject(void) const
-{
-    return *m_Object;
-}
-
-
-inline 
-const CBioseq_Base_Info& CSeq_entry_Info::x_GetBaseInfo(void) const
-{
-    return *m_Contents;
-}
 
 inline
 bool CSeq_entry_Info::IsSet(void) const
diff --git a/c++/include/objmgr/impl/seq_id_sort.hpp b/c++/include/objmgr/impl/seq_id_sort.hpp
index 08bb0e7..d7e26a6 100644
--- a/c++/include/objmgr/impl/seq_id_sort.hpp
+++ b/c++/include/objmgr/impl/seq_id_sort.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJMGR_IMPL_SEQ_ID_SORT__HPP
 #define OBJMGR_IMPL_SEQ_ID_SORT__HPP
 
-/*  $Id: seq_id_sort.hpp 496835 2016-03-31 15:49:15Z ivanov $
+/*  $Id: seq_id_sort.hpp 495071 2016-03-14 17:45:32Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objmgr/impl/seq_table_info.hpp b/c++/include/objmgr/impl/seq_table_info.hpp
index 59df0fa..0e25558 100644
--- a/c++/include/objmgr/impl/seq_table_info.hpp
+++ b/c++/include/objmgr/impl/seq_table_info.hpp
@@ -1,7 +1,7 @@
 #ifndef SEQ_TABLE_INFO__HPP
 #define SEQ_TABLE_INFO__HPP
 
-/*  $Id: seq_table_info.hpp 458003 2015-01-29 19:47:52Z vasilche $
+/*  $Id: seq_table_info.hpp 502681 2016-05-26 16:04:36Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -37,6 +37,7 @@
 #include <objmgr/impl/seq_table_setter.hpp>
 #include <objects/seq/seq_id_handle.hpp>
 #include <objects/seqloc/Na_strand.hpp>
+#include <objects/seqtable/Seq_table.hpp>
 #include <objects/seqtable/SeqTable_column.hpp>
 #include <objects/seqtable/SeqTable_column_info.hpp>
 #include <util/range.hpp>
@@ -53,6 +54,8 @@ class CSeq_point;
 class CSeq_feat;
 struct SAnnotObject_Key;
 struct SAnnotObject_Index;
+struct SAnnotTypeSelector;
+struct SAnnotSelector;
 
 /////////////////////////////////////////////////////////////////////////////
 // information about Seq-table column
@@ -83,6 +86,8 @@ public:
             return m_Column.GetPointer();
         }
 
+    bool IsSingular(void) const;
+
     bool IsSet(size_t row) const;
 
     bool GetBool(size_t row) const
@@ -152,6 +157,7 @@ public:
     CConstRef<CSeq_loc> GetLoc(size_t row) const;
     CConstRef<CSeq_id> GetId(size_t row) const;
     CSeq_id_Handle GetIdHandle(size_t row) const;
+    TSeqPos GetFrom(size_t row) const;
     CRange<TSeqPos> GetRange(size_t row) const;
     ENa_strand GetStrand(size_t row) const;
 
@@ -162,11 +168,14 @@ public:
         return m_Is_real_loc;
     }
 
+
     void SetTableKeyAndIndex(size_t row,
                              SAnnotObject_Key& key,
                              SAnnotObject_Index& index) const;
 
 private:
+    friend class CSeqTableInfo;
+
     CTempString m_FieldName;
     CSeqTable_column_info::EField_id m_BaseValue;
 
@@ -205,12 +214,23 @@ public:
         return m_IsFeatTable;
     }
 
+    size_t GetNumRows(void) const {
+        return m_Seq_table->GetNum_rows();
+    }
+
     void UpdateSeq_feat(size_t row,
                         CRef<CSeq_feat>& seq_feat,
                         CRef<CSeq_point>& seq_pnt,
                         CRef<CSeq_interval>& seq_int) const;
 
     CConstRef<CSeq_loc> GetTableLocation(void) const;
+    TSeqPos GetSortedMaxLength(void) const;
+
+    bool IsSorted(void) const {
+        return m_IsSorted;
+    }
+
+    SAnnotTypeSelector GetType(void) const;
 
     const CSeqTableLocColumns& GetLocation(void) const {
         return m_Location;
@@ -224,6 +244,24 @@ public:
     bool IsPartial(size_t row) const {
         return m_Partial.GetBool(row);
     }
+    
+    CConstRef<CSeq_id> GetLocationId(size_t row) const {
+        return GetLocation().GetId(row);
+    }
+    TSeqPos GetLocationFrom(size_t row) const {
+        return GetLocation().GetFrom(row);
+    }
+    CRange<TSeqPos> GetLocationRange(size_t row) const {
+        return GetLocation().GetRange(row);
+    }
+    ENa_strand GetLocationStrand(size_t row) const {
+        return GetLocation().GetStrand(row);
+    }
+
+    bool HasLabel(size_t row) const;
+    string GetLabel(size_t row) const;
+
+    bool MatchBitFilter(const SAnnotSelector& sel, size_t row) const;
 
     // returns null if column not found
     const CSeqTableColumnInfo* FindColumn(int field_id) const;
@@ -240,14 +278,20 @@ private:
     typedef vector<TColumnInfo> TExtraColumns;
 
     void x_Initialize(const CSeq_table& table);
+    bool x_IsSorted(void) const;
 
+    CConstRef<CSeq_table> m_Seq_table;
     bool m_IsFeatTable;
+    bool m_IsSorted;
     CSeqTableColumnInfo m_Disabled;
     CSeqTableLocColumns m_Location;
     CSeqTableLocColumns m_Product;
     CSeqTableColumnInfo m_Partial;
     TExtraColumns m_ExtraColumns;
 
+    CConstRef<CSeq_loc> m_TableLocation;
+    TSeqPos m_SortedMaxLength;
+
     typedef map<int, CSeqTableColumnInfo> TColumnsById;
     typedef map<string, CSeqTableColumnInfo> TColumnsByName;
     TColumnsById m_ColumnsById;
diff --git a/c++/include/objmgr/impl/seq_table_setters.hpp b/c++/include/objmgr/impl/seq_table_setters.hpp
index 0c18456..a447a84 100644
--- a/c++/include/objmgr/impl/seq_table_setters.hpp
+++ b/c++/include/objmgr/impl/seq_table_setters.hpp
@@ -1,7 +1,7 @@
 #ifndef SEQ_TABLE_SETTERS__HPP
 #define SEQ_TABLE_SETTERS__HPP
 
-/*  $Id: seq_table_setters.hpp 458003 2015-01-29 19:47:52Z vasilche $
+/*  $Id: seq_table_setters.hpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -86,8 +86,8 @@ public:
 class CSeqTableSetQual : public CSeqTableSetFeatField
 {
 public:
-    CSeqTableSetQual(const CTempString& name)
-        : name(name.substr(2))
+    CSeqTableSetQual(const CTempString& name_str)
+        : name(name_str.substr(2))
         {
         }
 
@@ -122,8 +122,8 @@ private:
 class CSeqTableSetDbxref : public CSeqTableSetFeatField
 {
 public:
-    CSeqTableSetDbxref(const CTempString& name)
-        : name(name.substr(2))
+    CSeqTableSetDbxref(const CTempString& name_str)
+        : name(name_str.substr(2))
         {
         }
 
diff --git a/c++/include/objmgr/impl/seq_vector_cvt_gen.hpp b/c++/include/objmgr/impl/seq_vector_cvt_gen.hpp
index 46435db..fce3a41 100644
--- a/c++/include/objmgr/impl/seq_vector_cvt_gen.hpp
+++ b/c++/include/objmgr/impl/seq_vector_cvt_gen.hpp
@@ -1,6 +1,6 @@
 #ifndef SEQ_VECTOR_CVT_GEN__HPP
 #define SEQ_VECTOR_CVT_GEN__HPP
-/*  $Id: seq_vector_cvt_gen.hpp 103491 2007-05-04 17:18:18Z kazimird $
+/*  $Id: seq_vector_cvt_gen.hpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -245,9 +245,9 @@ void copy_2bit(DstIter dst, size_t count,
         _ASSERT(src >= srcCont.begin() && src < srcCont.end());
         char c3 = *src;
         ++src;
-        char c0 = c3 >> 6;
-        char c1 = c3 >> 4;
-        char c2 = c3 >> 2;
+        char c0 = char(c3 >> 6);
+        char c1 = char(c3 >> 4);
+        char c2 = char(c3 >> 2);
         c0 &= 0x03;
         c1 &= 0x03;
         c2 &= 0x03;
@@ -303,9 +303,9 @@ void copy_2bit_table(DstIter dst, size_t count,
         _ASSERT(src >= srcCont.begin() && src < srcCont.end());
         char c3 = *src;
         ++src;
-        char c0 = c3 >> 6;
-        char c1 = c3 >> 4;
-        char c2 = c3 >> 2;
+        char c0 = char(c3 >> 6);
+        char c1 = char(c3 >> 4);
+        char c2 = char(c3 >> 2);
         c0 = table[c0 & 0x03];
         c1 = table[c1 & 0x03];
         *dst   = c0;
@@ -359,9 +359,9 @@ void copy_2bit_reverse(DstIter dst, size_t count,
     for ( DstIter end = dst + (count & ~3); dst != end; dst += 4 ) {
         _ASSERT(src > srcCont.begin() && src <= srcCont.end());
         char c0 = *--src;
-        char c1 = c0 >> 2;
-        char c2 = c0 >> 4;
-        char c3 = c0 >> 6;
+        char c1 = char(c0 >> 2);
+        char c2 = char(c0 >> 4);
+        char c3 = char(c0 >> 6);
         c0 &= 0x03;
         c1 &= 0x03;
         c2 &= 0x03;
@@ -416,9 +416,9 @@ void copy_2bit_table_reverse(DstIter dst, size_t count,
     for ( DstIter end = dst + (count & ~3); dst != end; dst += 4 ) {
         _ASSERT(src > srcCont.begin() && src <= srcCont.end());
         char c0 = *--src;
-        char c1 = c0 >> 2;
-        char c2 = c0 >> 4;
-        char c3 = c0 >> 6;
+        char c1 = char(c0 >> 2);
+        char c2 = char(c0 >> 4);
+        char c3 = char(c0 >> 6);
         c0 = table[c0 & 0x03];
         c1 = table[c1 & 0x03];
         *dst   = c0;
diff --git a/c++/include/objmgr/impl/snp_annot_info.hpp b/c++/include/objmgr/impl/snp_annot_info.hpp
index 7055bea..690f734 100644
--- a/c++/include/objmgr/impl/snp_annot_info.hpp
+++ b/c++/include/objmgr/impl/snp_annot_info.hpp
@@ -1,7 +1,7 @@
 #ifndef SNP_ANNOT_INFO__HPP
 #define SNP_ANNOT_INFO__HPP
 
-/*  $Id: snp_annot_info.hpp 484035 2015-11-05 18:59:48Z vasilche $
+/*  $Id: snp_annot_info.hpp 500967 2016-05-10 14:39:30Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -202,6 +202,9 @@ public:
     CSeq_annot& GetRemainingSeq_annot(void);
     void Reset(void);
 
+    bool HasLabel(size_t index) const;
+    string GetLabel(size_t index) const;
+
     // filling SNP table from parser
     void x_AddSNP(const SSNP_Info& snp_info);
     void x_FinishParsing(void);
@@ -425,6 +428,20 @@ size_t CSeq_annot_SNP_Info::GetIndex(const SSNP_Info& info) const
 }
 
 
+inline
+bool CSeq_annot_SNP_Info::HasLabel(size_t index) const
+{
+    return GetInfo(index).HasLabel(*this);
+}
+
+
+inline
+string CSeq_annot_SNP_Info::GetLabel(size_t index) const
+{
+    return GetInfo(index).GetLabel(*this);
+}
+
+
 END_SCOPE(objects)
 END_NCBI_SCOPE
 
diff --git a/c++/include/objmgr/impl/snp_info.hpp b/c++/include/objmgr/impl/snp_info.hpp
index 7fb0cef..74845a2 100644
--- a/c++/include/objmgr/impl/snp_info.hpp
+++ b/c++/include/objmgr/impl/snp_info.hpp
@@ -1,7 +1,7 @@
 #ifndef SNP_INFO__HPP
 #define SNP_INFO__HPP
 
-/*  $Id: snp_info.hpp 406813 2013-07-16 15:04:34Z vasilche $
+/*  $Id: snp_info.hpp 500967 2016-05-10 14:39:30Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -167,6 +167,7 @@ public:
         fQualityCodesMask  = fQualityCodesStr | fQualityCodesOs
     };
 
+    bool HasAlleles(void) const;
     size_t GetAllelesCount(void) const;
     TAlleleIndex GetAlleleStrIndex(size_t index) const;
     TExtraIndex GetExtraIndex(void) const;
@@ -174,6 +175,9 @@ public:
     TQualityCodesIndex GetQualityCodesStrIndex(void) const;
     TQualityCodesIndex GetQualityCodesOsIndex(void) const;
 
+    bool HasLabel(const CSeq_annot_SNP_Info& info) const;
+    string GetLabel(const CSeq_annot_SNP_Info& info) const;
+
     TSeqPos         m_ToPosition;
     TSNPId          m_SNP_Id;
     TFlags          m_Flags;
@@ -260,6 +264,13 @@ bool SSNP_Info::NotThis(const TRange& range) const
 
 
 inline
+bool SSNP_Info::HasAlleles(void) const
+{
+    return m_AllelesIndices[0] != kNo_AlleleIndex;
+}
+
+
+inline
 SSNP_Info::TAlleleIndex SSNP_Info::GetAlleleStrIndex(size_t index) const
 {
     _ASSERT(index < GetAllelesCount());
@@ -268,6 +279,13 @@ SSNP_Info::TAlleleIndex SSNP_Info::GetAlleleStrIndex(size_t index) const
 
 
 inline
+bool SSNP_Info::HasLabel(const CSeq_annot_SNP_Info&) const
+{
+    return HasAlleles();
+}
+
+
+inline
 SSNP_Info::TExtraIndex SSNP_Info::GetExtraIndex(void) const
 {
     return m_ExtraIndex;
diff --git a/c++/include/objmgr/impl/tse_info.hpp b/c++/include/objmgr/impl/tse_info.hpp
index 7d7f143..8cc9b82 100644
--- a/c++/include/objmgr/impl/tse_info.hpp
+++ b/c++/include/objmgr/impl/tse_info.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_OBJMGR_IMPL___TSE_INFO__HPP
 #define OBJECTS_OBJMGR_IMPL___TSE_INFO__HPP
 
-/*  $Id: tse_info.hpp 446824 2014-09-18 14:47:47Z vasilche $
+/*  $Id: tse_info.hpp 518178 2016-11-01 11:46:07Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -371,6 +371,7 @@ public:
     const CTSE_Split_Info& GetSplitInfo(void) const;
     bool HasSplitInfo(void) const;
     bool x_NeedsDelayedMainChunk(void) const;
+    void x_LoadDelayedMainChunk(void) const;
 
     const CSeq_id_Handle& GetRequestedId(void) const;
     void SetRequestedId(const CSeq_id_Handle& requested_id) const;
diff --git a/c++/include/objmgr/impl/tse_info_object.hpp b/c++/include/objmgr/impl/tse_info_object.hpp
index 21b1383..830af92 100644
--- a/c++/include/objmgr/impl/tse_info_object.hpp
+++ b/c++/include/objmgr/impl/tse_info_object.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_OBJMGR_IMPL___TSE_INFO_OBJECT__HPP
 #define OBJECTS_OBJMGR_IMPL___TSE_INFO_OBJECT__HPP
 
-/*  $Id: tse_info_object.hpp 381070 2012-11-19 15:49:14Z vasilche $
+/*  $Id: tse_info_object.hpp 516279 2016-10-12 13:41:47Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -130,7 +130,8 @@ public:
         fNeedUpdate_children_annot    = fNeedUpdate_annot   <<kNeedUpdate_bits,
         fNeedUpdate_children_seq_data = fNeedUpdate_seq_data<<kNeedUpdate_bits,
         fNeedUpdate_children_core     = fNeedUpdate_core    <<kNeedUpdate_bits,
-        fNeedUpdate_children_assembly = fNeedUpdate_assembly<<kNeedUpdate_bits
+        fNeedUpdate_children_assembly = fNeedUpdate_assembly<<kNeedUpdate_bits,
+        fNeedUpdate_children_bioseq   = fNeedUpdate_bioseq  <<kNeedUpdate_bits
     };
     typedef int TNeedUpdateFlags;
     bool x_NeedUpdate(ENeedUpdate flag) const;
diff --git a/c++/include/objmgr/impl/tse_split_info.hpp b/c++/include/objmgr/impl/tse_split_info.hpp
index d621998..bc451b9 100644
--- a/c++/include/objmgr/impl/tse_split_info.hpp
+++ b/c++/include/objmgr/impl/tse_split_info.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_OBJMGR_IMPL___TSE_SPLIT_INFO__HPP
 #define OBJECTS_OBJMGR_IMPL___TSE_SPLIT_INFO__HPP
 
-/*  $Id: tse_split_info.hpp 471824 2015-07-01 17:23:26Z vasilche $
+/*  $Id: tse_split_info.hpp 518178 2016-11-01 11:46:07Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -111,6 +111,7 @@ public:
 
     bool x_HasDelayedMainChunk(void) const;
     bool x_NeedsDelayedMainChunk(void) const;
+    void x_LoadDelayedMainChunk(void) const;
 
     // split information
     void x_AddDescInfo(const TDescInfo& info, TChunkId chunk_id);
diff --git a/c++/include/objmgr/object_manager.hpp b/c++/include/objmgr/object_manager.hpp
index 9ba69a3..23b9311 100644
--- a/c++/include/objmgr/object_manager.hpp
+++ b/c++/include/objmgr/object_manager.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECT_MANAGER__HPP
 #define OBJECT_MANAGER__HPP
 
-/*  $Id: object_manager.hpp 498421 2016-04-15 18:44:37Z ivanov $
+/*  $Id: object_manager.hpp 498345 2016-04-15 14:39:08Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objmgr/objmgr_exception.hpp b/c++/include/objmgr/objmgr_exception.hpp
index f33e123..3e6e827 100644
--- a/c++/include/objmgr/objmgr_exception.hpp
+++ b/c++/include/objmgr/objmgr_exception.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJMGR_EXCEPTION__HPP
 #define OBJMGR_EXCEPTION__HPP
 
-/*  $Id: objmgr_exception.hpp 494477 2016-03-07 19:25:35Z ivanov $
+/*  $Id: objmgr_exception.hpp 493168 2016-02-24 19:28:38Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objmgr/scope.hpp b/c++/include/objmgr/scope.hpp
index b66fa1b..03e0856 100644
--- a/c++/include/objmgr/scope.hpp
+++ b/c++/include/objmgr/scope.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJMGR_SCOPE__HPP
 #define OBJMGR_SCOPE__HPP
 
-/*  $Id: scope.hpp 494477 2016-03-07 19:25:35Z ivanov $
+/*  $Id: scope.hpp 493168 2016-02-24 19:28:38Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objmgr/seq_feat_handle.hpp b/c++/include/objmgr/seq_feat_handle.hpp
index 9a2b9ff..9ec4a68 100644
--- a/c++/include/objmgr/seq_feat_handle.hpp
+++ b/c++/include/objmgr/seq_feat_handle.hpp
@@ -1,7 +1,7 @@
 #ifndef SEQ_FEAT_HANDLE__HPP
 #define SEQ_FEAT_HANDLE__HPP
 
-/*  $Id: seq_feat_handle.hpp 483571 2015-11-02 17:33:20Z vasilche $
+/*  $Id: seq_feat_handle.hpp 499886 2016-04-28 19:54:10Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -103,6 +103,9 @@ public:
     /// Check if this is non-SNP table feature
     bool IsTableFeat(void) const;
 
+    /// Check if this is a simple feature from sorted Seq-table
+    bool IsSortedTableFeat(void) const;
+
     /// Check if this is SNP table feature
     bool IsTableSNP(void) const;
 
@@ -224,10 +227,11 @@ protected:
     friend class CScope_Impl;
     typedef Int4 TFeatIndex;
     enum {
-        kSNPTableBit   = 0x80000000,
+        kNoAnnotObjectInfo = 0x80000000,
         kFeatIndexMask = 0x7fffffff
     };
 
+    bool x_HasAnnotObjectInfo() const;
     TFeatIndex x_GetFeatIndex() const;
 
     // Seq-annot retrieval
@@ -285,6 +289,13 @@ CScope& CSeq_feat_Handle::GetScope(void) const
 
 
 inline
+bool CSeq_feat_Handle::x_HasAnnotObjectInfo(void) const
+{
+    return (m_FeatIndex & kNoAnnotObjectInfo) == 0;
+}
+
+
+inline
 CSeq_feat_Handle::TFeatIndex CSeq_feat_Handle::x_GetFeatIndex(void) const
 {
     return m_FeatIndex & kFeatIndexMask;
@@ -416,7 +427,7 @@ inline
 bool CSeq_feat_Handle::IsSetProduct(void) const
 {
     // table SNP features do not have product
-    return !IsTableSNP() && GetSeq_feat()->IsSetProduct();
+    return x_HasAnnotObjectInfo() && GetSeq_feat()->IsSetProduct();
 }
 
 
@@ -585,24 +596,6 @@ const CSeq_feat::TExts& CSeq_feat_Handle::GetExts(void) const
 }
 
 
-inline
-CSeqFeatData::E_Choice CSeq_feat_Handle::GetFeatType(void) const
-{
-    return IsTableSNP()?
-        CSeqFeatData::e_Imp:
-        x_GetAnnotObject_Info().GetFeatType();
-}
-
-
-inline
-CSeqFeatData::ESubtype CSeq_feat_Handle::GetFeatSubtype(void) const
-{
-    return IsTableSNP()?
-        CSeqFeatData::eSubtype_variation:
-        x_GetAnnotObject_Info().GetFeatSubtype();
-}
-
-
 /////////////////////////////////////////////////////////////////////////////
 ///
 ///  CSeq_feat_EditHandle --
@@ -801,8 +794,8 @@ class NCBI_XOBJMGR_EXPORT CSeq_annot_ftable_I
 {
 public:
     enum EFlags {
-        fIncludeTable    = 1<<0,
-        fOnlyTable       = 1<<1
+        fIncludeTable    = 1<<0, // include SNP table into iteration
+        fOnlyTable       = 1<<1  // only SNP table features
     };
     typedef int TFlags;
 
diff --git a/c++/include/objmgr/seq_loc_mapper.hpp b/c++/include/objmgr/seq_loc_mapper.hpp
index 82f4398..93040e3 100644
--- a/c++/include/objmgr/seq_loc_mapper.hpp
+++ b/c++/include/objmgr/seq_loc_mapper.hpp
@@ -1,7 +1,7 @@
 #ifndef SEQ_LOC_MAPPER__HPP
 #define SEQ_LOC_MAPPER__HPP
 
-/*  $Id: seq_loc_mapper.hpp 479439 2015-09-21 13:04:11Z grichenk $
+/*  $Id: seq_loc_mapper.hpp 505837 2016-06-29 15:06:52Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -113,23 +113,23 @@ public:
     /// target one. If scope is set, synonyms are resolved for each source ID.
     /// Only the first row matching target ID is used, all other rows
     /// are considered source.
-    CSeq_loc_Mapper(const CSeq_align& map_align,
-                    const CSeq_id&    to_id,
-                    CScope*           scope = 0,
-                    TMapOptions       opts = 0);
-    CSeq_loc_Mapper(const CSeq_align& map_align,
-                    size_t            to_row,
-                    CScope*           scope = 0,
-                    TMapOptions       opts = 0);
+    CSeq_loc_Mapper(const CSeq_align&       map_align,
+                    const CSeq_id&          to_id,
+                    CScope*                 scope = 0,
+                    CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
+    CSeq_loc_Mapper(const CSeq_align&       map_align,
+                    size_t                  to_row,
+                    CScope*                 scope = 0,
+                    CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
 
     /// Mapping between segments and the top level sequence.
     /// @param target_seq
     ///  Top level bioseq
     /// @param direction
     ///  Direction of mapping: up (from segments to master) or down.
-    CSeq_loc_Mapper(CBioseq_Handle   target_seq,
-                    ESeqMapDirection direction,
-                    TMapOptions      opts = 0);
+    CSeq_loc_Mapper(CBioseq_Handle          target_seq,
+                    ESeqMapDirection        direction,
+                    CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
 
     /// Mapping between segments and the top level sequence.
     /// @param target_seq
@@ -139,10 +139,10 @@ public:
     /// @param selector
     ///  Seq-map selector with additional restrictions (range, strand etc.).
     ///  Some properties of the selector are always adjusted by the mapper.
-    CSeq_loc_Mapper(CBioseq_Handle   target_seq,
-                    ESeqMapDirection direction,
-                    SSeqMapSelector  selector,
-                    TMapOptions      opts = 0);
+    CSeq_loc_Mapper(CBioseq_Handle          target_seq,
+                    ESeqMapDirection        direction,
+                    SSeqMapSelector         selector,
+                    CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
 
     /// Mapping through a seq-map.
     /// @param seq_map
@@ -152,11 +152,11 @@ public:
     /// @param top_level_id
     ///  Explicit destination id when mapping up, may be used with
     ///  seq-maps constructed from a seq-loc with multiple ids.
-    CSeq_loc_Mapper(const CSeqMap&   seq_map,
-                    ESeqMapDirection direction,
-                    const CSeq_id*   top_level_id = 0,
-                    CScope*          scope = 0,
-                    TMapOptions      opts = 0);
+    CSeq_loc_Mapper(const CSeqMap&          seq_map,
+                    ESeqMapDirection        direction,
+                    const CSeq_id*          top_level_id = 0,
+                    CScope*                 scope = 0,
+                    CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
 
     /// Mapping through a seq-map.
     /// @param seq_map
@@ -169,12 +169,12 @@ public:
     /// @param top_level_id
     ///  Explicit destination id when mapping up, may be used with
     ///  seq-maps constructed from a seq-loc with multiple ids.
-    CSeq_loc_Mapper(const CSeqMap&   seq_map,
-                    ESeqMapDirection direction,
-                    SSeqMapSelector  selector,
-                    const CSeq_id*   top_level_id = 0,
-                    CScope*          scope = 0,
-                    TMapOptions      opts = 0);
+    CSeq_loc_Mapper(const CSeqMap&          seq_map,
+                    ESeqMapDirection        direction,
+                    SSeqMapSelector         selector,
+                    const CSeq_id*          top_level_id = 0,
+                    CScope*                 scope = 0,
+                    CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
 
     /// Mapping between segments and the top level sequence limited by depth.
     /// @param depth
@@ -183,10 +183,10 @@ public:
     ///  Top level bioseq
     /// @param direction
     ///  Direction of mapping: up (from segments to master) or down.
-    CSeq_loc_Mapper(size_t                depth,
-                    const CBioseq_Handle& top_level_seq,
-                    ESeqMapDirection      direction,
-                    TMapOptions           opts = 0);
+    CSeq_loc_Mapper(size_t                  depth,
+                    const CBioseq_Handle&   top_level_seq,
+                    ESeqMapDirection        direction,
+                    CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
 
     /// Depth-limited mapping through a seq-map.
     /// @param depth
@@ -198,12 +198,12 @@ public:
     /// @param top_level_id
     ///  Explicit destination id when mapping up, may be used with
     ///  seq-maps constructed from a seq-loc with multiple ids.
-    CSeq_loc_Mapper(size_t           depth,
-                    const CSeqMap&   top_level_seq,
-                    ESeqMapDirection direction,
-                    const CSeq_id*   top_level_id = 0,
-                    CScope*          scope = 0,
-                    TMapOptions      opts = 0);
+    CSeq_loc_Mapper(size_t                  depth,
+                    const CSeqMap&          top_level_seq,
+                    ESeqMapDirection        direction,
+                    const CSeq_id*          top_level_id = 0,
+                    CScope*                 scope = 0,
+                    CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
 
     /// Destination of seq-id mapping through a GC-Assembly.
     enum EGCAssemblyAlias {
@@ -231,12 +231,12 @@ public:
                     CScope*             scope = 0,
                     EScopeFlag          scope_flag = eCopyScope);
     /// Initialize the mapper to map through deltas from a GC-Assembly.
-    CSeq_loc_Mapper(const CGC_Assembly& gc_assembly,
-                    ESeqMapDirection    direction,
-                    SSeqMapSelector     selector,
-                    CScope*             scope = 0,
-                    EScopeFlag          scope_flag = eCopyScope,
-                    TMapOptions         opts = 0);
+    CSeq_loc_Mapper(const CGC_Assembly&     gc_assembly,
+                    ESeqMapDirection        direction,
+                    SSeqMapSelector         selector,
+                    CScope*                 scope = 0,
+                    EScopeFlag              scope_flag = eCopyScope,
+                    CSeq_loc_Mapper_Options options = CSeq_loc_Mapper_Options());
 
     ~CSeq_loc_Mapper(void);
 
diff --git a/c++/include/objmgr/seq_map.hpp b/c++/include/objmgr/seq_map.hpp
index 822e04c..d9ccc0b 100644
--- a/c++/include/objmgr/seq_map.hpp
+++ b/c++/include/objmgr/seq_map.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_OBJMGR___SEQ_MAP__HPP
 #define OBJECTS_OBJMGR___SEQ_MAP__HPP
 
-/*  $Id: seq_map.hpp 499042 2016-04-21 17:39:04Z ivanov $
+/*  $Id: seq_map.hpp 496211 2016-03-24 15:33:11Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objmgr/seq_map_ci.hpp b/c++/include/objmgr/seq_map_ci.hpp
index 7844834..ffcb3f6 100644
--- a/c++/include/objmgr/seq_map_ci.hpp
+++ b/c++/include/objmgr/seq_map_ci.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_OBJMGR___SEQ_MAP_CI__HPP
 #define OBJECTS_OBJMGR___SEQ_MAP_CI__HPP
 
-/*  $Id: seq_map_ci.hpp 499042 2016-04-21 17:39:04Z ivanov $
+/*  $Id: seq_map_ci.hpp 496211 2016-03-24 15:33:11Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objmgr/seq_vector_ci.hpp b/c++/include/objmgr/seq_vector_ci.hpp
index 91ad057..cc9b4fc 100644
--- a/c++/include/objmgr/seq_vector_ci.hpp
+++ b/c++/include/objmgr/seq_vector_ci.hpp
@@ -1,7 +1,7 @@
 #ifndef SEQ_VECTOR_CI__HPP
 #define SEQ_VECTOR_CI__HPP
 
-/*  $Id: seq_vector_ci.hpp 414728 2013-09-26 15:15:41Z vasilche $
+/*  $Id: seq_vector_ci.hpp 520631 2016-11-30 13:12:58Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -133,7 +133,7 @@ public:
     void GetSeqData(string& buffer, TSeqPos count);
 
     /// Get number of chars from current position to the current buffer end
-    size_t GetBufferSize(void) const;
+    TSeqPos GetBufferSize(void) const;
     /// Get pointer to current char in the buffer
     const char* GetBufferPtr(void) const;
     /// Get pointer to current position+size.
@@ -201,6 +201,8 @@ public:
 
     DECLARE_OPERATOR_BOOL(IsValid());
 
+    const CSeqMap_CI& GetCurrentSeqMap_CI() const;
+
     /// true if current position of CSeqVector_CI is inside of sequence gap
     bool IsInGap(void) const;
     /// returns gap Seq-data object ref
@@ -474,6 +476,13 @@ CSeqVector_CI::TResidue CSeqVector_CI::operator*(void) const
 
 
 inline
+const CSeqMap_CI& CSeqVector_CI::GetCurrentSeqMap_CI(void) const
+{
+    return m_Seg;
+}
+
+
+inline
 bool CSeqVector_CI::IsInGap(void) const
 {
     return m_Seg.GetType() == CSeqMap::eSeqGap;
@@ -517,9 +526,9 @@ void CSeqVector_CI::GetSeqData(TSeqPos start, TSeqPos stop, string& buffer)
 
 
 inline
-size_t CSeqVector_CI::GetBufferSize(void) const
+TSeqPos CSeqVector_CI::GetBufferSize(void) const
 {
-    return m_CacheEnd - m_Cache;
+    return TSeqPos(m_CacheEnd - m_Cache);
 }
 
 
diff --git a/c++/include/objmgr/split/size.hpp b/c++/include/objmgr/split/size.hpp
index 8941f5e..24c3356 100644
--- a/c++/include/objmgr/split/size.hpp
+++ b/c++/include/objmgr/split/size.hpp
@@ -1,7 +1,7 @@
 #ifndef NCBI_OBJMGR_SPLIT_SIZE__HPP
 #define NCBI_OBJMGR_SPLIT_SIZE__HPP
 
-/*  $Id: size.hpp 160976 2009-05-21 15:38:31Z vasilche $
+/*  $Id: size.hpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -96,7 +96,7 @@ public:
         }
     double GetRatio(void) const
         {
-            return double(m_ZipSize)/m_AsnSize;
+            return (double)m_ZipSize/(double)m_AsnSize;
         }
 
     CNcbiOstream& Print(CNcbiOstream& out) const;
diff --git a/c++/include/objmgr/util/create_defline.hpp b/c++/include/objmgr/util/create_defline.hpp
index 2df694f..b513704 100644
--- a/c++/include/objmgr/util/create_defline.hpp
+++ b/c++/include/objmgr/util/create_defline.hpp
@@ -276,6 +276,9 @@ private:
     bool m_IsUnverified;
     CTempString m_TargetedLocus;
 
+    /// comment fields
+    bool m_IsPseudogene;
+
     /// map fields
     string m_rEnzyme;
 
diff --git a/c++/include/objmgr/util/feature.hpp b/c++/include/objmgr/util/feature.hpp
index 6ac0749..046714a 100644
--- a/c++/include/objmgr/util/feature.hpp
+++ b/c++/include/objmgr/util/feature.hpp
@@ -1,7 +1,7 @@
 #ifndef FEAT__HPP
 #define FEAT__HPP
 
-/*  $Id: feature.hpp 499447 2016-04-26 14:17:39Z ivanov $
+/*  $Id: feature.hpp 497406 2016-04-06 15:30:54Z ludwigf $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -69,10 +69,11 @@ BEGIN_SCOPE(feature)
  */
 
 enum FFeatLabelFlags {
-    fFGL_Type       = 1 <<  1, ///< Always include the feature's type.
-    fFGL_Content    = 1 <<  2, ///< Include its content if there is any.
-    fFGL_Both       = fFGL_Type | fFGL_Content,
-    fFGL_NoComments = 1 <<  3  ///< Leave out comments, even as fallbacks.
+    fFGL_Type         = 1 <<  1, ///< Always include the feature's type.
+    fFGL_Content      = 1 <<  2, ///< Include its content if there is any.
+    fFGL_Both         = fFGL_Type | fFGL_Content,
+    fFGL_NoComments   = 1 <<  3, ///< Leave out comments, even as fallbacks.
+    fFGL_NoQualifiers = 1 <<  4  ///< Leave out qualifiers.
 };
 typedef int TFeatLabelFlags; ///< binary OR of FFeatLabelFlags
 
diff --git a/c++/include/objmgr/util/obj_sniff.hpp b/c++/include/objmgr/util/obj_sniff.hpp
index 237317e..6f1cbfa 100644
--- a/c++/include/objmgr/util/obj_sniff.hpp
+++ b/c++/include/objmgr/util/obj_sniff.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJ_SNIFF__HPP
 #define OBJ_SNIFF__HPP
 
-/*  $Id: obj_sniff.hpp 462343 2015-03-18 12:44:25Z vasilche $
+/*  $Id: obj_sniff.hpp 518485 2016-11-03 16:05:20Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -162,9 +162,26 @@ public:
     bool GetDiscardObjectInfo() const
         { return m_DiscardObjInfo; }
 
+    /// Report syntax errors to client (as an exception)
+    ///
+    /// In case Sniffer has enough information about expected data type
+    /// but the data has syntax error, the read attempt fails and the Sniffer
+    /// can either hide the error reporting it as an unrecognized type,
+    /// or rethrow the exception to be caught by client for further analysis.
+    ///
+    /// @param report
+    ///   Rethrow serialization exceptions
+    void SetReportDataErrors(bool report = true) {
+        m_ReportErrors = report;
+    }
+    bool GetReportDataErrors(void) const {
+        return m_ReportErrors;
+    }
+
 protected:
     void ProbeText(CObjectIStream& input);
     void ProbeASN1_Bin(CObjectIStream& input);
+    void ProbeAny(CObjectIStream& input);
 
 protected:
     TObjectStack         m_CallStack;
@@ -172,7 +189,7 @@ protected:
     friend class COffsetReadHook;
 private:
 
-    void x_ReadObject(CObjectIStream& input,
+    bool x_ReadObject(CObjectIStream& input,
                       CObjectTypeInfo object_info);
     bool x_TryReadObject(CObjectIStream& input,
                          CObjectTypeInfo object_info);
@@ -190,6 +207,8 @@ private:
     bool                m_DiscardCurrObj;
     /// Flag indicates that object info should be discarded
     bool                m_DiscardObjInfo;
+    /// Report data errors
+    bool                m_ReportErrors;
 };
 
 
diff --git a/c++/include/objmgr/util/seq_loc_util.hpp b/c++/include/objmgr/util/seq_loc_util.hpp
index f6912a6..311f967 100644
--- a/c++/include/objmgr/util/seq_loc_util.hpp
+++ b/c++/include/objmgr/util/seq_loc_util.hpp
@@ -1,7 +1,7 @@
 #ifndef SEQ_LOC_UTIL__HPP
 #define SEQ_LOC_UTIL__HPP
 
-/*  $Id: seq_loc_util.hpp 451986 2014-11-13 20:13:31Z grichenk $
+/*  $Id: seq_loc_util.hpp 500277 2016-05-03 16:55:57Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -300,7 +300,7 @@ enum EOverlapFlags {
     fOverlap_IgnoreTopology = 1 << 2, ///< Ignore sequence topology (circularity)
     fOverlap_Default = 0              ///< Enable multi-id, multi-strand, check topology
 };
-
+typedef int TOverlapFlags;
 
 /// Updated version of TestForOverlap64(). Allows more control over
 /// handling multi-id/multi-strand bioseqs.
@@ -311,7 +311,7 @@ Int8 TestForOverlapEx(const CSeq_loc& loc1,
                       const CSeq_loc& loc2,
                       EOverlapType    type,
                       CScope*         scope = 0,
-                      EOverlapFlags   flags = fOverlap_Default);
+                      TOverlapFlags   flags = fOverlap_Default);
 
 /// Calls TestForOverlap64() and if the result is greater than kMax_Int
 /// truncates it to kMax_Int. To get the exact value use TestForOverlap64().
diff --git a/c++/include/objmgr/util/sequence.hpp b/c++/include/objmgr/util/sequence.hpp
index f94ed77..d9213f7 100644
--- a/c++/include/objmgr/util/sequence.hpp
+++ b/c++/include/objmgr/util/sequence.hpp
@@ -1,7 +1,7 @@
 #ifndef SEQUENCE__HPP
 #define SEQUENCE__HPP
 
-/*  $Id: sequence.hpp 499692 2016-04-27 17:18:50Z ivanov $
+/*  $Id: sequence.hpp 520815 2016-12-01 18:50:10Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -584,6 +584,22 @@ CConstRef<CSeq_feat> GetOverlappingGene(
     ETransSplicing eTransSplicing = eTransSplicing_Auto);
 
 
+/// Finds gene for feature, but obeys SeqFeatXref directives
+NCBI_XOBJUTIL_EXPORT
+CConstRef<CSeq_feat> GetGeneForFeature(const CSeq_feat& feat, CScope& scope);
+
+/// Determines whether given feature is pseudo, using gene associated with feature
+/// if necessary
+/// Checks to see if a feature is pseudo. Looks for pseudo flag set on feature,
+/// looks for pseudogene qualifier on feature, performs same checks for gene
+/// associated with feature
+/// @param feat Seq-feat to check
+/// @param scope CScope to use when looking for associated gene
+/// @return Boolean return value indicates whether any of the "pseudo" markers are found
+NCBI_XOBJUTIL_EXPORT
+bool IsPseudo(const CSeq_feat& feat, CScope& scope);
+
+
 NCBI_XOBJUTIL_EXPORT
 CConstRef<CSeq_feat> GetOverlappingmRNA(const CSeq_loc& loc, CScope& scope);
 
@@ -726,19 +742,20 @@ END_SCOPE(sequence)
 class NCBI_XOBJUTIL_EXPORT CFastaOstream {
 public:
     enum EFlags {
-        fAssembleParts      = 0x0001, ///< assemble FAR delta sequences; on by dflt
-        fInstantiateGaps    = 0x0002, ///< honor specifed gap mode; on by default
-        fSuppressRange      = 0x0004, ///< never include location details in defline
-        fReverseStrand      = 0x0008, ///< flip the (implicit) location
-        fKeepGTSigns        = 0x0010, ///< don't convert '>' to '_' in title
-        fMapMasksUp         = 0x0020, ///< honor masks specified at a lower level
-        fMapMasksDown       = 0x0040, ///< honor masks specified at a higher level
-        fNoExpensiveOps     = 0x0080, ///< don't try too hard to find titles
-        fShowModifiers      = 0x0100, ///< show key-value pair modifiers (e.g. "[organism=Homo sapiens]")
-        fNoDupCheck         = 0x0200, ///< skip check for duplicate sequence IDs
-        fShowGapModifiers   = 0x0400, ///< show gap key-value pair modifiers (e.g. "[linkage-evidence=map;strobe]"). Only works if gap mode is eGM_count.
-        fKeepUnknGapNomLen  = 0x0800, ///< Keep unknown gap's nominal length.  That is, when a gap has an unknown length but nominal length, use that instead of just making it 100.
-        fShowGapsOfSizeZero = 0x1000, ///< Use this to show gaps of size zero as a lone hyphen at the end of a line.
+        fAssembleParts      = 1 <<  0, ///< assemble FAR delta sequences; on by dflt
+        fInstantiateGaps    = 1 <<  1, ///< honor specifed gap mode; on by default
+        fSuppressRange      = 1 <<  2, ///< never include location details in defline
+        fReverseStrand      = 1 <<  3, ///< flip the (implicit) location
+        fKeepGTSigns        = 1 <<  4, ///< don't convert '>' to '_' in title
+        fMapMasksUp         = 1 <<  5, ///< honor masks specified at a lower level
+        fMapMasksDown       = 1 <<  6, ///< honor masks specified at a higher level
+        fNoExpensiveOps     = 1 <<  7, ///< don't try too hard to find titles
+        fShowModifiers      = 1 <<  8, ///< show key-value pair modifiers (e.g. "[organism=Homo sapiens]")
+        fNoDupCheck         = 1 <<  9, ///< skip check for duplicate sequence IDs
+        fShowGapModifiers   = 1 << 10, ///< show gap key-value pair modifiers (e.g. "[linkage-evidence=map;strobe]"). Only works if gap mode is eGM_count.
+        fKeepUnknGapNomLen  = 1 << 11, ///< Keep unknown gap's nominal length.  That is, when a gap has an unknown length but nominal length, use that instead of just making it 100.
+        fShowGapsOfSizeZero = 1 << 12, ///< Use this to show gaps of size zero as a lone hyphen at the end of a line.
+        fEnableGI           = 1 << 13, ///< Use this flag to enable GI output in the defline
         // historically misnamed as eFlagName
         eAssembleParts   = fAssembleParts,
         eInstantiateGaps = fInstantiateGaps
@@ -844,6 +861,7 @@ protected:
 
     virtual void x_WriteSeqIds    ( const CBioseq& bioseq,
                                     const CSeq_loc* location);
+    virtual void x_WriteAsFasta   ( const CBioseq& bioseq );
     virtual void x_WriteModifiers ( const CBioseq_Handle & handle );
     virtual void x_WriteSeqTitle  ( const CBioseq& bioseq,
                                     CScope* scope,
diff --git a/c++/include/objtools/align_format/align_format_util.hpp b/c++/include/objtools/align_format/align_format_util.hpp
index e58e7e3..91aa89a 100644
--- a/c++/include/objtools/align_format/align_format_util.hpp
+++ b/c++/include/objtools/align_format/align_format_util.hpp
@@ -1,4 +1,4 @@
-/*  $Id: align_format_util.hpp 488861 2016-01-06 15:45:07Z fongah2 $
+/*  $Id: align_format_util.hpp 520427 2016-11-28 18:24:56Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -63,9 +63,10 @@ BEGIN_SCOPE(align_format)
 ///class info
 static const char kClassInfo[] = "class=\"info\"";
 
+static const char kDefaultProtocol[] = "https:";
 ///entrez
 // .ncbirc alias: ENTREZ
-static const char kEntrezUrl[] = "<a title=\"Show report for <@acc@>\" <@cssInf@>href=\"//www.ncbi.nlm.nih.gov/<@db@>/<@gi@>?report=genbank&log$=<@log@>&blast_rank=<@blast_rank@>&RID=<@rid@>\" <@target@>>";
+static const char kEntrezUrl[] = "<a title=\"Show report for <@acc@>\" <@cssInf@>href=\"<@protocol@>//www.ncbi.nlm.nih.gov/<@db@>/<@gi@>?report=genbank&log$=<@log@>&blast_rank=<@blast_rank@>&RID=<@rid@>\" <@target@>>";
 
 //.ncbirc alias: ENTREZ_TM
 static const char kEntrezTMUrl[] = "//www.ncbi.nlm.nih.gov/<@db@>/<@gi@>?report=genbank&log$=<@log@>&blast_rank=<@blast_rank@>&RID=<@rid@>";
@@ -466,6 +467,16 @@ public:
         eDbTypeNotSet
     };
 
+    //Formatting flag for adding spaces
+    enum SpacesFormatingFlag {        
+        eSpacePosToCenter = (1 << 0),       ///place the param in the center of the string
+        eSpacePosAtLineStart = (1 << 1),    ///add spaces at the begining of the string
+        eSpacePosAtLineEnd = (1 << 2),      ///add spaces at the end of the string  
+        eAddEOLAtLineStart = (1 << 3),      ///add EOL at the beginning of the string  
+        eAddEOLAtLineEnd =  (1 << 4)        ///add EOL at the end of the string  
+    };
+
+
     ///Output blast errors
     ///@param error_return: list of errors to report
     ///@param error_post: post to stderr or not
@@ -634,6 +645,7 @@ public:
                              int& comp_adj_method);
 
     
+    static void GetUseThisSequence(const objects::CSeq_align& aln,list<TGi>& use_this_gi);
     ///Add the specified white space
     ///@param out: ostream to add white space
     ///@param number: the number of white spaces desired
@@ -1092,7 +1104,29 @@ public:
     ///
     ///<@tmplParamName@> is replaced by templParamVal
     static string MapTemplate(string inpString,string tmplParamName,string templParamVal);
-    
+        
+    ///Replace template tags by real data and calculate and add spaces dependent on maxParamLength and spacesFormatFlag
+    ///@param inpString: string containing template data
+    ///@param tmplParamName:string with template tag name
+    ///@param templParamVal: string value that replaces template
+    ///@param maxParamLength: unsigned int maxParamLength
+    ///@param spacesFormatFlag: int formatting flag
+    ///@return:string containing template data replaced by real data
+    ///
+    ///<@tmplParamName@> is replaced by templParamVal
+    static string MapSpaceTemplate(string inpString,string tmplParamName,string templParamVal, unsigned int maxParamLength, int spacesFormatFlag = eSpacePosAtLineEnd);
+
+    ///Calculate the number of spaces and add them to paramVal
+    ///@param string: input parameter value
+    ///@param string: max length for the string that holds parameter
+    ///@param int: additional fomatting after adding spaces
+    ///@param  string: the position of spaces and additional formatting
+    ///@return:string containing paramVal and spaces place appropriately
+    static string AddSpaces(string paramVal, unsigned int maxParamLength, int spacesFormatFlag = eSpacePosToCenter);
+
+
+    static string GetProtocol(void);
+
     ///Create URL for seqid
     ///@param seqUrlInfo: struct SSeqURLInfo containing data for URL construction
     ///@param id: seqid CSeq_id
@@ -1194,6 +1228,18 @@ public:
     ///@param aln_id: CSeq_id object for alignment seq [in]
     ///@param use_this_gi: list<int> list of gis to use [in]
     ///@param gi: gi to be used for display if exists or 0    
+    ///@param taxid: taxid to be used for display if exists or 0    
+    ///@return: CSeq_id object to be used for display
+    static CRef<objects::CSeq_id> GetDisplayIds(const objects::CBioseq_Handle& handle,
+                                                const objects::CSeq_id& aln_id,
+                                                list<TGi>& use_this_gi,
+                                                TGi& gi,
+                                                int& taxid);
+    ///Scan the the list of blast deflines and find seqID to be use in display    
+    ///@param handle: CBioseq_Handle [in]
+    ///@param aln_id: CSeq_id object for alignment seq [in]
+    ///@param use_this_gi: list<int> list of gis to use [in]
+    ///@param gi: gi to be used for display if exists or 0    
     ///@return: CSeq_id object to be used for display
     static CRef<objects::CSeq_id> GetDisplayIds(const objects::CBioseq_Handle& handle,
                                                 const objects::CSeq_id& aln_id,
@@ -1229,6 +1275,9 @@ public:
 
     static string GetTitle(const objects::CBioseq_Handle & bh);
 
+    /// Get sequence id with no database source (bare accession)
+    static string GetBareId(const objects::CSeq_id& id);
+
 protected:
 
     ///Wrap a string to specified length.  If break happens to be in
diff --git a/c++/include/objtools/align_format/format_flags.hpp b/c++/include/objtools/align_format/format_flags.hpp
index c9a3ae2..85773fb 100644
--- a/c++/include/objtools/align_format/format_flags.hpp
+++ b/c++/include/objtools/align_format/format_flags.hpp
@@ -1,4 +1,4 @@
-/*  $Id: format_flags.hpp 495725 2016-03-21 14:24:26Z ivanov $
+/*  $Id: format_flags.hpp 518046 2016-10-31 14:58:35Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -160,7 +160,8 @@ NCBI_ALIGN_FORMAT_EXPORT extern const size_t kNumTabularOutputFormatSpecifiers;
 NCBI_ALIGN_FORMAT_EXPORT string DescribeTabularOutputFormatSpecifiers(bool is_igblast=false);
 
 enum ESAMField {
-    eSAM_SeqData = 0			///< Include seq data
+    eSAM_SeqData = 0,			///< Include seq data
+    eSAM_SubjAsRefSeq           ///< Subject as reference seqs
 };
 
 struct SSAMFormatSpec {
diff --git a/c++/include/objtools/align_format/showalign.hpp b/c++/include/objtools/align_format/showalign.hpp
index b72dea8..f8ca315 100644
--- a/c++/include/objtools/align_format/showalign.hpp
+++ b/c++/include/objtools/align_format/showalign.hpp
@@ -1,4 +1,4 @@
-/*  $Id: showalign.hpp 403059 2013-06-12 14:34:48Z zaretska $
+/*  $Id: showalign.hpp 513849 2016-09-15 17:36:45Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -35,7 +35,7 @@
 #define OBJTOOLS_ALIGN_FORMAT___SHOWALIGN_HPP
 
 #include <corelib/ncbireg.hpp>
-#include <corelib/hash_set.hpp>
+#include <unordered_set>
 
 #include <objects/seqalign/Seq_align.hpp>
 #include <objects/seqloc/Seq_loc.hpp>
@@ -255,7 +255,7 @@ class NCBI_ALIGN_FORMAT_EXPORT CDisplaySeqalign {
     }
 
     //Display pariwise seqalign for the set of seq IDS (for future use)
-    void DisplayPairwiseSeqalign(CNcbiOstream& out,hash_set <string> selectedIDs);        
+    void DisplayPairwiseSeqalign(CNcbiOstream& out,unordered_set <string> selectedIDs);        
     //Data representing templates for defline display 
     struct SAlignTemplates {
         string alignHeaderTmpl; ///< Template for displaying header,deflines and gene info  - BLAST_ALIGN_HEADER
@@ -416,6 +416,9 @@ class NCBI_ALIGN_FORMAT_EXPORT CDisplaySeqalign {
         m_PreComputedResID = preComputedResID;
     }
 
+    /// Sets usage of long sequence ids (database|accession)
+    void UseLongSequenceIds(void) {m_UseLongSeqIds = true;}
+
     /// static functions
     ///Need to call this if the seqalign is stdseg or dendiag for ungapped
     ///blast alignment display as each stdseg ro dendiag is a distinct
@@ -670,6 +673,9 @@ protected:
     ///result position index for multiple query case
     int m_ResultPositionIndex;
 
+    /// print long sequence ids (with gi and accession with database source)
+    bool m_UseLongSeqIds;
+
     string x_PrintDynamicFeatures(void); 
     ///Display the current alnvec
     ///@param out: stream for display
diff --git a/c++/include/objtools/align_format/showdefline.hpp b/c++/include/objtools/align_format/showdefline.hpp
index 145a161..4460efd 100644
--- a/c++/include/objtools/align_format/showdefline.hpp
+++ b/c++/include/objtools/align_format/showdefline.hpp
@@ -1,4 +1,4 @@
-/*  $Id: showdefline.hpp 436590 2014-05-29 15:00:05Z zaretska $
+/*  $Id: showdefline.hpp 513849 2016-09-15 17:36:45Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -93,7 +93,8 @@ public:
         eNoShowHeader = (1 << 6),       //defline annotation at the top
         eNewTargetWindow = (1 << 7),    //open url link in a new window
         eShowNewSeqGif = (1 << 8),      //show new sequence gif image
-        eShowPercentIdent = (1 << 9)    //show percent identity column
+        eShowPercentIdent = (1 << 9),   //show percent identity column
+        eLongSeqId = (1 << 10)          //print long sequences id (with bars)
     };
 
     ///Data Representing each defline
@@ -108,7 +109,8 @@ public:
         string score_url;              //score url (quick jump to alignment)
         bool is_new;                   //is this sequence new (for psiblast)?
         bool was_checked;              //was this sequence checked before?
-	string fullDefline;            //defline, containing all seq defines (PIG for example)
+	    string fullDefline;            //defline, containing all seq defines (PIG for example)
+        int    taxid;
     };
 
     //Data representing templates for defline display 
@@ -123,6 +125,17 @@ public:
         bool   advancedView;
     };
 
+    //data represnting info to record in applog amd metadata
+    struct SAppLogInfo {
+        int     topMatchesNum;
+        int     currInd;
+        vector <string> deflIdVec;
+        vector <string> taxidVec;
+        vector <string> queryCoverageVec;
+        vector <string> percentIdentityVec;
+    };
+
+    
     ///options per DisplayOption
     ///@param option: input option using bit numbers defined in DisplayOption
     ///
@@ -258,6 +271,13 @@ public:
     void SetDeflineTemplates (SDeflineTemplates *deflineTemplates) {
         m_DeflineTemplates = deflineTemplates;
     }
+
+    ///Set this to record datda in applog
+    ///Param appLogInfo: struct containg applog setup info
+    ///
+    void SetApplog(SAppLogInfo *appLogInfo) {
+        m_AppLogInfo = appLogInfo;
+    }
     
     ///Sets CDD precomputed results ID
     /// @param string containing seq id used in contsructing URL to CDART
@@ -359,7 +379,7 @@ protected:
         CRange<TSeqPos> subjRange;     //subject sequence range
         bool flip;					   //indicates opposite strands in the first seq align	
     };
-
+    
     ///Seqalign 
     CConstRef<objects::CSeq_align_set> m_AlnSetRef;   
 
@@ -461,6 +481,10 @@ protected:
     ///result position index for multiple query case
     int m_PositionIndex;
 
+    //info to record in applog amd metadata
+    SAppLogInfo *m_AppLogInfo;
+    
+
     ///Internal function to return score info
     ///@param aln seq-align we are working with [in]
     ///@param blast_rank ordinal nubmer of defline [in]
diff --git a/c++/include/objtools/align_format/tabular.hpp b/c++/include/objtools/align_format/tabular.hpp
index 70bf4bb..d69f160 100644
--- a/c++/include/objtools/align_format/tabular.hpp
+++ b/c++/include/objtools/align_format/tabular.hpp
@@ -1,4 +1,4 @@
-/* $Id: tabular.hpp 495725 2016-03-21 14:24:26Z ivanov $ 
+/* $Id: tabular.hpp 503717 2016-06-07 17:51:40Z jianye $ 
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -617,6 +617,7 @@ public:
         m_IgDomains.push_back(domain);
     };
 
+
     /// Set gene info
     void SetVGene(const string &id, int s, int e) {
         m_VGene.Set(id, s,e);
@@ -636,6 +637,30 @@ public:
     void SetIgAnnotation(const CRef<blast::CIgAnnotation> &annot, 
                          const CConstRef<blast::CIgBlastOptions> &ig_opts);
 
+    ///Getter
+    const void GetIgInfo (string& v, 
+                          string& d, 
+                          string& j,
+                          string& master_chain_to_show,
+                          string& cdr3_nuc,
+                          string& cdr3_aa,
+                          string& productive) const {
+        v = m_VGene.sid;
+        d = m_DGene.sid;  
+        j = m_JGene.sid;
+        master_chain_to_show = m_MasterChainTypeToShow;
+        cdr3_nuc = m_Cdr3Seq;
+        cdr3_aa = m_Cdr3SeqTrans;
+        productive = m_OtherInfo[4];
+    }
+
+    ///Get Ig domain
+    const vector<SIgDomain*>& GetIgDomains() const {
+
+        return m_IgDomains; 
+    }    
+                         
+
 protected:
     void x_ResetIgFields();
     void x_PrintIgGenes(bool isHtml=false, const string& header="# ") const;
@@ -654,12 +679,16 @@ private:
     SIgGene m_VGene;
     SIgGene m_DGene;
     SIgGene m_JGene;
-    vector<SIgDomain *> m_IgDomains;                                        
+    vector<SIgDomain *> m_IgDomains; 
+    // index 4, productive/non-productive
+    // index 3, stop codon or not
+
     vector<string> m_OtherInfo;
     int m_Cdr3Start;
     int m_Cdr3End;
     string m_Cdr3Seq;
     string m_Cdr3SeqTrans;
+        
 };
 
 END_SCOPE(align_format)
diff --git a/c++/include/objtools/align_format/taxFormat.hpp b/c++/include/objtools/align_format/taxFormat.hpp
index 595bf9b..ab83062 100644
--- a/c++/include/objtools/align_format/taxFormat.hpp
+++ b/c++/include/objtools/align_format/taxFormat.hpp
@@ -1,4 +1,4 @@
-/*  $Id: taxFormat.hpp 486926 2015-12-11 17:32:50Z zaretska $
+/*  $Id: taxFormat.hpp 506577 2016-07-08 17:18:41Z zaretska $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -63,29 +63,47 @@ BEGIN_SCOPE(align_format)
  * @endcode
  */
  
- const string kTaxBrowserURL           = "//www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi";
+ const string kTaxBrowserURL           = "<@protocol@>//www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi";
  const string kBlastNameLink           = "<a href=\"<@taxBrowserURL@>?id=<@bl_taxid@>\" target=\"lnktx<@rid@>\" title=\"Show taxonomy info for <@blast_name@> (taxid <@bl_taxid@>)\"><@blast_name@></a>";
 
- const string kOrgReportTable          = "<table><caption><h1>Organism Report</h1></caption><tr><th>Accession</th><th>Descr</th><th>Score</th><th>E-value</th></tr><@table_rows@></table><@taxidToSeqsMap@>";
- const string kOrgReportOrganismHeader = "<tr><th colspan=\"4\"><a href=\"<@taxBrowserURL@>?id=<@taxid@>\" name=\"<@taxid@>\" title=\"Show taxonomy info for <@scientific_name@> (taxid <@taxid@>)\" target=\"lnktx<@rid@>\"><@scientific_name@>[<@blast_name_link@>] taxid <@taxid@></th></tr>";
- const string kOrgReportOrganismHeaderNoTaxConnect = "<tr><th colspan=\"4\"><a href=\"<@taxBrowserURL@>?id=<@taxid@>\" name=\"<@taxid@>\" title=\"Show taxonomy info for <@scientific_name@> (taxid <@taxid@>)\" target=\"lnktx<@rid@>\"><@scientific_name@>[<@blast_name@>]</th></tr>";
+ const string kOrgReportTable          = "<table><caption><h2>Organism Report</h2></caption><tr><th>Accession</th><th>Descr</th><th>Score</th><th>E-value</th></tr><@table_rows@></table><@taxidToSeqsMap@>";
+ const string kOrgReportOrganismHeader = "<tr><th colspan=\"4\"><a href=\"<@taxBrowserURL@>?id=<@taxid@>\" name=\"<@taxid@>\" title=\"Show taxonomy info for <@scientific_name@> (taxid <@taxid@>)\" target=\"lnktx<@rid@>\"><@scientific_name@> <@common_name@> [<@blast_name_link@>] taxid <@taxid@></th></tr>";
+ const string kOrgReportOrganismHeaderNoTaxConnect = "<tr><th colspan=\"4\"><a href=\"<@taxBrowserURL@>?id=<@taxid@>\" name=\"<@taxid@>\" title=\"Show taxonomy info for <@scientific_name@> (taxid <@taxid@>)\" target=\"lnktx<@rid@>\"><@scientific_name@> <@common_name@> [<@blast_name@>]</th></tr>";
  const string kOrgReportTableHeader    = "<tr><th>Accession</th><th>Description</th><th>Score</th><th>E-value</th></tr>";
- const string kOrgReportTableRow       = "<tr><td><a title=\"Show report for <@acc@>\" target=\"lnktx<@rid@>\" href=\"//www.ncbi.nlm.nih.gov/protein/<@gi@>?report=fwwwtax&log$=taxrep&RID=<@rid@>\"><@acc@></a></td><td><@descr_abbr@></td><td><@score@></td><td><@evalue@></td></tr>";
+ const string kOrgReportTableRow       = "<tr><td><a title=\"Show report for <@acc@>\" target=\"lnktx<@rid@>\" href=\"<@protocol@>//www.ncbi.nlm.nih.gov/protein/<@gi@>?report=fwwwtax&log$=taxrep&RID=<@rid@>\"><@acc@></a></td><td><@descr_abbr@></td><td><@score@></td><td><@evalue@></td></tr>";
 
  const string kTaxIdToSeqsMap          = "<input type=\"hidden\" id=\"txForSeq_<@taxid@>\" value=\"<@giList@>\" />";
 
- const string kLineageReportTable          = "<table><caption><h1>Linage Report</h1><caption><@table_rows@></table>";
+ const string kLineageReportTable          = "<table><caption><h2>Linage Report</h2><caption><@table_rows@></table>";
  const string kLineageReportTableHeader    = "<tr><th>Organism</th><th>Blast Name</th><th>Score</th><th>Number of Hits</th><th>Description</th></tr>";
  const string kLineageReportOrganismHeader = "<tr><td><@depth@><a href=\"//<@taxBrowserURL@>?id=<@taxid@>\" title=\"Show taxonomy info for <@scientific_name@> (taxid <@taxid@>)\" target=\"lnktx<@rid@>\"><@scientific_name@></a><td><@blast_name_link@></td><td colspan =\"3\"></td></tr>";
- const string kLineageReportTableRow       = "<tr><td><@depth@><a href=\"//<@taxBrowserURL@>?id=<@taxid@>\" title=\"Show taxonomy info for <@scientific_name@> (taxid <@taxid@>)\" target=\"lnktx<@rid@>\"><@scientific_name@></a></td><td><@blast_name_link@></td><td><@score@></td><td><a href=\"#<@taxid@>\" title=\"Show organism report for <@scientific_name@>\"><@numhits@></a></td><td><a title=\"Show report for <@acc@> <@descr_abbr@>\" target=\"lnktx<@rid@>\" href=\"//www.ncbi.nlm.nih.gov/pro [...]
+ const string kLineageReportTableRow       = "<tr><td><@depth@><a href=\"//<@taxBrowserURL@>?id=<@taxid@>\" title=\"Show taxonomy info for <@scientific_name@> (taxid <@taxid@>)\" target=\"lnktx<@rid@>\"><@scientific_name@></a></td><td><@blast_name_link@></td><td><@score@></td><td><a href=\"#<@taxid@>\" title=\"Show organism report for <@scientific_name@>\"><@numhits@></a></td><td><a title=\"Show report for <@acc@> <@descr_abbr@>\" target=\"lnktx<@rid@>\" href=\"<@protocol@>//www.ncbi.nlm [...]
 
 
- const string kTaxonomyReportTable          = "<table><caption><h1>Taxonomy Report</h1><caption><@table_rows@></table>";
+ const string kTaxonomyReportTable          = "<table><caption><h2>Taxonomy Report</h2><caption><@table_rows@></table>";
  const string kTaxonomyReportTableHeader    = "<tr><th>Taxonomy</th><th>Number of hits</th><th>Number of organisms</th><th>Description</th></tr>"; 
  const string kTaxonomyReportOrganismHeader = "<tr><td><@depth@><a href=\"//<@taxBrowserURL@>?id=<@taxid@>\" title=\"Show taxonomy info for <@scientific_name@> (taxid <@taxid@>)\" target=\"lnktx<@rid@>\"><@scientific_name@></a></td><td><@numhits@></td><td><@numOrgs@></td><td><@descr_abbr@></td></tr>"; 
  const string kTaxonomyReportTableRow       = "<tr><td><@depth@><a href=\"//<@taxBrowserURL@>?id=<@taxid@>\" title=\"Show taxonomy info for <@scientific_name@> (taxid <@taxid@>)\" target=\"lnktx<@rid@>\"><@scientific_name@></a></td><td><@numhits@></td><td><@numOrgs@></td><td><@descr_abbr@></td></tr>";
 
  
+ const string kOrgReportTxtTable          = "<@org_report_caption@>\n<@acc_hd@><@descr_hd@><@score_hd@><@evalue_hd@>\n<@table_rows@>"; 
+ const string kOrgReportTxtOrganismHeader = "<@scientific_name@> <@common_name@> [<@blast_name_link@>] taxid <@taxid@>"; 
+ const string kOrgReportTxtOrganismHeaderNoTaxConnect = "<@scientific_name@> <@common_name@> [<@blast_name@>]";
+ const string kOrgReportTxtTableHeader    = " <@acc_hd@><@descr_hd@><@score_hd@><@evalue_hd@>\n";
+ const string kOrgReportTxtTableRow       = " <@acc@><@descr_text@><@score@><@evalue@>\n";
+
+ 
+ const string kOrgReportTxtTableCaption =  "Organism Report";
+ const string kOrgAccTxtTableHeader     =  "Accession";
+ const string kOrgDescrTxtTableHeader   =  "Description";
+ const string kOrgScoreTxtTableHeader   =  "Score";
+ const string kOrgEValueTxtTableHeader =   "E-value";
+
+ const unsigned int kMinLineLength = 100; //used for text output
+
+
+
+
 
 class NCBI_ALIGN_FORMAT_EXPORT CTaxFormat {
 
@@ -96,12 +114,22 @@ class NCBI_ALIGN_FORMAT_EXPORT CTaxFormat {
     ///@param seqalign: seqalign used to display taxonomy info     
     ///@param scope: scope to fetch your sequence 
     ///@param connectToTaxServe: default true indicates to connect to Tax server
+    ///@param lineLength: lineLength for text formatting
+    ///@param displayOption: displayOption HTML or text formatting
     CTaxFormat(const objects::CSeq_align_set & seqalign,
                      objects::CScope & scope,
-                     bool connectToTaxServer = true);
+                     unsigned int displayOption = eHtml,
+                     bool connectToTaxServer = true,
+                     unsigned int lineLength = 100);
+                     
                      
         /// Destructor
-    ~CTaxFormat();    
+    ~CTaxFormat();   
+
+    enum eDisplayOption {
+        eHtml,
+        eText
+    };
 
     ///Displays Organism Report
     ///@param out: stream for display
@@ -124,11 +152,12 @@ class NCBI_ALIGN_FORMAT_EXPORT CTaxFormat {
         CRef<objects::CSeq_id> seqID;    ///< seqID used in defline
         string label;                    ///< sequence label        
         string title;                    ///< sequnce title
-        double bit_score;                ///< score 
-        double evalue;                   ///< evalue
+        string bit_score;                ///< score 
+        string evalue;                   ///< evalue
         TGi displGi;                     ///<gi for seq that is displayed in alignment section
     };
-
+    
+                                             
     struct STaxInfo {
         int taxid;                       ///< taxid   
         string commonName;               ///< commonName
@@ -181,6 +210,9 @@ class NCBI_ALIGN_FORMAT_EXPORT CTaxFormat {
     ///
     void SetConnectToTaxServer(bool connectToTaxServer) {m_ConnectToTaxServer = connectToTaxServer;}
 
+    void SetDisplayOption(unsigned int displayOption){m_DisplayOption = displayOption;}
+
+    
     ///set blast request id
     ///@param rid: blast RID
     ///
@@ -250,9 +282,22 @@ protected:
 
     bool    m_Debug;
 
+    unsigned int m_DisplayOption;
     bool  m_ConnectToTaxServer;
     bool  m_TaxTreeLoaded;    
     CRef< ITreeIterator > m_TreeIterator;
+
+
+    //Text formatting
+    unsigned int m_MaxAccLength;
+    unsigned int m_MaxDescrLength;
+    unsigned int m_MaxScoreLength;
+    unsigned int m_MaxEvalLength;
+
+    unsigned int m_LineLength;
+    
+
+    string   m_Protocol; ///< protocol, default https otherwise get from .ncbirc
     
     CTaxFormat::SSeqInfo *x_FillTaxDispParams(const CRef< objects::CBlast_def_line > &bdl,
                                   const objects::CBioseq_Handle& bsp_handle,
@@ -284,6 +329,7 @@ protected:
     string x_MapSeqTemplate(string seqTemplate, SSeqInfo *seqInfo);
     string x_MapSeqTemplate(string seqTemplate, STaxInfo &taxInfo);
     string x_MapTaxInfoTemplate(string tableRowTemplate,STaxInfo &taxInfo,unsigned int depth = 0);
+    void x_InitTextFormatInfo(CTaxFormat::SSeqInfo *seqInfo);
 
     void x_PrintTaxInfo(vector <int> taxids, string title);       
     void x_PrintLineage(void);
diff --git a/c++/include/objtools/alnmgr/sparse_aln.hpp b/c++/include/objtools/alnmgr/sparse_aln.hpp
index 79d1904..0f57ed2 100644
--- a/c++/include/objtools/alnmgr/sparse_aln.hpp
+++ b/c++/include/objtools/alnmgr/sparse_aln.hpp
@@ -1,6 +1,6 @@
 #ifndef OBJTOOLS_ALNMGR___SPARSE_ALN__HPP
 #define OBJTOOLS_ALNMGR___SPARSE_ALN__HPP
-/*  $Id: sparse_aln.hpp 498721 2016-04-19 13:29:11Z ivanov $
+/*  $Id: sparse_aln.hpp 519681 2016-11-17 15:42:28Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -237,10 +237,24 @@ public:
         return aln_pos/GetBaseWidth(row);
     }
 
+    /// For protein sequences get frame for the specified coordinated.
+    /// For genomic sequences always returns 0.
+    int AlnPosToNativeFrame(TNumrow row, TSignedSeqPos aln_pos) const
+    {
+        int w = GetBaseWidth(row);
+        return (w == 3) ? aln_pos % 3 + 1 : 0;
+    }
+
     /// Convert sequence position to alignment (genomic) coordinate.
-    TSignedSeqPos NativeSeqPosToAlnPos(TNumrow row, TSignedSeqPos seq_pos) const
+    /// Optional frame can be used with protein positions.
+    TSignedSeqPos NativeSeqPosToAlnPos(TNumrow row,
+                                       TSignedSeqPos seq_pos,
+                                       int frame = 0) const
     {
-        return seq_pos*GetBaseWidth(row);
+        int w = GetBaseWidth(row);
+        TSignedSeqPos ret = seq_pos*w;
+        if (w == 3  &&  frame) ret += frame - 1;
+        return ret;
     }
 
     /// Convert alignment range (genomic coordinates) on the selected row
@@ -269,14 +283,19 @@ public:
     }
 
     /// Convert sequence range to alignment range (genomic coordinates).
+    /// Optional frames argument can be provided for protein ranges.
     /// NOTE: Need to use template since there are many range types:
     /// TRng, TAlnRng, TRange, TSignedRange etc.
     template<class _TRange>
-    _TRange NativeSeqRangeToAlnRange(TNumrow row, _TRange seq_range) const
+    _TRange NativeSeqRangeToAlnRange(TNumrow row,
+                                     _TRange seq_range,
+                                     TFrames frames = TFrames(0, 0)) const
     {
         if (seq_range.Empty()  ||  seq_range.IsWhole()) return seq_range;
         int w = GetBaseWidth(row);
-        return _TRange(seq_range.GetFrom()*w, seq_range.GetToOpen()*w - 1);
+        int from_frame = frames.first ? frames.first - 1 : 0;
+        int to_frame = frames.second ? frames.second - 1 : 0;
+        return _TRange(seq_range.GetFrom()*w + from_frame, seq_range.GetToOpen()*w + to_frame - 1);
     }
 
 protected:
diff --git a/c++/include/objtools/blast/blastdb_format/blastdb_dataextract.hpp b/c++/include/objtools/blast/blastdb_format/blastdb_dataextract.hpp
index b94f9b4..52bc1d2 100644
--- a/c++/include/objtools/blast/blastdb_format/blastdb_dataextract.hpp
+++ b/c++/include/objtools/blast/blastdb_format/blastdb_dataextract.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blastdb_dataextract.hpp 434826 2014-05-12 14:08:40Z rackerst $
+/*  $Id: blastdb_dataextract.hpp 516398 2016-10-13 12:26:59Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -69,11 +69,17 @@ public:
               m_UseCtrlA(ctrl_a),
               m_Oid(0)
     {
-	m_Gi2TaxidMap.first = -1;
-	m_Gi2AccMap.first = -1;
-	m_Gi2TitleMap.first = -1;
-	m_Oid2Pig.first = -1;
-	m_Gi2SeqIdMap.first = -1;
+        m_Gi2TaxidMap.first = -1;
+        m_Gi2AccMap.first = -1;
+        m_Gi2TitleMap.first = -1;
+        m_Oid2Pig.first = -1;
+        m_Gi2SeqIdMap.first = -1;
+
+        CNcbiApplication* app = CNcbiApplication::Instance();
+        if (app) {
+            const CNcbiRegistry& registry = app->GetConfig();
+            m_UseLongSeqIds = (registry.Get("BLAST", "LONG_SEQID") == "1");
+        }
     }
 
     /// Setting seqid
@@ -146,6 +152,8 @@ protected:
     pair<TOID, CSeqDB::TPIG> m_Oid2Pig;
     // Pair with a gi2seqid for one Oid.
     pair<TOID, map<TGi, string> > m_Gi2SeqIdMap;
+    /// Use long sequence ids (with gi and accessions with database source)
+    bool m_UseLongSeqIds;
 private:
     void x_ExtractMaskingData(CSeqDB::TSequenceRanges &ranges, int algo_id);
     int x_ExtractTaxId();
@@ -164,6 +172,70 @@ private:
     void x_SetGi();
 };
 
+class NCBI_BLASTDB_FORMAT_EXPORT CBlastDeflineUtil
+{
+public:
+	struct BlastDeflineFields{
+		unsigned int accession:1;
+		unsigned int seq_id:1;
+		unsigned int gi:1;
+		unsigned int title:1;
+		unsigned int membership:1;
+		unsigned int tax_id:1;
+		unsigned int leaf_node_tax_ids:1;
+		// The tax names include: scientific_name, common_name, blast_name and super kingdom
+		unsigned int tax_names:1;
+		unsigned int leaf_node_tax_names:1;
+		unsigned int pig:1;
+		unsigned int links:1;
+		unsigned int asn_defline:1;
+
+	};
+
+	enum FieldIndex {
+		accession = 0,
+		seq_id,
+		gi,
+		title,
+		membership,
+		pig,
+		tax_id,
+		leaf_node_tax_ids,
+		scientific_name,
+		leaf_node_scientific_names,
+		common_name,
+		leaf_node_common_names,
+		blast_name,
+		super_kingdom,
+		links,
+		asn_defline,
+		max_index
+	};
+	static void ExtractDataFromBlastDeflineSet(const CBlast_def_line_set & dl_set,
+			                                   vector<string> & results,
+			                                   BlastDeflineFields fields,
+			                                   string target_id,
+			                                   bool use_long_id);
+
+	static void ExtractDataFromBlastDefline(const CBlast_def_line & dl,
+				                            vector<string> & results,
+				                            BlastDeflineFields fields,
+				                            bool use_long_id);
+
+	static void ProcessFastaDeflines(CBioseq & bioseq, string & out, bool use_ctrla);
+};
+
+class NCBI_BLASTDB_FORMAT_EXPORT CBlastSeqUtil
+{
+public:
+	static Uint4 GetSeqHash(const char* buffer, int length);
+	static void ApplySeqMask(string & seq,
+			                 const CSeqDB::TSequenceRanges & masks,
+			                 const TSeqRange r=TSeqRange::GetEmpty());
+	static void GetReverseStrandSeq(string & seq);
+	static string GetMasksString(const CSeqDB::TSequenceRanges & masks);
+
+};
 
 END_NCBI_SCOPE
 
diff --git a/c++/include/objtools/blast/blastdb_format/blastdb_seqid.hpp b/c++/include/objtools/blast/blastdb_format/blastdb_seqid.hpp
index b024f30..6fd23d2 100644
--- a/c++/include/objtools/blast/blastdb_format/blastdb_seqid.hpp
+++ b/c++/include/objtools/blast/blastdb_format/blastdb_seqid.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blastdb_seqid.hpp 496013 2016-03-23 11:31:35Z ivanov $
+/*  $Id: blastdb_seqid.hpp 495929 2016-03-22 17:15:46Z rackerst $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/blast/blastdb_format/seq_formatter.hpp b/c++/include/objtools/blast/blastdb_format/seq_formatter.hpp
new file mode 100644
index 0000000..867c3b2
--- /dev/null
+++ b/c++/include/objtools/blast/blastdb_format/seq_formatter.hpp
@@ -0,0 +1,197 @@
+/*
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author: Amelia Fong
+ *
+ */
+
+/** @file seq_formatter.hpp
+ *  Definition of a blastdb formatter interfaces
+ */
+
+#ifndef OBJTOOLS_BLASTDB_FORMAT___SEQ_FORMATTER__HPP
+#define OBJTOOLS_BLASTDB_FORMAT___SEQ_FORMATTER__HPP
+
+#include <objtools/blast/blastdb_format/blastdb_seqid.hpp>
+#include <objtools/blast/blastdb_format/blastdb_dataextract.hpp>
+
+BEGIN_NCBI_SCOPE
+
+/// Configuration object for CBlastDB_Formatter classes
+struct CBlastDB_FormatterConfig {
+    /// Default constructor
+    CBlastDB_FormatterConfig() {
+        m_SeqRange = TSeqRange();
+        m_Strand = objects::eNa_strand_other;
+        m_UseCtrlA = false;
+        m_FiltAlgoId = -1;
+        m_FmtAlgoId = -1;
+    }
+
+
+    /// The range of the sequence to retrieve, if empty, the
+    /// entire sequence will be retrived
+    TSeqRange m_SeqRange;
+    /// All SeqLoc types will have this strand assigned; If set to 'other', the
+    /// strand will be set to 'unknown' for protein sequences and 'both' for
+    /// nucleotide
+    objects::ENa_strand m_Strand;
+    /// Determines whether Ctrl-A characters should be used as defline
+    /// separators
+    bool m_UseCtrlA;
+    /// Filtering algorithm ID to mask the FASTA
+    int m_FiltAlgoId;
+    /// Filtering algorithm ID for outfmt %m
+    int m_FmtAlgoId;
+};
+
+class NCBI_BLASTDB_FORMAT_EXPORT CBlastDB_Formatter
+{
+public:
+    CBlastDB_Formatter() {}
+
+    virtual int Write(CSeqDB::TOID oid, const CBlastDB_FormatterConfig & config, string target_id = kEmptyStr) = 0;
+    virtual void DumpAll(const CBlastDB_FormatterConfig & config) = 0;
+    virtual ~CBlastDB_Formatter() {}
+
+private:
+    /// Prohibit copy constructor
+    CBlastDB_Formatter(const CBlastDB_Formatter& rhs);
+    /// Prohibit assignment operator
+    CBlastDB_Formatter& operator=(const CBlastDB_Formatter& rhs);
+
+};
+
+/// Customizable sequence formatter interface
+class NCBI_BLASTDB_FORMAT_EXPORT CBlastDB_SeqFormatter : public CBlastDB_Formatter
+{
+public:
+    /// Constructor
+    /// @param fmt_spec format specification [in]
+    /// @param blastdb BLAST database from which to retrieve the data [in]
+    /// @param out output stream to write the data [in]
+    CBlastDB_SeqFormatter(const string& fmt_spec, CSeqDB& blastdb, CNcbiOstream& out);
+
+    int Write(CSeqDB::TOID oid, const CBlastDB_FormatterConfig & config, string target_id = kEmptyStr);
+    void DumpAll(const CBlastDB_FormatterConfig & config);
+
+private:
+    /// Fields not in defline
+    enum EOtherFields {
+    	e_seq = 0,
+    	e_mask,
+    	e_hash,
+    	e_max_other_fields
+    };
+
+    /// Stream to write output
+    CNcbiOstream& m_Out;
+    /// The output format specification
+    string m_FmtSpec;
+    /// The BLAST database from which to extract data
+    CSeqDB& m_BlastDb;
+    /// Vector of offsets where the replacements will take place
+    vector<string> m_Seperators;
+    /// Vector of convertor objects
+    vector<char> m_ReplTypes;
+    bool m_GetDefline;
+    CBlastDeflineUtil::BlastDeflineFields m_DeflineFields;
+    /// Bit Mask for other fields
+    unsigned int m_OtherFields;
+    /// Build data for write
+    void x_Print(CSeqDB::TOID oid, vector<string> & defline_data, vector<string> & other_fields);
+
+    void x_DataRequired();
+
+    void x_GetSeq(CSeqDB::TOID oid, const CBlastDB_FormatterConfig & config, string & seq);
+    string x_GetSeqHash(CSeqDB::TOID oid);
+    string x_GetSeqMask(CSeqDB::TOID oid, int algo_id);
+
+    /// Prohibit copy constructor
+    CBlastDB_SeqFormatter(const CBlastDB_SeqFormatter& rhs);
+    /// Prohibit assignment operator
+    CBlastDB_SeqFormatter& operator=(const CBlastDB_SeqFormatter& rhs);
+
+};
+
+/// Fasta formatter  interface
+class NCBI_BLASTDB_FORMAT_EXPORT CBlastDB_FastaFormatter : public CBlastDB_Formatter
+{
+public:
+    /// Constructor
+    /// @param blastdb BLAST database from which to retrieve the data [in]
+    /// @param out output stream to write the data [in]
+    /// @param width fasta line width [in]
+    CBlastDB_FastaFormatter(CSeqDB& blastdb, CNcbiOstream& out, TSeqPos width = 80, bool useLongSeqId = false);
+
+    void DumpAll(const CBlastDB_FormatterConfig  & config);
+
+    /// Retun 0 if Sucess otherwise -1
+    int Write(CSeqDB::TOID oid, const CBlastDB_FormatterConfig & config, string target_id = kEmptyStr);
+
+private:
+
+    /// The BLAST database from which to extract data
+    CSeqDB& m_BlastDb;
+    CNcbiOstream& m_Out;
+    CFastaOstream m_fasta;
+    bool m_UseLongSeqIds;
+
+    /// Prohibit copy constructor
+    CBlastDB_FastaFormatter(const CBlastDB_FastaFormatter& rhs);
+    /// Prohibit assignment operator
+    CBlastDB_FastaFormatter& operator=(const CBlastDB_FastaFormatter& rhs);
+};
+
+class NCBI_BLASTDB_FORMAT_EXPORT CBlastDB_BioseqFormatter : public CBlastDB_Formatter
+{
+public:
+    /// Constructor
+    /// @param blastdb BLAST database from which to retrieve the data [in]
+    /// @param out output stream to write the data [in]
+    CBlastDB_BioseqFormatter(CSeqDB& blastdb, CNcbiOstream& out);
+
+    void DumpAll(const CBlastDB_FormatterConfig  & config);
+
+    /// Retun 0 if Sucess otherwise -1
+    int Write(CSeqDB::TOID oid, const CBlastDB_FormatterConfig & config, string target_id = kEmptyStr);
+
+private:
+
+    /// The BLAST database from which to extract data
+    CSeqDB& m_BlastDb;
+    CNcbiOstream& m_Out;
+
+    /// Prohibit copy constructor
+    CBlastDB_BioseqFormatter(const CBlastDB_BioseqFormatter& rhs);
+    /// Prohibit assignment operator
+    CBlastDB_BioseqFormatter& operator=(const CBlastDB_BioseqFormatter& rhs);
+
+};
+
+END_NCBI_SCOPE
+
+#endif /* OBJTOOLS_BLASTDB_FORMAT___SEQ_FORMATTER__HPP */
+
diff --git a/c++/include/objtools/blast/blastdb_format/seq_writer.hpp b/c++/include/objtools/blast/blastdb_format/seq_writer.hpp
index 61d162b..4c70855 100644
--- a/c++/include/objtools/blast/blastdb_format/seq_writer.hpp
+++ b/c++/include/objtools/blast/blastdb_format/seq_writer.hpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_writer.hpp 404550 2013-06-25 16:51:53Z madden $
+/*  $Id: seq_writer.hpp 516393 2016-10-13 12:26:14Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -40,7 +40,7 @@
 BEGIN_NCBI_SCOPE
 
 /// Configuration object for CSeqFormatter
-struct CSeqFormatterConfig {
+struct NCBI_DEPRECATED CSeqFormatterConfig {
     /// Default constructor
     CSeqFormatterConfig() {
         m_LineWidth = 80;
@@ -74,7 +74,7 @@ struct CSeqFormatterConfig {
 };
 
 /// Customizable sequence writer interface
-class NCBI_BLASTDB_FORMAT_EXPORT CSeqFormatter 
+class NCBI_BLASTDB_FORMAT_EXPORT NCBI_DEPRECATED CSeqFormatter 
 {
 public:
     /// Constructor
diff --git a/c++/include/objtools/blast/seqdb_reader/impl/seqdbatlas.hpp b/c++/include/objtools/blast/seqdb_reader/impl/seqdbatlas.hpp
index 7232181..8d960e1 100644
--- a/c++/include/objtools/blast/seqdb_reader/impl/seqdbatlas.hpp
+++ b/c++/include/objtools/blast/seqdb_reader/impl/seqdbatlas.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_READERS_SEQDB__SEQDBATLAS_HPP
 #define OBJTOOLS_READERS_SEQDB__SEQDBATLAS_HPP
 
-/*  $Id: seqdbatlas.hpp 484524 2015-11-12 15:32:31Z rackerst $
+/*  $Id: seqdbatlas.hpp 516398 2016-10-13 12:26:59Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1785,12 +1785,14 @@ public:
         path += CDirEntry::NormalizePath(env.Get("BLASTDB"),eFollowLinks);
         path += splitter;
         // Finally, the config file.
-        CMetaRegistry::SEntry sentry =
-             CMetaRegistry::Load("ncbi", CMetaRegistry::eName_RcOrIni);
-        if (sentry.registry) {
-            path += CDirEntry::NormalizePath(sentry.registry->Get("BLAST", "BLASTDB"),eFollowLinks);
-            path += splitter;
-        }
+        CNcbiApplication* app = CNcbiApplication::Instance();
+        if (app) {
+            const CNcbiRegistry& registry = app->GetConfig();
+            if (registry.HasEntry("BLAST", "BLASTDB")) {
+                path += CDirEntry::NormalizePath(registry.Get("BLAST", "BLASTDB"),eFollowLinks);
+                path += splitter;
+            }
+        } 
         return path;
     }
 
diff --git a/c++/include/objtools/blast/seqdb_reader/impl/seqdbgeneral.hpp b/c++/include/objtools/blast/seqdb_reader/impl/seqdbgeneral.hpp
index 4c67ef3..9c5b061 100644
--- a/c++/include/objtools/blast/seqdb_reader/impl/seqdbgeneral.hpp
+++ b/c++/include/objtools/blast/seqdb_reader/impl/seqdbgeneral.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB__SEQDB__SEQDBGENERAL_HPP
 #define CORELIB__SEQDB__SEQDBGENERAL_HPP
 
-/*  $Id: seqdbgeneral.hpp 480259 2015-09-29 14:58:22Z fongah2 $
+/*  $Id: seqdbgeneral.hpp 514045 2016-09-19 12:26:51Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -434,6 +434,7 @@ private:
 /// @param front Region before delim if found. [out]
 /// @param delim Character for which to search. [in]
 /// @return true if the character was found, false otherwise.
+NCBI_XOBJREAD_EXPORT
 bool SeqDB_SplitString(CSeqDB_Substring & buffer,
                        CSeqDB_Substring & front,
                        char               delim);
@@ -460,6 +461,7 @@ bool SeqDB_SplitString(CSeqDB_Substring & buffer,
 ///   The file extension (without the "."), or NULL if none.
 /// @param outp
 ///   A returned string containing the combined path and file name
+NCBI_XOBJREAD_EXPORT
 void SeqDB_CombinePath(const CSeqDB_Substring & path,
                        const CSeqDB_Substring & file,
                        const CSeqDB_Substring * extn,
@@ -475,6 +477,7 @@ void SeqDB_CombinePath(const CSeqDB_Substring & path,
 ///   Input path
 /// @return
 ///   Path minus file extension
+NCBI_XOBJREAD_EXPORT
 CSeqDB_Substring SeqDB_RemoveFileName(CSeqDB_Substring s);
 
 
@@ -487,6 +490,7 @@ CSeqDB_Substring SeqDB_RemoveFileName(CSeqDB_Substring s);
 ///   Input path
 /// @return
 ///   Filename portion of path
+NCBI_XOBJREAD_EXPORT
 CSeqDB_Substring SeqDB_RemoveDirName(CSeqDB_Substring s);
 
 
@@ -499,6 +503,7 @@ CSeqDB_Substring SeqDB_RemoveDirName(CSeqDB_Substring s);
 ///   Input path
 /// @return
 ///   Path minus file extension
+NCBI_XOBJREAD_EXPORT
 CSeqDB_Substring SeqDB_RemoveExtn(CSeqDB_Substring s);
 
 
@@ -511,6 +516,7 @@ CSeqDB_Substring SeqDB_RemoveExtn(CSeqDB_Substring s);
 /// filesystem sources such as alias files.
 ///
 /// @param dbs This string will be changed in-place.
+NCBI_XOBJREAD_EXPORT
 void SeqDB_ConvertOSPath(string & dbs);
 
 
@@ -1085,11 +1091,13 @@ string SeqDB_FindBlastDBPath(const string   & file_name,
 ///   Second component
 /// @param delim
 ///   The delimiter to use when joining elements
+NCBI_XOBJREAD_EXPORT
 void SeqDB_JoinDelim(string & a, const string & b, const string & delim);
 
 
 /// Thow a SeqDB exception; this is seperated into a function
 /// primarily to allow a breakpoint to be set.
+NCBI_XOBJREAD_EXPORT
 void SeqDB_ThrowException(CSeqDBException::EErrCode code, const string & msg);
 
 
@@ -1108,6 +1116,7 @@ void SeqDB_ThrowException(CSeqDBException::EErrCode code, const string & msg);
 /// @param file Name of the file containing the assert.
 /// @param line The line the assert in on.
 /// @param text The text version of the asserted condition.
+NCBI_XOBJREAD_EXPORT
 void SeqDB_FileIntegrityAssert(const string & file,
                                int            line,
                                const string & text);
@@ -1200,6 +1209,7 @@ private:
 ///
 /// @param dbs Database names to combine.
 /// @param dbname Combined database name.
+NCBI_XOBJREAD_EXPORT
 void SeqDB_CombineAndQuote(const vector<string> & dbs,
                            string               & dbname);
 
@@ -1207,6 +1217,7 @@ void SeqDB_CombineAndQuote(const vector<string> & dbs,
 ///
 /// @param dbname Combined database name.
 /// @param dbs Database names to combine.
+NCBI_XOBJREAD_EXPORT
 void SeqDB_SplitQuoted(const string             & dbname,
                        vector<CSeqDB_Substring> & dbs,
                        bool keep_quote = false);
diff --git a/c++/include/objtools/blast/seqdb_reader/seqdb.hpp b/c++/include/objtools/blast/seqdb_reader/seqdb.hpp
index 27c49c6..3e78b59 100644
--- a/c++/include/objtools/blast/seqdb_reader/seqdb.hpp
+++ b/c++/include/objtools/blast/seqdb_reader/seqdb.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_BLAST_SEQDB_READER___SEQDB__HPP
 #define OBJTOOLS_BLAST_SEQDB_READER___SEQDB__HPP
 
-/*  $Id: seqdb.hpp 468781 2015-05-28 12:51:59Z vasilche $
+/*  $Id: seqdb.hpp 516402 2016-10-13 12:28:06Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1016,6 +1016,9 @@ public:
     /// Translate a GI to an OID.
     bool GiToOid(TGi gi, int & oid) const;
 
+    /// Translate a GI To an OID with filter check
+    bool GiToOidwFilterCheck(TGi gi, int & oid) const;
+
     /// Translate a GI to a PIG.
     bool GiToPig(TGi gi, int & pig) const;
 
diff --git a/c++/include/objtools/blast/seqdb_writer/build_db.hpp b/c++/include/objtools/blast/seqdb_writer/build_db.hpp
index 52a40f5..834d332 100644
--- a/c++/include/objtools/blast/seqdb_writer/build_db.hpp
+++ b/c++/include/objtools/blast/seqdb_writer/build_db.hpp
@@ -1,4 +1,4 @@
-/*  $Id: build_db.hpp 485504 2015-11-23 14:41:02Z rackerst $
+/*  $Id: build_db.hpp 514245 2016-09-20 17:05:47Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -150,12 +150,15 @@ public:
     /// @param Logging will be done to this stream. [in]
     /// @param use_gi_mask if true will generate GI-based mask files [in]
     /// @param logfile file to write the log to [in]
+    /// @param long_seqids if true, requires long sequence ids
+    /// (database|accession) when parsing fasta sequences [in]
     CBuildDatabase(const string         & dbname,
                    const string         & title,
                    bool                   is_protein,
                    CWriteDB::TIndexType   indexing,
                    bool                   use_gi_mask,
-                   ostream              * logfile);
+                   ostream              * logfile,
+                   bool                   long_seqids = false);
 
     // Note -- should deprecate (or just remove) the following one:
     // - sparse does nothing
@@ -176,13 +179,16 @@ public:
     /// @param parse_seqids specify true to parse the sequence IDs [in]
     /// @param use_gi_mask if true will generate GI-based mask files [in]
     /// @param indexing index fields to add to database. [in]
+    /// @param long_seqids if true, requires long sequence ids
+    /// (database|accession) when parsing fasta sequences [in]
     CBuildDatabase(const string         & dbname,
                    const string         & title,
                    bool                   is_protein,
                    bool                   sparse,
                    bool                   parse_seqids,
                    bool                   use_gi_mask,
-                   ostream              * logfile);
+                   ostream              * logfil,
+                   bool                   long_seqids = false);
 
     ~CBuildDatabase();
 
@@ -621,6 +627,9 @@ private:
     /// If true, string IDs found in FASTA input will be parsed as Seq-ids.
     bool m_ParseIDs;
 
+    /// If true, use long sequence ids (database|accession)
+    bool m_LongIDs;
+
     /// If true, there were sequences whose IDs matched those in the provided
     /// masking locations (via SetMaskDataSource). Used to display a warning in
     /// case this didn't happen
diff --git a/c++/include/objtools/blast/seqdb_writer/impl/criteria.hpp b/c++/include/objtools/blast/seqdb_writer/impl/criteria.hpp
index 278fca5..08c1b8a 100644
--- a/c++/include/objtools/blast/seqdb_writer/impl/criteria.hpp
+++ b/c++/include/objtools/blast/seqdb_writer/impl/criteria.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_BLAST_SEQDB_WRITER_IMPL___CRITERIA__HPP
 #define OBJTOOLS_BLAST_SEQDB_WRITER_IMPL___CRITERIA__HPP
 
-/*  $Id: criteria.hpp 401964 2013-06-04 15:01:28Z camacho $
+/*  $Id: criteria.hpp 513036 2016-09-06 19:42:13Z fukanchi $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -64,7 +64,7 @@ BEGIN_NCBI_SCOPE
 /// Structure which corresponds to format of records in DI files.
 struct SDIRecord {
     int     oid;            /// Ordinal ID
-    int     gi;             /// GenInfo ID
+    TGi     gi;             /// GenInfo ID
     int     taxid;          /// Taxonomy ID
     int     owner;          /// Owner
     string  div;            /// 3-letter division
@@ -75,7 +75,8 @@ struct SDIRecord {
     int     mol;            /// Molecule type, as in Seq-inst::mol
 
     SDIRecord() {
-        oid = gi = taxid = owner = len = hash = sat_key = mol = 0;
+        oid = taxid = owner = len = hash = sat_key = mol = 0;
+        gi = ZERO_GI;
     }
 };
 
@@ -481,7 +482,7 @@ NCBI_XOBJWRITE_EXPORT
 int
 CCriteriaSet_CalculateMemberships(
         const SDIRecord& direcord,      /// DI record data
-        objects::CBlast_def_line& defline   /// The 
+        objects::CBlast_def_line& defline   /// The
 );
 
 
diff --git a/c++/include/objtools/blast/seqdb_writer/writedb.hpp b/c++/include/objtools/blast/seqdb_writer/writedb.hpp
index 72af6c9..2ed03ec 100644
--- a/c++/include/objtools/blast/seqdb_writer/writedb.hpp
+++ b/c++/include/objtools/blast/seqdb_writer/writedb.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_BLAST_SEQDB_WRITER___WRITEDB__HPP
 #define OBJTOOLS_BLAST_SEQDB_WRITER___WRITEDB__HPP
 
-/*  $Id: writedb.hpp 480531 2015-10-01 15:03:55Z rackerst $
+/*  $Id: writedb.hpp 513849 2016-09-15 17:36:45Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -144,6 +144,9 @@ public:
     ///   Indicates the type of indices to build if specified. [in]
     /// @param parse_ids
     ///   If true, generate ISAM files [in]
+    /// @param long_ids
+    ///   If true, assume long sequence ids (database|accession) when parsing
+    ///   string ids [in]
     /// @param use_gi_mask
     ///   If true, generate GI-based mask files [in]
     CWriteDB(const string & dbname,
@@ -151,6 +154,7 @@ public:
              const string & title,
              int            itype = eDefault,
              bool           parse_ids = true,
+             bool           long_ids = false,
              bool           use_gi_mask = false);
 
     /// Destructor.
@@ -345,9 +349,11 @@ public:
     ///
     /// @param bs The bioseq from which to extract a defline set. [in]
     /// @param parse_ids If seqid should be parsed [in]
+    /// @param long_ids It true, use long sequence ids (database|accession) [in]
     /// @return A set of deflines for this CBioseq.
     static CRef<CBlast_def_line_set>
-    ExtractBioseqDeflines(const CBioseq & bs, bool parse_ids=true);
+    ExtractBioseqDeflines(const CBioseq & bs, bool parse_ids=true,
+                          bool long_ids=false);
 
     /// Set letters that should not be used in sequences.
     ///
diff --git a/c++/include/objtools/blast/services/blast_services.hpp b/c++/include/objtools/blast/services/blast_services.hpp
index 9225870..551f19b 100644
--- a/c++/include/objtools/blast/services/blast_services.hpp
+++ b/c++/include/objtools/blast/services/blast_services.hpp
@@ -1,7 +1,7 @@
 #ifndef ALGO_BLAST_API___REMOTE_SERVICES__HPP
 #define ALGO_BLAST_API___REMOTE_SERVICES__HPP
 
-/*  $Id: blast_services.hpp 464987 2015-04-15 19:29:32Z merezhuk $
+/*  $Id: blast_services.hpp 500813 2016-05-09 14:10:24Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -57,6 +57,9 @@ END_SCOPE(objects)
 
 using namespace ncbi::objects;
 
+#ifndef NCBI_MODULE
+#define NCBI_MODULE NETBLAST
+#endif
 
 /// RemoteServicesException
 ///
@@ -278,6 +281,8 @@ private:
     bool m_Verbose;
 };
 
+#undef NCBI_MODULE
+
 END_NCBI_SCOPE
 
 /* @} */
diff --git a/c++/include/objtools/cleanup/cleanup.hpp b/c++/include/objtools/cleanup/cleanup.hpp
index e8a6bc9..1c98ebd 100644
--- a/c++/include/objtools/cleanup/cleanup.hpp
+++ b/c++/include/objtools/cleanup/cleanup.hpp
@@ -1,7 +1,7 @@
 #ifndef CLEANUP___CLEANUP__HPP
 #define CLEANUP___CLEANUP__HPP
 
-/*  $Id: cleanup.hpp 500220 2016-05-03 14:56:08Z ivanov $
+/*  $Id: cleanup.hpp 520817 2016-12-01 18:50:34Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -69,11 +69,17 @@ public:
         eClean_GpipeMode         = 0x2,
         eClean_NoNcbiUserObjects = 0x4,
         eClean_SyncGenCodes      = 0x8,
-        eClean_NoProteinTitles   = 0x10
+        eClean_NoProteinTitles   = 0x10,
+        eClean_KeepTopSet        = 0x20
+    };
+
+    enum EScopeOptions {
+        eScope_Copy,
+        eScope_UseInPlace
     };
 
     // Construtor / Destructor
-    CCleanup(CScope* scope = NULL);
+    CCleanup(CScope* scope = NULL, EScopeOptions scope_handling = eScope_Copy);
     ~CCleanup();
 
     void SetScope(CScope* scope);
@@ -153,6 +159,28 @@ public:
 /// @return Boolean return value indicates whether gene-xrefs were removed
     static bool RemoveNonsuppressingGeneXrefs(CSeq_feat& f);
 
+
+/// Repairs non-reciprocal xref pairs for specified feature if xrefs between
+/// subtypes are permitted and feature with missing xref does not have an 
+/// xref to a different feature of the same subtype
+/// @param f Seq-feat to edit [in]
+/// @param tse top-level Seq-entry in which to search for the other half of the xref pair
+/// @return Boolean return value indicates whether xrefs were created
+    static bool RepairXrefs(const CSeq_feat& f, const CTSE_Handle& tse);
+
+/// Repairs non-reciprocal xref pairs for specified feature pair if xrefs between
+/// subtypes are permitted and feature with missing xref does not have an 
+/// xref to a different feature of the same subtype
+/// @param f Seq-feat to edit [in]
+/// @param tse top-level Seq-entry in which to search for the other half of the xref pair
+/// @return Boolean return value indicates whether xrefs were created
+    static bool RepairXrefs(const CSeq_feat& src, CSeq_feat_Handle& dst, const CTSE_Handle& tse);
+
+/// Repairs non-reciprocal xref pairs in specified seq-entry
+/// @param seh Seq-entry to edit [in]
+/// @return Boolean return value indicates whether xrefs were created
+    static bool RepairXrefs(CSeq_entry_Handle seh);
+
 /// Detects gene features with matching locus
 /// @param f Seq-feat parent feature of gene_xref [in]
 /// @param gene_xref Gene-ref of gene-xref [in]
@@ -179,6 +207,14 @@ public:
 /// @return Boolean return value indicates whether gene-xrefs were removed
     static bool RemoveOrphanLocus_tagGeneXrefs(CSeq_feat& f, CBioseq_Handle bsh);
 
+/// Extends a location to the specificed position.
+/// @param loc Seq-loc to extend
+/// @param pos position of new end of location
+/// @param scope Scope in which to look for sequences
+/// @return Boolean return value indicates whether the location was extended
+    static bool SeqLocExtend(CSeq_loc& loc, size_t pos, CScope& scope);
+
+
 /// Extends a coding region up to 50 nt. if the coding region:
 /// 1. does not end with a stop codon
 /// 2. is adjacent to a stop codon
@@ -196,7 +232,8 @@ public:
 /// @param bsh CBioseq_Handle on which the feature is located
 /// @param limit maximum number of nt to extend, or 0 if unlimited
 /// @return Boolean return value indicates whether the feature was extended
-    static bool ExtendToStopCodon(CSeq_feat& f, CBioseq_Handle bsh, size_t limit, CCdregion::TFrame frame = CCdregion::eFrame_not_set);
+    static bool ExtendToStopCodon(CSeq_feat& f, CBioseq_Handle bsh, size_t limit);
+    static bool ExtendStopPosition(CSeq_feat& f, const CSeq_feat* cdregion, size_t extension = 0);
 
 /// Translates coding region and selects best frame (without stops, or longest)
 /// @param cds Coding region Seq-feat to edit
@@ -224,11 +261,31 @@ public:
 /// @return Boolean return value indicates whether the coding region changed
     static bool SetCDSPartialsByFrameAndTranslation(CSeq_feat& cds, CScope& scope);
 
+
+/// Clear internal partials
+    static bool ClearInternalPartials(CSeq_loc& loc, bool is_first = true, bool is_last = true);
+    static bool ClearInternalPartials(CSeq_loc_mix& mix, bool is_first = true, bool is_last = true);
+    static bool ClearInternalPartials(CPacked_seqint& pint, bool is_first = true, bool is_last = true);
+    static bool ClearInternalPartials(CSeq_entry_Handle seh);
+
+/// Set feature partial based on feature location
+    static bool SetFeaturePartial(CSeq_feat& f);
+
 /// Update EC numbers
 /// @param ec_num_list Prot-ref ec number list to clean
 /// @return Boolean value indicates whether any changes were made
     static bool UpdateECNumbers(CProt_ref::TEc & ec_num_list);
 
+/// Delete EC numbers
+/// @param ec_num_list Prot-ref ec number list to clean
+/// @return Boolean value indicates whether any changes were made
+    static bool RemoveBadECNumbers(CProt_ref::TEc & ec_num_list);
+
+/// Fix EC numbers
+/// @param entry Seq-entry-handle to clean
+/// @return Boolean value indicates whether any changes were made
+    static bool FixECNumbers(CSeq_entry_Handle entry);
+
 /// Set partialness of gene to match longest feature contained in gene
 /// @param gene  Seq-feat to edit
 /// @param scope Scope in which to find gene
@@ -240,14 +297,6 @@ public:
     static const string& GetProteinName(const CProt_ref& prot);
     static const string& GetProteinName(const CSeq_feat& cds, CScope& scope);
 
-/// Checks to see if a feature is pseudo. Looks for pseudo flag set on feature,
-/// looks for pseudogene qualifier on feature, performs same checks for gene
-/// associated with feature
-/// @param feat Seq-feat to check
-/// @param scope CScope to use when looking for associated gene
-/// @return Boolean return value indicates whether any of the "pseudo" markers are found
-    static bool IsPseudo(const CSeq_feat& feat, CScope& scope);
-
 /// Sets MolInfo::tech for a sequence
 /// @param seq Bioseq to edit
 /// @param tech tech value to set
@@ -366,6 +415,9 @@ public:
 /// @return bool indicates whether any changes were made
     static bool RescueSiteRefPubs(CSeq_entry_Handle seh);
 
+/// Is this a "minimal" pub? (If yes, do not rescue from a Seq-feat.cit)
+    static bool IsMinPub(const CPubdesc& pd, bool is_refseq_prot);
+
     //helper function for moving feature to pubdesc descriptor
     static void MoveOneFeatToPubdesc(CSeq_feat_Handle feat, CRef<CSeqdesc> d, CBioseq_Handle b, bool remove_feat = true);
 
@@ -385,8 +437,6 @@ public:
 /// @return bool indicates whether any changes were made
     static bool ConvertSrcFeatsToSrcDescs(CSeq_entry_Handle seh);
 
-    static CConstRef <CSeq_feat> GetGeneForFeature(const CSeq_feat& feat, CScope& scope);
-
 /// Examine all genes and gene xrefs in the Seq-entry.
 /// If no genes have locus and some have locus tag AND no gene xrefs have locus-tag
 /// and some gene xrefs have locus, change all gene xrefs to use locus tag.
@@ -402,6 +452,22 @@ public:
 /// @return bool indicates whether any changes were made
     static bool RenormalizeNucProtSets(CSeq_entry_Handle seh);
 
+/// decodes various tags, including carriage-return-line-feed constructs
+    static bool DecodeXMLMarkChanged(std::string & str);
+
+    static CRef<CSeq_loc> GetProteinLocationFromNucleotideLocation(const CSeq_loc& nuc_loc, CScope& scope);
+    static CRef<CSeq_loc> GetProteinLocationFromNucleotideLocation(const CSeq_loc& nuc_loc, const CSeq_feat& cds, CScope& scope, bool require_inframe = false);
+
+/// Find proteins that are not packaged in the same nuc-prot set as the
+/// coding region for which they are a product, and move them to that
+/// nuc-prot set. Ignore coding regions that are in gen-prod-sets.
+/// @param seh Seq-entry to edit
+/// @return bool indicates whether any changes were made
+    static bool RepackageProteins(CSeq_entry_Handle seh);
+    static bool RepackageProteins(const CSeq_feat& cds, CBioseq_set_Handle np);
+
+    static bool ConvertDeltaSeqToRaw(CSeq_entry_Handle seh, CSeq_inst::EMol filter = CSeq_inst::eMol_not_set);
+
 private:
     // Prohibit copy constructor & assignment operator
     CCleanup(const CCleanup&);
diff --git a/c++/include/objtools/cleanup/cleanup_change.hpp b/c++/include/objtools/cleanup/cleanup_change.hpp
index 411def0..bb50adc 100644
--- a/c++/include/objtools/cleanup/cleanup_change.hpp
+++ b/c++/include/objtools/cleanup/cleanup_change.hpp
@@ -1,7 +1,7 @@
 #ifndef CLEANUP___CLEANUP_CHANGE__HPP
 #define CLEANUP___CLEANUP_CHANGE__HPP
 
-/*  $Id: cleanup_change.hpp 468092 2015-05-20 13:08:50Z bollin $
+/*  $Id: cleanup_change.hpp 518386 2016-11-02 17:27:13Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -159,6 +159,7 @@ public:
         eRemoveDupBioSource, // 90
         eCleanOrgref,
         eTrimInternalSemicolons,
+        eAddSeqFeatXref,
 
         // set when any other change is made.
         eChangeOther,
diff --git a/c++/include/objtools/data_loaders/genbank/cache/writer_cache.hpp b/c++/include/objtools/data_loaders/genbank/cache/writer_cache.hpp
index 69a984b..5b16433 100644
--- a/c++/include/objtools/data_loaders/genbank/cache/writer_cache.hpp
+++ b/c++/include/objtools/data_loaders/genbank/cache/writer_cache.hpp
@@ -1,7 +1,7 @@
 #ifndef WRITER_CACHE__HPP_INCLUDED
 #define WRITER_CACHE__HPP_INCLUDED
 
-/*  $Id: writer_cache.hpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: writer_cache.hpp 493171 2016-02-24 19:31:13Z vasilche $
 * ===========================================================================
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
diff --git a/c++/include/objtools/data_loaders/genbank/gbloader.hpp b/c++/include/objtools/data_loaders/genbank/gbloader.hpp
index d954c75..626bbfa 100644
--- a/c++/include/objtools/data_loaders/genbank/gbloader.hpp
+++ b/c++/include/objtools/data_loaders/genbank/gbloader.hpp
@@ -1,7 +1,7 @@
 #ifndef GBLOADER__HPP_INCLUDED
 #define GBLOADER__HPP_INCLUDED
 
-/*  $Id: gbloader.hpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: gbloader.hpp 493171 2016-02-24 19:31:13Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/data_loaders/genbank/impl/dispatcher.hpp b/c++/include/objtools/data_loaders/genbank/impl/dispatcher.hpp
index 9d571b5..0a2e8a7 100644
--- a/c++/include/objtools/data_loaders/genbank/impl/dispatcher.hpp
+++ b/c++/include/objtools/data_loaders/genbank/impl/dispatcher.hpp
@@ -2,7 +2,7 @@
 #define DISPATCHER__HPP_INCLUDED
 /* */
 
-/*  $Id: dispatcher.hpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: dispatcher.hpp 493171 2016-02-24 19:31:13Z vasilche $
 * ===========================================================================
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
diff --git a/c++/include/objtools/data_loaders/genbank/impl/info_cache.hpp b/c++/include/objtools/data_loaders/genbank/impl/info_cache.hpp
index d51e77c..4252f86 100644
--- a/c++/include/objtools/data_loaders/genbank/impl/info_cache.hpp
+++ b/c++/include/objtools/data_loaders/genbank/impl/info_cache.hpp
@@ -1,7 +1,7 @@
 #ifndef GENBANK_IMPL_INFO_CACHE
 #define GENBANK_IMPL_INFO_CACHE
 
-/*  $Id: info_cache.hpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: info_cache.hpp 497447 2016-04-06 18:19:05Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -42,7 +42,7 @@
 #include <list>
 #include <set>
 #include <map>
-#include <corelib/hash_map.hpp>
+#include <unordered_map>
 
 BEGIN_NCBI_SCOPE
 BEGIN_SCOPE(objects)
@@ -275,8 +275,8 @@ protected:
             return size_t(ptr)>>3;
         }
     };
-    typedef hash_map<CInfo_Base*, CRef<CInfoRequestorLock>, PtrHash> TLockMap;
-    typedef hash_map<CInfoCache_Base*, vector<CInfo_Base*>, PtrHash> TCacheMap;
+    typedef unordered_map<CInfo_Base*, CRef<CInfoRequestorLock>, PtrHash> TLockMap;
+    typedef unordered_map<CInfoCache_Base*, vector<CInfo_Base*>, PtrHash> TCacheMap;
     
     CRef<CInfoManager> m_Manager;
     TLockMap m_LockMap; // map from CInfo_Base -> CInfoRequestorLock
diff --git a/c++/include/objtools/data_loaders/genbank/impl/reader_id1_base.hpp b/c++/include/objtools/data_loaders/genbank/impl/reader_id1_base.hpp
index 953b4bc..d431588 100644
--- a/c++/include/objtools/data_loaders/genbank/impl/reader_id1_base.hpp
+++ b/c++/include/objtools/data_loaders/genbank/impl/reader_id1_base.hpp
@@ -1,6 +1,6 @@
 #ifndef READER_ID1_BASE__HPP_INCLUDED
 #define READER_ID1_BASE__HPP_INCLUDED
-/*  $Id: reader_id1_base.hpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: reader_id1_base.hpp 493171 2016-02-24 19:31:13Z vasilche $
 * ===========================================================================
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
diff --git a/c++/include/objtools/data_loaders/genbank/impl/reader_id2_base.hpp b/c++/include/objtools/data_loaders/genbank/impl/reader_id2_base.hpp
index 50f4d45..2aa511a 100644
--- a/c++/include/objtools/data_loaders/genbank/impl/reader_id2_base.hpp
+++ b/c++/include/objtools/data_loaders/genbank/impl/reader_id2_base.hpp
@@ -1,7 +1,7 @@
 #ifndef READER_ID2_BASE__HPP_INCLUDED
 #define READER_ID2_BASE__HPP_INCLUDED
 
-/*  $Id: reader_id2_base.hpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: reader_id2_base.hpp 504899 2016-06-20 17:49:29Z vasilche $
 * ===========================================================================
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
@@ -65,9 +65,11 @@ class CID2S_Reply_Get_Chunk;
 class CID2S_Chunk_Id;
 class CID2S_Chunk;
 class CID2Processor;
-
+class CId2ReaderProcessorResolver;
 class CReaderRequestResult;
 struct SId2LoadedSet;
+struct SId2PacketInfo;
+struct SId2PacketReplies;
 
 class NCBI_XREADER_EXPORT CId2ReaderBase : public CReader
 {
@@ -249,7 +251,26 @@ protected:
     bool x_LoadSeq_idBlob_idsSet(CReaderRequestResult& result,
                                  const TSeqIds& seq_ids);
 
+    friend class CId2ReaderProcessorResolver;
+
+    void x_DumpPacket(TConn conn, const CID2_Request_Packet& packet);
+    void x_DumpReply(TConn conn, const char* source, CID2_Reply& reply);
     void x_SetContextData(CID2_Request& request);
+    void x_SendToConnection(TConn conn, CID2_Request_Packet& packet);
+    CRef<CID2_Reply> x_ReceiveFromConnection(TConn conn);
+    void x_AssignSerialNumbers(SId2PacketInfo& info,
+                               CID2_Request_Packet& packet);
+    int x_GetReplyIndex(CReaderRequestResult& result,
+                        CConn* conn,
+                        SId2PacketInfo& packet,
+                        const CID2_Reply& reply);
+    bool x_DoneReply(SId2PacketInfo& info,
+                     int num,
+                     const CID2_Reply& reply);
+
+    void x_GetPacketReplies(CReaderRequestResult& result,
+                            SId2PacketReplies& replies,
+                            CID2_Request_Packet& packet);
 
 private:
     CAtomicCounter_WithAutoInit m_RequestSerialNumber;
diff --git a/c++/include/objtools/data_loaders/genbank/impl/request_result.hpp b/c++/include/objtools/data_loaders/genbank/impl/request_result.hpp
index d697719..b37def6 100644
--- a/c++/include/objtools/data_loaders/genbank/impl/request_result.hpp
+++ b/c++/include/objtools/data_loaders/genbank/impl/request_result.hpp
@@ -1,7 +1,7 @@
 #ifndef GBLOADER_REQUEST_RESULT__HPP_INCLUDED
 #define GBLOADER_REQUEST_RESULT__HPP_INCLUDED
 
-/*  $Id: request_result.hpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: request_result.hpp 493171 2016-02-24 19:31:13Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/data_loaders/genbank/reader.hpp b/c++/include/objtools/data_loaders/genbank/reader.hpp
index e2c31e8..11949e8 100644
--- a/c++/include/objtools/data_loaders/genbank/reader.hpp
+++ b/c++/include/objtools/data_loaders/genbank/reader.hpp
@@ -1,6 +1,6 @@
 #ifndef READER__HPP_INCLUDED
 #define READER__HPP_INCLUDED
-/*  $Id: reader.hpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: reader.hpp 493171 2016-02-24 19:31:13Z vasilche $
 * ===========================================================================
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
diff --git a/c++/include/objtools/data_loaders/genbank/reader_interface.hpp b/c++/include/objtools/data_loaders/genbank/reader_interface.hpp
index 8544b5a..61579eb 100644
--- a/c++/include/objtools/data_loaders/genbank/reader_interface.hpp
+++ b/c++/include/objtools/data_loaders/genbank/reader_interface.hpp
@@ -1,6 +1,6 @@
 #ifndef READER_INTERFACE__HPP_INCLUDED
 #define READER_INTERFACE__HPP_INCLUDED
-/*  $Id: reader_interface.hpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: reader_interface.hpp 493171 2016-02-24 19:31:13Z vasilche $
 * ===========================================================================
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
diff --git a/c++/include/objtools/data_loaders/genbank/writer.hpp b/c++/include/objtools/data_loaders/genbank/writer.hpp
index 26c3711..7b9b91a 100644
--- a/c++/include/objtools/data_loaders/genbank/writer.hpp
+++ b/c++/include/objtools/data_loaders/genbank/writer.hpp
@@ -2,7 +2,7 @@
 #define WRITER__HPP_INCLUDED
 /* */
 
-/*  $Id: writer.hpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: writer.hpp 493171 2016-02-24 19:31:13Z vasilche $
 * ===========================================================================
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
diff --git a/c++/include/objtools/data_loaders/genbank/writer_interface.hpp b/c++/include/objtools/data_loaders/genbank/writer_interface.hpp
index 719e4f3..702507d 100644
--- a/c++/include/objtools/data_loaders/genbank/writer_interface.hpp
+++ b/c++/include/objtools/data_loaders/genbank/writer_interface.hpp
@@ -2,7 +2,7 @@
 #define WRITER_INTERFACE__HPP_INCLUDED
 /* */
 
-/*  $Id: writer_interface.hpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: writer_interface.hpp 493171 2016-02-24 19:31:13Z vasilche $
 * ===========================================================================
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
diff --git a/c++/include/objtools/data_loaders/loaders.hpp b/c++/include/objtools/data_loaders/loaders.hpp
index f105474..3d7b809 100644
--- a/c++/include/objtools/data_loaders/loaders.hpp
+++ b/c++/include/objtools/data_loaders/loaders.hpp
@@ -1,7 +1,7 @@
 #ifndef DATA_LOADERS___LOADERS__HPP
 #define DATA_LOADERS___LOADERS__HPP
 
-/* $Id: loaders.hpp 110873 2007-09-18 18:27:53Z jcherry $
+/* $Id: loaders.hpp 504655 2016-06-16 21:18:41Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE                          
diff --git a/c++/include/objtools/edit/apply_object.hpp b/c++/include/objtools/edit/apply_object.hpp
index 737eb5b..cffae1c 100644
--- a/c++/include/objtools/edit/apply_object.hpp
+++ b/c++/include/objtools/edit/apply_object.hpp
@@ -1,4 +1,4 @@
-/*  $Id: apply_object.hpp 447037 2014-09-22 11:21:25Z bollin $
+/*  $Id: apply_object.hpp 494538 2016-03-08 14:31:04Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/edit/autodef.hpp b/c++/include/objtools/edit/autodef.hpp
index 0f8e90e..1fd07d6 100644
--- a/c++/include/objtools/edit/autodef.hpp
+++ b/c++/include/objtools/edit/autodef.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_EDIT___AUTODEF__HPP
 #define OBJTOOLS_EDIT___AUTODEF__HPP
 
-/*  $Id: autodef.hpp 490362 2016-01-25 12:43:11Z bollin $
+/*  $Id: autodef.hpp 510717 2016-08-15 17:12:40Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -95,6 +95,7 @@ public:
     void SetGeneClusterOppStrand(bool gene_opp_strand);
     void SetSuppressFeatureAltSplice (bool suppress_alt_splice);
     void SuppressMobileElementAndInsertionSequenceSubfeatures(bool suppress);
+    void SuppressMiscFeatSubfeatures(bool suppress);
     void SetKeepExons(bool keep);
     void SetKeepIntrons(bool keep);
     void SetKeepRegulatoryFeatures(bool keep);
@@ -105,8 +106,10 @@ public:
     void SetKeepOptionalMobileElements(bool keep);
     void SetKeepPrecursorRNA(bool keep);
     void SetKeepRepeatRegion(bool keep);
+    void SetKeepMiscRecomb(bool keep);
 	void SetUseNcRNAComment (bool use_comment);
     void SetUseFakePromoters (bool use_fake);
+    void SetCustomFeatureClause(const string& custom_feature_clause);
     
     void SuppressFeature(objects::CFeatListItem feat); 
     void SuppressFeature(objects::CSeqFeatData::ESubtype subtype);
@@ -236,6 +239,13 @@ void CAutoDef::SuppressMobileElementAndInsertionSequenceSubfeatures(bool suppres
 }
 
 
+inline 
+void CAutoDef::SuppressMiscFeatSubfeatures(bool suppress)
+{
+    m_Options.SetSuppressMiscFeatureSubfeatures(suppress);
+}
+
+
 inline
 void CAutoDef::SetKeepExons(bool keep)
 {
@@ -303,6 +313,12 @@ void CAutoDef::SetKeepRepeatRegion(bool keep)
 }
 
 inline
+void CAutoDef::SetKeepMiscRecomb(bool keep)
+{
+    m_Options.SetKeepMiscRecomb(keep);
+}
+
+inline
 void CAutoDef::SetUseNcRNAComment(bool use_comment)
 {
     m_Options.SetUseNcRNAComment(use_comment);
@@ -316,6 +332,11 @@ void CAutoDef::SetUseFakePromoters(bool use_fake)
 }
 
 
+inline
+void CAutoDef::SetCustomFeatureClause(const string& custom_feature_clause)
+{
+    m_Options.SetCustomFeatureClause(custom_feature_clause);
+}
 
 END_SCOPE(objects)
 END_NCBI_SCOPE
diff --git a/c++/include/objtools/edit/autodef_feature_clause.hpp b/c++/include/objtools/edit/autodef_feature_clause.hpp
index a8e6a0f..34d1024 100644
--- a/c++/include/objtools/edit/autodef_feature_clause.hpp
+++ b/c++/include/objtools/edit/autodef_feature_clause.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_EDIT___AUTODEF_FEATURE_CLAUSE__HPP
 #define OBJTOOLS_EDIT___AUTODEF_FEATURE_CLAUSE__HPP
 
-/*  $Id: autodef_feature_clause.hpp 493843 2016-03-02 14:04:45Z ivanov $
+/*  $Id: autodef_feature_clause.hpp 519214 2016-11-14 16:05:29Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -77,7 +77,7 @@ public:
     virtual sequence::ECompare CompareLocation(const CSeq_loc& loc);
     virtual void AddToLocation(CRef<CSeq_loc> loc, bool also_set_partials = true);
     virtual bool SameStrand(const CSeq_loc& loc);
-    virtual bool IsPartial();
+    virtual bool IsPartial() const;
     virtual CRef<CSeq_loc> GetLocation();
 
     // functions for grouping
@@ -90,6 +90,7 @@ public:
     virtual void ReverseCDSClauseLists();
     
     virtual bool ShouldRemoveExons();
+    virtual bool IsExonWithNumber();
     
     virtual bool IsBioseqPrecursorRNA();
 
@@ -97,7 +98,11 @@ protected:
     CAutoDefFeatureClause();
 
     bool x_GetGenericInterval (string &interval, bool suppress_allele);
+    void x_GetOperonSubfeatures(string &interval);
+
     virtual bool x_IsPseudo();
+
+    void x_TypewordFromSequence();
    
     const CSeq_feat& m_MainFeat;
     CRef<CSeq_loc> m_ClauseLocation;
diff --git a/c++/include/objtools/edit/autodef_feature_clause_base.hpp b/c++/include/objtools/edit/autodef_feature_clause_base.hpp
index 38fbfce..ece2ba5 100644
--- a/c++/include/objtools/edit/autodef_feature_clause_base.hpp
+++ b/c++/include/objtools/edit/autodef_feature_clause_base.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_EDIT___AUTODEF_FEATURE_CLAUSE_BASE__HPP
 #define OBJTOOLS_EDIT___AUTODEF_FEATURE_CLAUSE_BASE__HPP
 
-/*  $Id: autodef_feature_clause_base.hpp 490362 2016-01-25 12:43:11Z bollin $
+/*  $Id: autodef_feature_clause_base.hpp 519214 2016-11-14 16:05:29Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -64,7 +64,7 @@ public:
     virtual void AddToOtherLocation(CRef<CSeq_loc> loc);
     virtual void AddToLocation(CRef<CSeq_loc> loc, bool also_set_partials = true);
     virtual bool SameStrand(const CSeq_loc& loc);
-    virtual bool IsPartial() { return false; }
+    virtual bool IsPartial() const { return false; }
     virtual bool IsMobileElement() { return false; }
     virtual bool IsInsertionSequence() { return false; }
     virtual bool IsControlRegion() { return false; }
@@ -88,24 +88,24 @@ public:
 
     bool IsGeneMentioned(CAutoDefFeatureClause_Base *gene_clause);
     bool IsUnattachedGene() const;
-    bool IsTypewordFirst() { return m_ShowTypewordFirst; }
+    bool IsTypewordFirst() const { return m_ShowTypewordFirst; }
     bool DisplayAlleleName ();
 
-    string GetInterval() { return m_Interval; }
-    string GetTypeword() { return m_Typeword; }
-    string GetDescription() { return m_Description; }
-    string GetProductName() { return m_ProductName; }
-    string GetGeneName() { return m_GeneName; }
-    string GetAlleleName() { return m_AlleleName; }
+    const string& GetInterval() { return m_Interval; }
+    const string& GetTypeword() const { return m_Typeword; }
+    const string& GetDescription() const { return m_Description; }
+    const string& GetProductName() { return m_ProductName; }
+    const string& GetGeneName() { return m_GeneName; }
+    const string& GetAlleleName() { return m_AlleleName; }
     virtual void SetProductName(string product_name);
-    bool   GetGeneIsPseudo() { return m_GeneIsPseudo; }
-    bool   NeedPlural() { return m_MakePlural; }
-    bool   IsAltSpliced() { return m_IsAltSpliced; }
+    bool   GetGeneIsPseudo() const { return m_GeneIsPseudo; }
+    bool   NeedPlural() const { return m_MakePlural; }
+    bool   IsAltSpliced() const { return m_IsAltSpliced; }
     void   SetAltSpliced(string splice_name);
-    bool IsMarkedForDeletion() { return m_DeleteMe; }
+    bool IsMarkedForDeletion() const { return m_DeleteMe; }
     void MarkForDeletion() { m_DeleteMe = true; }
     void SetMakePlural() { m_MakePlural = true; }
-    bool HasmRNA() { return m_HasmRNA; }
+    bool HasmRNA() const { return m_HasmRNA; }
     void SetInfoOnly (bool info_only) { m_ClauseInfoOnly = info_only; }
     void PluralizeInterval();
     void PluralizeDescription();
@@ -142,9 +142,12 @@ public:
     void RemoveFeaturesByType(unsigned int feature_type, bool except_promoter = false);
     bool IsFeatureTypeLonely(unsigned int feature_type);
     void RemoveFeaturesInmRNAsByType(unsigned int feature_type, bool except_promoter = false);
+    void RemoveFeaturesUnderType(unsigned int feature_type);
+    void RemoveFeaturesInLocation(const CSeq_loc& loc);
     
-    virtual bool ShouldRemoveExons();
-    
+    virtual bool ShouldRemoveExons() { return false; }
+    virtual bool IsExonWithNumber() { return false; }
+
     void RemoveUnwantedExons();
     
     virtual bool IsBioseqPrecursorRNA();
@@ -188,9 +191,10 @@ protected:
     
     bool   m_DeleteMe;
 
-    unsigned int x_LastIntervalChangeBeforeEnd ();
+    size_t x_LastIntervalChangeBeforeEnd () const;
     bool x_OkToConsolidate (unsigned int clause1, unsigned int clause2);
-    bool x_MeetAltSpliceRules (unsigned int clause1, unsigned int clause2, string &splice_name);
+    bool x_OkToConsolidate(const CAutoDefFeatureClause_Base& other) const;
+    bool x_MeetAltSpliceRules (size_t clause1, size_t clause2, string &splice_name);
 
     void x_RemoveNullClauses();
 
@@ -201,6 +205,7 @@ protected:
         eMiscRnaWordType_RNAIntergenicSpacer,
         eMiscRnaWordType_RNA,
         eMiscRnaWordType_IntergenicSpacer,
+        eMiscRnaWordType_tRNA,
         eMiscRnaWordType_Unrecognized
     } ERnaMiscWord;
     static bool x_AddOneMiscWordElement(const string& phrase, vector<string>& elements);
diff --git a/c++/include/objtools/edit/autodef_mod_combo.hpp b/c++/include/objtools/edit/autodef_mod_combo.hpp
index 561cd42..0c73301 100644
--- a/c++/include/objtools/edit/autodef_mod_combo.hpp
+++ b/c++/include/objtools/edit/autodef_mod_combo.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_EDIT___AUTODEF_MOD_COMBO__HPP
 #define OBJTOOLS_EDIT___AUTODEF_MOD_COMBO__HPP
 
-/*  $Id: autodef_mod_combo.hpp 500380 2016-05-04 13:50:52Z ivanov $
+/*  $Id: autodef_mod_combo.hpp 500268 2016-05-03 16:31:45Z bollin $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/edit/autodef_options.hpp b/c++/include/objtools/edit/autodef_options.hpp
index 8b35784..ddd1f09 100644
--- a/c++/include/objtools/edit/autodef_options.hpp
+++ b/c++/include/objtools/edit/autodef_options.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_EDIT___AUTODEF_OPTIONS__HPP
 #define OBJTOOLS_EDIT___AUTODEF_OPTIONS__HPP
 
-/*  $Id: autodef_options.hpp 490362 2016-01-25 12:43:11Z bollin $
+/*  $Id: autodef_options.hpp 510717 2016-08-15 17:12:40Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -88,10 +88,13 @@ public:
         eOptionFieldType_KeepMobileElements,
         eOptionFieldType_KeepPrecursorRNA,
         eOptionFieldType_KeepRepeatRegion,
+        eOptionFieldType_KeepMiscRecomb,
         eOptionFieldType_UseNcRNAComment,
         eOptionFieldType_SuppressedFeatures,
         eOptionFieldType_ModifierList,
         eOptionFieldType_TargetedLocusName,
+        eOptionFieldType_SuppressMiscFeatureSubfeatures,
+        eOptionFieldType_CustomFeatureClause,
         eOptionFieldMax
     };
 
@@ -187,7 +190,9 @@ public:
     AUTODEFBOOLFIELD(KeepMobileElements)
     AUTODEFBOOLFIELD(KeepPrecursorRNA)
     AUTODEFBOOLFIELD(KeepRepeatRegion)
+    AUTODEFBOOLFIELD(KeepMiscRecomb)
     AUTODEFBOOLFIELD(UseNcRNAComment)
+    AUTODEFBOOLFIELD(SuppressMiscFeatureSubfeatures)
 
     bool IsFeatureSuppressed(CSeqFeatData::ESubtype subtype) const;
     bool AreAnyFeaturesSuppressed() const { return !m_SuppressedFeatureSubtypes.empty(); }
@@ -221,6 +226,9 @@ public:
     string GetTargetedLocusName() const { return m_TargetedLocusName;  }
     void SetTargetedLocusName(const string& tls) { m_TargetedLocusName = tls; }
 
+    string GetCustomFeatureClause() const { return m_CustomFeatureClause; }
+    void SetCustomFeatureClause(const string& val) { m_CustomFeatureClause = val; }
+
 private:
 
     bool m_BooleanFlags[eOptionFieldMax];
@@ -233,6 +241,7 @@ private:
     typedef vector<CSeqFeatData::ESubtype> TSuppressedFeatureSubtypes;
     TSuppressedFeatureSubtypes m_SuppressedFeatureSubtypes;
     string m_TargetedLocusName;
+    string m_CustomFeatureClause;
 
     TOrgMods m_OrgMods;
     TSubSources m_SubSources;
@@ -255,6 +264,7 @@ private:
 
     CRef<CUser_field> x_MakeMaxMods() const;
     CRef<CUser_field> x_MakeTargetedLocusName() const;
+    CRef<CUser_field> x_MakeCustomFeatureClause() const;
 
 #define AUTODEFENUMFIELD(Fieldname) \
     CRef<CUser_field> x_Make##Fieldname() const { \
diff --git a/c++/include/objtools/edit/cds_fix.hpp b/c++/include/objtools/edit/cds_fix.hpp
index e781a4f..cfcdf16 100644
--- a/c++/include/objtools/edit/cds_fix.hpp
+++ b/c++/include/objtools/edit/cds_fix.hpp
@@ -1,4 +1,4 @@
-/*  $Id: cds_fix.hpp 499447 2016-04-26 14:17:39Z ivanov $
+/*  $Id: cds_fix.hpp 496460 2016-03-28 18:04:05Z gotvyans $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/edit/feattable_edit.hpp b/c++/include/objtools/edit/feattable_edit.hpp
index 08542c1..914f1b6 100644
--- a/c++/include/objtools/edit/feattable_edit.hpp
+++ b/c++/include/objtools/edit/feattable_edit.hpp
@@ -1,4 +1,4 @@
-/*  $Id: feattable_edit.hpp 498135 2016-04-13 17:19:58Z ivanov $
+/*  $Id: feattable_edit.hpp 503729 2016-06-07 18:22:50Z ludwigf $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -70,7 +70,10 @@ public:
     void GenerateMissingMrnaForCds();
     void GenerateMissingGeneForMrna();
     void GenerateMissingGeneForCds();
-
+    void GenerateMissingParentFeatures(
+        bool forEukaryote);
+    void GenerateMissingParentFeaturesForEukaryote();
+    void GenerateMissingParentFeaturesForProkaryote();
     unsigned int PendingLocusTagNumber() const {
         return mLocusTagNumber;
     }
@@ -106,6 +109,12 @@ protected:
         const CMappedFeat&);
     void xGenerateMissingGeneForSubtype(
         CSeqFeatData::ESubtype);
+    void xGenerateMissingGeneForChoice(
+        CSeqFeatData::E_Choice);
+    bool xCreateMissingParentGene(
+        CMappedFeat);
+    bool xAdjustExistingParentGene(
+        CMappedFeat);
 
     CSeq_annot& mAnnot;
     CRef<CScope> mpScope;
diff --git a/c++/include/objtools/edit/gaps_edit.hpp b/c++/include/objtools/edit/gaps_edit.hpp
index ddd18c1..89c5e4f 100644
--- a/c++/include/objtools/edit/gaps_edit.hpp
+++ b/c++/include/objtools/edit/gaps_edit.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_EDIT_GAPS_EDITOR_HPP_INCLUDED
 #define OBJTOOLS_EDIT_GAPS_EDITOR_HPP_INCLUDED
 
-/*  $Id: gaps_edit.hpp 468747 2015-05-27 18:57:10Z gotvyans $
+/*  $Id: gaps_edit.hpp 513301 2016-09-09 12:02:54Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -51,25 +51,28 @@ public:
     // optionally specify linkage evidence or leave it default
     //CLinkage_evidence::EType
     typedef set<int> TEvidenceSet;
-    static
-        void ConvertNs2Gaps(CSeq_entry& entry,
-        TSeqPos gapNmin, TSeqPos gap_Unknown_length,
-        CSeq_gap::EType gap_type = (CSeq_gap::EType) - 1,
-        const TEvidenceSet& evidences = TEvidenceSet() );
+    CGapsEditor(CSeq_gap::EType gap_type, const TEvidenceSet& evidences,
+        TSeqPos gapNmin, TSeqPos gap_Unknown_length);
 
-    static
-    void ConvertNs2Gaps(CBioseq& bioseq, 
-       TSeqPos gapNmin, TSeqPos gap_Unknown_length, 
-       CSeq_gap::EType gap_type,
-       const TEvidenceSet& evidences);
+    void ConvertNs2Gaps(CSeq_entry& entry);
 
-    static 
-    void ConvertNs2Gaps(CBioseq::TInst& inst, TSeqPos gap_min);
-    static
-    void ConvertNs2Gaps(const CSeq_data& data, TSeqPos len, CDelta_ext& ext, TSeqPos gap_min);
-    static
-    CRef<CDelta_seq> CreateGap(CBioseq& bioseq, TSeqPos gap_start, TSeqPos gap_length, 
-        CSeq_gap::EType gap_type, const TEvidenceSet& evidences);
+    void ConvertNs2Gaps(CBioseq& bioseq);
+
+    void ConvertNs2Gaps(CBioseq::TInst& inst);
+    void ConvertNs2Gaps(const CSeq_data& data, TSeqPos len, CDelta_ext& ext);
+    CRef<CDelta_seq> CreateGap(CBioseq& bioseq, TSeqPos gap_start, TSeqPos gap_length);
+
+    void ConvertBioseqToDelta(CBioseq& bioseq);
+    void AppendGap(CBioseq& bioseq);
+    void AddBioseqAsLiteral(CBioseq& parent, CBioseq& bioseq);
+
+private:
+    void x_SetGapParameters(CDelta_seq& gap);
+
+    CSeq_gap::EType m_gap_type;
+    TEvidenceSet    m_evidences;
+    TSeqPos         m_gapNmin;
+    TSeqPos         m_gap_Unknown_length;
 };
 
 END_SCOPE(objects)
diff --git a/c++/include/objtools/edit/mail_report.hpp b/c++/include/objtools/edit/mail_report.hpp
index 55d20bc..4ed2769 100644
--- a/c++/include/objtools/edit/mail_report.hpp
+++ b/c++/include/objtools/edit/mail_report.hpp
@@ -1,4 +1,4 @@
-/*  $Id: mail_report.hpp 435187 2014-05-14 14:28:00Z bollin $
+/*  $Id: mail_report.hpp 519250 2016-11-14 18:26:30Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -41,7 +41,7 @@ BEGIN_SCOPE(edit)
 
 NCBI_XOBJEDIT_EXPORT CRef<CSeq_table> MakeMailReportPreReport(CSeq_entry_Handle seh);
 NCBI_XOBJEDIT_EXPORT void MakeMailReportPostReport(CSeq_table& table, CScope& scope);
-NCBI_XOBJEDIT_EXPORT string GetReportFromMailReportTable(const CSeq_table& table);
+NCBI_XOBJEDIT_EXPORT string GetReportFromMailReportTable(const CSeq_table& table, CScope* scope = NULL);
 
 
 END_SCOPE(edit)
diff --git a/c++/include/objtools/edit/publication_edit.hpp b/c++/include/objtools/edit/publication_edit.hpp
index 653e36a..90c6c1a 100644
--- a/c++/include/objtools/edit/publication_edit.hpp
+++ b/c++/include/objtools/edit/publication_edit.hpp
@@ -1,6 +1,6 @@
 #ifndef OBJTOOLS_EDIT__PUBLICATION_EDIT__HPP
 #define OBJTOOLS_EDIT__PUBLICATION_EDIT__HPP
-/*  $Id: publication_edit.hpp 493845 2016-03-02 14:05:29Z ivanov $
+/*  $Id: publication_edit.hpp 491874 2016-02-09 20:13:49Z asztalos $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/edit/rna_edit.hpp b/c++/include/objtools/edit/rna_edit.hpp
index bdb5b15..1d65b18 100644
--- a/c++/include/objtools/edit/rna_edit.hpp
+++ b/c++/include/objtools/edit/rna_edit.hpp
@@ -1,4 +1,4 @@
-/*  $Id: rna_edit.hpp 476471 2015-08-19 13:10:52Z asztalos $
+/*  $Id: rna_edit.hpp 513140 2016-09-07 18:34:49Z fukanchi $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -57,7 +57,14 @@ private:
     CFindITSParser& operator=(const CFindITSParser& value);
 
     CRef <CSeq_feat> x_ParseLine(const CTempString &line, CSeq_entry_Handle tse, CBioseq_Handle &bsh, bool &negative, string &msg);
-    CRef <CSeq_feat> x_CreateMiscRna(const string &accession, const string &comment, CBioseq_Handle bsh);
+    CRef <CSeq_feat> x_CreateMiscRna(const string &comment, CBioseq_Handle bsh);
+    CRef <CSeq_feat> x_CreateRRna(const string &comment, CBioseq_Handle bsh);
+    bool IsLengthTooLarge(const string& str, int max_length,  int i,
+                          const vector<int>& starts,
+                          const vector<int>& stops,
+                          const vector<bool>& spans,
+                          int bioseq_length);
+    void GetSpan(const string& str, vector<int>& starts, vector<int>& stops, vector<bool>& spans);
     CBioseq_Handle x_GetBioseqHandleFromIdGuesser(const string &id_str, objects::CSeq_entry_Handle tse);
     CNcbiIfstream m_istr;
     CRef<ILineReader> m_lr;
diff --git a/c++/include/objtools/edit/seq_entry_edit.hpp b/c++/include/objtools/edit/seq_entry_edit.hpp
index 5bd7449..43f11c2 100644
--- a/c++/include/objtools/edit/seq_entry_edit.hpp
+++ b/c++/include/objtools/edit/seq_entry_edit.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_EDIT___SEQ_ENTRY_EDIT__HPP
 #define OBJTOOLS_EDIT___SEQ_ENTRY_EDIT__HPP
 
-/*  $Id: seq_entry_edit.hpp 500101 2016-05-02 15:35:32Z ivanov $
+/*  $Id: seq_entry_edit.hpp 499249 2016-04-25 12:22:22Z bollin $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/edit/seqid_guesser.hpp b/c++/include/objtools/edit/seqid_guesser.hpp
index 7e171c3..c2fbb22 100644
--- a/c++/include/objtools/edit/seqid_guesser.hpp
+++ b/c++/include/objtools/edit/seqid_guesser.hpp
@@ -1,4 +1,4 @@
-/*  $Id: seqid_guesser.hpp 438363 2014-06-16 13:35:48Z bollin $
+/*  $Id: seqid_guesser.hpp 501263 2016-05-12 18:07:30Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,7 +29,7 @@
 #define _SEQID_GUESSER_H_
 
 #include <corelib/ncbistd.hpp>
-#include <corelib/hash_map.hpp>
+#include <unordered_map>
 #include <objects/seqloc/Seq_id.hpp>
 #include <objmgr/bioseq_handle.hpp>
 #include <objtools/edit/string_constraint.hpp>
@@ -50,7 +50,7 @@ public:
     static bool DoesSeqMatchConstraint(CBioseq_Handle bsh, CRef<CStringConstraint> string_constraint);
     static vector<string> GetIdStrings(CBioseq_Handle bsh);
 
-    typedef hash_map<string, CRef<CSeq_id> > TStringIdHash;
+    typedef unordered_map<string, CRef<CSeq_id> > TStringIdHash;
 
 private:
     CSeq_entry_Handle m_SeqEntry;
diff --git a/c++/include/objtools/edit/string_constraint.hpp b/c++/include/objtools/edit/string_constraint.hpp
index 56e20f9..39ad85e 100644
--- a/c++/include/objtools/edit/string_constraint.hpp
+++ b/c++/include/objtools/edit/string_constraint.hpp
@@ -1,4 +1,4 @@
-/*  $Id: string_constraint.hpp 423869 2014-01-09 12:49:24Z bollin $
+/*  $Id: string_constraint.hpp 515131 2016-09-28 15:33:44Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -102,7 +102,7 @@ public:
     const string& GetMatchText() { return m_MatchText; }
     void SetMatchText(const string& match_text) { m_MatchText = match_text; }
     void Assign(const CStringConstraint& other);
-
+    bool IsInRange(const string& str, const string &tmp);
 private:
     string m_MatchText;
     EMatchType m_MatchType;
diff --git a/c++/include/objtools/edit/struc_comm_field.hpp b/c++/include/objtools/edit/struc_comm_field.hpp
index 57a74a6..2eb68c7 100644
--- a/c++/include/objtools/edit/struc_comm_field.hpp
+++ b/c++/include/objtools/edit/struc_comm_field.hpp
@@ -1,4 +1,4 @@
-/*  $Id: struc_comm_field.hpp 493879 2016-03-02 14:17:26Z ivanov $
+/*  $Id: struc_comm_field.hpp 492413 2016-02-17 15:49:17Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/error_codes.hpp b/c++/include/objtools/error_codes.hpp
index 07d848d..a38a3e8 100644
--- a/c++/include/objtools/error_codes.hpp
+++ b/c++/include/objtools/error_codes.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS___ERROR_CODES__HPP
 #define OBJTOOLS___ERROR_CODES__HPP
 
-/*  $Id: error_codes.hpp 480266 2015-09-29 15:09:58Z vasilche $
+/*  $Id: error_codes.hpp 504655 2016-06-16 21:18:41Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/format/context.hpp b/c++/include/objtools/format/context.hpp
index 1ff0351..f524602 100644
--- a/c++/include/objtools/format/context.hpp
+++ b/c++/include/objtools/format/context.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_FORMAT___CONTEXT__HPP
 #define OBJTOOLS_FORMAT___CONTEXT__HPP
 
-/*  $Id: context.hpp 495720 2016-03-21 14:22:27Z ivanov $
+/*  $Id: context.hpp 511385 2016-08-22 13:31:32Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -236,6 +236,7 @@ public:
     const SAnnotSelector* GetAnnotSelector(void) const;
     SAnnotSelector& SetAnnotSelector(void);
     const CSeq_loc* GetMasterLocation(void) const;
+    const bool GetSGS(void) const;
     bool IsGenbankFormat(void) const;
 
     bool HasOperon(void) const;
@@ -429,7 +430,8 @@ public:
     const CSubmit_block* GetSubmitBlock(void) const { return m_Submit; }
     void SetSubmit(const CSubmit_block& sub) { m_Submit = ⊂ }
 
-    CFlatFileConfig& GetConfig(void) { return m_Cfg; }
+    const CFlatFileConfig& GetConfig(void) const { return m_Cfg; }
+    CFlatFileConfig& SetConfig(void) { return m_Cfg; }
 
     const SAnnotSelector* GetAnnotSelector(void) const;
     SAnnotSelector& SetAnnotSelector(void);
@@ -442,6 +444,9 @@ public:
     feature::CFeatTree* GetFeatTree(void) { return m_FeatTree; }
     void SetFeatTree(feature::CFeatTree* tree) { m_FeatTree.Reset(tree); }
     
+    const bool GetSGS(void) const { return m_SmallGenomeSet; }
+    void SetSGS(const bool sgs) { m_SmallGenomeSet = sgs; }
+
     void AddSection(TSection& section) { m_Sections.push_back(section); }
 
     void Reset(void);
@@ -455,6 +460,7 @@ private:
     auto_ptr<SAnnotSelector>    m_Selector;
     CConstRef<CSeq_loc>         m_Loc;
     CRef<feature::CFeatTree>    m_FeatTree;
+    bool                        m_SmallGenomeSet;
 };
 
 /////////////////////////////////////////////////////////////////////////////
@@ -674,6 +680,12 @@ const CSeq_loc* CBioseqContext::GetMasterLocation(void) const
 
 
 inline
+const bool CBioseqContext::GetSGS(void) const
+{
+    return m_FFCtx.GetSGS();
+}
+
+inline
 CMolInfo::TTech CBioseqContext::GetTech(void) const
 {
     return m_Molinfo ? m_Molinfo->GetTech() : CMolInfo::eTech_unknown;
@@ -748,6 +760,7 @@ void CFlatFileContext::Reset(void)
     m_Submit.Reset();
     m_Selector.reset();
     m_Loc.Reset();
+    m_SmallGenomeSet = false;
 }
 
 
diff --git a/c++/include/objtools/format/flat_file_config.hpp b/c++/include/objtools/format/flat_file_config.hpp
index 913aec0..3942f53 100644
--- a/c++/include/objtools/format/flat_file_config.hpp
+++ b/c++/include/objtools/format/flat_file_config.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_FORMAT___FLAT_FILE_CONFIG__HPP
 #define OBJTOOLS_FORMAT___FLAT_FILE_CONFIG__HPP
 
-/*  $Id: flat_file_config.hpp 500529 2016-05-05 14:28:05Z ivanov $
+/*  $Id: flat_file_config.hpp 507549 2016-07-19 22:29:29Z kans $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -70,9 +70,48 @@ class CWGSItem;
 class CTSAItem;
 class CEndSectionItem;
 class IFlatItem;
+class CSeq_id;
+class CSeq_loc;
+struct SModelEvidance;
 
 // --- Flat File configuration class
 
+// NEW_HTML_FMT define enables new interceptor interface for HTML links generation
+//#define NEW_HTML_FMT
+
+#ifdef NEW_HTML_FMT
+
+class IHTMLFormatter: public CObject
+{
+public:
+    virtual ~IHTMLFormatter() {};
+    
+    virtual void FormatProteinId(string& str, const CSeq_id& seq_id, const string& prot_id) const = 0;
+    virtual void FormatNucSearch(CNcbiOstream& os, const string& id) const = 0;
+    virtual void FormatNucId(string& str, const CSeq_id& seq_id, TIntId gi, const string& acc_id) const = 0;
+    virtual void FormatTaxid(string& str, const int taxid, const string& taxname) const = 0;
+    virtual void FormatLocation(string& str, const CSeq_loc& loc, TIntId gi, const string& visible_text) const = 0;
+    virtual void FormatModelEvidence(string& str, const SModelEvidance& me) const = 0;
+    virtual void FormatTranscript(string& str, const string& name) const = 0;
+    virtual void FormatGeneralId(CNcbiOstream& os, const string& id) const = 0;
+};
+
+class CHTMLEmptyFormatter : public IHTMLFormatter
+{
+public:
+    virtual ~CHTMLEmptyFormatter() {};
+
+    void FormatProteinId(string& str, const CSeq_id& seq_id, const string& prot_id) const;
+    void FormatNucSearch(CNcbiOstream& os, const string& id) const;
+    void FormatNucId(string& str, const CSeq_id& seq_id, TIntId gi, const string& acc_id) const;
+    void FormatTaxid(string& str, const int taxid, const string& taxname) const;
+    void FormatLocation(string& str, const CSeq_loc& loc, TIntId gi, const string& visible_text) const;
+    void FormatModelEvidence(string& str, const SModelEvidance& me) const;
+    void FormatTranscript(string& str, const string& name) const;
+    void FormatGeneralId(CNcbiOstream& os, const string& id) const;
+};
+#endif
+
 class NCBI_FORMAT_EXPORT CFlatFileConfig
 {
 public:
@@ -146,7 +185,8 @@ public:
 
     enum ECustom {
         // additional customization flags
-        fHideProteinID         = 1
+        fHideProteinID         = 1,
+        fHideGI                = 1 << 1
     };
 
     enum EView {
@@ -350,6 +390,17 @@ public:
     // destructor
     ~CFlatFileConfig(void);
 
+#ifdef NEW_HTML_FMT
+    void SetHTMLFormatter(CRef<IHTMLFormatter> html_fmt)
+    {
+        m_html_formatter = html_fmt;
+    }
+    const IHTMLFormatter& GetHTMLFormatter() const
+    {
+        return *m_html_formatter;
+    }
+#endif
+
     // -- Format
     // getters
     const TFormat& GetFormat(void) const { return m_Format; }
@@ -537,10 +588,12 @@ public:
     // getters
     const TCustom& GetCustom(void) const { return m_Custom; }
     bool HideProteinID         (void) const;
+    bool HideGI                (void) const;
 
     // setters
     void SetCustom(const TCustom& custom) { m_Custom = custom; }
     CFlatFileConfig& SetHideProteinID        (bool val = true);
+    CFlatFileConfig& SetHideGI               (bool val = true);
 
     // adjust mode dependant flags for RefSeq
     void SetRefSeqConventions(void);
@@ -678,6 +731,9 @@ private:
     const ICanceled * m_pCanceledCallback; // instance does NOT own it
     bool        m_BasicCleanup;
     TCustom     m_Custom;
+#ifdef NEW_HTML_FMT
+    CRef<IHTMLFormatter> m_html_formatter;
+#endif
 };
 
 
@@ -763,6 +819,7 @@ CUSTOM_ARG_GET(x) \
 CUSTOM_ARG_SET(x)
 
 CUSTOM_ARG_IMP(HideProteinID)
+CUSTOM_ARG_IMP(HideGI)
 
 #undef FLAG_ARG_IMP
 #undef FLAG_ARG_GET
diff --git a/c++/include/objtools/format/gather_items.hpp b/c++/include/objtools/format/gather_items.hpp
index 6d52fb0..47397db 100644
--- a/c++/include/objtools/format/gather_items.hpp
+++ b/c++/include/objtools/format/gather_items.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_FORMAT___GATHER_ITEMS__HPP
 #define OBJTOOLS_FORMAT___GATHER_ITEMS__HPP
 
-/*  $Id: gather_items.hpp 495720 2016-03-21 14:22:27Z ivanov $
+/*  $Id: gather_items.hpp 494523 2016-03-08 01:22:14Z kans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/format/genbank_gather.hpp b/c++/include/objtools/format/genbank_gather.hpp
index 28d2769..d115df8 100644
--- a/c++/include/objtools/format/genbank_gather.hpp
+++ b/c++/include/objtools/format/genbank_gather.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_FORMAT___GENBANK_GATHER__HPP
 #define OBJTOOLS_FORMAT___GENBANK_GATHER__HPP
 
-/*  $Id: genbank_gather.hpp 495730 2016-03-21 14:26:04Z ivanov $
+/*  $Id: genbank_gather.hpp 495539 2016-03-17 23:42:34Z kans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/format/item_formatter.hpp b/c++/include/objtools/format/item_formatter.hpp
index 9c89914..91eafba 100644
--- a/c++/include/objtools/format/item_formatter.hpp
+++ b/c++/include/objtools/format/item_formatter.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_FORMAT___ITEM_FORMATTER_HPP
 #define OBJTOOLS_FORMAT___ITEM_FORMATTER_HPP
 
-/*  $Id: item_formatter.hpp 360035 2012-04-19 13:43:48Z kornbluh $
+/*  $Id: item_formatter.hpp 506085 2016-07-01 14:25:26Z gotvyans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -116,7 +116,8 @@ public:
 
     // Context
     void SetContext(CFlatFileContext& ctx);
-    CFlatFileContext& GetContext(void) { return *m_Ctx; }
+    const CFlatFileContext& GetContext(void) const
+    { return *m_Ctx; }
 
 protected:
     typedef NStr::TWrapFlags    TWrapFlags;
diff --git a/c++/include/objtools/format/items/comment_item.hpp b/c++/include/objtools/format/items/comment_item.hpp
index 82f3fed..9704530 100644
--- a/c++/include/objtools/format/items/comment_item.hpp
+++ b/c++/include/objtools/format/items/comment_item.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_FORMAT_ITEMS___COMMENT_ITEM__HPP
 #define OBJTOOLS_FORMAT_ITEMS___COMMENT_ITEM__HPP
 
-/*  $Id: comment_item.hpp 495720 2016-03-21 14:22:27Z ivanov $
+/*  $Id: comment_item.hpp 506085 2016-07-01 14:25:26Z gotvyans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -127,8 +127,8 @@ public:
         eGenomeBuildComment_No = 0,
         eGenomeBuildComment_Yes
     };
-    static string GetStringForRefTrack(const CUser_object& uo,
-        const CBioseq_Handle& seq, ECommentFormat format = eFormat_Text,
+    static string GetStringForRefTrack(const CBioseqContext& ctx, const CUser_object& uo,
+        const CBioseq_Handle& seq, 
         EGenomeBuildComment eGenomeBuildComment = eGenomeBuildComment_Yes
         );
     static string GetStringForRefSeqGenome(const CUser_object& uo);
@@ -138,8 +138,7 @@ public:
     static string GetStringForMolinfo(const CMolInfo& mi, CBioseqContext& ctx);
     static string GetStringForHTGS(CBioseqContext& ctx);
     static string GetStringForUnordered(CBioseqContext& ctx);
-    static string GetStringForModelEvidance(const SModelEvidance& me,
-        ECommentFormat format = eFormat_Text);
+    static string GetStringForModelEvidance(const CBioseqContext& ctx, const SModelEvidance& me);
     static TRefTrackStatus GetRefTrackStatus(const CUser_object& uo,
         string* st = 0);
     static string GetStringForEncode(CBioseqContext& ctx);
diff --git a/c++/include/objtools/format/items/feature_item.hpp b/c++/include/objtools/format/items/feature_item.hpp
index 89bf531..078e044 100644
--- a/c++/include/objtools/format/items/feature_item.hpp
+++ b/c++/include/objtools/format/items/feature_item.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_FORMAT_ITEMS___FLAT_FEATURE__HPP
 #define OBJTOOLS_FORMAT_ITEMS___FLAT_FEATURE__HPP
 
-/*  $Id: feature_item.hpp 463068 2015-03-24 16:16:20Z gotvyans $
+/*  $Id: feature_item.hpp 512461 2016-08-31 11:22:40Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -257,13 +257,24 @@ protected:
     void x_AddFTableBiosrcQuals(const CBioSource& src);
     void x_AddFTableDbxref(const CSeq_feat::TDbxref& dbxref);
     void x_AddFTableExtQuals(const CSeq_feat::TExt& ext);
-    void x_AddFTableQual(const string& name, const string& val = kEmptyStr, 
-        CFormatQual::ETrim trim = CFormatQual::eTrim_Normal) 
+    const string kProteinId = "protein_id";
+    const string kTranscriptId = "transcript_id";
+    const string& x_GetFtableNameAlias(const string& name)
+    {
+        if (NStr::Equal(name, "orig_protein_id")) {
+            return kProteinId;
+        } else if (NStr::Equal(name, "orig_transcript_id")) {
+            return kTranscriptId;
+        } else {
+            return name;
+        }
+    }
+    void x_AddFTableQual(const string& name, const string& val = kEmptyStr,
+        CFormatQual::ETrim trim = CFormatQual::eTrim_Normal)
     {
         CFormatQual::EStyle style = val.empty() ? CFormatQual::eEmpty : CFormatQual::eQuoted;
-        m_FTableQuals.push_back(CRef<CFormatQual>(new CFormatQual(name, val, style, 0, trim)));
+        m_FTableQuals.push_back(CRef<CFormatQual>(new CFormatQual(x_GetFtableNameAlias(name), val, style, 0, trim)));
     }
-    
     // typdef
     typedef CQualContainer<EFeatureQualifier> TQuals;
     typedef TQuals::iterator                  TQI;
diff --git a/c++/include/objtools/format/items/flat_qual_slots.hpp b/c++/include/objtools/format/items/flat_qual_slots.hpp
index 744e284..1574fa0 100644
--- a/c++/include/objtools/format/items/flat_qual_slots.hpp
+++ b/c++/include/objtools/format/items/flat_qual_slots.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_FLAT___FLAT_QUAL_SLOTS__HPP
 #define OBJTOOLS_FLAT___FLAT_QUAL_SLOTS__HPP
 
-/*  $Id: flat_qual_slots.hpp 449759 2014-10-20 19:44:53Z kans $
+/*  $Id: flat_qual_slots.hpp 514604 2016-09-22 18:31:56Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -135,6 +135,7 @@ enum EFeatureQualifier {
     eFQ_rad_map,
     eFQ_region,
     eFQ_region_name,
+    eFQ_recombination_class,
     eFQ_regulatory_class,
     eFQ_replace,
     eFQ_ribosomal_slippage,
diff --git a/c++/include/objtools/format/items/gene_finder.hpp b/c++/include/objtools/format/items/gene_finder.hpp
index af6bd70..825653c 100644
--- a/c++/include/objtools/format/items/gene_finder.hpp
+++ b/c++/include/objtools/format/items/gene_finder.hpp
@@ -1,4 +1,4 @@
-/*  $Id: gene_finder.hpp 493806 2016-03-02 13:53:13Z ivanov $
+/*  $Id: gene_finder.hpp 491036 2016-02-01 16:07:35Z bollin $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/format/items/locus_item.hpp b/c++/include/objtools/format/items/locus_item.hpp
index ee98738..6aec4db 100644
--- a/c++/include/objtools/format/items/locus_item.hpp
+++ b/c++/include/objtools/format/items/locus_item.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_FORMAT_ITEMS___LOCUS_ITEM__HPP
 #define OBJTOOLS_FORMAT_ITEMS___LOCUS_ITEM__HPP
 
-/*  $Id: locus_item.hpp 413681 2013-09-17 17:28:11Z kans $
+/*  $Id: locus_item.hpp 501627 2016-05-17 17:47:33Z kans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -65,6 +65,7 @@ public:
     void Format(IFormatter& formatter, IFlatTextOStream& text_os) const;
 
     const string& GetName     (void) const;
+    const string& GetFullName (void) const;
     size_t        GetLength   (void) const;
     TStrand       GetStrand   (void) const;
     TBiomol       GetBiomol   (void) const;
@@ -92,6 +93,7 @@ private:
 
     // data
     string          m_Name;
+    string          m_FullName;
     size_t          m_Length;
     TStrand         m_Strand;
     TBiomol         m_Biomol;
@@ -113,6 +115,13 @@ const string& CLocusItem::GetName(void) const
 
 
 inline
+const string& CLocusItem::GetFullName(void) const
+{
+    return m_FullName;
+}
+
+
+inline
 size_t CLocusItem::GetLength(void) const
 {
     return m_Length;
diff --git a/c++/include/objtools/format/items/tsa_item.hpp b/c++/include/objtools/format/items/tsa_item.hpp
index f9f4236..cbd7be5 100644
--- a/c++/include/objtools/format/items/tsa_item.hpp
+++ b/c++/include/objtools/format/items/tsa_item.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_FORMAT_ITEMS___TSA_ITEM__HPP
 #define OBJTOOLS_FORMAT_ITEMS___TSA_ITEM__HPP
 
-/*  $Id: tsa_item.hpp 495730 2016-03-21 14:26:04Z ivanov $
+/*  $Id: tsa_item.hpp 495539 2016-03-17 23:42:34Z kans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/readers/aln_reader.hpp b/c++/include/objtools/readers/aln_reader.hpp
index 9fad257..0050f34 100644
--- a/c++/include/objtools/readers/aln_reader.hpp
+++ b/c++/include/objtools/readers/aln_reader.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_READERS___ALN_READER__HPP
 #define OBJTOOLS_READERS___ALN_READER__HPP
 
-/*  $Id: aln_reader.hpp 438196 2014-06-13 13:41:41Z bollin $
+/*  $Id: aln_reader.hpp 505117 2016-06-22 15:06:00Z foleyjp $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -49,7 +49,8 @@ public:
         eAlnErr_NoError = 0,
         eAlnErr_Fatal,
         eAlnErr_BadData,
-        eAlnErr_BadFormat
+        eAlnErr_BadFormat,
+        eAlnErr_BadChar
     } EAlnErr;
     
     // constructor
@@ -82,7 +83,6 @@ private:
 /// class CAlnReader supports importing a large variety of text-based
 /// alignment formats into standard data structures.
 ///
-
 class NCBI_XOBJREAD_EXPORT CAlnReader
 {
 public:
@@ -93,11 +93,51 @@ public:
         eAlpha_Protein
     };
  
+    class CAlnErrorContainer 
+    {
+
+    private:
+        list<CAlnError> errors;
+        map<CAlnError::EAlnErr, size_t> error_count;
+
+    public:
+        size_t GetErrorCount(CAlnError::EAlnErr category) const
+        {
+            auto it = error_count.find(category);
+            if (it != error_count.end()) {
+                return it->second;
+            }
+            return 0;
+        }
+
+        void clear(void) {
+            errors.clear();
+            error_count.clear();
+        }
+
+        void push_back(const CAlnError& error) {
+            errors.push_back(error);
+            ++error_count[error.GetCategory()];
+        }
+
+        size_t size(void) const {
+            return errors.size();
+        }
+
+        typedef list<CAlnError> TErrors;
+        typedef TErrors::const_iterator const_iterator;
+        const_iterator begin(void) const { return errors.begin(); }
+        const_iterator end(void)   const { return errors.end();   }
+    };
+
     // error messages
-    typedef vector<CAlnError> TErrorList;
+    typedef CAlnErrorContainer TErrorList;
 
     // constructor
-    CAlnReader(CNcbiIstream& is) : m_IS(is), m_ReadDone(false) { m_Errors.clear(); };
+    // defaults to protein alphabet and A2M gap characters
+    CAlnReader(CNcbiIstream& is) : m_IS(is), m_ReadDone(false) { m_Errors.clear();
+                                                                 SetAlphabet(eAlpha_Protein);
+                                                                 SetAllGap(".-"); };
 
     // destructor
     ~CAlnReader(void);
@@ -110,6 +150,7 @@ public:
     string&       SetAlphabet(void);
     void          SetAlphabet(const string& value);
     void          SetAlphabet(EAlphabet alpha);
+    bool          IsAlphabet(EAlphabet alpha) const;
 
     const string& GetBeginningGap(void) const;
     string&       SetBeginningGap(void);
@@ -165,7 +206,6 @@ public:
 
 
 private:
-
     /// Prohibit copy constructor and assignment operator
     CAlnReader(const CAlnReader& value);
     CAlnReader& operator=(const CAlnReader& value);
@@ -310,6 +350,26 @@ void CAlnReader::SetAlphabet(EAlphabet alpha)
 }
 
 
+inline 
+bool CAlnReader::IsAlphabet(EAlphabet alpha) const
+{
+    switch (alpha) {
+    case eAlpha_Nucleotide:
+        return (m_Alphabet == "ABCDGHKMNRSTUVWXYabcdghkmnrstuvwxy");
+
+    case eAlpha_Protein:
+        return (m_Alphabet == "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
+
+    default:
+        return false;
+    }
+    return false;
+}
+
+
+
+
+
 inline
 void CAlnReader::SetAllGap(const string& value)
 {
diff --git a/c++/include/objtools/readers/bed_reader.hpp b/c++/include/objtools/readers/bed_reader.hpp
index e0351ea..6f56d80 100644
--- a/c++/include/objtools/readers/bed_reader.hpp
+++ b/c++/include/objtools/readers/bed_reader.hpp
@@ -1,4 +1,4 @@
-/*  $Id: bed_reader.hpp 472138 2015-07-07 16:07:55Z grichenk $
+/*  $Id: bed_reader.hpp 515629 2016-10-04 17:46:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -167,6 +167,7 @@ public:
 public:
     enum EBedFlags {
         fThreeFeatFormat = 1<<8,
+        fDirectedFeatureModel = 1<<9,
     };
     typedef int TFlags;
 
@@ -209,11 +210,15 @@ protected:
     virtual bool xParseTrackLine(
         const string&,
         ILineErrorListener*);
-        
+  
+    bool xParseFeature(
+        const string&,
+        CRef<CSeq_annot>&,
+        ILineErrorListener*);
+      
     bool xParseFeature(
         const vector<string>&,
         CRef<CSeq_annot>&,
-        unsigned int,
         ILineErrorListener*);
 
     bool xParseFeatureUserFormat(
@@ -224,7 +229,6 @@ protected:
     bool xParseFeatureThreeFeatFormat(
         const vector<string>&,
         CRef<CSeq_annot>&,
-        unsigned int,
         ILineErrorListener*);
 
     bool xAppendFeatureChrom(
@@ -245,6 +249,29 @@ protected:
         unsigned int,
         ILineErrorListener*);
 
+    bool xParseFeatureGeneModelFormat(
+        const vector<string>&,
+        CRef<CSeq_annot>&,
+        ILineErrorListener*);
+
+    bool xAppendFeatureGene(
+        const vector<string>&,
+        CRef<CSeq_annot>&,
+        unsigned int,
+        ILineErrorListener*);
+
+    bool xAppendFeatureRna(
+        const vector<string>&,
+        CRef<CSeq_annot>&,
+        unsigned int,
+        ILineErrorListener*);
+
+    bool xAppendFeatureCds(
+        const vector<string>&,
+        CRef<CSeq_annot>&,
+        unsigned int,
+        ILineErrorListener*);
+
     void x_SetFeatureLocation(
         CRef<CSeq_feat>&,
         const vector<string>&);
@@ -252,29 +279,50 @@ protected:
     void xSetFeatureLocationChrom(
         CRef<CSeq_feat>&,
         const vector<string>&);
+    void xSetFeatureLocationGene(
+        CRef<CSeq_feat>&,
+        const vector<string>&);
         
     void xSetFeatureLocationThick(
         CRef<CSeq_feat>&,
         const vector<string>&);
+    void xSetFeatureLocationCds(
+        CRef<CSeq_feat>&,
+        const vector<string>&);
         
     void xSetFeatureLocationBlock(
         CRef<CSeq_feat>&,
         const vector<string>&);
+    void xSetFeatureLocationRna(
+        CRef<CSeq_feat>&,
+        const vector<string>&);
         
     void xSetFeatureIdsChrom(
         CRef<CSeq_feat>&,
         const vector<string>&,
         unsigned int);
+    void xSetFeatureIdsGene(
+        CRef<CSeq_feat>&,
+        const vector<string>&,
+        unsigned int);
         
     void xSetFeatureIdsThick(
         CRef<CSeq_feat>&,
         const vector<string>&,
         unsigned int);
+    void xSetFeatureIdsCds(
+        CRef<CSeq_feat>&,
+        const vector<string>&,
+        unsigned int);
         
     void xSetFeatureIdsBlock(
         CRef<CSeq_feat>&,
         const vector<string>&,
         unsigned int);
+    void xSetFeatureIdsRna(
+        CRef<CSeq_feat>&,
+        const vector<string>&,
+        unsigned int);
         
     void xSetFeatureBedData(
         CRef<CSeq_feat>&,
@@ -284,24 +332,51 @@ protected:
         CRef<CSeq_feat>&,
         const vector<string>&);
         
+    void xSetFeatureScore(
+        CRef<CUser_object>,
+        const vector<string>&);
+    void xSetFeatureColor(
+        CRef<CUser_object>,
+        const vector<string>&);
+
+    void xSetFeatureColorFromItemRgb(
+        CRef<CUser_object>,
+        const string&);
+    void xSetFeatureColorFromScore(
+        CRef<CUser_object>,
+        const string&);
+    void xSetFeatureColorByStrand(
+        CRef<CUser_object>,
+        const string&,
+        ENa_strand);
+    void xSetFeatureColorDefault(
+        CRef<CUser_object>);
+
     bool xContainsThickFeature(
         const vector<string>&) const;
 
     bool xContainsBlockFeature(
         const vector<string>&) const;
 
+    bool xContainsRnaFeature(
+        const vector<string>&) const;
+
+    bool xContainsCdsFeature(
+        const vector<string>&) const;
+
     ENa_strand xGetStrand(
         const vector<string>&) const;
 
+    virtual void xAssignBedColumnCount(
+        CSeq_annot&);
+                    
     void x_SetFeatureDisplayData(
         CRef<CSeq_feat>&,
         const vector<string>&);
 
-    virtual void xSetTrackData(
+    virtual void xPostProcessAnnot(
         CRef<CSeq_annot>&,
-        CRef<CUser_object>&,
-        const string&,
-        const string&);
+        ILineErrorListener*);
 
     CRef< CSeq_annot > x_AppendAnnot(
         vector< CRef< CSeq_annot > >& );
@@ -328,6 +403,7 @@ protected:
     string m_currentId;
 
     vector<string>::size_type m_columncount;
+    unsigned int m_CurrentFeatureCount;
     bool m_usescore;
     unsigned int m_CurBatchSize;
     const unsigned int m_MaxBatchSize;
diff --git a/c++/include/objtools/readers/fasta.hpp b/c++/include/objtools/readers/fasta.hpp
index 9fc3aaf..72e2d90 100644
--- a/c++/include/objtools/readers/fasta.hpp
+++ b/c++/include/objtools/readers/fasta.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_READERS___FASTA__HPP
 #define OBJTOOLS_READERS___FASTA__HPP
 
-/*  $Id: fasta.hpp 499434 2016-04-26 14:13:36Z ivanov $
+/*  $Id: fasta.hpp 515641 2016-10-04 17:51:17Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -190,13 +190,6 @@ public:
 
     void IgnoreProblem(ILineError::EProblem problem);
 
-protected:
-    enum EInternalFlags {
-        fAligning = 0x40000000,
-        fInSegSet = 0x20000000
-    };
-
-    typedef CTempString TStr;
     struct SLineTextAndLoc {
         SLineTextAndLoc(
             const string & sLineText,
@@ -208,13 +201,50 @@ protected:
         TSeqPos m_iLineNum;
     };
 
+    using TIgnoredProblems = vector<ILineError::EProblem>;
+    using TSeqTitles = vector<SLineTextAndLoc>;
+    typedef CTempString TStr;
+
+    struct SDefLineParseInfo {
+        TReaderFlags fBaseFlags;
+        TFlags fFastaFlags;
+        size_t maxIdLength;
+        size_t lineNumber;
+    };
+
+    static void ParseDefLine(const TStr& defLine, 
+        const SDefLineParseInfo& info,
+        const TIgnoredProblems& ignoredErrors,
+        list<CRef<CSeq_id>>& ids, 
+        bool& hasRange,
+        TSeqPos& rangeStart,
+        TSeqPos& rangeEnd,
+        TSeqTitles& seqTitles, 
+        ILineErrorListener* pMessageListener);
+
+protected:
+    enum EInternalFlags {
+        fAligning = 0x40000000,
+        fInSegSet = 0x20000000
+    };
+
+
     virtual CRef<CSeq_entry> x_ReadSegSet(ILineErrorListener * pMessageListener);
 
     virtual void   ParseDefLine  (const TStr& s, ILineErrorListener * pMessageListener);
-    virtual bool   ParseIDs      (const TStr& s, ILineErrorListener * pMessageListener);
-    virtual size_t ParseRange    (const TStr& s, TSeqPos& start, TSeqPos& end, ILineErrorListener * pMessageListener);
+
+    virtual bool   ParseIDs(const TStr& s, ILineErrorListener * pMessageListener);
+
+    static bool ParseIDs (const TStr& s, 
+        const SDefLineParseInfo& info,
+        const TIgnoredProblems& ignoredErrors,
+        list<CRef<CSeq_id>>& ids, 
+        ILineErrorListener* pMessageListener);
+
+    static size_t ParseRange    (const TStr& s, TSeqPos& start, TSeqPos& end, ILineErrorListener * pMessageListener);
     virtual void   ParseTitle    (const SLineTextAndLoc & lineInfo, ILineErrorListener * pMessageListener);
-    virtual bool   IsValidLocalID(const TStr& s);
+    virtual bool   IsValidLocalID(const TStr& s) const;
+    static bool IsValidLocalID(const TStr& idString, TFlags fFastaFlags);
     virtual void   GenerateID    (void);
     virtual void   ParseDataLine (const TStr& s, ILineErrorListener * pMessageListener);
     virtual void   CheckDataLine (const TStr& s, ILineErrorListener * pMessageListener);
@@ -227,12 +257,24 @@ protected:
     virtual bool   CreateWarningsForSeqDataInTitle(
         const TStr& sLineText, 
         TSeqPos iLineNum,
-        ILineErrorListener * pMessageListener);
+        ILineErrorListener * pMessageListener) const;
+    static bool ExcessiveSeqDataInTitle(const string& title, 
+                                        TFlags fFastaFlags);
     virtual void   PostWarning(ILineErrorListener * pMessageListener,
             EDiagSev _eSeverity, size_t _uLineNum, CTempString _MessageStrmOps, 
             CObjReaderParseException::EErrCode _eErrCode, 
             ILineError::EProblem _eProblem, 
-            CTempString _sFeature, CTempString _sQualName, CTempString _sQualValue);
+            CTempString _sFeature, CTempString _sQualName, CTempString _sQualValue) const;
+
+    static void PostWarning(ILineErrorListener* pMessageListener, 
+                            const size_t lineNumber,
+                            const string& errMessage, 
+                            CObjReaderParseException::EErrCode errCode);
+
+    static void PostError(ILineErrorListener* pMessageListener, 
+                          const size_t lineNumber,
+                          const string& errMessage, 
+                          CObjReaderParseException::EErrCode errCode);
 
     typedef int                         TRowNum;
     typedef map<TRowNum, TSignedSeqPos> TSubMap;
@@ -277,7 +319,7 @@ protected:
 
     std::string x_NucOrProt(void) const;
     
-private:
+protected:
     struct SGap : public CObject {
         enum EKnownSize {
             eKnownSize_No,
@@ -321,6 +363,7 @@ private:
     typedef CRef<SGap> TGapRef;
     typedef vector<TGapRef>     TGaps;
     typedef set<CSeq_id_Handle> TIDTracker;
+   
 
     CRef<ILineReader>       m_LineReader;
     stack<TFlags>           m_Flags;
@@ -352,7 +395,7 @@ private:
     SGap::TLinkEvidSet      m_gap_linkage_evidence;
     SGap::TNullableGapType  m_gap_type;
 
-    vector<SLineTextAndLoc> m_CurrentSeqTitles;
+    TSeqTitles m_CurrentSeqTitles;
     CRef<CSourceModParser::CModFilter> m_pModFilter;
     std::vector<ILineError::EProblem> m_ignorable;
 };
@@ -381,7 +424,7 @@ public:
     void SetCounter(TInt n)           { m_Counter.Set(n); }
     void SetSuffix (const string& s)  { m_Suffix  = s;    }
 
-private:
+protected:
     string         m_Prefix, m_Suffix;
     CAtomicCounter_WithAutoInit m_Counter;
 };
diff --git a/c++/include/objtools/readers/gff2_data.hpp b/c++/include/objtools/readers/gff2_data.hpp
index 85483a3..1c4b42c 100644
--- a/c++/include/objtools/readers/gff2_data.hpp
+++ b/c++/include/objtools/readers/gff2_data.hpp
@@ -1,4 +1,4 @@
-/*  $Id: gff2_data.hpp 489339 2016-01-12 15:46:54Z ludwigf $
+/*  $Id: gff2_data.hpp 512392 2016-08-30 17:42:36Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -100,7 +100,8 @@ public:
         return m_pePhase != 0; 
     };
     bool IsAlignmentRecord() const {
-        if (NStr::StartsWith(Type(), "match")) {
+        if (NStr::StartsWith(Type(), "match") ||
+            NStr::EndsWith(Type(), "_match")) {
             return true;
         }
         return false;
@@ -166,6 +167,15 @@ protected:
     virtual bool xInitFeatureData(
         int,
         CRef<CSeq_feat> ) const;
+    virtual bool xInitFeatureDataBond(
+        int,
+        CRef<CSeq_feat> ) const;
+    virtual bool xInitFeatureDataNcrna(
+        int,
+        CRef<CSeq_feat> ) const;
+    virtual bool xInitFeatureDataSpecialImp(
+        int,
+        CRef<CSeq_feat> ) const;
 
     virtual bool xUpdateFeatureData(
         int,
diff --git a/c++/include/objtools/readers/gff2_reader.hpp b/c++/include/objtools/readers/gff2_reader.hpp
index 29049b9..53f4248 100644
--- a/c++/include/objtools/readers/gff2_reader.hpp
+++ b/c++/include/objtools/readers/gff2_reader.hpp
@@ -1,4 +1,4 @@
- /*  $Id: gff2_reader.hpp 497078 2016-04-04 14:59:49Z ivanov $
+ /*  $Id: gff2_reader.hpp 520506 2016-11-29 16:03:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -37,6 +37,8 @@
 #include <objects/seq/Annotdesc.hpp>
 #include <objects/seqfeat/Seq_feat.hpp>
 #include <objects/seqfeat/Cdregion.hpp>
+#include <objects/seqalign/Spliced_exon.hpp>
+#include <objects/seqalign/Score.hpp>
 
 #include <objtools/readers/message_listener.hpp>
 #include <objtools/readers/reader_base.hpp>
@@ -65,6 +67,8 @@ public:
     } TFlags;
 
     typedef map<string, CRef<CSeq_feat> > IdToFeatureMap;
+    
+    using TScoreValueMap = map<string, CRef<CScore::TValue>>;
 
 public:
 
@@ -86,6 +90,11 @@ public:
     unsigned int 
     ObjectType() const { return OT_SEQENTRY; };
     
+    virtual CRef< CSeq_annot >
+    ReadSeqAnnot(
+        ILineReader& lr,
+        ILineErrorListener* pErrors=0 );
+
     CRef< CSeq_entry >
     ReadSeqEntry(
         ILineReader&,
@@ -132,10 +141,30 @@ public:
         const string&,
         CRef< CAnnotdesc >& );
                                 
-    virtual bool x_ParseStructuredCommentGff(
-        const string&,
-        CRef< CAnnotdesc >& );
+    virtual bool xParseStructuredComment(
+        const string&);
     
+    virtual bool xParseFeature(
+        const string&,
+        CRef<CSeq_annot>&,
+        ILineErrorListener*);
+      
+    virtual bool xParseAlignment(
+        const string&,
+        CRef<CSeq_annot>&,
+        ILineErrorListener*);
+      
+    virtual bool xIsCurrentDataType(
+        const string&);
+
+    virtual void xPostProcessAnnot(
+        CRef<CSeq_annot>&,
+        ILineErrorListener*);
+
+    virtual void xAssignAnnotId(
+        CRef<CSeq_annot>&,
+        const string& = "");
+
     virtual bool x_ParseDataGff(
         const string&,
         TAnnots&,
@@ -147,6 +176,35 @@ public:
         ILineErrorListener*);
 
     virtual bool x_ParseAlignmentGff(
+        const string& strLine, 
+        list<string>& id_list,
+        map<string, list<CRef<CSeq_align>>>& alignments);
+
+    void x_GetAlignmentScores(
+        const CSeq_align& alignment,
+        TScoreValueMap& score_values);
+      //  map<string, CRef<CScore::TValue>>& score_values);
+
+    void x_FindMatchingScores(
+        const TScoreValueMap& scores_1,
+        const TScoreValueMap& scores_2,
+        set<string>& matching_scores);
+
+    virtual bool x_CreateAlignment(
+        const CGff2Record& gff,
+        CRef<CSeq_align>& pAlign);
+
+    bool x_MergeAlignments(
+        const list<CRef<CSeq_align>>& alignment_list,
+        CRef<CSeq_align>& processed);
+     
+    void x_ProcessAlignmentsGff(
+        const list<string>& id_list,
+        const map<string, list<CRef<CSeq_align>>>& alignments,
+        CRef<CSeq_annot> pAnnot);
+
+
+    virtual bool x_ParseAlignmentGff(
         const string&,
         TAnnots&);
 
@@ -162,7 +220,8 @@ public:
 
     virtual bool x_UpdateAnnotAlignment(
         const CGff2Record&,
-        CRef< CSeq_annot > );
+        CRef< CSeq_annot >,
+        ILineErrorListener* =0);
 
     virtual bool xAddFeatureToAnnot(
         CRef< CSeq_feat >,
@@ -226,7 +285,7 @@ public:
         const string&,
         CRef< CSeq_feat >& );
 
-    bool x_GetParentFeature(
+    bool xGetParentFeature(
         const CSeq_feat&,
         CRef< CSeq_feat >& );
 
@@ -247,6 +306,13 @@ public:
         const CGff2Record&,
         CRef<CSeq_align> );
 
+    bool xSetDensegStarts(
+        const vector<string>& gapParts, 
+        bool oppositeStrands,
+        size_t targetStart,
+        const CGff2Record& gff,
+        CSeq_align::C_Segs::TDenseg& denseg);
+
     virtual bool xReadInit();
 
     virtual bool xAnnotPostProcess(
@@ -254,6 +320,21 @@ public:
     virtual bool xGenerateParentChildXrefs(
         CRef<CSeq_annot>);
 
+
+    bool xUpdateSplicedAlignment(const CGff2Record& gff, 
+                                 CRef<CSeq_align> pAlign) const;
+
+    bool xUpdateSplicedSegment(const CGff2Record& gff, 
+                               CSpliced_seg& segment) const;
+
+    bool xSetSplicedExon(
+        const CGff2Record& gff,
+        CRef<CSpliced_exon> pExon) const;
+
+    bool xGetTargetParts(const CGff2Record& gff, 
+                         vector<string>& targetParts) const;
+
+
     bool xAlignmentSetSegment(
         const CGff2Record&,
         CRef<CSeq_align> );
@@ -310,10 +391,11 @@ protected:
     //  data:
     //
 protected:
-//    TFlags             m_iFlags;
     ILineErrorListener* m_pErrors;
-    CRef<CAnnotdesc> m_CurrentTrackInfo;
+    unsigned int mCurrentFeatureCount;
+    bool mParsingAlignment;
     CRef<CAnnotdesc> m_CurrentBrowserInfo;
+    CRef<CAnnotdesc> m_CurrentTrackInfo;
 };
 
 END_SCOPE(objects)
diff --git a/c++/include/objtools/readers/gff3_reader.hpp b/c++/include/objtools/readers/gff3_reader.hpp
index 3c5df52..233258e 100644
--- a/c++/include/objtools/readers/gff3_reader.hpp
+++ b/c++/include/objtools/readers/gff3_reader.hpp
@@ -1,4 +1,4 @@
- /*  $Id: gff3_reader.hpp 497078 2016-04-04 14:59:49Z ivanov $
+ /*  $Id: gff3_reader.hpp 506819 2016-07-12 14:49:11Z ludwigf $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -59,6 +59,9 @@ public:
     CGff3ReadRecord() {};
     ~CGff3ReadRecord() {};
 
+    virtual bool AssignFromGff(
+        const string& );
+
 protected:
     string x_NormalizedAttributeKey(
         const string& );
@@ -150,7 +153,7 @@ protected:
 
     string xNextGenericId();
 
-    void xVerifyExonLocation(
+    bool xVerifyExonLocation(
         const string&,
         const CGff2Record&,
         ILineErrorListener*);
diff --git a/c++/include/objtools/readers/gff3_sofa.hpp b/c++/include/objtools/readers/gff3_sofa.hpp
index f5d83b7..771fdf2 100644
--- a/c++/include/objtools/readers/gff3_sofa.hpp
+++ b/c++/include/objtools/readers/gff3_sofa.hpp
@@ -1,4 +1,4 @@
-/*  $Id: gff3_sofa.hpp 403742 2013-06-18 15:26:09Z grichenk $
+/*  $Id: gff3_sofa.hpp 520685 2016-11-30 18:53:22Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -40,8 +40,33 @@
 BEGIN_NCBI_SCOPE
 BEGIN_SCOPE(objects) // namespace ncbi::objects::
 
-typedef map< string, CFeatListItem > TLookupSofaToGenbank;
+//  ----------------------------------------------------------------------------
+class CompareNoCase 
+//  ----------------------------------------------------------------------------
+{
+public:
+    bool operator()(string x, const string& y) const {
+        string::const_iterator pX = x.begin();
+        string::const_iterator pY = y.begin();
+        while (pX != x.end()  &&  pY != y.end()  &&  
+                tolower(*pX) ==  tolower(*pY)) {
+            ++pX;
+            ++pY;
+        }
+        if (pX == x.end()) {
+            return (pY != y.end());
+        }
+        if (pY == y.end()) {
+            return false;
+        }
+        return (tolower(*pX) < tolower(*pY)); 
+    }
+};
+
+typedef map< string, CFeatListItem, CompareNoCase > TLookupSofaToGenbank;
 typedef TLookupSofaToGenbank::const_iterator TLookupSofaToGenbankCit;
+typedef map< string, string, CompareNoCase > TAliasToTerm;
+typedef TAliasToTerm::const_iterator TAliasToTermCit;
 
 //  ----------------------------------------------------------------------------
 class NCBI_XOBJREAD_EXPORT CGff3SofaTypes
@@ -54,13 +79,20 @@ public:
     ~CGff3SofaTypes();
 
     CSeqFeatData::ESubtype MapSofaTermToGenbankType(
-        const string& );
+        const string&);
 
     CFeatListItem MapSofaTermToFeatListItem(
-        const string& );
+        const string&);
+
+    string MapSofaAliasToSofaTerm(
+        const string&);
+
+    bool IsStringSofaAlias(
+        const string&);
 
 protected:
     static CSafeStatic<TLookupSofaToGenbank> m_Lookup;
+    static CSafeStatic<TAliasToTerm> m_Aliases;
 };
 
 //  ----------------------------------------------------------------------------
diff --git a/c++/include/objtools/readers/gtf_reader.hpp b/c++/include/objtools/readers/gtf_reader.hpp
index 56dc9db..d1bcbcb 100644
--- a/c++/include/objtools/readers/gtf_reader.hpp
+++ b/c++/include/objtools/readers/gtf_reader.hpp
@@ -1,4 +1,4 @@
- /*  $Id: gtf_reader.hpp 493620 2016-03-01 13:41:06Z ivanov $
+ /*  $Id: gtf_reader.hpp 506324 2016-07-06 17:22:57Z ludwigf $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -162,6 +162,10 @@ protected:
         const CGff2Record&,
         CRef< CSeq_feat > );
             
+    bool xFeatureSetQualifiersGene(
+        const CGff2Record& record,
+        CRef<CSeq_feat>);
+
     bool x_CreateParentCds(
         const CGff2Record&,
         CRef< CSeq_annot > );
@@ -199,10 +203,6 @@ protected:
         const CGff2Record&,
         CRef< CSeq_feat >& );
 
-    bool x_FeatureSetQualifiers(
-        const CGff2Record&,
-        CRef< CSeq_feat >);
-
     virtual bool x_ProcessQualifierSpecialCase(
         CGff2Record::TAttrCit,
         CRef< CSeq_feat > );
@@ -210,10 +210,6 @@ protected:
     bool x_CdsIsPartial(
         const CGff2Record& );
 
-    bool x_SkipAttribute(
-        const CGff2Record&,
-        const string& ) const;
-
     typedef map< string, CRef< CSeq_feat > > TIdToFeature;
     TIdToFeature m_GeneMap;
     TIdToFeature m_CdsMap;
diff --git a/c++/include/objtools/readers/gvf_reader.hpp b/c++/include/objtools/readers/gvf_reader.hpp
index c37540d..085d13d 100644
--- a/c++/include/objtools/readers/gvf_reader.hpp
+++ b/c++/include/objtools/readers/gvf_reader.hpp
@@ -1,4 +1,4 @@
- /*  $Id: gvf_reader.hpp 489339 2016-01-12 15:46:54Z ludwigf $
+ /*  $Id: gvf_reader.hpp 515629 2016-10-04 17:46:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -95,13 +95,16 @@ public:
     virtual ~CGvfReader();
 
 protected:
-    virtual bool x_ParseStructuredCommentGff(
-        const string&,
-        CRef< CAnnotdesc >& );
+    virtual bool xParseStructuredComment(
+        const string&);
                                 
-    virtual bool x_ParseFeatureGff(
+    bool xParseFeature(
         const string&,
-        TAnnots&,
+        CRef<CSeq_annot>&,
+        ILineErrorListener*);
+      
+    virtual void xPostProcessAnnot(
+        CRef<CSeq_annot>&,
         ILineErrorListener*);
 
     CRef<CSeq_annot> x_GetAnnotById(
@@ -124,6 +127,18 @@ protected:
     bool xFeatureSetLocationPoint(
         const CGff2Record&,
         CRef< CSeq_feat > );
+
+    bool x_SetLocation(
+        const CGff2Record&,
+        CRef<CSeq_loc> );
+    
+    bool x_SetLocationInterval(
+        const CGff2Record&,
+        CRef<CSeq_loc> );
+
+    bool x_SetLocationPoint(
+        const CGff2Record&,
+        CRef<CSeq_loc> );
     
     bool x_FeatureSetVariation(
         const CGvfReadRecord&,
@@ -150,36 +165,68 @@ protected:
         const CGvfReadRecord&,
         CRef<CVariation_ref> );
 
+    bool xVariationMakeIndels(
+        const CGvfReadRecord&,
+        CRef<CVariation_ref>);
+
+    bool xVariationMakeInversions(
+        const CGvfReadRecord&,
+        CRef<CVariation_ref> );
+
+    bool xVariationMakeEversions(
+        const CGvfReadRecord&,
+        CRef<CVariation_ref> );
+
+    bool xVariationMakeTranslocations(
+        const CGvfReadRecord&,
+        CRef<CVariation_ref> );
+
+    bool xVariationMakeComplex(
+        const CGvfReadRecord&,
+        CRef<CVariation_ref> );
+
+    bool xVariationMakeUnknown(
+        const CGvfReadRecord&,
+        CRef<CVariation_ref> );
+
     bool xVariationSetInsertions(
         const CGvfReadRecord&,
-        CRef< CVariation_ref > );
+        CRef<CVariation_ref> );
 
     bool xVariationSetDeletions(
         const CGvfReadRecord&,
-        CRef< CVariation_ref > );
+        CRef<CVariation_ref> );
+
+    bool xVariationSetCommon(
+        const CGvfReadRecord&,
+        CRef<CVariation_ref> );
 
     virtual bool xVariationSetId(
         const CGvfReadRecord&,
-        CRef< CVariation_ref > );
+        CRef<CVariation_ref> );
 
     virtual bool xVariationSetParent(
         const CGvfReadRecord&,
-        CRef< CVariation_ref > );
+        CRef<CVariation_ref> );
 
     virtual bool xVariationSetName(
         const CGvfReadRecord&,
-        CRef< CVariation_ref > );
+        CRef<CVariation_ref> );
 
     virtual bool xVariationSetSnvs(
         const CGvfReadRecord&,
-        CRef< CVariation_ref > );
+        CRef<CVariation_ref> );
 
     virtual bool xVariationSetProperties(
         const CGvfReadRecord&,
-        CRef< CVariation_ref > );
+        CRef<CVariation_ref> );
 
     virtual CGff2Record* x_CreateRecord() { return new CGvfReadRecord(m_uLineNumber); };   
 
+    bool x_IsDbvarCall(const string& nameAttr) const;
+
+    bool x_GetNameAttribute(const CGvfReadRecord& record, string& name) const;
+    
 protected:
     CRef< CAnnotdesc > m_Pragmas;
  
diff --git a/c++/include/objtools/readers/microarray_reader.hpp b/c++/include/objtools/readers/microarray_reader.hpp
index 7a81a17..0814751 100644
--- a/c++/include/objtools/readers/microarray_reader.hpp
+++ b/c++/include/objtools/readers/microarray_reader.hpp
@@ -1,4 +1,4 @@
-/*  $Id: microarray_reader.hpp 472138 2015-07-07 16:07:55Z grichenk $
+/*  $Id: microarray_reader.hpp 515629 2016-10-04 17:46:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -96,12 +96,6 @@ protected:
         CRef<CSeq_feat>&,
         const vector<string>& );
 
-    virtual void xSetTrackData(
-    CRef<CSeq_annot>&,
-        CRef<CUser_object>&,
-        const string&,
-        const string& );
-                
     static void xCleanColumnValues(
         vector<string>&);
 
diff --git a/c++/include/objtools/readers/reader_base.hpp b/c++/include/objtools/readers/reader_base.hpp
index 4742a67..c78a0a9 100644
--- a/c++/include/objtools/readers/reader_base.hpp
+++ b/c++/include/objtools/readers/reader_base.hpp
@@ -1,4 +1,4 @@
-/*  $Id: reader_base.hpp 479221 2015-09-17 15:56:21Z gotvyans $
+/*  $Id: reader_base.hpp 515629 2016-10-04 17:46:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -38,6 +38,7 @@
 #include <util/format_guess.hpp>
 #include <util/line_reader.hpp>
 #include <util/icanceled.hpp>
+#include <objtools/readers/track_data.hpp>
 #include <objtools/readers/line_error.hpp>
 
 BEGIN_NCBI_SCOPE
@@ -237,6 +238,9 @@ protected:
     virtual bool xIsBrowserLine(
         const CTempString& );
 
+    virtual bool xIsTrackTerminator(
+        const CTempString& );
+
     virtual void xAssignTrackData(
         CRef<CSeq_annot>& );
                 
@@ -258,12 +262,10 @@ protected:
         CAnnot_descr&,
         ILineErrorListener*);
 
-    virtual void xSetTrackData(
+    virtual void xPostProcessAnnot(
         CRef<CSeq_annot>&,
-        CRef<CUser_object>&,
-        const string&,
-        const string&);
-                
+        ILineErrorListener*);
+
     virtual void xAddConversionInfo(
         CRef< CSeq_annot >&,
         ILineErrorListener* );
diff --git a/c++/include/objtools/readers/readfeat.hpp b/c++/include/objtools/readers/readfeat.hpp
index 6d37cfe..ba43187 100644
--- a/c++/include/objtools/readers/readfeat.hpp
+++ b/c++/include/objtools/readers/readfeat.hpp
@@ -157,23 +157,8 @@ public:
         string & out_annotname );
 
 private:
-    // this class uses a singleton internally to manage the specifics
-    // of the feature table reader implementation
-    // these are the variables / functions that control the singleton
-    static auto_ptr<CFeature_table_reader_imp> sm_Implementation;
-
-    static void                       x_InitImplementation(void);
-    static CFeature_table_reader_imp& x_GetImplementation (void);
 };
 
-inline
-CFeature_table_reader_imp& CFeature_table_reader::x_GetImplementation(void)
-{
-    if ( !sm_Implementation.get() ) {
-        x_InitImplementation();
-    }
-    return *sm_Implementation;
-}
 
 
 END_objects_SCOPE
diff --git a/c++/include/objtools/readers/source_mod_parser.hpp b/c++/include/objtools/readers/source_mod_parser.hpp
index 8ef6f9c..b1ab343 100644
--- a/c++/include/objtools/readers/source_mod_parser.hpp
+++ b/c++/include/objtools/readers/source_mod_parser.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_READERS___SOURCE_MOD_PARSER__HPP
 #define OBJTOOLS_READERS___SOURCE_MOD_PARSER__HPP
 
-/*  $Id: source_mod_parser.hpp 499427 2016-04-26 14:11:26Z ivanov $
+/*  $Id: source_mod_parser.hpp 493669 2016-03-01 16:52:34Z gotvyans $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/objtools/readers/struct_cmt_reader.hpp b/c++/include/objtools/readers/struct_cmt_reader.hpp
new file mode 100644
index 0000000..7537ef0
--- /dev/null
+++ b/c++/include/objtools/readers/struct_cmt_reader.hpp
@@ -0,0 +1,96 @@
+#ifndef __STRUCT_CMT_READER_HPP_INCLUDED__
+#define __STRUCT_CMT_READER_HPP_INCLUDED__
+
+#include <corelib/ncbistl.hpp>
+#include <corelib/ncbiobj.hpp>
+
+BEGIN_NCBI_SCOPE
+
+// forward declarations
+namespace objects
+{
+    class CSeq_descr;
+    class CSeqdesc;
+    class CSeq_id;
+    class CUser_object;
+    class ILineErrorListener;
+};
+
+class CSerialObject;
+class ILineReader;
+
+/*
+  Usage examples
+
+  CStructuredCommentsReader reader(error_logger);
+
+  std::list<CStructuredCommentsReader::TStructComment> comments;
+
+  ILineReader reader1(ILineReader::New(filename);
+  reader.LoadComments(reader1, comments);
+
+  for (const CStructuredCommentsReader::TStructComment& cmt: comments)
+  {
+     // do something
+  }
+*/
+
+class CStructuredCommentsReader
+{
+public:
+   // If you need messages and error to be logged
+   // supply an optional ILineErrorListener instance
+   CStructuredCommentsReader(objects::ILineErrorListener* logger);
+   ~CStructuredCommentsReader();
+
+   typedef struct {
+       CRef<objects::CSeq_id> m_id;
+       vector<CRef<objects::CSeqdesc> > m_descs;
+   } TStructComment;
+
+#if 0
+   template<typename _container>
+   size_t LoadComments(ILineReader& reader, _container& cont)
+   {
+       vector<string> cols;
+       _LoadHeaderLine(reader, cols);
+       if (cols.empty())
+           return 0;
+
+       size_t loader = 0;
+
+       while (!reader.AtEOF())
+       {
+           reader.ReadLine();
+           // First line is a collumn definitions
+           CTempString current = reader.GetCurrentLine();
+           if (current.empty())
+               continue;
+
+           // Each line except first is a set of values, first collumn is a sequence id
+           vector<CTempString> values;
+           NStr::Split(current, "\t", values);
+           if (!values[0].empty())
+           {
+               // try to find destination sequence
+               cont.push_back(TStructComment());
+               TStructComment& cmt = cont.back();
+               cmt.m_id.Reset(new objects::CSeq_id(values[0], objects::CSeq_id::fParse_AnyLocal));
+               _BuildStructuredComment(cmt, cols, values);
+           }
+       }
+   }
+#endif
+
+   objects::CUser_object* FindStructuredComment(objects::CSeq_descr& descr);
+protected:
+   void _LoadHeaderLine(ILineReader& reader, vector<string>& cols);
+   void _BuildStructuredComment(TStructComment& cmt, const vector<string>& cols, const vector<CTempString>& values);
+   objects::CUser_object* _AddStructuredComment(objects::CUser_object* user_obj, TStructComment& cmt, const CTempString& name, const CTempString& value);
+   objects::ILineErrorListener* m_logger;
+};
+
+END_NCBI_SCOPE
+
+
+#endif
diff --git a/c++/include/objtools/readers/track_data.hpp b/c++/include/objtools/readers/track_data.hpp
new file mode 100644
index 0000000..51d6426
--- /dev/null
+++ b/c++/include/objtools/readers/track_data.hpp
@@ -0,0 +1,77 @@
+/*  $Id: track_data.hpp 515629 2016-10-04 17:46:33Z ivanov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author: Frank Ludwig
+ *
+ * File Description:
+ *   data structures of interest to multiple readers
+ *
+ */
+
+#ifndef OBJTOOLS_READERS___TRACKDATA__HPP
+#define OBJTOOLS_READERS___TRACKDATA__HPP
+
+BEGIN_NCBI_SCOPE
+BEGIN_SCOPE(objects) // namespace ncbi::objects::
+
+//  ============================================================================
+class NCBI_XOBJREAD_EXPORT CTrackData
+//  ============================================================================
+{
+public:
+    typedef std::vector<std::string> LineData;
+    typedef std::map<const std::string, std::string > TrackData;
+public:
+    CTrackData();
+    ~CTrackData() {};
+    bool ParseLine(
+        const LineData& );
+    static bool IsTrackData(
+        const LineData& );
+    const TrackData& Values() const {return mData;};
+    bool WriteToAnnot(
+        CSeq_annot&);
+    bool ContainsData() const {return !mData.empty();};
+
+    //convenience accessors
+    string Type() const {return ValueOf("type");};
+    string Description() const {return ValueOf("description");};
+    string Name() const {return ValueOf("name");};
+    int Offset() const;
+
+    string ValueOf(
+        const std::string&) const;
+
+protected:
+    TrackData mData;
+    //string m_strType;
+    //string m_strDescription;
+    //string m_strName;
+};
+
+END_SCOPE(objects)
+END_NCBI_SCOPE
+
+#endif // OBJTOOLS_READERS___TRACKDATA__HPP
diff --git a/c++/include/objtools/readers/vcf_reader.hpp b/c++/include/objtools/readers/vcf_reader.hpp
index ab906c5..b09940b 100644
--- a/c++/include/objtools/readers/vcf_reader.hpp
+++ b/c++/include/objtools/readers/vcf_reader.hpp
@@ -1,4 +1,4 @@
-/*  $Id: vcf_reader.hpp 472138 2015-07-07 16:07:55Z grichenk $
+/*  $Id: vcf_reader.hpp 503934 2016-06-09 14:44:15Z foleyjp $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -218,7 +218,8 @@ protected:
         
     virtual bool
     xAssignVcfMeta(
-        CRef<CSeq_annot> );
+        CRef<CSeq_annot>,
+        ILineErrorListener* );
 
     virtual bool
     xAssignVariationAlleleSet(
@@ -314,6 +315,7 @@ protected:
     vector<string> m_MetaDirectives;
     vector<string> m_GenotypeHeaders;
     CMessageListenerLenient m_ErrorsPrivate;
+    bool m_MetaHandled;
 };
 
 END_SCOPE(objects)
diff --git a/c++/include/objtools/readers/wiggle_reader.hpp b/c++/include/objtools/readers/wiggle_reader.hpp
index 42845ec..b39a875 100644
--- a/c++/include/objtools/readers/wiggle_reader.hpp
+++ b/c++/include/objtools/readers/wiggle_reader.hpp
@@ -1,4 +1,4 @@
-/*  $Id: wiggle_reader.hpp 472138 2015-07-07 16:07:55Z grichenk $
+/*  $Id: wiggle_reader.hpp 511582 2016-08-23 15:29:38Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -168,7 +168,7 @@ public:
         m_pInterval.Reset(new CSeq_interval());
         m_pInterval->SetId(id);
         m_pInterval->SetFrom(start-1);
-        m_pInterval->SetTo(start+span-1);
+        m_pInterval->SetTo(start-1+span-1);
         m_value = value;
     };
     
diff --git a/c++/include/serial/impl/enumerated.hpp b/c++/include/serial/impl/enumerated.hpp
index fc39293..a0e8911 100644
--- a/c++/include/serial/impl/enumerated.hpp
+++ b/c++/include/serial/impl/enumerated.hpp
@@ -1,7 +1,7 @@
 #ifndef ENUMERATED__HPP
 #define ENUMERATED__HPP
 
-/*  $Id: enumerated.hpp 103491 2007-05-04 17:18:18Z kazimird $
+/*  $Id: enumerated.hpp 515165 2016-09-28 17:51:10Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -34,6 +34,7 @@
 
 #include <serial/impl/stdtypes.hpp>
 #include <serial/enumvalues.hpp>
+#include <limits>
 
 
 /** @addtogroup TypeInfoCPP
@@ -44,6 +45,7 @@
 
 BEGIN_NCBI_SCOPE
 
+
 class NCBI_XSERIAL_EXPORT CEnumeratedTypeInfo : public CPrimitiveTypeInfo
 {
     typedef CPrimitiveTypeInfo CParent;
@@ -101,9 +103,20 @@ inline
 CEnumeratedTypeInfo* CreateEnumeratedTypeInfo(const T& ,
                                               const CEnumeratedTypeValues* values)
 {
-    return new CEnumeratedTypeInfo(sizeof(T), values, T(-1) < 0);
+// C++ enums are not signed and not unsigned
+    bool is_signed = std::is_signed<T>::value;
+    if (std::is_enum<T>::value) {
+        for (const auto& v : values->GetValues()) {
+            if (v.second < 0) {
+                is_signed = true;
+                break;
+            }
+        }
+    }
+    return new CEnumeratedTypeInfo(sizeof(T), values, is_signed);
 }
 
+
 END_NCBI_SCOPE
 
 /* @} */
diff --git a/c++/include/serial/impl/objectiter.inl b/c++/include/serial/impl/objectiter.inl
index f11a79e..69d1c99 100644
--- a/c++/include/serial/impl/objectiter.inl
+++ b/c++/include/serial/impl/objectiter.inl
@@ -1,7 +1,7 @@
 #if defined(OBJECTITER__HPP)  &&  !defined(OBJECTITER__INL)
 #define OBJECTITER__INL
 
-/*  $Id: objectiter.inl 103491 2007-05-04 17:18:18Z kazimird $
+/*  $Id: objectiter.inl 502193 2016-05-23 12:28:12Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -656,6 +656,11 @@ CObjectTypeInfo CObjectTypeInfoCV::GetChoiceType(void) const
 }
 
 inline
+CObjectTypeInfoCV::operator CObjectTypeInfo(void) const
+{
+    return GetVariantInfo()->GetTypeInfo();
+}
+inline
 CObjectTypeInfo CObjectTypeInfoCV::GetVariantType(void) const
 {
     return GetVariantInfo()->GetTypeInfo();
diff --git a/c++/include/serial/impl/objistrasnb.inl b/c++/include/serial/impl/objistrasnb.inl
index 1982df3..da5e676 100644
--- a/c++/include/serial/impl/objistrasnb.inl
+++ b/c++/include/serial/impl/objistrasnb.inl
@@ -1,7 +1,7 @@
 #if defined(OBJISTRASNB__HPP)  &&  !defined(OBJISTRASNB__INL)
 #define OBJISTRASNB__INL
 
-/*  $Id: objistrasnb.inl 412224 2013-09-05 15:30:00Z gouriano $
+/*  $Id: objistrasnb.inl 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -143,6 +143,27 @@ void CObjectIStreamAsnBinary::ExpectSysTag(ETagValue tag_value)
 }
 
 inline
+void CObjectIStreamAsnBinary::ExpectIntegerTag(void)
+{
+    if (m_SkipNextTag) {
+        m_SkipNextTag = false;
+        return;
+    }
+    Uint1 tag = StartTag(PeekTagByte());
+    Uint1 exp = MakeTagByte(  eUniversal, ePrimitive, eInteger);
+    if (tag != exp) {
+        if (tag != MakeTagByte(eApplication, ePrimitive, eInteger)) {
+            UnexpectedSysTagByte(exp);
+        }
+        SetSpecialCaseUsed(CObjectIStream::eReadAsBigInt);
+    }
+    m_CurrentTagLength = 1;
+#if CHECK_INSTREAM_STATE
+    m_CurrentTagState = eTagParsed;
+#endif
+}
+
+inline
 void CObjectIStreamAsnBinary::ExpectTagClassByte(TByte first_tag_byte,
                                                  TByte expected_class_byte)
 {
diff --git a/c++/include/serial/impl/objstack.hpp b/c++/include/serial/impl/objstack.hpp
index 64cc425..4986995 100644
--- a/c++/include/serial/impl/objstack.hpp
+++ b/c++/include/serial/impl/objstack.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJSTACK__HPP
 #define OBJSTACK__HPP
 
-/*  $Id: objstack.hpp 461337 2015-03-09 18:00:58Z gouriano $
+/*  $Id: objstack.hpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -61,7 +61,7 @@ class NCBI_XSERIAL_EXPORT CObjectStackFrame
 {
 public:
     enum EFrameType {
-        eFrameOther,
+        eFrameOther = 0,
         eFrameNamed,
         eFrameArray,
         eFrameArrayElement,
@@ -101,13 +101,13 @@ protected:
 private:
     friend class CObjectStack;
 
-    EFrameType m_FrameType;
-    bool m_Notag; // means no XML tag
-    bool m_NoEOC; // no binary ASN end-of-content mark
-    ENsQualifiedMode m_NsqMode;
     TTypeInfo m_TypeInfo;
     const CMemberId* m_MemberId;
     TConstObjectPtr m_ObjectPtr;
+    EFrameType m_FrameType;
+    ENsQualifiedMode m_NsqMode;
+    bool m_Notag; // means no XML tag
+    bool m_NoEOC; // no binary ASN end-of-content mark
 };
 
 #define ThrowError(flag, mess) \
@@ -156,6 +156,7 @@ public:
     TFrame& FetchFrameFromTop(size_t index);
     const TFrame& FetchFrameFromTop(size_t index) const;
     const TFrame& FetchFrameFromBottom(size_t index) const;
+    TTypeInfo GetRecentTypeInfo(void) const;
 
     virtual void UnendedFrame(void);
     const string& GetStackPath(void);
diff --git a/c++/include/serial/impl/objstack.inl b/c++/include/serial/impl/objstack.inl
index 026b34a..ea3b13c 100644
--- a/c++/include/serial/impl/objstack.inl
+++ b/c++/include/serial/impl/objstack.inl
@@ -1,7 +1,7 @@
 #if defined(OBJSTACK__HPP)  &&  !defined(OBJSTACK__INL)
 #define OBJSTACK__INL
 
-/*  $Id: objstack.inl 412224 2013-09-05 15:30:00Z gouriano $
+/*  $Id: objstack.inl 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -35,13 +35,13 @@
 inline
 void CObjectStackFrame::Reset(void)
 {
-    m_FrameType = eFrameOther;
-    m_Notag = false;
-    m_NoEOC = false;
-    m_NsqMode = eNSQNotSet;
     m_TypeInfo = 0;
     m_MemberId = 0;
     m_ObjectPtr = 0;
+    m_FrameType = eFrameOther;
+    m_NsqMode = eNSQNotSet;
+    m_Notag = false;
+    m_NoEOC = false;
 }
 
 inline
@@ -265,6 +265,17 @@ const CObjectStack::TFrame& CObjectStack::FetchFrameFromBottom(size_t index) con
 }
 
 inline
+TTypeInfo CObjectStack::GetRecentTypeInfo(void) const
+{
+    for (TFrame* ptr = m_StackPtr; ptr >= m_Stack; --ptr) {
+        if (ptr->HasTypeInfo()) {
+            return ptr->GetTypeInfo();
+        }
+    }
+    return nullptr;
+}
+
+inline
 void CObjectStack::WatchPathHooks(bool set)
 {
     m_WatchPathHooks = set;
diff --git a/c++/include/serial/impl/objstrasnb.inl b/c++/include/serial/impl/objstrasnb.inl
index fb93bfd..b29c16e 100644
--- a/c++/include/serial/impl/objstrasnb.inl
+++ b/c++/include/serial/impl/objstrasnb.inl
@@ -1,7 +1,7 @@
 #if defined(OBJSTRASNB__HPP)  &&  !defined(OBJSTRASNB__INL)
 #define OBJSTRASNB__INL
 
-/*  $Id: objstrasnb.inl 412224 2013-09-05 15:30:00Z gouriano $
+/*  $Id: objstrasnb.inl 500790 2016-05-09 11:30:33Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -61,7 +61,7 @@ CAsnBinaryDefs::MakeContainerTagByte(bool random_order)
 
 inline
 CAsnBinaryDefs::ETagValue
-CAsnBinaryDefs::StringTag(EStringType type)
+CAsnBinaryDefs::StringTag(EStringType /*type*/)
 {
     return eVisibleString;
     //return type == eStringTypeVisible? eVisibleString: eUTF8String;
diff --git a/c++/include/serial/impl/stdtypes.hpp b/c++/include/serial/impl/stdtypes.hpp
index 69fe121..365cd73 100644
--- a/c++/include/serial/impl/stdtypes.hpp
+++ b/c++/include/serial/impl/stdtypes.hpp
@@ -1,7 +1,7 @@
 #ifndef STDTYPES__HPP
 #define STDTYPES__HPP
 
-/*  $Id: stdtypes.hpp 405847 2013-07-09 13:56:53Z gouriano $
+/*  $Id: stdtypes.hpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -325,6 +325,16 @@ public:
     static CTypeInfo* CreateTypeInfo(void);
 };
 
+class bigint_type {
+};
+EMPTY_TEMPLATE
+class NCBI_XSERIAL_EXPORT CStdTypeInfo<bigint_type>
+{
+public:
+    static TTypeInfo GetTypeInfo(void);
+    static CTypeInfo* CreateTypeInfo(void);
+};
+
 EMPTY_TEMPLATE
 class NCBI_XSERIAL_EXPORT CStdTypeInfo<char*>
 {
diff --git a/c++/include/serial/objectiter.hpp b/c++/include/serial/objectiter.hpp
index f799755..8a2c0e4 100644
--- a/c++/include/serial/objectiter.hpp
+++ b/c++/include/serial/objectiter.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTITER__HPP
 #define OBJECTITER__HPP
 
-/*  $Id: objectiter.hpp 358154 2012-03-29 15:05:12Z gouriano $
+/*  $Id: objectiter.hpp 502193 2016-05-23 12:28:12Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -493,6 +493,7 @@ public:
     /// Get containing choice
     CObjectTypeInfo GetChoiceType(void) const;
 
+    operator CObjectTypeInfo(void) const;
     /// Get variant data type
     CObjectTypeInfo GetVariantType(void) const;
     /// Get variant data type
diff --git a/c++/include/serial/objhook.hpp b/c++/include/serial/objhook.hpp
index c3b98a1..2dc5288 100644
--- a/c++/include/serial/objhook.hpp
+++ b/c++/include/serial/objhook.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJHOOK__HPP
 #define OBJHOOK__HPP
 
-/*  $Id: objhook.hpp 367319 2012-06-22 18:19:19Z gouriano $
+/*  $Id: objhook.hpp 502193 2016-05-23 12:28:12Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -70,7 +70,7 @@ public:
                      const CObjectInfo& object);
     /// Default skip
     void DefaultSkip(CObjectIStream& in,
-                     const CObjectInfo& object);
+                     const CObjectTypeInfo& object);
 };
 
 /// Read hook for data member of a containing object (eg, SEQUENCE)
@@ -88,7 +88,7 @@ public:
     void DefaultRead(CObjectIStream& in,
                      const CObjectInfoMI& object);
     void DefaultSkip(CObjectIStream& in,
-                     const CObjectInfoMI& object);
+                     const CObjectTypeInfoMI& object);
     void ResetMember(const CObjectInfoMI& object,
                      CObjectInfoMI::EEraseFlag flag =
                          CObjectInfoMI::eErase_Optional);
@@ -124,7 +124,8 @@ public:
                                    const CObjectInfoCV& variant) = 0;
     void DefaultRead(CObjectIStream& in,
                      const CObjectInfoCV& object);
-    // No default skip method - can not skip variants
+    void DefaultSkip(CObjectIStream& in,
+                     const CObjectTypeInfoCV& object);
 };
 
 /// Read hook for a choice variant (CHOICE)
@@ -179,6 +180,9 @@ public:
                                   const CConstObjectInfoMI& member) = 0;
     void DefaultWrite(CObjectOStream& out,
                       const CConstObjectInfoMI& member);
+    void CustomWrite(CObjectOStream& out,
+                     const CConstObjectInfoMI& member,
+                     const CConstObjectInfo& custom_object);
 };
 
 /// Write hook for a choice variant (CHOICE)
@@ -191,6 +195,9 @@ public:
                                     const CConstObjectInfoCV& variant) = 0;
     void DefaultWrite(CObjectOStream& out,
                       const CConstObjectInfoCV& variant);
+    void CustomWrite(CObjectOStream& out,
+                     const CConstObjectInfoCV& variant,
+                     const CConstObjectInfo& custom_object);
 };
 
 /// Skip hook for a standalone object
@@ -221,6 +228,8 @@ public:
                                  const CObjectTypeInfoMI& member) = 0;
     virtual void SkipMissingClassMember(CObjectIStream& stream,
                                         const CObjectTypeInfoMI& member);
+    void DefaultRead(CObjectIStream& in,
+                     const CObjectInfo& object);
     void DefaultSkip(CObjectIStream& stream,
                      const CObjectTypeInfoMI& member);
 };
@@ -233,8 +242,10 @@ public:
 
     virtual void SkipChoiceVariant(CObjectIStream& stream,
                                    const CObjectTypeInfoCV& variant) = 0;
-//    void DefaultSkip(CObjectIStream& stream,
-//                     const CObjectTypeInfoCV& variant);
+    void DefaultRead(CObjectIStream& in,
+                     const CObjectInfo& object);
+    void DefaultSkip(CObjectIStream& stream,
+                     const CObjectTypeInfoCV& variant);
 };
 
 
diff --git a/c++/include/serial/objistr.hpp b/c++/include/serial/objistr.hpp
index e607845..87a5e85 100644
--- a/c++/include/serial/objistr.hpp
+++ b/c++/include/serial/objistr.hpp
@@ -1,7 +1,7 @@
 #ifndef SERIAL___OBJISTR__HPP
 #define SERIAL___OBJISTR__HPP
 
-/*  $Id: objistr.hpp 421693 2013-12-13 14:11:00Z gouriano $
+/*  $Id: objistr.hpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -1071,7 +1071,8 @@ public:
     enum ESpecialCaseRead {
         eReadAsNormal  = 0,
         eReadAsDefault = 1,
-        eReadAsNil     = 2
+        eReadAsNil     = 2,
+        eReadAsBigInt  = 3
     };
 private:
     TConstObjectPtr m_MemberDefault;
diff --git a/c++/include/serial/objistrasnb.hpp b/c++/include/serial/objistrasnb.hpp
index 773619c..bc952ff 100644
--- a/c++/include/serial/objistrasnb.hpp
+++ b/c++/include/serial/objistrasnb.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJISTRASNB__HPP
 #define OBJISTRASNB__HPP
 
-/*  $Id: objistrasnb.hpp 421594 2013-12-12 19:03:07Z gouriano $
+/*  $Id: objistrasnb.hpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -298,6 +298,7 @@ private:
                       ETagConstructed tag_constructed,
                       ETagValue tag_value);
     void ExpectSysTag(ETagValue tag_value);
+    void ExpectIntegerTag(void);
 
     void ExpectTag(ETagClass tag_class,
                    ETagConstructed tag_constructed,
diff --git a/c++/include/serial/objostr.hpp b/c++/include/serial/objostr.hpp
index 205d0a3..878c60b 100644
--- a/c++/include/serial/objostr.hpp
+++ b/c++/include/serial/objostr.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJOSTR__HPP
 #define OBJOSTR__HPP
 
-/*  $Id: objostr.hpp 484578 2015-11-12 19:13:20Z vasilche $
+/*  $Id: objostr.hpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -754,7 +754,8 @@ public:
     enum ESpecialCaseWrite {
         eWriteAsNormal  = 0,
         eWriteAsDefault = 1,
-        eWriteAsNil     = 2
+        eWriteAsNil     = 2,
+        eWriteAsBigInt  = 3
     };
     void  SetSpecialCaseWrite( ESpecialCaseWrite how) {
         m_SpecialCaseWrite = how;
@@ -793,12 +794,12 @@ protected:
     TFlags m_Flags;
     AutoPtr<CWriteObjectList> m_Objects;
     string m_Separator;
-    bool   m_AutoSeparator;
     ESerialDataFormat   m_DataFormat;
-    bool  m_WriteNamedIntegersByValue;
     EDelayBufferParsing  m_ParseDelayBuffers;
-    bool  m_FastWriteDouble;
     ESpecialCaseWrite m_SpecialCaseWrite;
+    bool  m_AutoSeparator;
+    bool  m_WriteNamedIntegersByValue;
+    bool  m_FastWriteDouble;
     bool  m_EnforceWritingDefaults;
 
 private:
diff --git a/c++/include/serial/objostrxml.hpp b/c++/include/serial/objostrxml.hpp
index b061ab5..87b5b6f 100644
--- a/c++/include/serial/objostrxml.hpp
+++ b/c++/include/serial/objostrxml.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJOSTRXML__HPP
 #define OBJOSTRXML__HPP
 
-/*  $Id: objostrxml.hpp 459636 2015-02-20 14:45:49Z gouriano $
+/*  $Id: objostrxml.hpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -415,7 +415,7 @@ private:
     void x_EndTypeNamespace(void);
     bool x_BeginNamespace(const string& ns_name, const string& ns_prefix);
     void x_EndNamespace(const string& ns_name);
-    void x_SpecialCaseWrite(void);
+    bool x_SpecialCaseWrite(void);
     char x_VerifyChar(char);
 
     enum ETagAction {
diff --git a/c++/include/serial/rpcbase.hpp b/c++/include/serial/rpcbase.hpp
index b6d2848..4f81eb2 100644
--- a/c++/include/serial/rpcbase.hpp
+++ b/c++/include/serial/rpcbase.hpp
@@ -1,7 +1,7 @@
 #ifndef SERIAL___RPCBASE__HPP
 #define SERIAL___RPCBASE__HPP
 
-/*  $Id: rpcbase.hpp 489897 2016-01-19 18:58:14Z grichenk $
+/*  $Id: rpcbase.hpp 514363 2016-09-21 15:20:35Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -89,9 +89,9 @@ public:
     const STimeout* GetTimeout(EIO_Event direction = eIO_Read) const;
 
 protected:
-    virtual string GetAffinity(const TRequest& request) const
+    virtual string GetAffinity(const TRequest& /*request*/) const
     {
-        return "";
+        return string();
     }
 
     virtual void x_WriteRequest(CObjectOStream& out, const CSerialObject& request)
@@ -164,6 +164,7 @@ void CRPCClient<TRequest, TReply>::x_Connect(void)
     memset(&x_extra, 0, sizeof(x_extra));
     x_extra.data = &m_RetryCtx;
     x_extra.parse_header = sx_ParseHeader;
+    x_extra.flags = fHTTP_NoAutoRetry;
 
     x_SetStream(new CConn_ServiceStream(m_Service, fSERV_Any, net_info,
         &x_extra, m_Timeout));
@@ -195,7 +196,7 @@ void CRPCClient<TRequest, TReply>::x_ConnectURL(const string& url)
         &m_RetryCtx,    // user data for the callback
         0, // adjust callback
         0, // cleanup callback
-        fHTTP_AutoReconnect,
+        fHTTP_AutoReconnect | fHTTP_NoAutoRetry,
         m_Timeout));
 }
 
@@ -251,9 +252,11 @@ inline
 EHTTP_HeaderParse
 CRPCClient<TRequest, TReply>::sx_ParseHeader(const char* http_header,
                                              void*       user_data,
-                                             int         server_error)
+                                             int         /*server_error*/)
 {
-    if ( !user_data ) return eHTTP_HeaderContinue;
+    if ( !user_data ) {
+        return eHTTP_HeaderContinue;
+    }
     CHttpRetryContext* retry_ctx = reinterpret_cast<CHttpRetryContext*>(user_data);
     _ASSERT(retry_ctx);
     retry_ctx->ParseHeader(http_header);
diff --git a/c++/include/serial/rpcbase_impl.hpp b/c++/include/serial/rpcbase_impl.hpp
index e03b3ec..df6ca69 100644
--- a/c++/include/serial/rpcbase_impl.hpp
+++ b/c++/include/serial/rpcbase_impl.hpp
@@ -1,7 +1,7 @@
 #ifndef SERIAL___RPCBASE_IMPL__HPP
 #define SERIAL___RPCBASE_IMPL__HPP
 
-/*  $Id: rpcbase_impl.hpp 499300 2016-04-25 15:23:35Z ivanov $
+/*  $Id: rpcbase_impl.hpp 498886 2016-04-20 13:48:22Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/serial/serialbase.hpp b/c++/include/serial/serialbase.hpp
index f792421..84f8db3 100644
--- a/c++/include/serial/serialbase.hpp
+++ b/c++/include/serial/serialbase.hpp
@@ -1,7 +1,7 @@
 #ifndef SERIALBASE__HPP
 #define SERIALBASE__HPP
 
-/*  $Id: serialbase.hpp 389685 2013-02-20 14:11:37Z gouriano $
+/*  $Id: serialbase.hpp 498023 2016-04-12 18:53:26Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -329,19 +329,19 @@ public:
             return this;
         }
 
-    bool operator<(const TPrim& value) const
+    template<class T> bool operator<(const T& value) const
         {
             return m_Data < value;
         }
-    bool operator>(const TPrim& value) const
+    template<class T> bool operator>(const T& value) const
         {
             return m_Data > value;
         }
-    bool operator==(const TPrim& value) const
+    template<class T> bool operator==(const T& value) const
         {
             return m_Data == value;
         }
-    bool operator!=(const TPrim& value) const
+    template<class T> bool operator!=(const T& value) const
         {
             return m_Data != value;
         }
@@ -382,6 +382,21 @@ public:
 };
 
 
+#ifdef NCBI_STRICT_GI
+template <>
+class NCBI_XSERIAL_EXPORT CStdAliasBase<CStrictId64> : public CAliasBase<CStrictId64>
+{
+    typedef CAliasBase<CStrictId64> TParent;
+    typedef CStdAliasBase<CStrictId64> TThis;
+public:
+    CStdAliasBase(void)
+        : TParent(CStrictId64()) {}
+    explicit CStdAliasBase(const CStrictId64& value)
+        : TParent(value) {}
+};
+#endif
+
+
 template<typename T>
 class CUnionBuffer
 {   // char buffer support, used in choices
diff --git a/c++/include/serial/serialdef.hpp b/c++/include/serial/serialdef.hpp
index 8c6a3f3..b616378 100644
--- a/c++/include/serial/serialdef.hpp
+++ b/c++/include/serial/serialdef.hpp
@@ -1,7 +1,7 @@
 #ifndef SERIALDEF__HPP
 #define SERIALDEF__HPP
 
-/*  $Id: serialdef.hpp 395287 2013-04-10 17:58:30Z grichenk $
+/*  $Id: serialdef.hpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -195,7 +195,7 @@ enum ESerialRecursionMode {
 
 /// Defines namespace qualification of XML tags
 enum ENsQualifiedMode {
-    eNSQNotSet,
+    eNSQNotSet = 0,
     eNSUnqualified,
     eNSQualified
 };
diff --git a/c++/include/serial/serialimpl.hpp b/c++/include/serial/serialimpl.hpp
index c1b963b..d91b95f 100644
--- a/c++/include/serial/serialimpl.hpp
+++ b/c++/include/serial/serialimpl.hpp
@@ -1,7 +1,7 @@
 #ifndef SERIALIMPL__HPP
 #define SERIALIMPL__HPP
 
-/*  $Id: serialimpl.hpp 471224 2015-06-24 17:35:04Z gouriano $
+/*  $Id: serialimpl.hpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -111,6 +111,10 @@ TTypeInfoGetter GetStdTypeInfoGetter(const char* const* )
 #define SERIAL_REF_CStringUTF8() \
     &NCBI_NS_NCBI::CStdTypeInfo<NCBI_NS_NCBI::utf8_string_type>::GetTypeInfo
 
+#define SERIAL_TYPE_BigInt() Int8
+#define SERIAL_REF_BigInt() \
+    &NCBI_NS_NCBI::CStdTypeInfo<NCBI_NS_NCBI::bigint_type>::GetTypeInfo
+
 #define SERIAL_TYPE_ENUM(CType, EnumName) CType
 #define SERIAL_REF_ENUM(CType, EnumName) \
     NCBI_NS_NCBI::CreateEnumeratedTypeInfo(CType(0), ENUM_METHOD_NAME(EnumName)())
diff --git a/c++/include/serial/typeinfo.hpp b/c++/include/serial/typeinfo.hpp
index f0a724b..9427ef3 100644
--- a/c++/include/serial/typeinfo.hpp
+++ b/c++/include/serial/typeinfo.hpp
@@ -1,7 +1,7 @@
 #ifndef TYPEINFO__HPP
 #define TYPEINFO__HPP
 
-/*  $Id: typeinfo.hpp 412224 2013-09-05 15:30:00Z gouriano $
+/*  $Id: typeinfo.hpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -264,6 +264,12 @@ public:
     bool IsTagConstructed(void) const {
         return m_TagConstructed == CAsnBinaryDefs::eConstructed;
     }
+    void CodeVersion(size_t codever) {
+        m_CodeVer = codever;
+    }
+    size_t GetCodeVersion(void) const {
+        return m_CodeVer;
+    }
 private:
     // private constructors to avoid copying
     CTypeInfo(const CTypeInfo&);
@@ -275,6 +281,7 @@ private:
     string m_Name;
     string m_ModuleName;
     mutable CNamespaceInfoItem* m_InfoItem;
+    size_t m_CodeVer;
 
 protected:
     void SetCreateFunction(TTypeCreate func);
diff --git a/c++/include/util/align_range_coll.hpp b/c++/include/util/align_range_coll.hpp
index 5bf6afb..0910136 100644
--- a/c++/include/util/align_range_coll.hpp
+++ b/c++/include/util/align_range_coll.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL___ALIGN_RANGE_COLL__HPP
 #define UTIL___ALIGN_RANGE_COLL__HPP
 
-/*  $Id: align_range_coll.hpp 355704 2012-03-07 19:44:47Z grichenk $
+/*  $Id: align_range_coll.hpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -493,13 +493,13 @@ public:
         }
 
         vector<bool>* dead = NULL; // vector of indexes for elements that need to be removed
-        size_t size = m_Ranges.size();
+        size_t range_size = m_Ranges.size();
 
-        for (size_t i = size - 1; i > 0; --i) {
+        for (size_t i = range_size - 1; i > 0; --i) {
             if (m_Ranges[i - 1].IsAbutting(m_Ranges[i])) {
                 if (dead == NULL) {   // allocate temp vector
-                    dead = new vector<bool>(size, false);
-                    dead->reserve(size);
+                    dead = new vector<bool>(range_size, false);
+                    dead->reserve(range_size);
                 }
                 m_Ranges[i - 1].CombineWithAbutting(m_Ranges[i]); // merge i into i-1
                 (*dead)[i] = true;
@@ -507,7 +507,7 @@ public:
         }
         if (dead) {   // there are deal elements - need to compress
             size_t shift = 0;
-            for (size_t i = 0; i < size; i++ ) {
+            for (size_t i = 0; i < range_size; i++ ) {
                 if ((*dead)[i]) {
                     ++shift;
                 }
@@ -516,7 +516,7 @@ public:
                 }
             }
             delete dead;
-            m_Ranges.resize(size - shift);
+            m_Ranges.resize(range_size - shift);
         }
         x_ResetFlags(fAbutting);
         x_SetFlags(fNotValidated);
diff --git a/c++/include/util/bitset/bm.h b/c++/include/util/bitset/bm.h
index 02f3a38..7c45f16 100644
--- a/c++/include/util/bitset/bm.h
+++ b/c++/include/util/bitset/bm.h
@@ -349,6 +349,12 @@ public:
         {
         }
         
+        insert_iterator(const insert_iterator& iit)
+        : bvect_(iit.bvect_),
+          max_bit_(iit.max_bit_)
+        {
+        }
+        
         insert_iterator& operator=(bm::id_t n)
         {
             BM_ASSERT(n < bm::id_max);
@@ -372,9 +378,8 @@ public:
         insert_iterator& operator++() { return *this; }
         /*! Returns *this. This iterator does not move (no-op)*/
         insert_iterator& operator++(int) { return *this; }
-    //private:
-        //insert_iterator(const insert_iterator&);
-        //insert_iterator& operator=(const insert_iterator& );
+    private:
+        insert_iterator& operator=(const insert_iterator& );
         
     protected:
         bm::bvector<Alloc>&   bvect_;
@@ -398,10 +403,10 @@ public:
 
     public:
         enumerator() : iterator_base() {}
-        enumerator(const bvector<Alloc>* bvect, int position)
+        enumerator(const bvector<Alloc>* bv, int position)
             : iterator_base()
         { 
-            this->bv_ = const_cast<bvector<Alloc>*>(bvect);
+            this->bv_ = const_cast<bvector<Alloc>*>(bv);
             if (position == 0)
             {
                 go_first();
@@ -869,11 +874,11 @@ public:
 
 #endif
 
-    bvector& operator=(const bvector<Alloc>& bvect)
+    bvector& operator=(const bvector<Alloc>& bv)
     {
         clear(true); // memory free cleaning
-        resize(bvect.size());
-        bit_or(bvect);
+        resize(bv.size());
+        bit_or(bv);
         return *this;
     }
 
@@ -890,54 +895,54 @@ public:
         return get_bit(n);
     }
 
-    void operator &= (const bvector<Alloc>& bvect)
+    void operator &= (const bvector<Alloc>& bv)
     {
-        bit_and(bvect);
+        bit_and(bv);
     }
 
-    void operator ^= (const bvector<Alloc>& bvect)
+    void operator ^= (const bvector<Alloc>& bv)
     {
-        bit_xor(bvect);
+        bit_xor(bv);
     }
 
-    void operator |= (const bvector<Alloc>& bvect)
+    void operator |= (const bvector<Alloc>& bv)
     {
-        bit_or(bvect);
+        bit_or(bv);
     }
 
-    void operator -= (const bvector<Alloc>& bvect)
+    void operator -= (const bvector<Alloc>& bv)
     {
-        bit_sub(bvect);
+        bit_sub(bv);
     }
 
-    bool operator < (const bvector<Alloc>& bvect) const
+    bool operator < (const bvector<Alloc>& bv) const
     {
-        return compare(bvect) < 0;
+        return compare(bv) < 0;
     }
 
-    bool operator <= (const bvector<Alloc>& bvect) const
+    bool operator <= (const bvector<Alloc>& bv) const
     {
-        return compare(bvect) <= 0;
+        return compare(bv) <= 0;
     }
 
-    bool operator > (const bvector<Alloc>& bvect) const
+    bool operator > (const bvector<Alloc>& bv) const
     {
-        return compare(bvect) > 0;
+        return compare(bv) > 0;
     }
 
-    bool operator >= (const bvector<Alloc>& bvect) const
+    bool operator >= (const bvector<Alloc>& bv) const
     {
-        return compare(bvect) >= 0;
+        return compare(bv) >= 0;
     }
 
-    bool operator == (const bvector<Alloc>& bvect) const
+    bool operator == (const bvector<Alloc>& bv) const
     {
-        return compare(bvect) == 0;
+        return compare(bv) == 0;
     }
 
-    bool operator != (const bvector<Alloc>& bvect) const
+    bool operator != (const bvector<Alloc>& bv) const
     {
-        return compare(bvect) != 0;
+        return compare(bv) != 0;
     }
 
     bvector<Alloc> operator~() const
@@ -1180,7 +1185,7 @@ public:
         if (count_is_valid_)
             return count_ != 0;
     #endif
-
+        
         word_t*** blk_root = blockman_.get_rootblock();
         if (!blk_root) 
             return false;
@@ -1501,10 +1506,10 @@ public:
         combine_operation_with_block(nb, gap, blk, arg_blk, arg_gap, opcode);
     }
 private:
-#if 0 // unused, needs non-existent 6-arg variant
+#if 0
     void combine_count_operation_with_block(unsigned nb,
                                             const bm::word_t* arg_blk,
-                                            int arg_gap,
+                                            bool arg_gap,
                                             bm::operation opcode)
     {
         const bm::word_t* blk = get_block(nb);
@@ -1696,7 +1701,7 @@ bm::id_t bvector<Alloc>::count_range(bm::id_t left,
 {
     BM_ASSERT(left <= right);
 
-    unsigned count = 0;
+    unsigned cnt = 0;
 
     // calculate logical number of start and destination blocks
     unsigned nblock_left  = unsigned(left  >>  bm::set_block_shift);
@@ -1719,7 +1724,7 @@ bm::id_t bvector<Alloc>::count_range(bm::id_t left,
         {
             if (block_count_arr)
             {
-                count += block_count_arr[nblock_left];
+                cnt += block_count_arr[nblock_left];
             }
             else
             {
@@ -1730,20 +1735,20 @@ bm::id_t bvector<Alloc>::count_range(bm::id_t left,
         {
             if (left_gap)
             {
-                count += gap_bit_count_range(BMGAP_PTR(block), 
+                cnt += gap_bit_count_range(BMGAP_PTR(block),
                                             (gap_word_t)nbit_left,
                                             (gap_word_t)r);
             }
             else
             {
-                count += bit_block_calc_count_range(block, nbit_left, r);
+                cnt += bit_block_calc_count_range(block, nbit_left, r);
             }
         }
     }
 
     if (nblock_left == nblock_right)  // in one block
     {
-        return count + func.count();
+        return cnt + func.count();
     }
 
     for (unsigned nb = nblock_left+1; nb < nblock_right; ++nb)
@@ -1751,15 +1756,15 @@ bm::id_t bvector<Alloc>::count_range(bm::id_t left,
         block = blockman_.get_block(nb);
         if (block_count_arr)
         {
-            count += block_count_arr[nb];
+            cnt += block_count_arr[nb];
         }
         else 
         {
             if (block)
-                func(block);
+                func(block);//, nb);
         }
     }
-    count += func.count();
+    cnt += func.count();
 
     block = blockman_.get_block(nblock_right);
     bool right_gap = BM_IS_GAP(block);
@@ -1768,17 +1773,17 @@ bm::id_t bvector<Alloc>::count_range(bm::id_t left,
     {
         if (right_gap)
         {
-            count += gap_bit_count_range(BMGAP_PTR(block),
+            cnt += gap_bit_count_range(BMGAP_PTR(block),
                                         (gap_word_t)0,
                                         (gap_word_t)nbit_right);
         }
         else
         {
-            count += bit_block_calc_count_range(block, 0, nbit_right);
+            cnt += bit_block_calc_count_range(block, 0, nbit_right);
         }
     }
 
-    return count;
+    return cnt;
 }
 
 // -----------------------------------------------------------------------
@@ -1863,7 +1868,7 @@ void bvector<Alloc>::optimize(bm::word_t* temp_block,
                          = 0;
         ::memcpy(stat->gap_levels, 
                 blockman_.glen(), sizeof(gap_word_t) * bm::gap_levels);
-        stat->max_serialize_mem = sizeof(id_t) * 4;
+        stat->max_serialize_mem = (unsigned)sizeof(id_t) * 4;
 
     }
 
@@ -1875,7 +1880,7 @@ void bvector<Alloc>::optimize(bm::word_t* temp_block,
         unsigned safe_inc = stat->max_serialize_mem / 10; // 10% increment
         if (!safe_inc) safe_inc = 256;
         stat->max_serialize_mem += safe_inc;
-        stat->memory_used += sizeof(*this) - sizeof(blockman_);
+        stat->memory_used += (unsigned)(sizeof(*this) - sizeof(blockman_));
         stat->memory_used += blockman_.mem_used();
     }
 }
@@ -1917,13 +1922,13 @@ void bvector<Alloc>::set_gap_levels(const gap_word_t* glevel_len)
 // -----------------------------------------------------------------------
 
 template<typename Alloc> 
-int bvector<Alloc>::compare(const bvector<Alloc>& bvect) const
+int bvector<Alloc>::compare(const bvector<Alloc>& bv) const
 {
     int res;
     unsigned bn = 0;
 
     unsigned top_blocks = blockman_.effective_top_block_size();
-    unsigned bvect_top_blocks = bvect.blockman_.effective_top_block_size();
+    unsigned bvect_top_blocks = bv.blockman_.effective_top_block_size();
 
     if (bvect_top_blocks > top_blocks) top_blocks = bvect_top_blocks;
 
@@ -1931,7 +1936,7 @@ int bvector<Alloc>::compare(const bvector<Alloc>& bvect) const
     {
         const bm::word_t* const* blk_blk = blockman_.get_topblock(i);
         const bm::word_t* const* arg_blk_blk = 
-                                bvect.blockman_.get_topblock(i);
+                                bv.blockman_.get_topblock(i);
 
         if (blk_blk == arg_blk_blk) 
         {
@@ -2060,7 +2065,7 @@ void bvector<Alloc>::calc_stat(struct bvector<Alloc>::statistics* st) const
     unsigned blocks_memory = 0;
     gap_word_t* gapl_ptr = st->gap_length;
 
-    st->max_serialize_mem = sizeof(id_t) * 4;
+    st->max_serialize_mem = unsigned(sizeof(id_t) * 4);
 
     unsigned block_idx = 0;
 
@@ -2073,7 +2078,7 @@ void bvector<Alloc>::calc_stat(struct bvector<Alloc>::statistics* st) const
         if (!blk_blk) 
         {
             block_idx += bm::set_array_size;
-            st->max_serialize_mem += sizeof(unsigned) + 1;
+            st->max_serialize_mem += unsigned(sizeof(unsigned) + 1);
             continue;
         }
 
@@ -2082,7 +2087,7 @@ void bvector<Alloc>::calc_stat(struct bvector<Alloc>::statistics* st) const
             const bm::word_t* blk = blk_blk[j];
             if (IS_VALID_ADDR(blk))
             {
-                st->max_serialize_mem += empty_blocks << 2;
+                st->max_serialize_mem += unsigned(empty_blocks << 2);
                 empty_blocks = 0;
 
                 if (BM_IS_GAP(blk))
@@ -2092,12 +2097,12 @@ void bvector<Alloc>::calc_stat(struct bvector<Alloc>::statistics* st) const
                     bm::gap_word_t* gap_blk = BMGAP_PTR(blk);
 
                     unsigned mem_used = 
-                        bm::gap_capacity(gap_blk, blockman_.glen()) 
-                        * sizeof(gap_word_t);
+                        unsigned(bm::gap_capacity(gap_blk, blockman_.glen())
+                        * sizeof(gap_word_t));
 
                     *gapl_ptr = gap_length(gap_blk);
 
-                    st->max_serialize_mem += *gapl_ptr * sizeof(gap_word_t);
+                    st->max_serialize_mem += unsigned(*gapl_ptr * sizeof(gap_word_t));
                     blocks_memory += mem_used;
 
                     ++gapl_ptr;
@@ -2105,7 +2110,7 @@ void bvector<Alloc>::calc_stat(struct bvector<Alloc>::statistics* st) const
                 else // bit block
                 {
                     ++(st->bit_blocks);
-                    unsigned mem_used = sizeof(bm::word_t) * bm::set_block_size;
+                    unsigned mem_used = unsigned(sizeof(bm::word_t) * bm::set_block_size);
                     st->max_serialize_mem += mem_used;
                     blocks_memory += mem_used;
                 }
@@ -2123,7 +2128,7 @@ void bvector<Alloc>::calc_stat(struct bvector<Alloc>::statistics* st) const
 
     // Calc size of different odd and temporary things.
 
-    st->memory_used += sizeof(*this) - sizeof(blockman_);
+    st->memory_used += unsigned(sizeof(*this) - sizeof(blockman_));
     st->memory_used += blockman_.mem_used();
     st->memory_used += blocks_memory;
 }
@@ -2485,13 +2490,13 @@ bm::id_t bvector<Alloc>::check_or_next_extract(bm::id_t prev)
                     {
                         BMCOUNT_DEC
 
-                        unsigned nbit = 
+                        unsigned nbit1 = 
                             unsigned(prev & bm::set_block_mask); 
                         unsigned nword = 
-                            unsigned(nbit >> bm::set_word_shift);
-                        nbit &= bm::set_word_mask;
+                            unsigned(nbit1 >> bm::set_word_shift);
+                        nbit1 &= bm::set_word_mask;
                         bm::word_t* word = block + nword;
-                        bm::word_t  mask = ((bm::word_t)1) << nbit;
+                        bm::word_t  mask = ((bm::word_t)1) << nbit1;
                         *word &= ~mask;
 
                         return prev;
@@ -2515,31 +2520,36 @@ bm::id_t bvector<Alloc>::check_or_next_extract(bm::id_t prev)
 
 template<class Alloc> 
 void bvector<Alloc>::combine_operation(
-                                  const bm::bvector<Alloc>& bvect, 
+                                  const bm::bvector<Alloc>& bv, 
                                   bm::operation             opcode)
 {
+    /*typedef void (*block_bit_op)(bm::word_t*, const bm::word_t*);
+    typedef void (*block_bit_op_next)(bm::word_t*, 
+                                        const bm::word_t*, 
+                                        bm::word_t*, 
+                                        const bm::word_t*);*/
 
     unsigned top_blocks = blockman_.top_block_size();
-    unsigned bvect_top_blocks = bvect.blockman_.top_block_size();
+    unsigned bvect_top_blocks = bv.blockman_.top_block_size();
 
-    if (size_ == bvect.size_) 
+    if (size_ == bv.size_) 
     {
         BM_ASSERT(top_blocks >= bvect_top_blocks);
     }
     else
-    if (size_ < bvect.size_) // this vect shorter than the arg.
+    if (size_ < bv.size_) // this vect shorter than the arg.
     {
-        size_ = bvect.size_;
+        size_ = bv.size_;
         // stretch our capacity
         blockman_.reserve_top_blocks(bvect_top_blocks);
         top_blocks = blockman_.top_block_size();
     }
     else 
-    if (size_ > bvect.size_) // this vector larger
+    if (size_ > bv.size_) // this vector larger
     {
         if (opcode == BM_AND) // clear the tail with zeros
         {
-            set_range(bvect.size_, size_ - 1, false);
+            set_range(bv.size_, size_ - 1, false);
             if (bvect_top_blocks < top_blocks)
             {
                 // not to scan blocks we already swiped
@@ -2556,11 +2566,11 @@ void bvector<Alloc>::combine_operation(
 
     // calculate effective top size to avoid overscan
     top_blocks = blockman_.effective_top_block_size();
-    if (top_blocks < bvect.blockman_.effective_top_block_size())
+    if (top_blocks < bv.blockman_.effective_top_block_size())
     {
         if (opcode != BM_AND)
         {
-            top_blocks = bvect.blockman_.effective_top_block_size();
+            top_blocks = bv.blockman_.effective_top_block_size();
         }
     }
 
@@ -2574,7 +2584,7 @@ void bvector<Alloc>::combine_operation(
                 block_idx += bm::set_array_size;
                 continue; 
             }
-            const bm::word_t* const* bvbb = bvect.blockman_.get_topblock(i);
+            const bm::word_t* const* bvbb = bv.blockman_.get_topblock(i);
             if (bvbb == 0) // skip it because 0 OP 0 == 0 
             {
                 block_idx += bm::set_array_size;
@@ -2582,11 +2592,11 @@ void bvector<Alloc>::combine_operation(
             }
             // 0 - self, non-zero argument
             unsigned r = i * bm::set_array_size;
-            for (j = 0; j < bm::set_array_size; ++j)
+            for (j = 0; j < bm::set_array_size; ++j)//,++block_idx)
             {
-                const bm::word_t* arg_blk = bvect.blockman_.get_block(i, j);
+                const bm::word_t* arg_blk = bv.blockman_.get_block(i, j);
                 if (arg_blk )
-                    combine_operation_with_block(r + j,
+                    combine_operation_with_block(r + j,//block_idx, 
                                                  0, 0, 
                                                  arg_blk, BM_IS_GAP(arg_blk), 
                                                  opcode);
@@ -2602,7 +2612,7 @@ void bvector<Alloc>::combine_operation(
                 bm::word_t* blk = blk_blk[j];
                 if (blk)
                 {
-                    const bm::word_t* arg_blk = bvect.blockman_.get_block(i, j);            
+                    const bm::word_t* arg_blk = bv.blockman_.get_block(i, j);            
                     if (arg_blk)
                         combine_operation_with_block(r + j,
                                                      BM_IS_GAP(blk), blk, 
@@ -2617,10 +2627,10 @@ void bvector<Alloc>::combine_operation(
         else // OR, SUB, XOR
         {
             unsigned r = i * bm::set_array_size;
-            for (j = 0; j < bm::set_array_size; ++j)
+            for (j = 0; j < bm::set_array_size; ++j)//, ++block_idx)
             {            
                 bm::word_t* blk = blk_blk[j];
-                const bm::word_t* arg_blk = bvect.blockman_.get_block(i, j);            
+                const bm::word_t* arg_blk = bv.blockman_.get_block(i, j);            
                 if (arg_blk || blk)
                     combine_operation_with_block(r + j, BM_IS_GAP(blk), blk, 
                                                  arg_blk, BM_IS_GAP(arg_blk),
@@ -2698,7 +2708,7 @@ bvector<Alloc>::combine_operation_with_block(unsigned          nb,
                 int new_level = gap_calc_level(res_len, blockman_.glen());
                 if (new_level == -1)
                 {
-                    blockman_.convert_gap2bitset(nb, res, res_len-1);
+                    blockman_.convert_gap2bitset(nb, res);
                     return;
                 }
 
@@ -2755,7 +2765,7 @@ bvector<Alloc>::combine_operation_with_block(unsigned          nb,
                     unsigned gap_cnt = gap_bit_count(gap_blk);
                     if (gap_cnt < 128)
                     {
-                        gap_word_t tmp_buf[bm::gap_equiv_len * 3];         
+                        
                         gap_word_t arr_len = 
                             gap_convert_to_arr(tmp_buf, gap_blk, 
                                                bm::gap_equiv_len-10);
@@ -2772,7 +2782,7 @@ bvector<Alloc>::combine_operation_with_block(unsigned          nb,
                                                            );
                         BM_ASSERT(block_type==1); // GAP
                         gap_blk = BMGAP_PTR(blk);
-                        unsigned threshold = bm::gap_limit(gap_blk, blockman_.glen());
+                        threshold = bm::gap_limit(gap_blk, blockman_.glen());
                         for (; arr_i < arr_len; ++arr_i)
                         {
                             gap_word_t bit_idx = tmp_buf[arr_i];
@@ -3003,8 +3013,21 @@ void bvector<Alloc>::set_range_no_check(bm::id_t left,
             if (IS_FULL_BLOCK(block)) 
                 continue;
 
+            bool is_gap = BM_IS_GAP(block);
+
             blockman_.set_block(nb, FULL_BLOCK_ADDR);
-            blockman_.free_block(block);
+            blockman_.set_block_bit(nb);
+            
+            if (is_gap)
+            {
+                blockman_.get_allocator().free_gap_block(BMGAP_PTR(block), 
+                                                            blockman_.glen());
+            }
+            else
+            {
+                blockman_.get_allocator().free_bit_block(block);
+            }
+            
         } // for
     }
     else // value == 0
@@ -3014,8 +3037,19 @@ void bvector<Alloc>::set_range_no_check(bm::id_t left,
             block = blockman_.get_block(nb);
             if (block == 0)  // nothing to do
                 continue;
+            bool is_gap = BM_IS_GAP(block);
             blockman_.set_block(nb, 0, false /*bit*/);
-            blockman_.free_block(block);
+            //blockman_.set_block_bit(nb);
+
+            if (is_gap) 
+            {
+                blockman_.get_allocator().free_gap_block(BMGAP_PTR(block),
+                                                         blockman_.glen());
+            }
+            else
+            {
+                blockman_.get_allocator().free_bit_block(block);
+            }
 
         } // for
     } // if value else 
diff --git a/c++/include/util/bitset/bmalgo_impl.h b/c++/include/util/bitset/bmalgo_impl.h
index 18fc98b..50d8f78 100644
--- a/c++/include/util/bitset/bmalgo_impl.h
+++ b/c++/include/util/bitset/bmalgo_impl.h
@@ -114,7 +114,9 @@ struct distance_metric_descriptor
 */
 inline
 void combine_count_operation_with_block(const bm::word_t* blk,
+                                        //unsigned gap,
                                         const bm::word_t* arg_blk,
+                                        //int arg_gap,
                                         distance_metric_descriptor* dmit,
                                         distance_metric_descriptor* dmit_end)
                                             
@@ -195,7 +197,9 @@ void combine_count_operation_with_block(const bm::word_t* blk,
                  case bm::COUNT_SUB_BA:
                      dmd.metric = bm::COUNT_SUB_AB; // recursive call to SUB_AB
                      combine_count_operation_with_block(arg_blk,
+//                                                        arg_gap,
                                                         blk,
+//                                                        gap,
                                                         it, it+1);
                      dmd.metric = bm::COUNT_SUB_BA; // restore status quo
                      break;
@@ -288,6 +292,12 @@ void combine_count_operation_with_block(const bm::word_t* blk,
      //
      // Here we combine two plain bitblocks 
 
+     //const bm::word_t* blk_end;
+     //const bm::word_t* arg_end;
+
+     //blk_end = blk + (bm::set_block_size);
+     //arg_end = arg_blk + (bm::set_block_size);
+
 
      for (distance_metric_descriptor* it = dmit; it < dmit_end; ++it)
      {
@@ -617,7 +627,10 @@ void combine_any_operation_with_block(const bm::word_t* blk,
 */
 inline
 unsigned combine_count_operation_with_block(const bm::word_t* blk,
+//                                            unsigned gap,
                                             const bm::word_t* arg_blk,
+//                                            int arg_gap,
+                                            //bm::word_t* temp_blk,
                                             distance_metric metric)
 {
     distance_metric_descriptor dmd(metric);
@@ -788,6 +801,7 @@ unsigned distance_and_operation(const BV& bv1,
 
     bm::word_t*** blk_root = bman1.get_rootblock();
     bm::word_t*** blk_root_arg = bman2.get_rootblock();
+//    unsigned i, j;
 
     unsigned count = 0;
 
@@ -819,6 +833,29 @@ unsigned distance_and_operation(const BV& bv1,
             (blk_blk[j+3] && blk_blk_arg[j+3]) ? 
                 count += combine_count_and_operation_with_block(blk_blk[j+3],blk_blk_arg[j+3])
                 :0;
+/*
+            if ((blk = blk_blk[j]) && (arg_blk = blk_blk_arg[j]) )
+            {
+                count +=
+                combine_count_and_operation_with_block(blk,arg_blk);
+            }
+
+            if ((blk = blk_blk[j+1]) && (arg_blk = blk_blk_arg[j+1]) )
+            {
+                count +=
+                    combine_count_and_operation_with_block(blk,arg_blk);
+            }
+            if ((blk = blk_blk[j+2]) && (arg_blk = blk_blk_arg[j+2]) )
+            {
+                count +=
+                    combine_count_and_operation_with_block(blk, arg_blk);
+            }
+            if ((blk = blk_blk[j+3]) && (arg_blk = blk_blk_arg[j+3]) )
+            {
+                count +=
+                    combine_count_and_operation_with_block(blk, arg_blk);
+            }
+*/
         } // for j
 
     } // for i
diff --git a/c++/include/util/bitset/bmalloc.h b/c++/include/util/bitset/bmalloc.h
index e741281..6fc53d9 100644
--- a/c++/include/util/bitset/bmalloc.h
+++ b/c++/include/util/bitset/bmalloc.h
@@ -194,8 +194,8 @@ public:
                                     const gap_word_t* glevel_len)
     {
         BM_ASSERT(level < bm::gap_levels);
-        unsigned len = (unsigned)(glevel_len[level] / 
-                                  (sizeof(bm::word_t) / sizeof(gap_word_t)));
+        unsigned len = 
+            (unsigned)(glevel_len[level] / (sizeof(bm::word_t) / sizeof(gap_word_t)));
 
         return (bm::gap_word_t*)block_alloc_.allocate(len, 0);
     }
diff --git a/c++/include/util/bitset/bmblocks.h b/c++/include/util/bitset/bmblocks.h
old mode 100755
new mode 100644
index de40f59..e7978cd
--- a/c++/include/util/bitset/bmblocks.h
+++ b/c++/include/util/bitset/bmblocks.h
@@ -158,16 +158,16 @@ public:
 
         bm::id_t block_count(const bm::word_t* block, unsigned idx)
         {
-            bm::id_t count = 0;
+            bm::id_t cnt = 0;
             bm::id_t first_bit;
             
             if (IS_FULL_BLOCK(block) || (block == 0))
             {
-                count = 1;
+                cnt = 1;
                 if (idx)
                 {
                     first_bit = block ? 1 : 0;
-                    count -= !(prev_block_border_bit_ ^ first_bit);
+                    cnt -= !(prev_block_border_bit_ ^ first_bit);
                 }
                 prev_block_border_bit_ = block ? 1 : 0;
             }
@@ -176,11 +176,11 @@ public:
                 if (BM_IS_GAP(block))
                 {
                     gap_word_t* gap_block = BMGAP_PTR(block);
-                    count = gap_length(gap_block) - 1;
+                    cnt = gap_length(gap_block) - 1;
                     if (idx)
                     {
                         first_bit = gap_test(gap_block, 0);
-                        count -= !(prev_block_border_bit_ ^ first_bit);
+                        cnt -= !(prev_block_border_bit_ ^ first_bit);
                     }
                         
                     prev_block_border_bit_ = 
@@ -189,20 +189,20 @@ public:
                 else // bitset
                 {
                     unsigned bit_count;
-                    count = bit_block_calc_count_change(block,
+                    cnt = bit_block_calc_count_change(block,
                                                 block + bm::set_block_size,
                                                 &bit_count);
                     if (idx)
                     {
                         first_bit = block[0] & 1;
-                        count -= !(prev_block_border_bit_ ^ first_bit);
+                        cnt -= !(prev_block_border_bit_ ^ first_bit);
                     }
                     prev_block_border_bit_ = 
                         block[set_block_size-1] >> ((sizeof(block[0]) * 8) - 1);
                     
                 }
             }
-            return count;
+            return cnt;
         }
         
         bm::id_t count() const { return count_; }
@@ -226,7 +226,7 @@ public:
             : bm_func_base_const(bm) 
         {}
 
-        bool operator()(const bm::word_t* block, unsigned idx)
+        bool operator()(const bm::word_t* block, unsigned /*idx*/)
         {
             if (IS_FULL_BLOCK(block)) return true;
 
@@ -343,7 +343,7 @@ public:
             }
             if (stat_)
             {
-                stat_->max_serialize_mem += sizeof(unsigned) + 1;
+                stat_->max_serialize_mem += (unsigned)sizeof(unsigned) + 1;
             }
         }
         void on_empty_block(unsigned /* block_idx*/ ) { ++empty_; }
@@ -617,6 +617,17 @@ public:
                     new_blk = bman.get_allocator().alloc_bit_block();
                     bit_block_copy(new_blk, block);
                 }
+/*
+                if (IS_FULL_BLOCK(block))
+                {
+                    new_blk = block;
+                }
+                else
+                {
+                    new_blk = bman.get_allocator().alloc_bit_block();
+                    bit_block_copy(new_blk, block);
+                }
+*/
             }
             bman.set_block(idx, new_blk, is_gap);
         }
@@ -639,14 +650,20 @@ public:
     {
         ::memcpy(glevel_len_, glevel_len, sizeof(glevel_len_));
         blocks_ = 0;
-        top_block_size_ = effective_top_block_size_ = 0;
         if (max_bits) 
         {
             top_block_size_ = compute_top_block_size(max_bits);
             init_tree();
         } 
+        else 
+        {
+            top_block_size_ = effective_top_block_size_ = 0;
+        }
+        /*
         volatile const char* vp = _copyright<true>::_p;
-        cpr_ = *vp;
+        char c = *vp;
+        c = 0;
+        */
     }
 
     blocks_manager(const blocks_manager& blockman)
@@ -695,10 +712,11 @@ public:
             return bm::set_array_size;
         }
 
-        unsigned top_block_size = (unsigned)
-            (bits_to_store / (bm::set_block_size * sizeof(bm::word_t) * 
-                              bm::set_array_size * 8));
-        return top_block_size + (top_block_size < bm::set_array_size);
+        unsigned top_block_sz = (unsigned)
+            (bits_to_store / (bm::set_block_size * sizeof(bm::word_t) *
+                                                bm::set_array_size * 8));
+        if (top_block_sz < bm::set_array_size) ++top_block_sz;
+        return top_block_sz;
     }
 
     /**
@@ -774,16 +792,19 @@ public:
         for (;i < effective_top_block_size_; ++i) 
         { 
             bm::word_t** blk_blk = blocks_[i];
-            if (blk_blk)
-            {
-               unsigned r = i * bm::set_array_size;
-               do
-               {
-                   if (blk_blk[j] && !is_block_zero(r + j, blk_blk[j], deep_scan)) 
-                       return r + j;
-                   ++j;
-               } while (j < bm::set_array_size);
+            if (!blk_blk)
+            { 
+                nb += bm::set_array_size - j;
             }
+            else
+               for (;j < bm::set_array_size; ++j, ++nb)
+               {
+                   bm::word_t* blk = blk_blk[j];
+                   if (blk && !is_block_zero(nb, blk, deep_scan)) 
+                   {
+                       return nb;
+                   }
+               } // for j
             j = 0;
         } // for i
 
@@ -823,8 +844,17 @@ public:
         return bm->blocks_root();
     }
 
-    void free_block(bm::word_t* block)
+    void set_block_all_set(unsigned nb)
     {
+        bm::word_t* block = this->get_block(nb);
+        set_block(nb, const_cast<bm::word_t*>(FULL_BLOCK_ADDR));
+
+        // If we keep block type flag in pointer itself we dp not need 
+        // to clear gap bit 
+        #ifdef BM_DISBALE_BIT_IN_PTR
+        set_block_bit(nb);    
+        #endif
+
         if (BM_IS_GAP(block))
         {
             alloc_.free_gap_block(BMGAP_PTR(block), glevel_len_);
@@ -835,13 +865,6 @@ public:
         }
     }
 
-    void set_block_all_set(unsigned nb)
-    {
-        bm::word_t* block = 
-            set_block(nb, const_cast<bm::word_t*>(FULL_BLOCK_ADDR));
-        free_block(block);
-    }
-
     /**
         Create(allocate) bit block. Old block (if exists) gets deleted.
     */
@@ -851,7 +874,14 @@ public:
         bm::word_t* old_block = set_block(nb, block);
         if (IS_VALID_ADDR(old_block))
         {
-            free_block(old_block);
+            if (BM_IS_GAP(old_block))
+            {
+                alloc_.free_gap_block(BMGAP_PTR(old_block), glen());
+            }
+            else
+            {
+                alloc_.free_bit_block(old_block);
+            }
         }
         return block;
     }
@@ -965,7 +995,7 @@ public:
                 block = alloc_.alloc_bit_block();
                 // initialize block depending on its previous status
                 bit_block_set(block, block_flag ? 0xFF : 0);
-                set_block(nb, block, false /*bit*/);
+                set_block(nb, block);
             }
             else // gap block requested
             {
@@ -1013,10 +1043,13 @@ public:
 
     /**
         Places new block into descriptors table, returns old block's address.
-        NOTE:Old block is not deleted.
+        Old block is not deleted.
     */
     bm::word_t* set_block(unsigned nb, bm::word_t* block)
     {
+        bm::word_t* old_block;
+
+        // top block index
         register unsigned nblk_blk = nb >> bm::set_array_shift;
 
         // auto-resize the top block array
@@ -1032,17 +1065,21 @@ public:
             blocks_[nblk_blk] = (bm::word_t**)alloc_.alloc_ptr();
             ::memset(blocks_[nblk_blk], 0, 
                 bm::set_array_size * sizeof(bm::word_t*));
+
+            old_block = 0;
+        }
+        else
+        {
+            old_block = blocks_[nblk_blk][nb & bm::set_array_mask];
         }
 
-        // NOTE: block will be replaced without freeing
-        unsigned j = nb & bm::set_array_mask;
-        bm::word_t* old_block = blocks_[nblk_blk][j];
-        blocks_[nblk_blk][j] = block;
+        // NOTE: block will be replaced without freeing,
+        // potential memory leak may lay here....
+        blocks_[nblk_blk][nb & bm::set_array_mask] = block; // equivalent to %
 
         return old_block;
     }
 
-
     /**
     Allocate an place new GAP block (copy of provided block)
     */
@@ -1076,10 +1113,22 @@ public:
     */
     bm::word_t* set_block(unsigned nb, bm::word_t* block, bool gap)
     {
+        bm::word_t* old_block;
+
         if (block)
         {
             block = 
                 (bm::word_t*) (gap ? BMPTR_SETBIT0(block) : BMPTR_CLEARBIT0(block));
+/*
+            if (gap)
+            {
+                block = (bm::word_t*)BMPTR_SETBIT0(block);
+            }
+            else 
+            {
+                block = (bm::word_t*)BMPTR_CLEARBIT0(block);
+            }
+*/
         }
 
         // top block index
@@ -1098,12 +1147,17 @@ public:
             blocks_[nblk_blk] = (bm::word_t**)alloc_.alloc_ptr();
             ::memset(blocks_[nblk_blk], 0, 
                 bm::set_array_size * sizeof(bm::word_t*));
+
+            old_block = 0;
+        }
+        else
+        {
+            old_block = blocks_[nblk_blk][nb & bm::set_array_mask];
         }
 
-        // NOTE: block will be replaced without freeing
-        unsigned j = nb & bm::set_array_mask;
-        bm::word_t* old_block = blocks_[nblk_blk][j];
-        blocks_[nblk_blk][j] = block; 
+        // NOTE: block will be replaced without freeing,
+        // potential memory leak may lay here....
+        blocks_[nblk_blk][nb & bm::set_array_mask] = block; // equivalent to %
 
         return old_block;
     }
@@ -1122,12 +1176,9 @@ public:
         \param nb - Block's index. 
         \param gap_block - Pointer to the gap block, 
                             if NULL block nb will be taken
-        \param gap_len - GAP block length (optional)
         \return new bit block's memory
     */
-    bm::word_t* convert_gap2bitset(unsigned nb, 
-                                   const gap_word_t* gap_block=0, 
-                                   unsigned gap_len=0)
+    bm::word_t* convert_gap2bitset(unsigned nb, const gap_word_t* gap_block=0)
     {
         bm::word_t* block = this->get_block(nb);
         if (gap_block == 0)
@@ -1138,7 +1189,7 @@ public:
         BM_ASSERT(IS_VALID_ADDR((bm::word_t*)gap_block));
 
         bm::word_t* new_block = alloc_.alloc_bit_block();
-        gap_convert_to_bitset_l(new_block, gap_block, gap_len);
+        gap_convert_to_bitset(new_block, gap_block);
 
         // new block will replace the old one(no deletion)
         //set_block_ptr(nb, new_block); 
@@ -1152,6 +1203,11 @@ public:
             set_block(nb, new_block); 
         }
 
+        // If GAP flag is in block pointer no need to clean the gap bit twice
+        #ifdef BM_DISBALE_BIT_IN_PTR
+        set_block_bit(nb);
+        #endif
+
         return new_block;
     }
 
@@ -1182,7 +1238,15 @@ public:
     {
         bm::word_t* block = this->get_block(nb);
         if (!block) return block;
-        free_block(block);
+        if (BM_IS_GAP(block)) // gap block
+        {
+            get_allocator().free_gap_block(BMGAP_PTR(block), glen());
+        }
+        else
+        {
+            // deallocates only valid pointers
+            get_allocator().free_bit_block(block);
+        }
         set_block(nb, 0);
         return 0;
     }
@@ -1196,8 +1260,15 @@ public:
         bm::word_t* block = blk_blk[j];
         blk_blk[j] = 0;
 
-        free_block(block);
-
+        if (BM_IS_GAP(block))
+        {
+            get_allocator().free_gap_block(BMGAP_PTR(block), glen());
+        }
+        else
+        {
+            // deallocates only valid pointers
+            get_allocator().free_bit_block(block);
+        }
         return 0;
     }
 
@@ -1219,6 +1290,23 @@ public:
             count = (IS_FULL_BLOCK(block)) ? bm::bits_in_block
                 : bit_block_calc_count(block, block + bm::set_block_size);
         }
+/*
+        if (IS_FULL_BLOCK(block))
+            count = bm::bits_in_block;
+        else
+        {
+            if (BM_IS_GAP(block))
+            {
+                count = gap_bit_count(BMGAP_PTR(block));
+            }
+            else // bitset
+            {
+                count = 
+                    bit_block_calc_count(block, 
+                                         block + bm::set_block_size);
+            }
+        }
+*/
         return count;
     }
 
@@ -1254,22 +1342,34 @@ public:
 
     bool is_block_gap(unsigned nb) const 
     {
+        #ifdef BM_DISBALE_BIT_IN_PTR
+        return gap_flags_.test(nb)!=0;
+        #else
         bm::word_t* block = get_block(nb);
         return BMPTR_TESTBIT0(block) != 0;
+        #endif
     }
 
     void set_block_bit(unsigned nb) 
     { 
+        #ifdef BM_DISBALE_BIT_IN_PTR
+        gap_flags_.set(nb, false);
+        #else
         bm::word_t* block = get_block(nb);
         block = (bm::word_t*) BMPTR_CLEARBIT0(block);
         set_block_ptr(nb, block);
+        #endif
     }
 
     void set_block_gap(unsigned nb) 
     {
+        #ifdef BM_DISBALE_BIT_IN_PTR
+        gap_flags_.set(nb);
+        #else
         bm::word_t* block = get_block(nb);
         block = (bm::word_t*)BMPTR_SETBIT0(block);
         set_block_ptr(nb, block);
+        #endif
     }
 
     /**
@@ -1281,7 +1381,7 @@ public:
                            when deep scan is not requested result can be approximate
         \returns true if all bits are in the block are 0.
     */
-    bool is_block_zero(unsigned          nb, 
+    bool is_block_zero(unsigned          /*nb*/,
                        const bm::word_t* blk, 
                        bool              deep_scan = true) const
     {
@@ -1313,7 +1413,7 @@ public:
                            when deep scan is not requested result can be approximate
         \return true if block consists of 1 bits.
     */
-    bool is_block_one(unsigned          nb, 
+    bool is_block_one(unsigned          /*nb*/,
                       const bm::word_t* blk,
                       bool              deep_scan = true) const
     {
@@ -1374,16 +1474,21 @@ public:
 
     unsigned mem_used() const
     {
-        unsigned mem_used = sizeof(*this);
-        mem_used += temp_block_ ? sizeof(word_t) * bm::set_block_size : 0;
-        mem_used += sizeof(bm::word_t**) * top_block_size_;
+        unsigned used = (unsigned)sizeof(*this);
+        used += (unsigned)(temp_block_ ? sizeof(word_t) * bm::set_block_size : 0);
+        used += (unsigned)(sizeof(bm::word_t**) * top_block_size_);
+
+        #ifdef BM_DISBALE_BIT_IN_PTR
+        used += (unsigned)(gap_flags_.mem_used() - sizeof(gap_flags_));
+        #endif
 
         for (unsigned i = 0; i < top_block_size_; ++i)
         {
-            mem_used += blocks_[i] ? sizeof(void*) * bm::set_array_size : 0;
+            used += (unsigned)
+                (blocks_[i] ? sizeof(void*) * bm::set_array_size : 0);
         }
 
-        return mem_used;
+        return used;
     }
 
     /** Returns true if second level block pointer is 0.
@@ -1425,6 +1530,10 @@ public:
         blocks_ = bm.blocks_;
         bm.blocks_ = btmp;
 
+        #ifdef BM_DISBALE_BIT_IN_PTR
+        gap_flags_.swap(bm.gap_flags_);
+        #endif
+
 		xor_swap(this->top_block_size_, bm.top_block_size_);
         xor_swap(this->effective_top_block_size_, bm.effective_top_block_size_);
 
@@ -1549,7 +1658,6 @@ private:
     gap_word_t                             glevel_len_[bm::gap_levels];
     /// allocator
     allocator_type                         alloc_;
-    char                                   cpr_;
 };
 
 /**
diff --git a/c++/include/util/bitset/bmconst.h b/c++/include/util/bitset/bmconst.h
index 4307a57..a56db57 100644
--- a/c++/include/util/bitset/bmconst.h
+++ b/c++/include/util/bitset/bmconst.h
@@ -55,7 +55,7 @@ const unsigned set_block_mask  = 0xFFFFu;
 const unsigned set_blkblk_mask = 0xFFFFFFu;
 
 const unsigned set_block_plain_size = set_block_size / 32u;
-const unsigned set_block_plain_cnt = (unsigned)(sizeof(bm::word_t)) * 8u;
+const unsigned set_block_plain_cnt = (unsigned)(sizeof(bm::word_t) * 8u);
 
 // Word parameters
 
@@ -68,11 +68,9 @@ const unsigned set_word_mask  = 0x1Fu;
 typedef unsigned short gap_word_t;
 
 const unsigned gap_max_buff_len = 1280;
-const unsigned gap_length_threashold = set_block_size * 3; // should be 2-3 bits per word
 const unsigned gap_max_bits = 65536;
-const unsigned gap_equiv_len =
-     (unsigned)((sizeof(bm::word_t) * bm::set_block_size) / 
-                 sizeof(gap_word_t));
+const unsigned gap_equiv_len = (unsigned)
+   ((sizeof(bm::word_t) * bm::set_block_size) / sizeof(gap_word_t));
 const unsigned gap_levels = 4;
 const unsigned gap_max_level = bm::gap_levels - 1;
 
@@ -84,7 +82,7 @@ const unsigned set_array_shift = 8u;
 const unsigned set_array_mask  = 0xFFu;
 const unsigned set_total_blocks = (bm::set_array_size * bm::set_array_size);
 
-const unsigned bits_in_block = bm::set_block_size * (unsigned)sizeof(bm::word_t) * 8;
+const unsigned bits_in_block = bm::set_block_size * (unsigned)(sizeof(bm::word_t) * 8);
 const unsigned bits_in_array = bm::bits_in_block * bm::set_array_size;
 
 
diff --git a/c++/include/util/bitset/bmdbg.h b/c++/include/util/bitset/bmdbg.h
index a0f0197..2d8fbe3 100644
--- a/c++/include/util/bitset/bmdbg.h
+++ b/c++/include/util/bitset/bmdbg.h
@@ -64,10 +64,8 @@ void PrintGap(const bm::gap_word_t* gap_buf)
 inline
 void PrintDGap(const bm::gap_word_t* gap_buf, unsigned gap_len=0)
 {
-    bm::gap_word_t h;
-    memcpy(&h, gap_buf, sizeof(h));
 
-    unsigned len = gap_len ? gap_len : (h >> 3);
+    unsigned len = gap_len ? gap_len : (*gap_buf >> 3);
     cout << "[" " len=" << len << "] ";
     unsigned i = gap_len ? 0 : 1;
     for (; i < len; ++i)
@@ -114,9 +112,7 @@ inline
 void PrintDGapGamma(const bm::gap_word_t* gap_buf, unsigned gap_len=0)
 {
     unsigned total = 0;
-    bm::gap_word_t h;
-    memcpy(&h, gap_buf, sizeof(h));
-    unsigned len = gap_len ? gap_len : (h >> 3);
+    unsigned len = gap_len ? gap_len : (*gap_buf >> 3);
     cout << "[" " len=" << len << "] ";
     unsigned i = gap_len ? 0 : 1;
     for (; i < len; ++i)
@@ -142,7 +138,7 @@ void LoadBVector(const char* fname, TBV& bvector, unsigned* file_size=0)
         exit(1);
     }
     bv_file.seekg(0, ios_base::end);
-    unsigned length = bv_file.tellg();
+    unsigned length = (unsigned)bv_file.tellg();
     if (length == 0)
     {
         cout << "Empty file:" << fname << endl;
diff --git a/c++/include/util/bitset/bmdef.h b/c++/include/util/bitset/bmdef.h
index 6b3a3ec..332a27e 100644
--- a/c++/include/util/bitset/bmdef.h
+++ b/c++/include/util/bitset/bmdef.h
@@ -4,7 +4,6 @@
 //
 // Set all required preprocessor defines
 
-
 #include <climits>
 
 // macro to define/undefine unaligned memory access (x86, PowerPC)
@@ -86,7 +85,7 @@
 
 # define BMGAP_PTR(ptr) ((bm::gap_word_t*)BMPTR_CLEARBIT0(ptr))
 # define BMSET_PTRGAP(ptr) ptr = (bm::word_t*)BMPTR_SETBIT0(ptr)
-# define BM_IS_GAP(ptr) bool(BMPTR_TESTBIT0(ptr) != 0)
+# define BM_IS_GAP(ptr) bool(BMPTR_TESTBIT0(ptr)!=0)
 
 
 
diff --git a/c++/include/util/bitset/bmfunc.h b/c++/include/util/bitset/bmfunc.h
index 9d5045a..a9b5e54 100644
--- a/c++/include/util/bitset/bmfunc.h
+++ b/c++/include/util/bitset/bmfunc.h
@@ -39,14 +39,17 @@ For more information please visit:  http://bmagic.sourceforge.net
 namespace bm
 {
 
-bm::id_t bit_block_any_range(const bm::word_t* block,
-                             bm::word_t left,
-                             bm::word_t right);
 
+inline 
 bm::id_t bit_block_calc_count_range(const bm::word_t* block,
                                     bm::word_t left,
                                     bm::word_t right);
 
+inline 
+bm::id_t bit_block_any_range(const bm::word_t* block,
+                             bm::word_t left,
+                             bm::word_t right);
+
 /*!
     @brief Structure with statistical information about bitset's memory 
             allocation details. 
@@ -395,7 +398,7 @@ template<bool T> struct _copyright
 };
 
 template<bool T> const char _copyright<T>::_p[] = 
-    "BitMagic C++ Library. v.3.6.5 (c) 2002-2010 Anatoliy Kuznetsov.";
+    "BitMagic C++ Library. v.3.7.2 (c) 2002-2017 Anatoliy Kuznetsov.";
 
 
 /*! 
@@ -772,11 +775,11 @@ void for_each_dgap(const T* gap_buf, Func& func)
     ++pcurr;
     
     T prev = *pcurr;
-    func(prev + 1); // first element incremented to avoid 0
+    func((T)(prev + 1)); // first element incremented to avoid 0
     ++pcurr;
     do
     {
-        func(*pcurr - prev); // all others are [N] - [N-1]
+        func((T)(*pcurr - prev)); // all others are [N] - [N-1]
         prev = *pcurr;
     } while (++pcurr < pend);
 }
@@ -832,7 +835,7 @@ T* gap_2_dgap(const T* gap_buf, T* dgap_buf, bool copy_head=true)
 template<typename T>
 void dgap_2_gap(const T* dgap_buf, T* gap_buf, T gap_header=0)
 {
-    const T* pcurr = dgap_buf;
+    register const T* pcurr = dgap_buf;
     unsigned len;    
     if (!gap_header) // GAP header is already part of the stream
     {
@@ -1190,7 +1193,7 @@ template<typename T> unsigned gap_set_value(unsigned val,
 
     register T* pcurr = buf + curr;
     register T* pprev = pcurr - 1;
-    register T* pend  = buf + end;
+    register T* pend = buf + end;
 
     // Special case, first bit GAP operation. There is no platform beside it.
     // initial flag must be inverted.
@@ -1269,7 +1272,7 @@ unsigned gap_add_value(T* buf, unsigned pos)
 {
     BM_ASSERT(pos < bm::gap_max_bits);
 
-    register T end = (*buf >> 3);
+    register T end = (T)(*buf >> 3);
 	T curr = end;
     register T* pcurr = buf + end;
     register T* pend  = pcurr;
@@ -1325,13 +1328,13 @@ unsigned gap_add_value(T* buf, unsigned pos)
 	}
 	else  // Worst case we need to split current block.
 	{
-        *pcurr++ = pos - 1;
-        *pcurr = pos;
-		end+=2;
+        *pcurr++ = (T)(pos - 1);
+        *pcurr = (T)pos;
+		end = (T)(end+2);
 	}
 
     // Set correct length word.
-    *buf = (*buf & 7) + (end << 3);
+    *buf = (T)((*buf & 7) + (end << 3));
 
     buf[end] = bm::gap_max_bits - 1;
     return end;
@@ -1352,7 +1355,7 @@ unsigned gap_add_value(T* buf, unsigned pos)
 template<typename T> 
 unsigned gap_set_array(T* buf, const T* arr, unsigned len)
 {
-    *buf = (*buf & 6u) + (1u << 3); // gap header setup
+    *buf = (T)((*buf & 6u) + (1u << 3)); // gap header setup
 
 	T* pcurr = buf + 1;
 
@@ -1360,19 +1363,19 @@ unsigned gap_set_array(T* buf, const T* arr, unsigned len)
 	T curr = arr[i];
 	if (curr != 0) // need to add the first gap: (0 to arr[0]-1)
 	{
-		*pcurr = curr - 1;
+		*pcurr = (T)(curr - 1);
         ++pcurr;
 	}
     else
     {
-        *buf += 1; // GAP starts with 1
+        ++(*buf); // GAP starts with 1
     }
 	T prev = curr; 
     T acc = prev;
 
 	for (i = 1; i < len; ++i)
 	{
-		T curr = arr[i];
+		curr = arr[i];
 		if (curr == prev + 1)
 		{
             ++acc;
@@ -1382,7 +1385,7 @@ unsigned gap_set_array(T* buf, const T* arr, unsigned len)
         {
             *pcurr++ = acc;
             acc = curr;
-            *pcurr++ = curr-1;
+            *pcurr++ = (T)(curr-1);
         }
 		prev = curr;
 	}
@@ -1681,22 +1684,26 @@ inline void xor_bit_block(unsigned* dest,
    @ingroup gapfunc
 */
 template<typename T> 
-void gap_sub_to_bitset(unsigned* BMRESTRICT dest, const T* BMRESTRICT buf)
+void gap_sub_to_bitset(unsigned* dest, const T*  buf)
 {
-    const T* pend = buf + (*buf >> 3);
-    T b = *buf & 1;
-    ++buf;
+    register const T* pcurr = buf;    
+    register const T* pend = pcurr + (*pcurr >> 3);
+    ++pcurr;
 
-    if (b)  // Starts with 1
+    if (*buf & 1)  // Starts with 1
     {
-        sub_bit_block(dest, 0, *buf + 1);
-        ++buf;
+        sub_bit_block(dest, 0, *pcurr + 1);
+        ++pcurr;
     }
-    for (++buf; buf <= pend; buf += 2)
+    ++pcurr; // now we are in GAP "1" again
+
+    while (pcurr <= pend)
     {
-        T prev = *(buf-1);
-        BM_ASSERT(*buf > prev);
-        sub_bit_block(dest, prev + 1, *buf - prev);
+        unsigned bitpos = *(pcurr-1) + 1;
+        BM_ASSERT(*pcurr > *(pcurr-1));
+        unsigned gap_len = *pcurr - *(pcurr-1);
+        sub_bit_block(dest, bitpos, gap_len);
+        pcurr += 2;
     }
 }
 
@@ -1709,56 +1716,30 @@ void gap_sub_to_bitset(unsigned* BMRESTRICT dest, const T* BMRESTRICT buf)
    @ingroup gapfunc
 */
 template<typename T> 
-void gap_xor_to_bitset(unsigned* BMRESTRICT dest, const T* BMRESTRICT buf)
+void gap_xor_to_bitset(unsigned* dest, const T*  buf)
 {
-    const T* pend = buf + (*buf >> 3);
-    T b = *buf & 1;
-    ++buf;
+    register const T* pcurr = buf;    
+    register const T* pend = pcurr + (*pcurr >> 3);
+    ++pcurr;
 
-    if (b)  // Starts with 1
-    {
-        xor_bit_block(dest, 0, *buf + 1);
-        ++buf;
-    }
-    for (++buf; buf <= pend; buf += 2)
+    if (*buf & 1)  // Starts with 1
     {
-        T prev = *(buf-1);
-        BM_ASSERT(*buf > prev);
-        xor_bit_block(dest, prev + 1, *buf - prev);
+        xor_bit_block(dest, 0, *pcurr + 1);
+        ++pcurr;
     }
-}
-
-/*!
-\brief Adds(OR) GAP block to bitblock.
-\param dest - bitblock buffer pointer.
-\param buf  - GAP buffer pointer.
-\param buf_len - GAP buffer length
-
- at ingroup gapfunc
-*/
-template<typename T> 
-void gap_add_to_bitset_l(unsigned* dest, const T*  buf, unsigned buf_len)
-{
-    BM_ASSERT(buf_len);
-    register const T* pend = buf + buf_len;
-    T b = *buf & 1;
-    ++buf;
+    ++pcurr; // now we are in GAP "1" again
 
-    if (b)  // Starts with 1
-    {
-        or_bit_block(dest, 0, *buf + 1);
-        ++buf;
-    }
-    for (++buf; buf <= pend; buf += 2)
+    while (pcurr <= pend)
     {
-        T prev = *(buf-1);
-        BM_ASSERT(*buf > prev);
-        or_bit_block(dest, prev + 1, *buf - prev);
+        unsigned bitpos = *(pcurr-1) + 1;
+        BM_ASSERT(*pcurr > *(pcurr-1));
+        unsigned gap_len = *pcurr - *(pcurr-1);
+        xor_bit_block(dest, bitpos, gap_len);
+        pcurr += 2;
     }
 }
 
 
-
 /*!
    \brief Adds(OR) GAP block to bitblock.
    \param dest - bitblock buffer pointer.
@@ -1769,7 +1750,25 @@ void gap_add_to_bitset_l(unsigned* dest, const T*  buf, unsigned buf_len)
 template<typename T> 
 void gap_add_to_bitset(unsigned* dest, const T*  buf)
 {
-    gap_add_to_bitset_l(dest, buf, *buf >> 3);
+    register const T* pcurr = buf;    
+    register const T* pend = pcurr + (*pcurr >> 3);
+    ++pcurr;
+
+    if (*buf & 1)  // Starts with 1
+    {
+        or_bit_block(dest, 0, *pcurr + 1);
+        ++pcurr;
+    }
+    ++pcurr; // now we are in GAP "1" again
+
+    while (pcurr <= pend)
+    {
+        unsigned bitpos = *(pcurr-1) + 1;
+        BM_ASSERT(*pcurr > *(pcurr-1));
+        unsigned gap_len = *pcurr - *(pcurr-1);
+        or_bit_block(dest, bitpos, gap_len);
+        pcurr += 2;
+    }
 }
 
 
@@ -1783,21 +1782,25 @@ void gap_add_to_bitset(unsigned* dest, const T*  buf)
 template<typename T> 
 void gap_and_to_bitset(unsigned* dest, const T*  buf)
 {
-    register const T* pend = buf + (*buf >> 3);
-    T b = *buf & 1;
-    ++buf;
+    register const T* pcurr = buf;    
+    register const T* pend = pcurr + (*pcurr >> 3);
+    ++pcurr;
 
-    if (!b )  // Starts with 0 
+    if (! (*buf & 1) )  // Starts with 0 
     {
         // Instead of AND we can SUB 0 gaps here 
-        sub_bit_block(dest, 0, *buf + 1);
-        ++buf;
+        sub_bit_block(dest, 0, *pcurr + 1);
+        ++pcurr;
     }
-    for (++buf; buf <= pend; buf += 2)
+    ++pcurr; // now we are in GAP "0" again
+
+    while (pcurr <= pend)
     {
-        T prev = *(buf-1);
-        BM_ASSERT(*buf > prev);
-        sub_bit_block(dest, prev + 1, *buf - prev);
+        unsigned bitpos = *(pcurr-1) + 1;
+        BM_ASSERT(*pcurr > *(pcurr-1));
+        unsigned gap_len = *pcurr - *(pcurr-1);
+        sub_bit_block(dest, bitpos, gap_len);
+        pcurr += 2;
     }
 }
 
@@ -1969,7 +1972,7 @@ bm::id_t gap_bitset_xor_count(const unsigned* block, const T*  buf)
     
     for (bitval^=1, ++pcurr; pcurr <= pend; bitval^=1, ++pcurr)
     {
-        T prev = *(pcurr-1)+1;
+        T prev = (T)(*(pcurr-1)+1);
         bm::id_t c = bit_block_calc_count_range(block, prev, *pcurr);
         
         if (bitval) // 1 gap; means Result = Total_Bits - BitCount;
@@ -2007,7 +2010,7 @@ bm::id_t gap_bitset_xor_any(const unsigned* block, const T*  buf)
     
     for (bitval^=1, ++pcurr; pcurr <= pend; bitval^=1, ++pcurr)
     {
-        T prev = *(pcurr-1)+1;
+        T prev = (T)(*(pcurr-1)+1);
         bm::id_t c = bit_block_any_range(block, prev, *pcurr);
         
         if (bitval) // 1 gap; means Result = Total_Bits - BitCount;
@@ -2054,7 +2057,7 @@ bm::id_t gap_bitset_or_count(const unsigned* block, const T*  buf)
     
     for (bitval^=1, ++pcurr; pcurr <= pend; bitval^=1, ++pcurr)
     {
-        T prev = *(pcurr-1)+1;
+        T prev = (T)(*(pcurr-1)+1);
         bm::id_t c;
         
         if (bitval)
@@ -2101,7 +2104,7 @@ bm::id_t gap_bitset_or_any(const unsigned* block, const T*  buf)
     
     for (bitval^=1, ++pcurr; pcurr <= pend; bitval^=1, ++pcurr)
     {
-        T prev = *(pcurr-1)+1;
+        T prev = (T)(*(pcurr-1)+1);
         bm::id_t c;
         
         if (bitval)
@@ -2154,21 +2157,6 @@ void gap_convert_to_bitset(unsigned* dest, const T*  buf)
     gap_add_to_bitset(dest, buf);
 }
 
-/*!
-\brief GAP block to bitblock conversion.
-\param dest - bitblock buffer pointer.
-\param buf  - GAP buffer pointer.
-
- at ingroup gapfunc
-*/
-template<typename T> 
-void gap_convert_to_bitset_l(unsigned* dest, const T*  buf, unsigned buf_len)
-{
-    bit_block_set(dest, 0);
-    gap_add_to_bitset_l(dest, buf, buf_len ? buf_len : *buf >> 3);
-}
-
-
 
 /*!
    \brief GAP block to bitblock conversion.
@@ -2292,7 +2280,7 @@ void gap_init_range_block(T* buf,
         else
         {
             gap_len = 2;
-            buf[1] = to;
+            buf[1] = (T)to;
             buf[2] = (T)(set_max - 1);
             buf[0] = (T)((*buf & 6u) + (gap_len << 3) + value);
         }
@@ -2310,7 +2298,7 @@ void gap_init_range_block(T* buf,
     else
     {
         gap_len = 3;
-        buf[1] = from - 1;
+        buf[1] = (T) (from - 1);
         buf[2] = (T) to;
         buf[3] = (T)(set_max - 1);
     }
@@ -2441,7 +2429,7 @@ template<typename T>
 void set_gap_level(T* buf, unsigned level)
 {
     BM_ASSERT(level < bm::gap_levels);
-    *buf = ((level & 3) << 1) | (*buf & 1) | (*buf & ~7); 
+    *buf = (T)(((level & 3) << 1) | (*buf & 1) | (*buf & ~7));
 }
 
 
@@ -2561,7 +2549,7 @@ template<typename T>
                }
                bitval = bitval_next;
            }
-           bit_idx += sizeof(*src) * 8;
+           bit_idx += unsigned(sizeof(*src) * 8);
            if (bit_idx >= bits)
            {
                goto complete;
@@ -2707,7 +2695,7 @@ D gap_convert_to_arr(D* BMRESTRICT       dest,
         if (pending >= dest_len)
             return 0;
         dest_len -= pending;
-        T from = *(pcurr-1)+1;
+        T from = (T)(*(pcurr-1)+1);
         T to = *pcurr;
         for (T i = from; ;++i) 
         {
@@ -2823,7 +2811,7 @@ void bit_count_change32(const bm::word_t* block,
     
     BM_INCWORD_BITCOUNT(*bit_count, w);
     
-    const int w_shift = (int)sizeof(w) * 8 - 1;    
+    const int w_shift = int(sizeof(w) * 8 - 1);
     w ^= (w >> 1);
     BM_INCWORD_BITCOUNT(*gap_count, w);
     *gap_count -= (w_prev = (w0 >> w_shift)); // negative value correction
@@ -4407,7 +4395,7 @@ unsigned bit_count_nonzero_size(const T*     blk,
                     break;
             }
             blk = blk_j-1;
-            count += sizeof(gap_word_t);
+            count += (unsigned)sizeof(gap_word_t);
         }
         else
         {
@@ -4427,16 +4415,16 @@ unsigned bit_count_nonzero_size(const T*     blk,
                     break;
                 }
             }
-            count += sizeof(gap_word_t);
+            count += unsigned(sizeof(gap_word_t));
             // count all bit-words now
-            count += unsigned((blk_j - blk) * sizeof(T));
+            count += (unsigned)((blk_j - blk) * sizeof(T));
             blk = blk_j;
         }
         ++blk;
     }
     while(blk < blk_end); 
 
-    return count + (2 * sizeof(T));
+    return count + unsigned(2 * sizeof(T));
 }
 
 
@@ -4722,12 +4710,9 @@ bm::set_representation best_representation(unsigned bit_count,
                                            unsigned gap_count,
                                            unsigned block_size)
 {
-    unsigned arr_size = 
-        (unsigned)(sizeof(bm::gap_word_t) * bit_count + sizeof(bm::gap_word_t));
-    unsigned gap_size =
-        (unsigned)(sizeof(bm::gap_word_t) * gap_count + sizeof(bm::gap_word_t));
-    unsigned inv_arr_size = 
-        (unsigned)(sizeof(bm::gap_word_t) * (total_possible_bitcount - bit_count) + sizeof(bm::gap_word_t));
+    unsigned arr_size = unsigned(sizeof(bm::gap_word_t) * bit_count + sizeof(bm::gap_word_t));
+    unsigned gap_size = unsigned(sizeof(bm::gap_word_t) * gap_count + sizeof(bm::gap_word_t));
+    unsigned inv_arr_size = unsigned(sizeof(bm::gap_word_t) * (total_possible_bitcount - bit_count) + sizeof(bm::gap_word_t));
 
     if ((gap_size < block_size) && (gap_size < arr_size) && (gap_size < inv_arr_size))
     {
@@ -4762,7 +4747,7 @@ template<typename T> T bit_convert_to_arr(T* BMRESTRICT dest,
                                           unsigned mask = 0)
 {
     T* BMRESTRICT pcurr = dest;
-    for(unsigned bit_idx=0; bit_idx < bits; ++src,bit_idx += sizeof(*src) * 8)
+    for (unsigned bit_idx=0; bit_idx < bits; ++src,bit_idx += unsigned(sizeof(*src) * 8))
     {
         unsigned val = *src ^ mask; // possible to invert value by XOR 0xFF..
         if (val == 0) 
@@ -4776,7 +4761,7 @@ template<typename T> T bit_convert_to_arr(T* BMRESTRICT dest,
 
     	copy_to_array_functor_inc<T> func(pcurr, bit_idx);
     	bit_for_each_4(val, func);    	
-    	unsigned word_bit_cnt = unsigned(func.ptr() - pcurr);
+    	unsigned word_bit_cnt = (unsigned)(func.ptr() - pcurr);
         pcurr += word_bit_cnt;    
 
     } // for
@@ -5101,7 +5086,7 @@ template<typename W> struct bit_XOR
 /// Bit ASSIGN functor
 template<typename W> struct bit_ASSIGN
 {
-    W operator()(W w1, W w2) { return w2; }
+    W operator()(W, W w2) { return w2; }
 };
 
 /// Bit COUNT functor
@@ -5174,7 +5159,7 @@ template<typename W> struct bit_COUNT_SUB_BA
 /// Bit COUNT A functor
 template<typename W> struct bit_COUNT_A
 {
-    W operator()(W w1, W w2) 
+    W operator()(W w1, W )
     {
         W r = 0;
         BM_INCWORD_BITCOUNT(r, w1);
@@ -5185,7 +5170,7 @@ template<typename W> struct bit_COUNT_A
 /// Bit COUNT B functor
 template<typename W> struct bit_COUNT_B
 {
-    W operator()(W w1, W w2) 
+    W operator()(W, W w2)
     {
         W r = 0;
         BM_INCWORD_BITCOUNT(r, w2);
diff --git a/c++/include/util/bitset/bmrandom.h b/c++/include/util/bitset/bmrandom.h
index 6024d69..4ecd6f7 100644
--- a/c++/include/util/bitset/bmrandom.h
+++ b/c++/include/util/bitset/bmrandom.h
@@ -156,7 +156,6 @@ void random_subset<BV>::sample(BV&       bv_out,
         get_subset(tmp_bv, bv_in, bcnt, delta_count);
         bv_out = bv_in;
         bv_out -= tmp_bv;
-        bv_out.forget_count();
         return;
     }
 
diff --git a/c++/include/util/bitset/bmserial.h b/c++/include/util/bitset/bmserial.h
index d0bd6af..f2cdc2a 100644
--- a/c++/include/util/bitset/bmserial.h
+++ b/c++/include/util/bitset/bmserial.h
@@ -27,7 +27,7 @@ For more information please visit:  http://bmagic.sourceforge.net
 */
 
 
-/*! \defgroup  bvserial bvector serialization  
+/*! \defgroup bvserial bvector serialization  
  *  bvector serialization
  *  \ingroup bmagic 
  *
@@ -256,13 +256,10 @@ protected:
     deseriaizer_base(){}
 
     /// Read GAP block from the stream
-    ///
-    /// @return GAP length
-    ///
-    unsigned read_gap_block(decoder_type&   decoder, 
-                            unsigned        block_type, 
-                            bm::gap_word_t* dst_block,
-                            bm::gap_word_t& gap_head);
+    void read_gap_block(decoder_type&   decoder, 
+                        unsigned        block_type, 
+                        bm::gap_word_t* dst_block,
+                        bm::gap_word_t& gap_head);
 
 	/// Read list of bit ids
 	///
@@ -324,7 +321,8 @@ public:
     unsigned deserialize(bvector_type&         bv, 
                          serial_iterator_type& sit, 
                          bm::word_t*           temp_block,
-                         set_operation         op = bm::set_OR);
+                         set_operation         op = bm::set_OR,
+                         bool                  exit_on_one = false);
 
     /// experimental 3 way deserialization 
     /// target = mask %OPERATION% BLOB
@@ -512,7 +510,9 @@ public:
     unsigned deserialize(bvector_type&        bv, 
                          const unsigned char* buf, 
                          bm::word_t*          temp_block,
-                         set_operation        op = bm::set_OR);
+                         set_operation        op = bm::set_OR,
+                         bool                 exit_on_one = false ///<! exit early if any one are found
+                         );
 private:
     /// experimental
     static
@@ -642,7 +642,7 @@ void serializer<BV>::gamma_gap_block(bm::gap_word_t* gap_block, bm::encoder& enc
 
         // evaluate gamma coding efficiency
         encoder::position_type enc_pos1 = enc.get_pos();
-        size_t gamma_size = enc_pos1 - enc_pos0;        
+        unsigned gamma_size = (unsigned)(enc_pos1 - enc_pos0);        
         if (gamma_size > (len-1)*sizeof(gap_word_t))
         {
             enc.set_pos(enc_pos0);
@@ -688,7 +688,7 @@ void serializer<BV>::gamma_gap_array(const bm::gap_word_t* gap_array,
         }
 
         encoder::position_type enc_pos1 = enc.get_pos();
-        size_t gamma_size = enc_pos1 - enc_pos0;            
+        unsigned gamma_size = (unsigned)(enc_pos1 - enc_pos0);            
         if (gamma_size > (arr_len)*sizeof(gap_word_t))
         {
             enc.set_pos(enc_pos0);
@@ -933,9 +933,9 @@ unsigned serializer<BV>::serialize(const BV& bv,
        
         // compute alternative representation sizes
         //
-        unsigned arr_block_size = sizeof(gap_word_t) + (block_bc * sizeof(gap_word_t));
-        unsigned arr_block_size_inv = sizeof(gap_word_t) + (block_bc_inv * sizeof(gap_word_t));
-        unsigned gap_block_size = sizeof(gap_word_t) + ((bit_gaps+1) * sizeof(gap_word_t)); 
+        unsigned arr_block_size = unsigned(sizeof(gap_word_t) + (block_bc * sizeof(gap_word_t)));
+        unsigned arr_block_size_inv = unsigned(sizeof(gap_word_t) + (block_bc_inv * sizeof(gap_word_t)));
+        unsigned gap_block_size = unsigned(sizeof(gap_word_t) + ((bit_gaps+1) * sizeof(gap_word_t)));
         unsigned interval_block_size;
         interval_block_size = bit_count_nonzero_size(blk, bm::set_block_size);
         bool inverted = false;
@@ -1083,7 +1083,7 @@ enum serialization_flags {
 template<class BV>
 unsigned serialize(const BV& bv, 
                    unsigned char* buf, 
-                   bm::word_t*    temp_block,
+                   bm::word_t*    /*temp_block*/,
                    unsigned       serialization_flags = 0)
 {
     bm::serializer<BV> bv_serial;
@@ -1205,14 +1205,14 @@ unsigned deseriaizer_base<DEC>::read_id_list(decoder_type&   decoder,
         {
             bit_in_type bin(decoder);
             len = (gap_word_t)bin.gamma();
-            gap_word_t prev, bit_idx;
-            prev = 0;
+            gap_word_t prev = 0;
             for (gap_word_t k = 0; k < len; ++k)
             {
-                bit_idx = (gap_word_t)bin.gamma();
-                bit_idx -= (k == 0);
-                bit_idx += prev;
-				dst_arr[k] = prev = bit_idx;
+                gap_word_t bit_idx = (gap_word_t)bin.gamma();
+                if (k == 0) --bit_idx; // TODO: optimization
+                bit_idx = (gap_word_t)(bit_idx + prev);
+                prev = bit_idx;
+				dst_arr[k] = bit_idx;
             } // for
         }
         break;
@@ -1224,32 +1224,29 @@ unsigned deseriaizer_base<DEC>::read_id_list(decoder_type&   decoder,
 
 
 template<class DEC>
-unsigned deseriaizer_base<DEC>::read_gap_block(decoder_type&   decoder, 
-                                               unsigned        block_type, 
-                                               bm::gap_word_t* dst_block,
-                                               bm::gap_word_t& gap_head)
+void deseriaizer_base<DEC>::read_gap_block(decoder_type&   decoder, 
+                                           unsigned        block_type, 
+                                           bm::gap_word_t* dst_block,
+                                           bm::gap_word_t& gap_head)
 {
     typedef bit_in<DEC> bit_in_type;
-    unsigned gap_len = 0;
 
     switch (block_type)
     {
     case set_block_gap:
         {
-            gap_len = gap_length(&gap_head);
-            --gap_len;
+            unsigned len = gap_length(&gap_head);
+            --len;
             *dst_block = gap_head;
-            decoder.get_16(dst_block+1, gap_len - 1);
-            dst_block[gap_len] = gap_max_bits - 1;
-            ++gap_len;
+            decoder.get_16(dst_block+1, len - 1);
+            dst_block[len] = gap_max_bits - 1;
         }
         break;
     case set_block_bit_1bit:
         {
 			gap_set_all(dst_block, bm::gap_max_bits, 0);
             gap_word_t bit_idx = decoder.get_16();
-			gap_len = gap_add_value(dst_block, bit_idx);
-            ++gap_len;
+			gap_add_value(dst_block, bit_idx);
         }
         break;
     case set_block_arrgap:
@@ -1261,9 +1258,8 @@ unsigned deseriaizer_base<DEC>::read_gap_block(decoder_type&   decoder,
             for (gap_word_t k = 0; k < len; ++k)
             {
                 gap_word_t bit_idx = decoder.get_16();
-				gap_len = gap_add_value(dst_block, bit_idx);
+				gap_add_value(dst_block, bit_idx);
             } // for
-            ++gap_len;
         }
         break;
     case set_block_arrgap_egamma:
@@ -1271,13 +1267,14 @@ unsigned deseriaizer_base<DEC>::read_gap_block(decoder_type&   decoder,
         {
         	unsigned arr_len = read_id_list(decoder, block_type, id_array_);
             dst_block[0] = 0;
-            gap_len = gap_set_array(dst_block, id_array_, arr_len);
+            //unsigned gap_len = 
+                gap_set_array(dst_block, id_array_, arr_len);
         }
         break;
     case set_block_gap_egamma:
         {
-        gap_len = (gap_head >> 3);
-        --gap_len;
+        unsigned len = (gap_head >> 3);
+        --len;
         // read gamma GAP block into a dest block
         {
             *dst_block = gap_head;
@@ -1286,13 +1283,14 @@ unsigned deseriaizer_base<DEC>::read_gap_block(decoder_type&   decoder,
             bit_in_type bin(decoder);
             {
 				gap_word_t v = (gap_word_t)bin.gamma();
-                gap_word_t gap_sum = *gap_data_ptr = v - 1;
-                for (unsigned i = 1; i < gap_len; ++i)
+                gap_word_t gap_sum = *gap_data_ptr = (gap_word_t)(v - 1);
+                for (unsigned i = 1; i < len; ++i)
                 {					
                     v = (gap_word_t)bin.gamma();
-                    *(++gap_data_ptr) = gap_sum += v;
-                } 
-                dst_block[++gap_len] = bm::gap_max_bits - 1;
+                    gap_sum = (gap_word_t)(gap_sum + v);
+                    *(++gap_data_ptr) = gap_sum;
+                }
+                dst_block[len+1] = bm::gap_max_bits - 1;
             }
         }
 
@@ -1307,7 +1305,6 @@ unsigned deseriaizer_base<DEC>::read_gap_block(decoder_type&   decoder,
     {
         gap_invert(dst_block);
     }
-    return gap_len;
 }
 
 
@@ -1318,36 +1315,40 @@ deserializer<BV, DEC>::deserialize_gap(unsigned char btype, decoder_type& dec,
                                        unsigned i,
                                        bm::word_t* blk)
 {
+    //typedef bit_in<DEC> bit_in_type;
     gap_word_t gap_head; 
-    gap_word_t gap_len = 0;
 
     switch (btype)
     {
     case set_block_gap: 
     case set_block_gapbit:
     {
-        gap_word_t gap_head = (gap_word_t)
+        gap_head = (gap_word_t)
             (sizeof(gap_word_t) == 2 ? dec.get_16() : dec.get_32());
 
-        gap_len = gap_length(&gap_head);
-        int level = gap_calc_level(gap_len, bman.glen());
-        --gap_len;
+        unsigned len = gap_length(&gap_head);
+        int level = gap_calc_level(len, bman.glen());
+        --len;
         if (level == -1)  // Too big to be GAP: convert to BIT block
         {
             *gap_temp_block_ = gap_head;
-            dec.get_16(gap_temp_block_+1, gap_len - 1);
-            gap_temp_block_[gap_len] = gap_max_bits - 1;
+            dec.get_16(gap_temp_block_+1, len - 1);
+            gap_temp_block_[len] = gap_max_bits - 1;
 
             if (blk == 0)  // block does not exist yet
             {
                 blk = bman.get_allocator().alloc_bit_block();
                 bman.set_block(i, blk);
-                gap_convert_to_bitset(blk, gap_temp_block_);
+                gap_convert_to_bitset(blk, gap_temp_block_);                
             }
             else  // We have some data already here. Apply OR operation.
             {
-                blk = bman.deoptimize_block(i);
-                gap_add_to_bitset(blk, gap_temp_block_);
+                gap_convert_to_bitset(temp_block_, 
+                                      gap_temp_block_);
+                bv.combine_operation_with_block(i, 
+                                                temp_block_, 
+                                                0, 
+                                                BM_OR);
             }
             return;
         } // level == -1
@@ -1363,16 +1364,15 @@ deserializer<BV, DEC>::deserialize_gap(unsigned char btype, decoder_type& dec,
             set_gap_level(gap_blk_ptr, level);
             bman.set_block(i, (bm::word_t*)gap_blk);
             bman.set_block_gap(i);
-            dec.get_16(gap_blk + 1, gap_len - 1);
-            gap_blk[gap_len] = bm::gap_max_bits - 1;
+            dec.get_16(gap_blk + 1, len - 1);
+            gap_blk[len] = bm::gap_max_bits - 1;
         }
         else // target block exists
         {
             // read GAP block into a temp memory and perform OR
             *gap_temp_block_ = gap_head;
-            dec.get_16(gap_temp_block_ + 1, gap_len - 1);
-            gap_temp_block_[gap_len] = bm::gap_max_bits - 1;
-            ++gap_len;
+            dec.get_16(gap_temp_block_ + 1, len - 1);
+            gap_temp_block_[len] = bm::gap_max_bits - 1;
             break;
         }
         return;
@@ -1380,9 +1380,10 @@ deserializer<BV, DEC>::deserialize_gap(unsigned char btype, decoder_type& dec,
     case set_block_arrgap: 
     case set_block_arrgap_egamma:
         {
-            unsigned arr_len = this->read_id_list(dec, btype, this->id_array_);
+        	unsigned arr_len = this->read_id_list(dec, btype, this->id_array_);
             gap_temp_block_[0] = 0; // reset unused bits in gap header
-            gap_len = gap_set_array(gap_temp_block_, this->id_array_, arr_len);
+            //unsigned gap_len =
+              gap_set_array(gap_temp_block_, this->id_array_, arr_len);
             break;
         }
     case set_block_gap_egamma:            
@@ -1390,32 +1391,16 @@ deserializer<BV, DEC>::deserialize_gap(unsigned char btype, decoder_type& dec,
             (sizeof(gap_word_t) == 2 ? dec.get_16() : dec.get_32());
     case set_block_arrgap_egamma_inv:
     case set_block_arrgap_inv:
-        gap_len = this->read_gap_block(dec, btype, gap_temp_block_, gap_head);
+        this->read_gap_block(dec, btype, gap_temp_block_, gap_head);
         break;
     default:
         BM_ASSERT(0);
     }
 
-    // check if encoded GAP block length is too high and use bit-block instead
-
-    if (gap_len > bm::gap_length_threashold)
-    {
-        blk = bman.deoptimize_block(i);
-        if (!blk)
-        {
-            blk = bman.get_allocator().alloc_bit_block();
-            bman.set_block(i, blk);
-            bit_block_set(blk, 0);
-        }
-        gap_add_to_bitset_l(blk, gap_temp_block_, gap_len-1);
-    } 
-    else 
-    {
-        bv.combine_operation_with_block(i, 
-                                       (bm::word_t*)gap_temp_block_, 
-                                        1, 
-                                        BM_OR);
-    }
+    bv.combine_operation_with_block(i, 
+                                   (bm::word_t*)gap_temp_block_, 
+                                    1, 
+                                    BM_OR);
 
 }
 
@@ -1472,12 +1457,11 @@ unsigned deserializer<BV, DEC>::deserialize(bvector_type&        bv,
 
     if (!(header_flag & BM_HM_NO_GAPL)) 
     {
-        // levels in serialized file are obsolete
-        /*gap_word_t glevels[bm::gap_levels];*/
+        //gap_word_t glevels[bm::gap_levels];
         // read GAP levels information
         for (i = 0; i < bm::gap_levels; ++i)
         {
-            /*glevels[i] = */dec.get_16();
+            /*glevels[i] =*/ dec.get_16();
         }
     }
 
@@ -1607,9 +1591,9 @@ unsigned deserializer<BV, DEC>::deserialize(bvector_type&        bv,
             {
                 blk = bman.get_allocator().alloc_bit_block();
                 bman.set_block(i, blk);
-                for (unsigned i = 0; i < head_idx; ++i)
+                for (unsigned k = 0; k < head_idx; ++k)
                 {
-                    blk[i] = 0;
+                    blk[k] = 0;
                 }
                 dec.get_32(blk + head_idx, tail_idx - head_idx + 1);
                 for (unsigned j = tail_idx + 1; j < bm::set_block_size; ++j)
@@ -2236,7 +2220,7 @@ serial_stream_iterator<DEC>::get_bit_block_COUNT(bm::word_t*  /*dst_block*/,
         break;
     case set_block_bit_0runs:
         {
-        unsigned count = 0;
+        //count = 0;
         unsigned char run_type = decoder_.get_8();
         for (unsigned j = 0; j < bm::set_block_size;run_type = !run_type)
         {
@@ -2357,7 +2341,7 @@ serial_stream_iterator<DEC>::get_bit_block_COUNT_AND(bm::word_t*  dst_block,
         break;
     case set_block_bit_0runs:
         {
-        unsigned count = 0;
+        //count = 0;
         unsigned char run_type = decoder_.get_8();
         for (unsigned j = 0; j < bm::set_block_size;run_type = !run_type)
         {
@@ -2765,9 +2749,9 @@ serial_stream_iterator<DEC>::get_gap_block(bm::gap_word_t* dst_block)
     BM_ASSERT(dst_block);
 
     this->read_gap_block(this->decoder_,
-                         this->block_type_,
-                         dst_block,
-                         this->gap_head_);
+                   this->block_type_,
+                   dst_block,
+                   this->gap_head_);
 
     ++(this->block_idx_);
     this->state_ = e_blocks;
@@ -2796,7 +2780,9 @@ unsigned operation_deserializer<BV>::deserialize(
                                         bvector_type&        bv, 
                                         const unsigned char* buf, 
                                         bm::word_t*          temp_block,
-                                        set_operation        op)
+                                        set_operation        op,
+                                        bool                 exit_on_one
+                                        )
 {
     ByteOrder bo_current = globals<true>::byte_order();
 
@@ -2820,7 +2806,7 @@ unsigned operation_deserializer<BV>::deserialize(
         serial_stream_current ss(buf);
         return 
             iterator_deserializer<BV, serial_stream_current>::
-                deserialize(bv, ss, temp_block, op);
+                deserialize(bv, ss, temp_block, op, exit_on_one);
     }
     switch (bo_current) 
     {
@@ -2829,14 +2815,14 @@ unsigned operation_deserializer<BV>::deserialize(
         serial_stream_be ss(buf);
         return 
             iterator_deserializer<BV, serial_stream_be>::
-                deserialize(bv, ss, temp_block, op);
+                deserialize(bv, ss, temp_block, op, exit_on_one);
         }
     case LittleEndian:
         {
         serial_stream_le ss(buf);
         return 
             iterator_deserializer<BV, serial_stream_le>::
-                deserialize(bv, ss, temp_block, op);
+                deserialize(bv, ss, temp_block, op, exit_on_one);
         }
     default:
         BM_ASSERT(0);
@@ -3321,7 +3307,8 @@ iterator_deserializer<BV, SerialIterator>::deserialize(
                                        bvector_type&         bv, 
                                        serial_iterator_type& sit, 
                                        bm::word_t*           temp_block,
-                                       set_operation         op)
+                                       set_operation         op,
+                                       bool                  exit_on_one)
 {
     BM_ASSERT(temp_block);
 
@@ -3415,6 +3402,9 @@ iterator_deserializer<BV, SerialIterator>::deserialize(
             // 2 bit blocks recombination
             unsigned c = sit.get_bit_block(blk, temp_block, sop);
             count += c;
+			if (exit_on_one && count) // early exit
+				return count;
+
             }
             break;
 
@@ -3446,6 +3436,8 @@ iterator_deserializer<BV, SerialIterator>::deserialize(
                     {
                     unsigned c = bman.block_bitcount(blk);//, bv_block_idx);
                     count += c;
+					if (exit_on_one && count) // early exit
+						return count;
                     }
                     break;
                 case set_END:
@@ -3531,6 +3523,8 @@ iterator_deserializer<BV, SerialIterator>::deserialize(
                     } // switch
                 } // else
             } // switch
+            if (exit_on_one && count) // early exit
+				   return count;
 
             }
             break;
@@ -3558,6 +3552,9 @@ iterator_deserializer<BV, SerialIterator>::deserialize(
                                         gptr,
                                         metric);
                 count += c;
+                if (exit_on_one && count) // early exit
+				    return count;
+
             }
             else // non-const set operation
             {
@@ -3601,7 +3598,18 @@ iterator_deserializer<BV, SerialIterator>::deserialize(
                                                 bop);
                     }
                 }
-            }
+                if (exit_on_one) 
+                {
+                    blk = bman.get_block(bv_block_idx);
+                    if (blk) 
+                    {
+                        bool z = bman.is_block_zero(bv_block_idx, blk);
+                        if (!z) 
+                            return 1;
+                    } 
+                } // if exit_on_one
+
+            } // if else non-const op
             }
             break;
 
diff --git a/c++/include/util/bitset/bmsse2.h b/c++/include/util/bitset/bmsse2.h
index e866c0b..193abc7 100644
--- a/c++/include/util/bitset/bmsse2.h
+++ b/c++/include/util/bitset/bmsse2.h
@@ -285,6 +285,7 @@ bm::id_t sse2_bit_block_calc_count_change(const __m128i* BMRESTRICT block,
        
 
        // compare with zero
+       // SSE4: _mm_test_all_zero()
        {
            // b = (b & 0x55555555) + (b >> 1 & 0x55555555);
            //tmp1 = _mm_srli_epi32(b, 1);                    // tmp1 = (b >> 1 & 0x55555555)
@@ -319,6 +320,8 @@ bm::id_t sse2_bit_block_calc_count_change(const __m128i* BMRESTRICT block,
        // ---------------------------------------------------------------------
        {
            //__m128i b = _mm_load_si128(block);
+           // TODO: SSE4...
+           //w = _mm_extract_epi32(b, i);               
 
            const bm::word_t* BMRESTRICT blk = (const bm::word_t*) block;
 
diff --git a/c++/include/util/bitset/bmsse4.h b/c++/include/util/bitset/bmsse4.h
index 443344e..1c34336 100644
--- a/c++/include/util/bitset/bmsse4.h
+++ b/c++/include/util/bitset/bmsse4.h
@@ -46,7 +46,6 @@ namespace bm
 
 
 
-
 /*!
     SSE4.2 optimized bitcounting .
     @ingroup SSE4
@@ -55,20 +54,15 @@ inline
 bm::id_t sse4_bit_count(const __m128i* block, const __m128i* block_end)
 {
     bm::id_t count = 0;
-
 #ifdef BM64_SSE4
+    const bm::id64_t* b = (bm::id64_t*) block;
+    const bm::id64_t* b_end = (bm::id64_t*) block_end;
     do
     {
-        __m128i tmp0 = _mm_load_si128(block);
-        count += _mm_popcnt_u64(_mm_extract_epi64(tmp0, 0)) +
-                 _mm_popcnt_u64(_mm_extract_epi64(tmp0, 1));
-        __m128i tmp1 = _mm_load_si128(block+1);
-        count += _mm_popcnt_u64(_mm_extract_epi64(tmp1, 0)) +
-                 _mm_popcnt_u64(_mm_extract_epi64(tmp1, 1));
-
-        block +=2;
-    } while (block < block_end);
-
+        count += _mm_popcnt_u64(b[0]) +
+                 _mm_popcnt_u64(b[1]);
+        b += 2;
+    } while (b < b_end);
 #else
     do
     {
diff --git a/c++/include/util/bitset/bmtrans.h b/c++/include/util/bitset/bmtrans.h
index 966eff4..d7fcb0f 100644
--- a/c++/include/util/bitset/bmtrans.h
+++ b/c++/include/util/bitset/bmtrans.h
@@ -502,7 +502,6 @@ void bit_iblock_reduce(
     unsigned  tmatrix_out[bm::set_block_plain_cnt][bm::set_block_plain_size])
 {
     ::memset(tmatrix_out, 0, bm::set_block_plain_cnt * sizeof(*tmatrix_out));
-    
     unsigned row = 0;
     do 
     {
@@ -656,19 +655,19 @@ void tmatrix_restore(TMatrix& tmatrix,
     \brief Copy GAP block body to bit block with DGap transformation 
     \internal
 */
-template<typename GT>//, typename BT>
+template<typename GT, typename BT>
 void gap_2_bitblock(const GT* BMRESTRICT gap_buf, 
-                          GT* BMRESTRICT block, 
+                          BT* BMRESTRICT block, 
                           unsigned       block_size)
 {
-    GT* dgap_buf = block;
-    GT* block_end = block + block_size;
+    GT* dgap_buf = (GT*) block;
+    BT* block_end = block + block_size;
 
     GT* dgap_end = gap_2_dgap<GT>(gap_buf, dgap_buf, false);
-//    GT* block_end2 = (GT*) block_end;
+    GT* block_end2 = (GT*) block_end;
     
     // zero the tail memory
-    for ( ;dgap_end < block_end; ++dgap_end)
+    for ( ;dgap_end < block_end2; ++dgap_end)
     {
         *dgap_end = 0;
     }
@@ -788,18 +787,20 @@ public:
     
     /// Transpose GAP block through a temp. block of aligned(!) memory
     /// 
-    void transpose(const GT* BMRESTRICT gap_buf)
+    void transpose(const GT* BMRESTRICT gap_buf, 
+                         BT* BMRESTRICT tmp_block)
     {
         const unsigned arr_size = BLOCK_SIZE * sizeof(unsigned) / sizeof(GT);
 
         BM_ASSERT(sizeof(tmatrix_.value) == tmatrix_type::n_columns * 
                                             tmatrix_type::n_rows * sizeof(GT));
+                
         // load all GAP as D-GAP(but not head word) into aligned bit-block
-        gap_2_bitblock(gap_buf, tmp_gap_block_, BLOCK_SIZE * 2);
+        gap_2_bitblock(gap_buf, tmp_block, BLOCK_SIZE);
         
         // transpose
         vect_bit_transpose<GT, tmatrix_type::n_rows, tmatrix_type::n_columns>
-                           (tmp_gap_block_, arr_size, tmatrix_.value);
+                           ((GT*)tmp_block, arr_size, tmatrix_.value);
 
         // calculate number of non-zero columns
         eff_cols_ = find_effective_columns(tmatrix_);        
@@ -808,19 +809,20 @@ public:
 	/// Transpose array of shorts
 	///
 	void transpose(const GT* BMRESTRICT garr,
-		           unsigned garr_size)
+		           unsigned garr_size,
+				   BT* BMRESTRICT tmp_block)
 	{
 		BM_ASSERT(garr_size);
 
-		bit_block_set(tmp_gap_block_, 0);
-		::memcpy(tmp_gap_block_, garr, sizeof(GT)*garr_size);
+		bit_block_set(tmp_block, 0);
+		::memcpy(tmp_block, garr, sizeof(GT)*garr_size);
 
         const unsigned arr_size = BLOCK_SIZE * sizeof(unsigned) / sizeof(GT);
         BM_ASSERT(sizeof(tmatrix_.value) == tmatrix_type::n_columns * 
                                             tmatrix_type::n_rows * sizeof(GT));
         // transpose
         vect_bit_transpose<GT, tmatrix_type::n_rows, tmatrix_type::n_columns>
-                           (tmp_gap_block_, arr_size, tmatrix_.value);
+                           ((GT*)tmp_block, arr_size, tmatrix_.value);
 
         // calculate number of non-zero columns
         eff_cols_ = find_effective_columns(tmatrix_);        
@@ -858,18 +860,20 @@ public:
     /// Restore GAP block from the transposed matrix
     ///
     void trestore(GT             gap_head, 
-                  GT* BMRESTRICT gap_buf)
+                  GT* BMRESTRICT gap_buf, 
+                  BT* BMRESTRICT tmp_block)
     {
         BM_ASSERT(sizeof(tmatrix_.value) == tmatrix_type::n_columns * 
                                             tmatrix_type::n_rows * sizeof(GT));
   
         // restore into a temp buffer
-        GT* gap_tmp = tmp_gap_block_;
+        GT* gap_tmp = (GT*)tmp_block;
+        //*gap_tmp++ = gap_head;
        
         vect_bit_trestore<GT, tmatrix_type::n_rows, tmatrix_type::n_columns>(tmatrix_.value, gap_tmp);
         
         // D-Gap to GAP block recalculation
-        gap_tmp = tmp_gap_block_;
+        gap_tmp = (GT*)tmp_block;
         dgap_2_gap<GT>(gap_tmp, gap_buf, gap_head);
     }
     
@@ -881,8 +885,6 @@ public:
     unsigned char                 pc_vector_[tmatrix_type::n_rows];
     unsigned                      pc_vector_stat_[bm::ibpc_end];
     typename tmatrix_type::rstat  rstat_vector_[tmatrix_type::n_rows];
-
-    GT  BM_ALIGN16                tmp_gap_block_[BLOCK_SIZE*2] BM_ALIGN16ATTR;
 };
 
 
diff --git a/c++/include/util/bitset/bmutil.h b/c++/include/util/bitset/bmutil.h
index 4ce5a81..ef77705 100644
--- a/c++/include/util/bitset/bmutil.h
+++ b/c++/include/util/bitset/bmutil.h
@@ -78,6 +78,7 @@ template<typename T>
 T ilog2(T x)
 {
     unsigned int l = 0;
+    
     if (x >= 1<<16) { x = (T)(x >> 16); l |= 16; }
     if (x >= 1<<8)  { x = (T)(x >> 8);  l |= 8; }
     if (x >= 1<<4)  { x = (T)(x >> 4);  l |= 4; }
@@ -140,7 +141,8 @@ template<>
 inline bm::gap_word_t ilog2_LUT<bm::gap_word_t>(bm::gap_word_t x)
 {
     unsigned l = 0;    
-    if (x & 0xff00) {
+    if (x & 0xff00) 
+    {
         l += 8;
         x = (bm::gap_word_t)(x >> 8);
     }
diff --git a/c++/include/util/bitset/bmvmin.h b/c++/include/util/bitset/bmvmin.h
index 742eb65..3f22d79 100644
--- a/c++/include/util/bitset/bmvmin.h
+++ b/c++/include/util/bitset/bmvmin.h
@@ -140,10 +140,10 @@ public:
     unsigned mem_used() const
     {
         return sizeof(*this) +
-               m_buf ? 
+               (m_buf ?
                  (m_type ? (BM_MINISET_GAPLEN * sizeof(gap_word_t))
                         : (BM_MINISET_ARRSIZE(N) * sizeof(bm::word_t)))
-                : 0; 
+                : 0);
     }
 
     void swap(miniset& mset)
@@ -222,7 +222,7 @@ template<size_t N> class bvmini
 {
 public:
 
-    bvmini(int start_strategy = 0) 
+    bvmini(int = 0)
     {
         ::memset(m_buf, 0, sizeof(m_buf));
     }
diff --git a/c++/include/util/bitset/encoding.h b/c++/include/util/bitset/encoding.h
index 4cf655d..58d2565 100644
--- a/c++/include/util/bitset/encoding.h
+++ b/c++/include/util/bitset/encoding.h
@@ -335,7 +335,7 @@ class bit_in
 public:
     bit_in(TDecoder& decoder)
         : src_(decoder),
-          used_bits_(sizeof(accum_) * 8),
+          used_bits_(unsigned(sizeof(accum_) * 8)),
           accum_(0)
     {
     }
@@ -355,7 +355,7 @@ public:
         {
             if (acc == 0)
             {
-                zero_bits += (sizeof(acc) * 8) - used;
+                zero_bits = unsigned(zero_bits +(sizeof(acc) * 8) - used);
                 used = 0;
                 acc = src_.get_32();
                 continue;
@@ -388,7 +388,7 @@ public:
         // get the value
         unsigned current;
         
-        unsigned free_bits = (sizeof(acc) * 8) - used;
+        unsigned free_bits = unsigned((sizeof(acc) * 8) - used);
         if (zero_bits <= free_bits)
         {
         take_accum:
@@ -507,8 +507,9 @@ private:
     \param size - size of the buffer
 */
 inline encoder::encoder(unsigned char* buf, unsigned /* size */)
-: buf_(buf), start_(buf) //, size_(size)
+: buf_(buf), start_(buf)
 {
+    // size_ = size;
 }
 /*!
     \grief Encode 8-bit prefix + an array
@@ -796,7 +797,7 @@ inline decoder_little_endian::decoder_little_endian(const unsigned char* buf)
 
 BMFORCEINLINE bm::short_t decoder_little_endian::get_16()
 {
-    bm::short_t a = bm::short_t(((bm::short_t)buf_[0] << 8) + ((bm::short_t)buf_[1]));
+    bm::short_t a = bm::short_t(((bm::short_t)buf_[0] << 8) + (bm::short_t)buf_[1]);
     buf_ += sizeof(a);
     return a;
 }
@@ -841,7 +842,7 @@ inline void decoder_little_endian::get_16(bm::short_t* s, unsigned count)
     const bm::short_t* s_end = s + count;
     do 
     {
-        bm::short_t a = bm::short_t(((bm::short_t)buf[0] << 8) + ((bm::short_t)buf[1]));
+        bm::short_t a = bm::short_t(((bm::short_t)buf[0] << 8) + (bm::short_t)buf[1]);
         *s++ = a;
         buf += sizeof(a);
     } while (s < s_end);
diff --git a/c++/include/util/bitset/ncbi_bitset_util.hpp b/c++/include/util/bitset/ncbi_bitset_util.hpp
old mode 100755
new mode 100644
index 817551e..56b5003
--- a/c++/include/util/bitset/ncbi_bitset_util.hpp
+++ b/c++/include/util/bitset/ncbi_bitset_util.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL___BITSET_UTIL__HPP
 #define UTIL___BITSET_UTIL__HPP
 
-/*  $Id: ncbi_bitset_util.hpp 300829 2011-06-03 17:28:09Z kuznets $
+/*  $Id: ncbi_bitset_util.hpp 498895 2016-04-20 14:46:07Z whlavina $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/util/cache/icache_cf.hpp b/c++/include/util/cache/icache_cf.hpp
index eb48f75..5631784 100644
--- a/c++/include/util/cache/icache_cf.hpp
+++ b/c++/include/util/cache/icache_cf.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL_ICACHE_CF__HPP
 #define UTIL_ICACHE_CF__HPP
 
-/* $Id: icache_cf.hpp 497436 2016-04-06 17:56:51Z ivanov $
+/* $Id: icache_cf.hpp 497217 2016-04-05 11:37:33Z ivanov $
 * ===========================================================================
 *
 *                            public DOMAIN NOTICE                          
diff --git a/c++/include/util/compress/bzip2/bzlib.h b/c++/include/util/compress/bzip2/bzlib.h
index 9ac43a1..8277123 100644
--- a/c++/include/util/compress/bzip2/bzlib.h
+++ b/c++/include/util/compress/bzip2/bzlib.h
@@ -4,59 +4,19 @@
 /*---                                               bzlib.h ---*/
 /*-------------------------------------------------------------*/
 
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward at acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
---*/
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
 
 
 #ifndef _BZLIB_H
@@ -110,8 +70,10 @@ typedef
 #define BZ_EXPORT
 #endif
 
+#ifndef BZ_NO_STDIO
 /* Need a definitition for FILE */
 #include <stdio.h>
+#endif
 
 #ifdef _WIN32
 #   include <windows.h>
@@ -260,8 +222,7 @@ BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
 
 
 /*--
-   Code contributed by Yoshioka Tsuneo
-   (QWF00133 at niftyserve.or.jp/tsuneo-y at is.aist-nara.ac.jp),
+   Code contributed by Yoshioka Tsuneo (tsuneo at rr.iij4u.or.jp)
    to support better zlib compatibility.
    This code is not _officially_ part of libbzip2 (yet);
    I haven't tested it, documented it, or considered the
diff --git a/c++/include/util/file_manifest.hpp b/c++/include/util/file_manifest.hpp
index 232bbb5..cb8a85a 100644
--- a/c++/include/util/file_manifest.hpp
+++ b/c++/include/util/file_manifest.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL___FILE_MANIFEST_HPP__
 #define UTIL___FILE_MANIFEST_HPP__
 
-/*  $Id: file_manifest.hpp 494188 2016-03-04 12:23:34Z ivanov $
+/*  $Id: file_manifest.hpp 492854 2016-02-22 16:33:44Z elisovdn $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/util/format_guess.hpp b/c++/include/util/format_guess.hpp
index 2c72698..3eae209 100644
--- a/c++/include/util/format_guess.hpp
+++ b/c++/include/util/format_guess.hpp
@@ -1,7 +1,7 @@
 #ifndef FORMATGUESS__HPP
 #define FORMATGUESS__HPP
 
-/*  $Id: format_guess.hpp 488617 2016-01-04 12:42:47Z ludwigf $
+/*  $Id: format_guess.hpp 513836 2016-09-15 17:32:16Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -89,6 +89,8 @@ public:
         eBam                 = 31, ///< Binary alignment/map file
         eVcf                 = 32, ///< VCF, CVcfReader
         eUCSCRegion          = 33, ///< USCS Region file format
+        eGffAugustus         = 34, ///< GFFish output of Augustus Gene Prediction
+        eJSON                = 35, ///< JSON 
         /// Max value of EFormat
         eFormat_max
     };
@@ -282,6 +284,10 @@ protected:
         EMode mode );
     bool TestFormatVcf(
         EMode mode );
+    bool TestFormatAugustus(
+        EMode mode );
+    bool TestFormatJson(
+        EMode mode );
 
     bool IsInputRepeatMaskerWithoutHeader();
     bool IsInputRepeatMaskerWithHeader();
@@ -304,6 +310,8 @@ protected:
 		const std::string& );
 	static bool IsLineGff2(
 		const std::string& );
+	static bool IsLineAugustus(
+		const std::string& );
 	static bool IsLinePhrapId(
         const std::string& );
     static bool IsLineRmo(
@@ -322,16 +330,51 @@ private:
     // ' ' ' \t' '\t' ',' '|'
     bool x_TestTableDelimiter(const string& delims);
 
+    // Check that the beginning of testString looks like JSON
+    bool x_CheckJsonStart(const string& testString) const;
+
+    // In-place deletion of JSON strings
+    void x_StripJsonStrings(string& testString) const;
+
+    // Starting at from_pos, find the next set of double quotes 
+    // indicating the end of a JSON string
+    size_t x_FindNextJsonStringStop(const string& input, const size_t from_pos) const;
+
+    void x_FindJsonStringLimits(const string& testString, list<size_t>& limits) const;
+
+    // Checks and removes punctuation from testString
+    bool x_CheckStripJsonPunctuation(string& testString) const;
+
+    // In-place deletion of JSON punctuation
+    // Returns the number of characters deleted.
+    size_t x_StripJsonPunctuation(string& testString) const;
+
+    // In-place deletion of JSON keywords: true, false, null
+    void x_StripJsonKeywords(string& testString) const;
+
+    bool x_CheckStripJsonNumbers(string& testString) const;
+
+    bool x_IsTruncatedJsonNumber(const string& testString) const;
+
+    // Is a truncation of true, false, or null
+    bool x_IsTruncatedJsonKeyword(const string& testString) const;
+
+    bool x_IsNumber(const string& testString) const;
+
+    // Return true if the string is blank or a list of space-delimited numbers
+    bool x_IsBlankOrNumbers(const string& testString) const;
+
     // data:
     static const char* const sm_FormatNames[eFormat_max];
 protected:
     static int s_CheckOrder[];
     
-    static const streamsize s_iTestBufferSize = 8096;
+    static const streamsize s_iTestBufferGranularity = 8096;
 
     CNcbiIstream& m_Stream;
     bool m_bOwnsStream;
     char* m_pTestBuffer;
+    streamsize m_iTestBufferSize;
     streamsize m_iTestDataSize;
 
     bool m_bStatsAreValid;
diff --git a/c++/include/util/id_mux.hpp b/c++/include/util/id_mux.hpp
index 9088641..37f4431 100644
--- a/c++/include/util/id_mux.hpp
+++ b/c++/include/util/id_mux.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL___ID_MUX__HPP
 #define UTIL___ID_MUX__HPP
 
-/*  $Id: id_mux.hpp 489095 2016-01-08 13:02:41Z ivanov $
+/*  $Id: id_mux.hpp 501456 2016-05-16 15:12:46Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -372,8 +372,8 @@ void CIdDeMux<TBV, TBVFact>::InitDim(size_t i, size_t dim_size)
 
     size_t old_size = dv.size();
     dv.resize(dim_size);
-    for (size_t i = old_size; i < dim_size; ++i) {
-        dv[i] = TBVFactory::Create();
+    for (size_t j = old_size; j < dim_size; ++j) {
+        dv[j] = TBVFactory::Create();
     }
 }
 
diff --git a/c++/include/util/rangemap.hpp b/c++/include/util/rangemap.hpp
index 2d08cf3..3d2b06f 100644
--- a/c++/include/util/rangemap.hpp
+++ b/c++/include/util/rangemap.hpp
@@ -1,7 +1,7 @@
 #ifndef RANGEMAP__HPP
 #define RANGEMAP__HPP
 
-/*  $Id: rangemap.hpp 354590 2012-02-28 16:30:13Z ucko $
+/*  $Id: rangemap.hpp 501456 2016-05-16 15:12:46Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -433,12 +433,12 @@ public:
         {
             typedef typename TSelectMap::const_iterator TSelectMapCI;
 
-            size_type size = 0;
+            size_type n = 0;
             for ( TSelectMapCI i = m_SelectMap.begin(),
-                      end = m_SelectMap.end(); i != end; ++i ) {
-                size += i->second.size();
+                      iend = m_SelectMap.end(); i != iend; ++i ) {
+                n += i->second.size();
             }
-            return size;
+            return n;
         }
     
     // iterators
diff --git a/c++/include/util/resize_iter.hpp b/c++/include/util/resize_iter.hpp
index a484a12..5d83076 100644
--- a/c++/include/util/resize_iter.hpp
+++ b/c++/include/util/resize_iter.hpp
@@ -1,7 +1,7 @@
 #ifndef RESIZE_ITER__HPP
 #define RESIZE_ITER__HPP
 
-/*  $Id: resize_iter.hpp 489095 2016-01-08 13:02:41Z ivanov $
+/*  $Id: resize_iter.hpp 506558 2016-07-08 15:55:21Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -161,15 +161,7 @@ size_t xx_BitsPerElement(const T*)
 template <class TIterator>
 size_t x_BitsPerElement(const TIterator&)
 {
-#ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
-    // Sun cares way too much about backward bug-for-bug compatibility...
-    return xx_BitsPerElement(__value_type(TIterator()));
-#elif defined(NCBI_COMPILER_MSVC)
-    // iterator_traits seems to be broken under MSVC. :-/
-    return xx_BitsPerElement(_Val_type(TIterator()));    
-#else
     return CHAR_BIT * sizeof(typename iterator_traits<TIterator>::value_type);
-#endif    
 }
 
 
@@ -177,18 +169,7 @@ template <class TIterator, class TOut>
 TOut ExtractBits(TIterator& start, const TIterator& end,
                  size_t& bit_offset, size_t bit_count)
 {
-#if 1
     static const size_t kBitsPerElement = x_BitsPerElement(start);
-#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
-    static const size_t kBitsPerElement
-        = xx_BitsPerElement(__value_type(TIterator()));
-#elif defined(NCBI_COMPILER_MSVC)
-    static const size_t kBitsPerElement
-        = xx_BitsPerElement(_Val_type(TIterator()));    
-#else
-    static const size_t kBitsPerElement
-        = CHAR_BIT * sizeof(typename iterator_traits<TIterator>::value_type);
-#endif
 
     const TOut kMask = (1 << bit_count) - 1;
     static const TOut kMask2 = (1 << kBitsPerElement) - 1;
diff --git a/c++/include/util/resource_pool.hpp b/c++/include/util/resource_pool.hpp
index ebbdea9..cd832c1 100644
--- a/c++/include/util/resource_pool.hpp
+++ b/c++/include/util/resource_pool.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL___RESOURCEPOOL__HPP
 #define UTIL___RESOURCEPOOL__HPP
 
-/*  $Id: resource_pool.hpp 144314 2008-10-28 22:52:29Z joukovv $
+/*  $Id: resource_pool.hpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -385,7 +385,7 @@ public:
                 if (m_Bucket.size() < i) {
                     break;
                 }
-                TResourcePool* rp = m_Bucket[i];
+                rp = m_Bucket[i];
             }}
             if (rp) {
                 rp->FreeAll();
diff --git a/c++/include/util/simple_buffer.hpp b/c++/include/util/simple_buffer.hpp
index 2e63fbc..8e6a6af 100644
--- a/c++/include/util/simple_buffer.hpp
+++ b/c++/include/util/simple_buffer.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL_SIMPLE_BUFFER__HPP
 #define UTIL_SIMPLE_BUFFER__HPP
 
-/*  $Id: simple_buffer.hpp 437337 2014-06-05 13:51:11Z ucko $
+/*  $Id: simple_buffer.hpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -88,14 +88,14 @@ public:
     typedef T             value_type;
     typedef size_t        size_type;
 public:
-    explicit CSimpleBufferT(size_type size=0)
+    explicit CSimpleBufferT(size_type new_size = 0)
     {
-        if (size) {
-            m_Buffer = x_Allocate(size);
+        if (new_size) {
+            m_Buffer = x_Allocate(new_size);
         } else {
             m_Buffer = 0;
         }
-        m_Size = m_Capacity = size;
+        m_Size = m_Capacity = new_size;
     }
     ~CSimpleBufferT()
     {
@@ -242,12 +242,15 @@ public:
 
 
 private:
+
+#ifdef _DEBUG
     void x_Fill(value_type* buffer, int value, size_t elem)
     {
-#ifdef _DEBUG
         memset(buffer, value, elem * sizeof(value_type));
-#endif
     }
+#else
+    void x_Fill(value_type*, int, size_t) {}
+#endif
 
     void x_Deallocate()
     {
diff --git a/c++/include/util/static_set.hpp b/c++/include/util/static_set.hpp
index f1661d7..49bdd89 100644
--- a/c++/include/util/static_set.hpp
+++ b/c++/include/util/static_set.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL___STATIC_SET__HPP
 #define UTIL___STATIC_SET__HPP
 
-/*  $Id: static_set.hpp 361095 2012-04-30 14:12:22Z vasilche $
+/*  $Id: static_set.hpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -738,18 +738,18 @@ protected:
         using namespace NStaticArray;
         CheckStaticType<value_type>(file, line);
         _ASSERT(array_size % sizeof(value_type) == 0);
-        size_t size = array_size / sizeof(value_type);
+        size_t sz = array_size / sizeof(value_type);
         if ( m_Begin.second() ) {
             _ASSERT(m_Begin.second() == array_ptr);
-            _ASSERT(m_End == array_ptr + size);
+            _ASSERT(m_End == array_ptr + sz);
             _ASSERT(!m_DeallocateFunc);
         }
         else {
-            x_Validate(array_ptr, size, value_comp(), file, line);
+            x_Validate(array_ptr, sz, value_comp(), file, line);
         }
         m_DeallocateFunc = 0;
         m_Begin.second() = array_ptr;
-        m_End = array_ptr + size;
+        m_End = array_ptr + sz;
     }
 
     /// Assign array pointer and end pointer from differently typed array.
@@ -762,10 +762,10 @@ protected:
         using namespace NStaticArray;
         CheckStaticType<Type>(file, line);
         _ASSERT(array2_size % sizeof(Type) == 0);
-        size_t size = array2_size / sizeof(Type);
+        size_t sz = array2_size / sizeof(Type);
         CArrayHolder holder(MakeConverter(static_cast<value_type*>(0),
                                           static_cast<Type*>(0)));
-        holder.Convert(array2_ptr, size, file, line, warn);
+        holder.Convert(array2_ptr, sz, file, line, warn);
         if ( !m_Begin.second() ) {
             x_Validate(static_cast<const value_type*>(holder.GetArrayPtr()),
                        holder.GetElementCount(), value_comp(), file, line);
@@ -775,7 +775,7 @@ protected:
             if ( !m_Begin.second() ) {
                 m_Begin.second() =
                     static_cast<const value_type*>(holder.ReleaseArrayPtr());
-                m_End = m_Begin.second() + size;
+                m_End = m_Begin.second() + sz;
                 m_DeallocateFunc = x_DeallocateFunc;
             }
         }}
diff --git a/c++/include/util/stream_source.hpp b/c++/include/util/stream_source.hpp
index 0c12d0a..dafa034 100644
--- a/c++/include/util/stream_source.hpp
+++ b/c++/include/util/stream_source.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL___STREAM_SOURCE__HPP
 #define UTIL___STREAM_SOURCE__HPP
 
-/*  $Id: stream_source.hpp 497775 2016-04-11 11:26:07Z mozese2 $
+/*  $Id: stream_source.hpp 500707 2016-05-06 18:14:09Z vakatov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -62,7 +62,7 @@ BEGIN_NCBI_SCOPE
 ///         CNcbiIstream& istr = *source;
 ///         ...
 ///     }
-/// \encode
+/// \endcode
 ///
 /// Streams are checked for error conditions at the start (badbit or
 /// failbit before being returned from the iterator) and end (badbit
diff --git a/c++/include/util/strsearch.hpp b/c++/include/util/strsearch.hpp
index d98d8b6..74cdcff 100644
--- a/c++/include/util/strsearch.hpp
+++ b/c++/include/util/strsearch.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL___STRSEARCH__HPP
 #define UTIL___STRSEARCH__HPP
 
-/*  $Id: strsearch.hpp 450776 2014-10-30 16:20:28Z vasilche $
+/*  $Id: strsearch.hpp 501456 2016-05-16 15:12:46Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -395,7 +395,7 @@ typename CTextFsm<MatchType>::CState *CTextFsm<MatchType>::GetState(int state)
 
 template <typename MatchType>
 int CTextFsm<MatchType>::GetNextState(const CState& from, char letter) const {
-    char ch = m_CaseSensitive ? letter : toupper((unsigned char) letter);
+    char ch = m_CaseSensitive ? letter : (char)toupper((unsigned char) letter);
     return from.GetNextState(ch);
 }
 
diff --git a/c++/include/util/table_printer.hpp b/c++/include/util/table_printer.hpp
index 6c9df72..9139c47 100644
--- a/c++/include/util/table_printer.hpp
+++ b/c++/include/util/table_printer.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL___TABLE_PRINTER__HPP
 #define UTIL___TABLE_PRINTER__HPP
 
-/*  $Id: table_printer.hpp 433382 2014-04-24 17:15:18Z gotvyans $
+/*  $Id: table_printer.hpp 500279 2016-05-03 17:12:04Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -257,7 +257,7 @@ private:
     template<>
     inline
     CTablePrinter & operator << <CTablePrinter::SEndOfCell>(
-        CTablePrinter & table_printer, const CTablePrinter::SEndOfCell & end_of_cell ) 
+        CTablePrinter & table_printer, const CTablePrinter::SEndOfCell & /*end_of_cell*/) 
     {
         return table_printer.EndOfCurrentCell();
     }
diff --git a/c++/include/util/tables/raw_scoremat.h b/c++/include/util/tables/raw_scoremat.h
index d0c9ace..b3f4b5b 100644
--- a/c++/include/util/tables/raw_scoremat.h
+++ b/c++/include/util/tables/raw_scoremat.h
@@ -1,7 +1,7 @@
 #ifndef UTIL_TABLES___SCOREMAT__H
 #define UTIL_TABLES___SCOREMAT__H
 
-/*  $Id: raw_scoremat.h 458581 2015-02-06 15:18:12Z boratyng $
+/*  $Id: raw_scoremat.h 501870 2016-05-19 16:29:22Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -42,7 +42,7 @@ extern "C" {
 
 /** data types */
 
-typedef signed char TNCBIScore;
+typedef int TNCBIScore; /* historically signed char */
 typedef struct SNCBIPackedScoreMatrix {
     const char*       symbols;  /**< order of residues */
     const TNCBIScore* scores;   /**< strlen(symbols) x strlen(symbols) */
diff --git a/c++/include/util/timsort.hpp b/c++/include/util/timsort.hpp
new file mode 100644
index 0000000..24a3a1b
--- /dev/null
+++ b/c++/include/util/timsort.hpp
@@ -0,0 +1,666 @@
+/*
+ * C++ implementation of timsort
+ *
+ * ported from Python's and OpenJDK's:
+ * - http://svn.python.org/projects/python/trunk/Objects/listobject.c
+ * - http://cr.openjdk.java.net/~martin/webrevs/openjdk7/timsort/raw_files/new/src/share/classes/java/util/TimSort.java
+ *
+ * Copyright (c) 2011 Fuji, Goro (gfx) <gfuji at cpan.org>.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef GFX_TIMSORT_HPP
+#define GFX_TIMSORT_HPP
+
+#include <vector>
+#include <cassert>
+#include <iterator>
+#include <algorithm>
+#include <utility>
+
+#ifdef ENABLE_TIMSORT_LOG
+#include <iostream>
+#define GFX_TIMSORT_LOG(expr) (std::clog << "# " << __func__ << ": " << expr << std::endl)
+#else
+#define GFX_TIMSORT_LOG(expr) ((void)0)
+#endif
+
+#if __cplusplus >= 201103L && !DISABLE_STD_MOVE
+#define ENABLE_STD_MOVE 1
+#endif
+
+#if ENABLE_STD_MOVE
+#define GFX_TIMSORT_MOVE(x) std::move(x)
+#define GFX_TIMSORT_MOVE_RANGE(in1, in2, out) std::move((in1), (in2), (out))
+#define GFX_TIMSORT_MOVE_BACKWARD(in1, in2, out) std::move_backward((in1), (in2), (out))
+#else
+#define GFX_TIMSORT_MOVE(x) (x)
+#define GFX_TIMSORT_MOVE_RANGE(in1, in2, out) std::copy((in1), (in2), (out))
+#define GFX_TIMSORT_MOVE_BACKWARD(in1, in2, out) std::copy_backward((in1), (in2), (out))
+#endif
+
+namespace gfx {
+
+// ---------------------------------------
+// Declaration
+// ---------------------------------------
+
+/**
+ * Same as std::stable_sort(first, last).
+ */
+template <typename RandomAccessIterator>
+inline void timsort(RandomAccessIterator const first, RandomAccessIterator const last);
+
+/**
+ * Same as std::stable_sort(first, last, c).
+ */
+template <typename RandomAccessIterator, typename LessFunction>
+inline void timsort(RandomAccessIterator const first, RandomAccessIterator const last, LessFunction compare);
+
+// ---------------------------------------
+// Implementation
+// ---------------------------------------
+
+template <typename Value, typename LessFunction> class Compare {
+  public:
+    typedef Value value_type;
+    typedef LessFunction func_type;
+
+    Compare(LessFunction f) : less_(f) {
+    }
+    Compare(const Compare<value_type, func_type> &other) : less_(other.less_) {
+    }
+
+    bool lt(value_type x, value_type y) {
+        return less_(x, y);
+    }
+    bool le(value_type x, value_type y) {
+        return less_(x, y) || !less_(y, x);
+    }
+    bool gt(value_type x, value_type y) {
+        return !less_(x, y) && less_(y, x);
+    }
+    bool ge(value_type x, value_type y) {
+        return !less_(x, y);
+    }
+
+    func_type &less_function() {
+        return less_;
+    }
+
+  private:
+    func_type less_;
+};
+
+template <typename RandomAccessIterator, typename LessFunction> class TimSort {
+    typedef RandomAccessIterator iter_t;
+    typedef typename std::iterator_traits<iter_t>::value_type value_t;
+    typedef typename std::iterator_traits<iter_t>::reference ref_t;
+    typedef typename std::iterator_traits<iter_t>::difference_type diff_t;
+    typedef Compare<const value_t &, LessFunction> compare_t;
+
+    static const int MIN_MERGE = 32;
+
+    compare_t comp_;
+
+    static const int MIN_GALLOP = 7;
+
+    int minGallop_; // default to MIN_GALLOP
+
+    std::vector<value_t> tmp_; // temp storage for merges
+    typedef typename std::vector<value_t>::iterator tmp_iter_t;
+
+    struct run {
+        iter_t base;
+        diff_t len;
+
+        run(iter_t const b, diff_t const l) : base(b), len(l) {
+        }
+    };
+    std::vector<run> pending_;
+
+    static void sort(iter_t const lo, iter_t const hi, compare_t c) {
+        assert(lo <= hi);
+
+        diff_t nRemaining = (hi - lo);
+        if (nRemaining < 2) {
+            return; // nothing to do
+        }
+
+        if (nRemaining < MIN_MERGE) {
+            diff_t const initRunLen = countRunAndMakeAscending(lo, hi, c);
+            GFX_TIMSORT_LOG("initRunLen: " << initRunLen);
+            binarySort(lo, hi, lo + initRunLen, c);
+            return;
+        }
+
+        TimSort ts(c);
+        diff_t const minRun = minRunLength(nRemaining);
+        iter_t cur = lo;
+        do {
+            diff_t runLen = countRunAndMakeAscending(cur, hi, c);
+
+            if (runLen < minRun) {
+                diff_t const force = std::min(nRemaining, minRun);
+                binarySort(cur, cur + force, cur + runLen, c);
+                runLen = force;
+            }
+
+            ts.pushRun(cur, runLen);
+            ts.mergeCollapse();
+
+            cur += runLen;
+            nRemaining -= runLen;
+        } while (nRemaining != 0);
+
+        assert(cur == hi);
+        ts.mergeForceCollapse();
+        assert(ts.pending_.size() == 1);
+
+        GFX_TIMSORT_LOG("size: " << (hi - lo) << " tmp_.size(): " << ts.tmp_.size()
+                                 << " pending_.size(): " << ts.pending_.size());
+    } // sort()
+
+    static void binarySort(iter_t const lo, iter_t const hi, iter_t start, compare_t compare) {
+        assert(lo <= start && start <= hi);
+        if (start == lo) {
+            ++start;
+        }
+        for (; start < hi; ++start) {
+            assert(lo <= start);
+            /*const*/ value_t pivot = GFX_TIMSORT_MOVE(*start);
+
+            iter_t const pos = std::upper_bound(lo, start, pivot, compare.less_function());
+            for (iter_t p = start; p > pos; --p) {
+                *p = GFX_TIMSORT_MOVE(*(p - 1));
+            }
+            *pos = GFX_TIMSORT_MOVE(pivot);
+        }
+    }
+
+    static diff_t countRunAndMakeAscending(iter_t const lo, iter_t const hi, compare_t compare) {
+        assert(lo < hi);
+
+        iter_t runHi = lo + 1;
+        if (runHi == hi) {
+            return 1;
+        }
+
+        if (compare.lt(*(runHi++), *lo)) { // descending
+            while (runHi < hi && compare.lt(*runHi, *(runHi - 1))) {
+                ++runHi;
+            }
+            std::reverse(lo, runHi);
+        } else { // ascending
+            while (runHi < hi && compare.ge(*runHi, *(runHi - 1))) {
+                ++runHi;
+            }
+        }
+
+        return runHi - lo;
+    }
+
+    static diff_t minRunLength(diff_t n) {
+        assert(n >= 0);
+
+        diff_t r = 0;
+        while (n >= MIN_MERGE) {
+            r |= (n & 1);
+            n >>= 1;
+        }
+        return n + r;
+    }
+
+    TimSort(compare_t c) : comp_(c), minGallop_(MIN_GALLOP) {
+    }
+
+    void pushRun(iter_t const runBase, diff_t const runLen) {
+        pending_.push_back(run(runBase, runLen));
+    }
+
+    void mergeCollapse() {
+        while (pending_.size() > 1) {
+            diff_t n = pending_.size() - 2;
+
+            if ((n > 0 && pending_[n - 1].len <= pending_[n].len + pending_[n + 1].len) ||
+                (n > 1 && pending_[n - 2].len <= pending_[n - 1].len + pending_[n].len)) {
+                if (pending_[n - 1].len < pending_[n + 1].len) {
+                    --n;
+                }
+                mergeAt(n);
+            } else if (pending_[n].len <= pending_[n + 1].len) {
+                mergeAt(n);
+            } else {
+                break;
+            }
+        }
+    }
+
+    void mergeForceCollapse() {
+        while (pending_.size() > 1) {
+            diff_t n = pending_.size() - 2;
+
+            if (n > 0 && pending_[n - 1].len < pending_[n + 1].len) {
+                --n;
+            }
+            mergeAt(n);
+        }
+    }
+
+    void mergeAt(diff_t const i) {
+        diff_t const stackSize = pending_.size();
+        assert(stackSize >= 2);
+        assert(i >= 0);
+        assert(i == stackSize - 2 || i == stackSize - 3);
+
+        iter_t base1 = pending_[i].base;
+        diff_t len1 = pending_[i].len;
+        iter_t base2 = pending_[i + 1].base;
+        diff_t len2 = pending_[i + 1].len;
+
+        assert(len1 > 0 && len2 > 0);
+        assert(base1 + len1 == base2);
+
+        pending_[i].len = len1 + len2;
+
+        if (i == stackSize - 3) {
+            pending_[i + 1] = pending_[i + 2];
+        }
+
+        pending_.pop_back();
+
+        diff_t const k = gallopRight(*base2, base1, len1, 0);
+        assert(k >= 0);
+
+        base1 += k;
+        len1 -= k;
+
+        if (len1 == 0) {
+            return;
+        }
+
+        len2 = gallopLeft(*(base1 + (len1 - 1)), base2, len2, len2 - 1);
+        assert(len2 >= 0);
+        if (len2 == 0) {
+            return;
+        }
+
+        if (len1 <= len2) {
+            mergeLo(base1, len1, base2, len2);
+        } else {
+            mergeHi(base1, len1, base2, len2);
+        }
+    }
+
+    template <typename Iter> diff_t gallopLeft(ref_t key, Iter const base, diff_t const len, diff_t const hint) {
+        assert(len > 0 && hint >= 0 && hint < len);
+
+        diff_t lastOfs = 0;
+        diff_t ofs = 1;
+
+        if (comp_.gt(key, *(base + hint))) {
+            diff_t const maxOfs = len - hint;
+            while (ofs < maxOfs && comp_.gt(key, *(base + (hint + ofs)))) {
+                lastOfs = ofs;
+                ofs = (ofs << 1) + 1;
+
+                if (ofs <= 0) { // int overflow
+                    ofs = maxOfs;
+                }
+            }
+            if (ofs > maxOfs) {
+                ofs = maxOfs;
+            }
+
+            lastOfs += hint;
+            ofs += hint;
+        } else {
+            diff_t const maxOfs = hint + 1;
+            while (ofs < maxOfs && comp_.le(key, *(base + (hint - ofs)))) {
+                lastOfs = ofs;
+                ofs = (ofs << 1) + 1;
+
+                if (ofs <= 0) {
+                    ofs = maxOfs;
+                }
+            }
+            if (ofs > maxOfs) {
+                ofs = maxOfs;
+            }
+
+            diff_t const tmp = lastOfs;
+            lastOfs = hint - ofs;
+            ofs = hint - tmp;
+        }
+        assert(-1 <= lastOfs && lastOfs < ofs && ofs <= len);
+
+        return std::lower_bound(base + (lastOfs + 1), base + ofs, key, comp_.less_function()) - base;
+    }
+
+    template <typename Iter> diff_t gallopRight(ref_t key, Iter const base, diff_t const len, diff_t const hint) {
+        assert(len > 0 && hint >= 0 && hint < len);
+
+        diff_t ofs = 1;
+        diff_t lastOfs = 0;
+
+        if (comp_.lt(key, *(base + hint))) {
+            diff_t const maxOfs = hint + 1;
+            while (ofs < maxOfs && comp_.lt(key, *(base + (hint - ofs)))) {
+                lastOfs = ofs;
+                ofs = (ofs << 1) + 1;
+
+                if (ofs <= 0) {
+                    ofs = maxOfs;
+                }
+            }
+            if (ofs > maxOfs) {
+                ofs = maxOfs;
+            }
+
+            diff_t const tmp = lastOfs;
+            lastOfs = hint - ofs;
+            ofs = hint - tmp;
+        } else {
+            diff_t const maxOfs = len - hint;
+            while (ofs < maxOfs && comp_.ge(key, *(base + (hint + ofs)))) {
+                lastOfs = ofs;
+                ofs = (ofs << 1) + 1;
+
+                if (ofs <= 0) { // int overflow
+                    ofs = maxOfs;
+                }
+            }
+            if (ofs > maxOfs) {
+                ofs = maxOfs;
+            }
+
+            lastOfs += hint;
+            ofs += hint;
+        }
+        assert(-1 <= lastOfs && lastOfs < ofs && ofs <= len);
+
+        return std::upper_bound(base + (lastOfs + 1), base + ofs, key, comp_.less_function()) - base;
+    }
+
+    void mergeLo(iter_t const base1, diff_t len1, iter_t const base2, diff_t len2) {
+        assert(len1 > 0 && len2 > 0 && base1 + len1 == base2);
+
+        copy_to_tmp(base1, len1);
+
+        tmp_iter_t cursor1 = tmp_.begin();
+        iter_t cursor2 = base2;
+        iter_t dest = base1;
+
+        *(dest++) = GFX_TIMSORT_MOVE(*(cursor2++));
+        if (--len2 == 0) {
+            GFX_TIMSORT_MOVE_RANGE(cursor1, cursor1 + len1, dest);
+            return;
+        }
+        if (len1 == 1) {
+            GFX_TIMSORT_MOVE_RANGE(cursor2, cursor2 + len2, dest);
+            *(dest + len2) = GFX_TIMSORT_MOVE(*cursor1);
+            return;
+        }
+
+        int minGallop(minGallop_);
+
+        // outer:
+        while (true) {
+            diff_t count1 = 0;
+            diff_t count2 = 0;
+
+            bool break_outer = false;
+            do {
+                assert(len1 > 1 && len2 > 0);
+
+                if (comp_.lt(*cursor2, *cursor1)) {
+                    *(dest++) = GFX_TIMSORT_MOVE(*(cursor2++));
+                    ++count2;
+                    count1 = 0;
+                    if (--len2 == 0) {
+                        break_outer = true;
+                        break;
+                    }
+                } else {
+                    *(dest++) = GFX_TIMSORT_MOVE(*(cursor1++));
+                    ++count1;
+                    count2 = 0;
+                    if (--len1 == 1) {
+                        break_outer = true;
+                        break;
+                    }
+                }
+            } while ((count1 | count2) < minGallop);
+            if (break_outer) {
+                break;
+            }
+
+            do {
+                assert(len1 > 1 && len2 > 0);
+
+                count1 = gallopRight(*cursor2, cursor1, len1, 0);
+                if (count1 != 0) {
+                    GFX_TIMSORT_MOVE_BACKWARD(cursor1, cursor1 + count1, dest + count1);
+                    dest += count1;
+                    cursor1 += count1;
+                    len1 -= count1;
+
+                    if (len1 <= 1) {
+                        break_outer = true;
+                        break;
+                    }
+                }
+                *(dest++) = GFX_TIMSORT_MOVE(*(cursor2++));
+                if (--len2 == 0) {
+                    break_outer = true;
+                    break;
+                }
+
+                count2 = gallopLeft(*cursor1, cursor2, len2, 0);
+                if (count2 != 0) {
+                    GFX_TIMSORT_MOVE_RANGE(cursor2, cursor2 + count2, dest);
+                    dest += count2;
+                    cursor2 += count2;
+                    len2 -= count2;
+                    if (len2 == 0) {
+                        break_outer = true;
+                        break;
+                    }
+                }
+                *(dest++) = GFX_TIMSORT_MOVE(*(cursor1++));
+                if (--len1 == 1) {
+                    break_outer = true;
+                    break;
+                }
+
+                --minGallop;
+            } while ((count1 >= MIN_GALLOP) | (count2 >= MIN_GALLOP));
+            if (break_outer) {
+                break;
+            }
+
+            if (minGallop < 0) {
+                minGallop = 0;
+            }
+            minGallop += 2;
+        } // end of "outer" loop
+
+        minGallop_ = std::min(minGallop, 1);
+
+        if (len1 == 1) {
+            assert(len2 > 0);
+            GFX_TIMSORT_MOVE_RANGE(cursor2, cursor2 + len2, dest);
+            *(dest + len2) = GFX_TIMSORT_MOVE(*cursor1);
+        } else {
+            assert(len1 != 0 && "Comparison function violates its general contract");
+            assert(len2 == 0);
+            assert(len1 > 1);
+            GFX_TIMSORT_MOVE_RANGE(cursor1, cursor1 + len1, dest);
+        }
+    }
+
+    void mergeHi(iter_t const base1, diff_t len1, iter_t const base2, diff_t len2) {
+        assert(len1 > 0 && len2 > 0 && base1 + len1 == base2);
+
+        copy_to_tmp(base2, len2);
+
+        iter_t cursor1 = base1 + len1;
+        tmp_iter_t cursor2 = tmp_.begin() + len2;
+        iter_t dest = base2 + len2;
+
+        *(--dest) = GFX_TIMSORT_MOVE(*(--cursor1));
+        if (--len1 == 0) {
+            GFX_TIMSORT_MOVE_RANGE(tmp_.begin(), tmp_.begin() + len2, dest - len2);
+            return;
+        }
+        if (len2 == 1) {
+            dest -= len1;
+            cursor1 -= len1;
+            GFX_TIMSORT_MOVE_BACKWARD(cursor1, cursor1 + len1, dest + len1);
+            *(--dest) = GFX_TIMSORT_MOVE(*(--cursor2));
+            return;
+        }
+
+        int minGallop(minGallop_);
+
+        // outer:
+        while (true) {
+            diff_t count1 = 0;
+            diff_t count2 = 0;
+
+            bool break_outer = false;
+            do {
+                assert(len1 > 0 && len2 > 1);
+
+                if (comp_.lt(*(cursor2-1), *(cursor1-1))) {
+                    *(--dest) = GFX_TIMSORT_MOVE(*(--cursor1));
+                    ++count1;
+                    count2 = 0;
+                    if (--len1 == 0) {
+                        break_outer = true;
+                        break;
+                    }
+                } else {
+                    *(--dest) = GFX_TIMSORT_MOVE(*(--cursor2));
+                    ++count2;
+                    count1 = 0;
+                    if (--len2 == 1) {
+                        break_outer = true;
+                        break;
+                    }
+                }
+            } while ((count1 | count2) < minGallop);
+            if (break_outer) {
+                break;
+            }
+
+            do {
+                assert(len1 > 0 && len2 > 1);
+
+                count1 = len1 - gallopRight(*(cursor2-1), base1, len1, len1 - 1);
+                if (count1 != 0) {
+                    dest -= count1;
+                    cursor1 -= count1;
+                    len1 -= count1;
+                    GFX_TIMSORT_MOVE_BACKWARD(cursor1, cursor1 + count1, dest + count1);
+
+                    if (len1 == 0) {
+                        break_outer = true;
+                        break;
+                    }
+                }
+                *(--dest) = GFX_TIMSORT_MOVE(*(--cursor2));
+                if (--len2 == 1) {
+                    break_outer = true;
+                    break;
+                }
+
+                count2 = len2 - gallopLeft(*(cursor1-1), tmp_.begin(), len2, len2 - 1);
+                if (count2 != 0) {
+                    dest -= count2;
+                    cursor2 -= count2;
+                    len2 -= count2;
+                    GFX_TIMSORT_MOVE_RANGE(cursor2, cursor2 + count2, dest);
+                    if (len2 <= 1) {
+                        break_outer = true;
+                        break;
+                    }
+                }
+                *(--dest) = GFX_TIMSORT_MOVE(*(--cursor1));
+                if (--len1 == 0) {
+                    break_outer = true;
+                    break;
+                }
+
+                minGallop--;
+            } while ((count1 >= MIN_GALLOP) | (count2 >= MIN_GALLOP));
+            if (break_outer) {
+                break;
+            }
+
+            if (minGallop < 0) {
+                minGallop = 0;
+            }
+            minGallop += 2;
+        } // end of "outer" loop
+
+        minGallop_ = std::min(minGallop, 1);
+
+        if (len2 == 1) {
+            assert(len1 > 0);
+            dest -= len1;
+            GFX_TIMSORT_MOVE_BACKWARD(cursor1 - len1, cursor1, dest + len1);
+            *(--dest) = GFX_TIMSORT_MOVE(*(--cursor2));
+        } else {
+            assert(len2 != 0 && "Comparison function violates its general contract");
+            assert(len1 == 0);
+            assert(len2 > 1);
+            GFX_TIMSORT_MOVE_RANGE(tmp_.begin(), tmp_.begin() + len2, dest - len2);
+        }
+    }
+
+    void copy_to_tmp(iter_t const begin, diff_t const len) {
+        tmp_.clear();
+        tmp_.reserve(len);
+        GFX_TIMSORT_MOVE_RANGE(begin, begin + len, std::back_inserter(tmp_));
+    }
+
+    // the only interface is the friend timsort() function
+    template <typename IterT, typename LessT> friend void timsort(IterT first, IterT last, LessT c);
+};
+
+template <typename RandomAccessIterator>
+inline void timsort(RandomAccessIterator const first, RandomAccessIterator const last) {
+    typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
+    timsort(first, last, std::less<value_type>());
+}
+
+template <typename RandomAccessIterator, typename LessFunction>
+inline void timsort(RandomAccessIterator const first, RandomAccessIterator const last, LessFunction compare) {
+    TimSort<RandomAccessIterator, LessFunction>::sort(first, last, compare);
+}
+
+} // namespace gfx
+
+#undef GFX_TIMSORT_LOG
+#undef GFX_TIMSORT_MOVE
+#undef GFX_TIMSORT_MOVE_RANGE
+#undef GFX_TIMSORT_MOVE_BACKWARD
+#endif // GFX_TIMSORT_HPP
diff --git a/c++/include/util/value_convert.hpp b/c++/include/util/value_convert.hpp
index 09ae369..8a5a257 100644
--- a/c++/include/util/value_convert.hpp
+++ b/c++/include/util/value_convert.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL___VALUE_CONVERT__HPP
 #define UTIL___VALUE_CONVERT__HPP
 
-/* $Id: value_convert.hpp 499843 2016-04-28 16:12:36Z ivanov $
+/* $Id: value_convert.hpp 499250 2016-04-25 12:27:42Z gouriano $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/include/util/value_convert_policy.hpp b/c++/include/util/value_convert_policy.hpp
index 5471d70..e34d59a 100644
--- a/c++/include/util/value_convert_policy.hpp
+++ b/c++/include/util/value_convert_policy.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL___VALUE_CONV_POLICY__HPP
 #define UTIL___VALUE_CONV_POLICY__HPP
 
-/* $Id: value_convert_policy.hpp 499843 2016-04-28 16:12:36Z ivanov $
+/* $Id: value_convert_policy.hpp 499250 2016-04-25 12:27:42Z gouriano $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NTOICE
diff --git a/c++/scripts/common/add_vdb.sh b/c++/scripts/common/add_vdb.sh
index 8d66b71..e6346b0 100755
--- a/c++/scripts/common/add_vdb.sh
+++ b/c++/scripts/common/add_vdb.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
-# $Id: add_vdb.sh 486134 2015-12-01 18:54:11Z ucko $
+# $Id: add_vdb.sh 515777 2016-10-05 17:33:58Z ivanov $
 . "`dirname $0`/common.sh"
 
 set -e
@@ -33,7 +33,7 @@ if [ ! -d interfaces ]; then
     git checkout master
 fi
 if [ "$platform" = IntelMAC ]; then
-    archflag=--arch=fat86
+    # archflag=--arch=fat86
     if [ ! -d $root/tmp/force-clang ]; then
         mkdir -p $root/tmp/force-clang
         ln -s /usr/bin/clang $root/tmp/force-clang/gcc
@@ -45,6 +45,12 @@ fi
 ./configure --prefix=$root/$name --build-prefix=$root/build/$name $archflag \
     ${LIBXML_LIBPATH:+"LDFLAGS=$LIBXML_LIBPATH"}
 make
+
+for x in lib lib64; do
+    if [ -L $root/$name/$x ]; then
+        rm $root/$name/$x
+    fi
+done
 make install
 if [ -f $root/$name/include/klib/rc.h ]; then
     :
diff --git a/c++/scripts/common/check/check_add.sh b/c++/scripts/common/check/check_add.sh
index e3793da..7ffcca1 100755
--- a/c++/scripts/common/check/check_add.sh
+++ b/c++/scripts/common/check/check_add.sh
@@ -1,5 +1,5 @@
 #! /bin/sh
-# $Id: check_add.sh 487040 2015-12-14 17:30:22Z ivanov $
+# $Id: check_add.sh 512371 2016-08-30 14:51:15Z ivanov $
 # Author:  Vladimir Ivanov, NCBI 
 #
 ###########################################################################
@@ -121,7 +121,14 @@ fi
 # Write data about current test into the list file
 for x_cmd in $x_run; do
     x_cmd=`echo "$x_cmd"  | sed -e 's/%gj_s4%/ /g'`
-    x_name=`echo "$x_cmd" | sed -e 's/^.*CHECK_NAME *= *\([A-Za-z0-9_]*\).*/\1/' -e 's/.*CHECK_CMD.*//'`
+    x_name=`echo "$x_cmd" | sed -e 's/^.*CHECK_NAME *= *//' -e 's/ *$//' -e 's/.*CHECK_CMD.*//'`
+    if [ -n "$x_name" ]; then
+       xx_name=`echo "$x_name" | sed -e 's/\([A-Za-z0-9_.-]*\).*/\1/'`
+       if [ "$x_name" != "$xx_name" ]; then
+          echo "Warning: Incorrect CHECK_NAME value '$x_name', '$xx_name' will be used instead. Please fix."
+          x_name=$xx_name
+       fi
+    fi
     x_cmd=`echo "$x_cmd"  | sed -e 's/ *\/CHECK_NAME.*//' -e 's/^[^=]*=//' -e 's/^ *//'  -e 's/\"/\\\\"/g'`
     echo "$x_srcdir_rel$x_delim$x_test$x_delim$x_app$x_delim$x_cmd$x_delim$x_name$x_delim$x_files$x_delim$x_timeout$x_delim$x_requires$x_delim$x_watchers" >> $x_out
 done
diff --git a/c++/scripts/common/check/check_make_cfg.sh b/c++/scripts/common/check/check_make_cfg.sh
index 89af5e4..57f32a5 100755
--- a/c++/scripts/common/check/check_make_cfg.sh
+++ b/c++/scripts/common/check/check_make_cfg.sh
@@ -1,6 +1,6 @@
 #! /bin/sh
 
-# $Id: check_make_cfg.sh 500063 2016-05-02 12:21:38Z ivanov $
+# $Id: check_make_cfg.sh 499855 2016-04-28 17:06:32Z ivanov $
 # Author:  Vladimir Ivanov, NCBI 
 #
 ###########################################################################
diff --git a/c++/scripts/common/check/check_make_unix.sh b/c++/scripts/common/check/check_make_unix.sh
index e8f9ac0..b739524 100755
--- a/c++/scripts/common/check/check_make_unix.sh
+++ b/c++/scripts/common/check/check_make_unix.sh
@@ -1,6 +1,6 @@
 #! /bin/sh
 
-# $Id: check_make_unix.sh 500063 2016-05-02 12:21:38Z ivanov $
+# $Id: check_make_unix.sh 501272 2016-05-12 20:12:39Z vakatov $
 # Author:  Vladimir Ivanov, NCBI 
 #
 ###########################################################################
@@ -432,7 +432,12 @@ fi
 if test "\$NCBI_CHECK_SETLIMITS" != "0"; then
    ulimit -c 1000000
    if [ \$cygwin = false ]; then
-      ulimit -v 4000000
+       if test "\$NCBI_CHECK_TOOLS" = "regular"; then
+          ulimit -v 4000000
+       else
+          # Increase memory limits if run under check tool
+          ulimit -v 16000000
+       fi
    fi
 fi
 
diff --git a/c++/scripts/common/check/inspxe-suppressions/_vs.sup b/c++/scripts/common/check/inspxe-suppressions/_vs.sup
index 05b25f0..c769d1e 100644
--- a/c++/scripts/common/check/inspxe-suppressions/_vs.sup
+++ b/c++/scripts/common/check/inspxe-suppressions/_vs.sup
@@ -263,39 +263,71 @@ suppression = {
 	}
 }
 suppression = {
-	name = "False positive in MS implementation of basic_string::assign()"
+	name = "libsybct64.dll internal problem"
 	type = {invalid_memory_access}
 	stacks = {
 		{
 			!!!;
-			src=xstring,func=assign,line=1160,func_line=12;
+			mod=ntdll.dll,func=RtlCompareUnicodeStrings;
+			...;
+			mod=libsybct64.dll,func=ct_dynsqlda;
 		}
 	}
 }
 suppression = {
-	name = "libsybct64.dll internal problem"
+	name = "Unreachable MSVCR120.dll memory error in stat64()"
 	type = {invalid_memory_access}
 	stacks = {
 		allocation={
-			!!!;
-			mod=ntdll.dll,func=RtlCompareUnicodeStrings;
 			...;
-			mod=libsybct64.dll,func=ct_dynsqlda;
+			mod=MSVCR120.dll,func=stat64;
+		}
+		{
+			...;
+			mod=MSVCR120.dll,func=stat64;
 		}
 	}
 }
 suppression = {
-	name = "MSVCR120.dll memory error in stat64()"
+	name = "Unreachable OLEAUT32.dll memory error in SysStringByteLen()"
 	type = {invalid_memory_access}
 	stacks = {
-		allocation={
+		{
 			...;
-			mod=MSVCR120.dll,func=stat64;
+			mod=OLEAUT32.dll,func=SysStringByteLen;
 		}
+	}
+}
+suppression = {
+	name = "Unreachable libgnutls-30.dll memory error in gnutls_psk_set_server_params_function()"
+	type = {invalid_memory_access}
+	stacks = {
+		{
+			!!!;
+			mod=libgnutls-30.dll,func=gnutls_psk_set_server_params_function;
+		}
+	}
+}
+suppression = {
+	name = "False positive in operator<<()"
+	type = {invalid_memory_access}
+	stacks = {
 		{
 			...;
-			mod=MSVCR120.dll,func=stat64;
+			mod=MSVCR120.dll,func=flsbuf;
+		}
+	}
+}
+suppression = {
+	name = "False positive in fclose()"
+	type = {invalid_memory_access}
+	stacks = {
+		{
+			...;
+			mod=MSVCR120.dll,func=write;
+			...;
+			mod=MSVCR120.dll,func=fclose;
+			func=close,src=fstream;
 		}
 	}
 }
-
diff --git a/c++/scripts/common/check/inspxe-suppressions/connect.sup b/c++/scripts/common/check/inspxe-suppressions/connect.sup
index 9436a0e..6dee664 100644
--- a/c++/scripts/common/check/inspxe-suppressions/connect.sup
+++ b/c++/scripts/common/check/inspxe-suppressions/connect.sup
@@ -46,3 +46,17 @@ suppression = {
 		}
 	}
 }
+suppression = {
+	name = "gnutls_handshake() non-important (only DLL build)"
+	type = {invalid_memory_access_partial}
+	stacks = {
+		allocation={
+			!!!;
+			mod=test_netstorage.exe,func=s_GnuTlsOpen;
+		}
+		{
+			!!!;
+			mod=libgnutls-28.dll,func=gnutls_psk_set_server_params_function;
+		}
+	}
+}
diff --git a/c++/scripts/common/check/inspxe-suppressions/corelib.sup b/c++/scripts/common/check/inspxe-suppressions/corelib.sup
index dd9a191..0028909 100644
--- a/c++/scripts/common/check/inspxe-suppressions/corelib.sup
+++ b/c++/scripts/common/check/inspxe-suppressions/corelib.sup
@@ -118,3 +118,27 @@ suppression = {
 		}
 	}
 }
+suppression = {
+	name = "False positive in basic_string::assign() called from CNcbiEnvironment constructor"
+	type = {invalid_memory_access}
+	stacks = {
+		{
+			...;
+			func=assign,src=xstring;
+			func=Reset,src=ncbienv.cpp;
+			func=CNcbiEnvironment,src=ncbienv.cpp;
+		}
+	}
+}
+suppression = {
+	name = "False positive in basic_string::assign() called from CNcbiEnvironment constructor"
+	type = {invalid_memory_access_partial}
+	stacks = {
+		{
+			...;
+			func=assign,src=xstring;
+			func=Reset,src=ncbienv.cpp;
+			func=CNcbiEnvironment,src=ncbienv.cpp;
+		}
+	}
+}
diff --git a/c++/scripts/common/check/inspxe-suppressions/misc.sup b/c++/scripts/common/check/inspxe-suppressions/misc.sup
index 3631e5d..130f9ab 100644
--- a/c++/scripts/common/check/inspxe-suppressions/misc.sup
+++ b/c++/scripts/common/check/inspxe-suppressions/misc.sup
@@ -18,3 +18,44 @@ suppression = {
 		}
 	}
 }
+suppression = {
+	name = "Deallocation without allocation in KNgcObjWriteToFile() at ncbi_vdb.dll - False positive"
+	type = {invalid_deallocation}
+	stacks = {
+		{
+			...;
+			func=KNgcObjWriteToFile;
+		}
+	}
+}
+suppression = {
+	name = "Missing allocation in vdbread.cpp:707 - False positive"
+	type = {invalid_deallocation}
+	stacks = {
+		{
+			!!!;
+			src=vdbread.cpp,func=Init;
+		}
+	}
+}
+suppression = {
+	name = "Invalid memory access in vdbread.cpp:477 - False positive"
+	type = {invalid_memory_access}
+	stacks = {
+		{
+			...;
+			src=vdbread.cpp,func=CVDB;
+		}
+	}
+}
+suppression = {
+	name = "Invalid memory access in libgnutls"
+	type = {invalid_memory_access}
+	stacks = {
+		allocation = {
+			...;
+			func=gnutls_pkcs12_export2;
+		}
+	}
+}
+
diff --git a/c++/scripts/common/check/inspxe.sh b/c++/scripts/common/check/inspxe.sh
index 5b5d2f0..fcac9c2 100755
--- a/c++/scripts/common/check/inspxe.sh
+++ b/c++/scripts/common/check/inspxe.sh
@@ -37,7 +37,7 @@ exe=$1.exe
 shift
 
 # Run test
-"$inspxe" -collect mi3 -knob detect-resource-leaks=false -knob stack-depth=32 -result-dir $rd -return-app-exitcode -suppression-file "$suppress_dir" -- $exe "$@"
+"$inspxe" -collect mi3 -knob detect-leaks-on-exit=false -knob enable-memory-growth-detection=false -knob enable-on-demand-leak-detection=false -knob still-allocated-memory=false -knob detect-resource-leaks=false -knob stack-depth=32 -result-dir $rd -return-app-exitcode -suppression-file "$suppress_dir" -- $exe "$@"
 app_result=$?
 "$inspxe" -report problems -report-all -result-dir $rd
 insp_result=$?
diff --git a/c++/scripts/common/check/valgrind.supp b/c++/scripts/common/check/valgrind.supp
index 8573afd..c7f4bc4 100644
--- a/c++/scripts/common/check/valgrind.supp
+++ b/c++/scripts/common/check/valgrind.supp
@@ -1,4 +1,4 @@
-# $Id: valgrind.supp 481966 2015-10-19 16:23:39Z vakatov $
+# $Id: valgrind.supp 493573 2016-02-29 19:59:14Z vakatov $
 #
 # Valgrind suppression file (version 3.5.0 -> 3.11.0).
 #
@@ -336,6 +336,29 @@
 }
 
 {
+   Sybase CTLIB 15.7-SP122-64bit (Case 1)
+   Memcheck:Addr1
+   fun:com_secure_memset
+   fun:ct__tds_loginover
+   fun:ct_async_exec_stack
+   fun:ct_connect
+}
+
+{
+   Sybase DBLIB 15.7-SP122-64bit (Case 2)
+   Memcheck:Param
+   socketcall.sendto(msg)
+   fun:send
+   fun:sybsoc_write
+   fun:sybnet_write
+   fun:write_buffer
+   fun:sendflush
+   fun:sendeom
+   fun:bcp__endbatch
+   fun:bcp_done
+}
+
+{
    Sybase DBLIB 12.5.1.10-ESD26-64bit (case 1)
    Memcheck:Param
    write(buf)
diff --git a/c++/scripts/common/impl/compress_tests.sh b/c++/scripts/common/impl/compress_tests.sh
index 7cc317f..643c3fb 100755
--- a/c++/scripts/common/impl/compress_tests.sh
+++ b/c++/scripts/common/impl/compress_tests.sh
@@ -39,7 +39,7 @@ for dir in "$@"; do
                 targets="$targets `basename $f`$ext"
                 ;;
             *blast* | datatool | gbench* | id1_fetch | idwwwget | lbsmc \
-                | one2all )
+                | one2all | run_with_lock )
                 ;;
             *)
                 test "$compress_others" = "no"  ||  \
diff --git a/c++/scripts/common/impl/install.sh b/c++/scripts/common/impl/install.sh
index 66b3d45..e8fab72 100755
--- a/c++/scripts/common/impl/install.sh
+++ b/c++/scripts/common/impl/install.sh
@@ -16,7 +16,7 @@
 
 echo "[`date`]"
 
-svn_location=`echo '$URL: https://svn.ncbi.nlm.nih.gov/repos/toolkit/release/blast/2.4.0/c++/scripts/common/impl/install.sh $' | sed "s%\\$[U]RL: *\\([^$][^$]*\\) \\$.*%\\1%"`
+svn_location=`echo '$URL: https://svn.ncbi.nlm.nih.gov/repos/toolkit/release/blast/2.6.0/c++/scripts/common/impl/install.sh $' | sed "s%\\$[U]RL: *\\([^$][^$]*\\) \\$.*%\\1%"`
 svn_revision=`echo '$Revision: 429376 $' | sed "s%\\$[R]evision: *\\([^$][^$]*\\) \\$.*%\\1%"`
 
 script_name=`basename $0`
diff --git a/c++/scripts/common/impl/python-config.py b/c++/scripts/common/impl/python-config.py
new file mode 100755
index 0000000..d13a6ac
--- /dev/null
+++ b/c++/scripts/common/impl/python-config.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# $Id: python-config.py 503831 2016-06-08 14:54:36Z ucko $
+
+from distutils import sysconfig
+import sys
+
+def lookup(want):
+    if want == 'VERSION':
+        return sysconfig.get_config_var('VERSION')
+    elif want == 'INCLUDE':
+        return ('-I%s -I%s' % (sysconfig.get_python_inc(),
+                               sysconfig.get_python_inc(True)))
+    elif want == 'LIBPATH':
+        return ' '.join(sysconfig.get_config_vars('LIBDIR', 'LIBPL'))
+    elif want == 'DEPS':
+        return ' '.join(sysconfig.get_config_vars('LIBS', 'SYSLIBS'))
+    elif want == 'LDVERSION':
+        return (sysconfig.get_config_var('LDVERSION')
+                or sysconfig.get_config_var('VERSION'))
+    elif want == 'LIBS':
+        return '-lpython' + lookup('LDVERSION') + ' ' + lookup('DEPS')
+    else:
+        raise RuntimeError('Unsupported mode ' + want)
+
+print(lookup(sys.argv[1].lstrip('-').upper()))
diff --git a/c++/scripts/common/new_project.sh b/c++/scripts/common/new_project.sh
index 42df854..9932811 100755
--- a/c++/scripts/common/new_project.sh
+++ b/c++/scripts/common/new_project.sh
@@ -1,9 +1,9 @@
 #! /bin/sh
-# $Id: new_project.sh 442644 2014-08-05 20:01:57Z ucko $
+# $Id: new_project.sh 501452 2016-05-16 15:10:32Z elisovdn $
 # Authors:  Denis Vakatov (vakatov at ncbi.nlm.nih.gov),
 #           Aaron Ucko    (ucko at ncbi.nlm.nih.gov)
 
-svn_revision=`echo '$Revision: 442644 $' | sed "s%\\$[R]evision: *\\([^$][^$]*\\) \\$.*%\\1%"`
+svn_revision=`echo '$Revision: 501452 $' | sed "s%\\$[R]evision: *\\([^$][^$]*\\) \\$.*%\\1%"`
 def_builddir="$NCBI/c++/Debug/build"
 
 repository_url='http://anonsvn.ncbi.nlm.nih.gov/repos/v1'
@@ -38,6 +38,7 @@ ARGUMENTS:
      lib/dtd         to build a library from an XML DTD
      lib/xsd         to build a library from an XML Schema
      app[/basic]     to build a simple application
+     app/multicmd    to build a simple command-based application
      app/alnmgr      to build an application using the alignment manager
      app/asn         to build a library from ASN.1 spec, and sample application
      app/blast       to build an application using BLAST
diff --git a/c++/scripts/common/new_project.wsf b/c++/scripts/common/new_project.wsf
index 9ca41d7..490ac1b 100644
--- a/c++/scripts/common/new_project.wsf
+++ b/c++/scripts/common/new_project.wsf
@@ -157,6 +157,7 @@
             usage_str += "    <name>      -- name of the project\n";
             usage_str += "    <type>      -- one of the following:\n";
             usage_str += "                   app[/basic]       a simple application\n";
+            usage_str += "                   app/multicmd      a simple command-based application\n";
             usage_str += "                   app/alnmgr        an application that uses Alignment Manager\n";
             usage_str += "                   app/asn           an application that uses ASN.1 specification\n";
             usage_str += "                   app/blast         a BLAST application\n";
@@ -244,6 +245,7 @@
                 prompt += "This can be one of the following:\n";
                 prompt += "\tapp\n";
                 prompt += "\tapp/basic\n";
+                prompt += "\tapp/multicmd\n";
                 prompt += "\tapp/alnmgr\n";
                 prompt += "\tapp/asn\n";
                 prompt += "\tapp/blast\n";
@@ -281,6 +283,7 @@
             this.TemplatesDict = new ActiveXObject("Scripting.Dictionary");
             this.TemplatesDict.Add("app",         "sample/app/basic");
             this.TemplatesDict.Add("app/basic",   "sample/app/basic");
+            this.TemplatesDict.Add("app/multicmd",   "sample/app/multicmd");
             this.TemplatesDict.Add("app/alnmgr",  "sample/app/alnmgr");
             this.TemplatesDict.Add("app/asn",     "sample/app/asn");
             this.TemplatesDict.Add("app/blast",   "sample/app/blast");
diff --git a/c++/scripts/common/new_project_msvc7.bat b/c++/scripts/common/new_project_msvc7.bat
deleted file mode 100755
index e8f9c1a..0000000
--- a/c++/scripts/common/new_project_msvc7.bat
+++ /dev/null
@@ -1,45 +0,0 @@
-IF _%1%==_ GOTO USAGE
-IF _%2%==_ GOTO USAGE
-ECHO %CD%
-
-:PREPARE
-SET TREE_ROOT=%CD%\..\
-
-SET PROJ_DIR=%TREE_ROOT%src\%1\
-SET COMPILERS_DIR=%TREE_ROOT%compilers\
-SET PTB_EXE_PATH=%COMPILERS_DIR%msvc710_prj\static\bin\debug\
-SET PTB_INI_PATH=%COMPILERS_DIR%msvc710_prj\
-
-IF EXIST %PTB_EXE_PATH%project_tree_builder.exe GOTO START_PTB
-:BUILD_PTB
-ECHO "Building project_tree_builder ..."
-devenv %COMPILERS_DIR%msvc710_prj\static\build\app\project_tree_builder\project_tree_builder.sln /build Debug /project "-BUILD-ALL-" > Debug.log
-IF ERRORLEVEL 1 GOTO ABORT
-ECHO "Completed."
-GOTO START_PTB
-
-:START_PTB
-ECHO "Creating requested solution ..."
-%PTB_EXE_PATH%project_tree_builder.exe -logfile out.log -conffile %PTB_INI_PATH%project_tree_builder.ini %TREE_ROOT% src\%1 %PROJ_DIR%%2
-IF ERRORLEVEL 1 GOTO ABORT
-ECHO "Completed."
-GOTO OPEN_SOLUTION
-
-:OPEN_SOLUTION
-devenv %PROJ_DIR%%2
-GOTO EXIT
-
-:USAGE
-ECHO "bat file for starting a new project with MSVC 7.10"
-ECHO "UNIX makefiles must be created first!"
-ECHO "USAGE:"
-ECHO "new_project_msvc7 <path-from-tree-root-to-your-project> <solution-name>"
-ECHO "Example:"
-ECHO "new_project_msvc7 internal\cppcore\test_stat test_stat.sln"
-GOTO EXIT
-
-:ABORT
-ECHO "FAILED"
-GOTO EXIT
-
-:EXIT
\ No newline at end of file
diff --git a/c++/scripts/common/project_utilits.js b/c++/scripts/common/project_utilits.js
index c1fca38..448d66b 100644
--- a/c++/scripts/common/project_utilits.js
+++ b/c++/scripts/common/project_utilits.js
@@ -1,6 +1,6 @@
+// $Id: project_utilits.js 501454 2016-05-16 15:12:21Z elisovdn $
 ////////////////////////////////////////////////////////////////////////////////////
 // Shared part of new_project.wsf and import_project.wsf
-
 // global settings
 var g_verbose       = false;
 var g_usefilecopy   = true;
@@ -10,7 +10,7 @@ var g_open_solution = true;
 var g_def_branch = "toolkit/trunk/internal/c++";
 var g_branch     = "toolkit/trunk/internal/c++";
 
-// valid:   "71", "80", "80x64", "90", "90x64", "100", "100x64", "120", "120x64"
+// valid:   "120", "120x64", "140", "140x64"
 var g_def_msvcver = "120";
 var g_msvcver     = "120";
 
@@ -159,18 +159,11 @@ function GetConfigs(oTask)
     if (oTask.DllBuild) {
         var configs = new Array ("DebugDLL", "ReleaseDLL");
         return configs;
-    } else {
-        if (g_msvcver == "71") {
-            var configs = new Array (
-                "Debug",   "DebugMT",   "DebugDLL", 
-                "Release", "ReleaseMT", "ReleaseDLL");
-            return configs;
-        } else {
-            var configs = new Array (
-                "DebugMT",   "DebugDLL", 
-                "ReleaseMT", "ReleaseDLL");
-            return configs;
-        }
+    } else {        
+        var configs = new Array (
+            "DebugMT",   "DebugDLL", 
+            "ReleaseMT", "ReleaseDLL");
+        return configs;
     }
 }       
 // recursive path creator - oFso is pre-created file system object
@@ -496,11 +489,10 @@ function SetMsvcVer(oArgs, flag)
 {
     var msvcver = GetFlaggedValue(oArgs, flag, "");
     if (msvcver.length  != 0) {
-        if (msvcver != "71" && msvcver != "80" &&  msvcver != "80x64"
-                            && msvcver != "90" &&  msvcver != "90x64"
-                            && msvcver != "100" && msvcver != "100x64"
-                            && msvcver != "110" && msvcver != "110x64"
-                            && msvcver != "120" && msvcver != "120x64"
+        if (
+				   msvcver != "110" && msvcver != "110x64"
+				&& msvcver != "120" && msvcver != "120x64"
+				&& msvcver != "140" && msvcver != "140x64"
            ) {
             WScript.Echo("ERROR: Unknown version of MSVC requested: " + msvcver);
             WScript.Quit(1);    
@@ -511,22 +503,16 @@ function SetMsvcVer(oArgs, flag)
 
 function GetMsvcFolder()
 {
-    if (g_msvcver == "80" || g_msvcver == "80x64") {
-        return "msvc800_prj";
-    }
-    if (g_msvcver == "90" || g_msvcver == "90x64") {
-        return "msvc900_prj";
-    }
-    if (g_msvcver == "100" || g_msvcver == "100x64") {
-        return "msvc1000_prj";
-    }
     if (g_msvcver == "110" || g_msvcver == "110x64") {
         return "vs2013";
     }
     if (g_msvcver == "120" || g_msvcver == "120x64") {
         return "vs2013";
     }
-    return "msvc710_prj";
+    if (g_msvcver == "140" || g_msvcver == "140x64") {
+        return "vs2015";
+    }
+    return "vs2013";
 }
 
 function GetFlaggedValue(oArgs, flag, default_val)
@@ -591,25 +577,15 @@ function GetPositionalValue(oArgs, position)
 // Configuration of pre-built C++ toolkit
 function GetDefaultSuffix()
 {
-    var s = "msvc8";
-    if (g_msvcver == "80") {
-        s = "msvc8";
-    } else if (g_msvcver == "80x64") {
-        s = "msvc8.64";
-    } else if (g_msvcver == "90") {
-        s = "msvc9";
-    } else if (g_msvcver == "90x64") {
-        s = "msvc9.64";
-    } else if (g_msvcver == "100") {
-        s = "msvc10";
-    } else if (g_msvcver == "100x64") {
-        s = "msvc10.64";
-    } else if (g_msvcver == "110" || g_msvcver == "120") {
+    var s = "vs2013";
+    if (g_msvcver == "110" || g_msvcver == "120") {
         s = "vs2013";
     } else if (g_msvcver == "110x64" || g_msvcver == "120x64") {
         s = "vs2013.64";
-    } else {
-        s = "msvc71";
+    } else if (g_msvcver == "140") {
+        s = "vs2015";
+    } else if (g_msvcver == "140x64") {
+        s = "vs2015.64";
     }
     return s;
 }
@@ -620,19 +596,7 @@ function GetPtbTargetSolutionArgs(oShell, ptb)
     if (ver < 180) {
         return s;
     }
-    if (g_msvcver == "80") {
-        s = " -ide 800 -arch Win32";
-    } else if (g_msvcver == "80x64") {
-        s = " -ide 800 -arch x64";
-    } else if (g_msvcver == "90") {
-        s = " -ide 900 -arch Win32";
-    } else if (g_msvcver == "90x64") {
-        s = " -ide 900 -arch x64";
-    } else if (g_msvcver == "100") {
-        s = " -ide 1000 -arch Win32";
-    } else if (g_msvcver == "100x64") {
-        s = " -ide 1000 -arch x64";
-    } else if (g_msvcver == "110") {
+    if (g_msvcver == "110") {
         s = " -ide 1100 -arch Win32";
     } else if (g_msvcver == "110x64") {
         s = " -ide 1100 -arch x64";
@@ -640,16 +604,19 @@ function GetPtbTargetSolutionArgs(oShell, ptb)
         s = " -ide 1200 -arch Win32";
     } else if (g_msvcver == "120x64") {
         s = " -ide 1200 -arch x64";
+    } else if (g_msvcver == "140") {
+        s = " -ide 1400 -arch Win32";
+    } else if (g_msvcver == "140x64") {
+        s = " -ide 1400 -arch x64";
     } else {
-        s = " -ide 710 -arch Win32";
+        s = " -ide 1200 -arch Win32";
     }
     return s;
 }
 function GetTargetPlatform()
 {
-    if (g_msvcver == "80x64"  || g_msvcver == "90x64" ||
-        g_msvcver == "100x64" || g_msvcver == "110x64" ||
-        g_msvcver == "120x64") {
+    if (g_msvcver == "110x64" ||
+        g_msvcver == "120x64" || g_msvcver == "140x64") {
         return "x64";
     }
     return "Win32";
diff --git a/c++/scripts/projects/blast/LICENSE b/c++/scripts/projects/blast/LICENSE
index f3577c2..b5e8446 100644
--- a/c++/scripts/projects/blast/LICENSE
+++ b/c++/scripts/projects/blast/LICENSE
@@ -17,3 +17,508 @@
   purpose.
 
   Please cite the author in any work or product based on this material.
+
+  ===========================================================================
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+

+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+

+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+

+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+

+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+

+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+

+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+

+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+

+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+

+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/c++/scripts/projects/blast/Manifest b/c++/scripts/projects/blast/Manifest
index 2b70f66..566bafc 100644
--- a/c++/scripts/projects/blast/Manifest
+++ b/c++/scripts/projects/blast/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 493735 2016-03-01 21:14:46Z camacho $
+# $Id: Manifest 512796 2016-09-02 19:46:40Z camacho $
 #
 # Author: Christiam Camacho
 #
@@ -25,9 +25,10 @@ APP: makeprofiledb blast_formatter
 COPY: $srcdir/src/app/blast/legacy_blast.pl $installdir/bin
 COPY: $srcdir/src/app/blast/update_blastdb.pl $installdir/bin
 
-POSTBUILD: $srcdir/scripts/projects/blast/post_build/make_installers.py -v $version $platform $installdir "$tarball"
+POSTBUILD: $srcdir/scripts/projects/blast/post_build/make_installers.py -v $version $platform $installdir "$tarball" $bindir
 
-DEFAULT_CONFIGURE_FLAGS: --without-debug --with-strip --with-openmp --with-mt --with-build-root=$srcdir/ReleaseMT
+# N.B.: This allows customization of configure script in prepare_release output
+DEFAULT_CONFIGURE_FLAGS: --without-debug --with-strip --with-openmp --with-mt --without-vdb --with-build-root=$srcdir/ReleaseMT
 
 # Each line describes a single configuration
 # The format is as follows:
@@ -40,17 +41,18 @@ DEFAULT_CONFIGURE_FLAGS: --without-debug --with-strip --with-openmp --with-mt --
 # ICC gives us about 10% improvement in the core2 microarchitecture, so prefer
 # that. The build-root is needed so that rpmbuild can find the proper directories
 # to copy the binaries from
-Linux64-Centos     : icc : ICC.sh            --with-strip --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-experimental=Int8GI
-#Linux64-Centos     : gcc : GCC.sh            --with-strip --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile
-#Linux64-Centos     : gcc-debug : GCC.sh            --with-strip --with-debug --without-pcre --with-mt --with-openmp --with-flat-makefile
+Linux64-Centos     : icc : ICC.sh           --with-bin-release --with-strip --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-experimental=Int8GI --without-vdb --with-gnutls=/netopt/ncbi_tools64/gnutls-3.4.0 --without-gcrypt
+#Linux64-Centos     : gcc : GCC.sh           --with-bin-release --with-strip --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-experimental=Int8GI --without-vdb
+#Linux64-Centos     : gcc-debug : GCC.sh                        --with-strip --with-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-experimental=Int8GI --without-vdb
 
 DEFAULT_CONFIGURATIONS: Linux64-Centos:icc
+#DEFAULT_CONFIGURATIONS: Linux64-Centos:gcc
 
-Win32         : plain : static  32  ReleaseMT
-Win64         : plain : static  64  ReleaseMT
+# FIXME: how to specify without VDB?
+Win64         : plain : static  64  ReleaseDLL <ENV>NCBI_CONFIG____ENABLEDUSERREQUESTS__NCBI-INT8-GI=1</ENV>
 
-#IntelMAC            : universal : GCC.sh   --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-universal=i386,x86_64 --with-ncbi-public
-IntelMAC    : universal : Clang.sh --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-universal=i386,x86_64 --with-ncbi-public --with-experimental=Int8GI
-#IntelMAC-Clang36    : clang     : Clang.sh --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-ncbi-public
+#IntelMAC            : gcc   : GCC.sh         --with-bin-release --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-ncbi-public --with-experimental=Int8GI --without-vdb --with-gnutls=/netopt/ncbi_tools/gnutls-3.4.0 --without-gcrypt
+#IntelMAC            : clang : Clang.sh       --with-bin-release --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-ncbi-public --with-experimental=Int8GI --without-vdb --with-gnutls=/netopt/ncbi_tools/gnutls-3.4.0 --without-gcrypt
+IntelMAC-Clang36    : clang : Clang.sh 7.0.2 --with-bin-release --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-ncbi-public --with-experimental=Int8GI --without-vdb --with-gnutls=/netopt/ncbi_tools/gnutls-3.4.0 --without-gcrypt
 
 USE_COMPONENTS
diff --git a/c++/scripts/projects/blast/components.link b/c++/scripts/projects/blast/components.link
index e8df490..86d2dd2 100644
--- a/c++/scripts/projects/blast/components.link
+++ b/c++/scripts/projects/blast/components.link
@@ -1,9 +1,9 @@
 [components]
-infrastructure  17.0
-core            17.0
-dbase           17.0
-web             17.0
-objects         17.0
-objtools        17.0
-algo            17.0
-app             17.0
+infrastructure  18.0
+core            18.0
+dbase           18.0
+web             18.0
+objects         18.0
+objtools        18.0
+algo            18.0
+app             18.0
diff --git a/c++/scripts/projects/blast/post_build/blast_utils.py b/c++/scripts/projects/blast/post_build/blast_utils.py
index 08da04a..2209bef 100644
--- a/c++/scripts/projects/blast/post_build/blast_utils.py
+++ b/c++/scripts/projects/blast/post_build/blast_utils.py
@@ -83,16 +83,14 @@ def create_new_tarball_name(platform, program, version):
     retval = "ncbi-" + program + "-" + version
     if program == "blast":
         retval += "+"
-    if platform.startswith("Win32"):
-        retval += "-ia32-win32"
-    elif platform.startswith("Win64"):
+    if platform.startswith("Win"):
         retval += "-x64-win64"
     elif platform.startswith("Linux32"):
         retval += "-ia32-linux"
     elif platform.startswith("Linux64"):
         retval += "-x64-linux"
-    elif platform == "IntelMAC":
-        retval += "-universal-macosx"
+    elif platform.startswith("IntelMAC"):
+        retval += "-x64-macosx"
     elif platform == "SunOSSparc":
         retval += "-sparc64-solaris"
     elif platform == "SunOSx86":
diff --git a/c++/scripts/projects/blast/post_build/macosx/ncbi-blast.sh b/c++/scripts/projects/blast/post_build/macosx/ncbi-blast.sh
index 05643ae..0e3a832 100755
--- a/c++/scripts/projects/blast/post_build/macosx/ncbi-blast.sh
+++ b/c++/scripts/projects/blast/post_build/macosx/ncbi-blast.sh
@@ -79,7 +79,10 @@ create_product_archive()
 
 create_disk_image()
 {
-	/usr/bin/hdiutil create $PRODUCT.dmg -srcfolder $PRODUCT
+    du -shc $PRODUCT    # For diagnostics
+    # Note: if this command fails, it could be because the -size argument is no
+    # longer large enough, adjust accordingly
+    /usr/bin/hdiutil create $PRODUCT.dmg -srcfolder $PRODUCT -verbose -size 150m
     mkdir $INSTALLDIR/installer
     mv $PRODUCT.dmg $INSTALLDIR/installer
 }
diff --git a/c++/scripts/projects/blast/post_build/make_installers.py b/c++/scripts/projects/blast/post_build/make_installers.py
index d7ce0b6..1157387 100755
--- a/c++/scripts/projects/blast/post_build/make_installers.py
+++ b/c++/scripts/projects/blast/post_build/make_installers.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 """Driver program for post-build processing"""
-# $Id: make_installers.py 495954 2016-03-22 19:12:50Z camacho $
+# $Id: make_installers.py 512684 2016-09-01 22:19:28Z camacho $
 #
 # Author: Christiam Camacho
 #
@@ -9,6 +9,7 @@ from __future__ import print_function
 import os, sys, os.path
 from optparse import OptionParser
 import blast_utils
+import shutil
 
 VERBOSE = False
 SCRIPTS_DIR = os.path.dirname(os.path.abspath(sys.argv[0]))
@@ -20,11 +21,11 @@ def main(): #IGNORE:R0911
     parser.add_option("-v", "--verbose", action="store_true", default=False,
                       help="Show verbose output", dest="VERBOSE")
     options, args = parser.parse_args()
-    if len(args) != 4:
+    if len(args) != 5:
         parser.error("Incorrect number of arguments")
         return 1
 
-    blast_version, platform, installdir, srctarball = args
+    blast_version, platform, installdir, srctarball, libdir = args
 
     global VERBOSE #IGNORE:W0603
     VERBOSE = options.VERBOSE
@@ -33,15 +34,32 @@ def main(): #IGNORE:R0911
         print("Platform:", platform)
         print("Installation directory:", installdir)
         print("Source tarball:", srctarball)
+        print("Lib directory:", libdir)
 
     if platform.startswith("Win"):
+        import glob
+        print("Files in libdir " + libdir + ":")
+        for dll in glob.glob(libdir + "/*"):
+            print(dll)
+        print("Files in install dir " + installdir + ":")
+        for dll in glob.glob(installdir + "/*"):
+            print(dll)
+
+
+    if platform.startswith("Win"):
+        shutil.copy(libdir + "libgcc_s_seh-1.dll", installdir + "bin")
+        shutil.copy(libdir + "libgmp-10.dll", installdir + "bin")
+        shutil.copy(libdir + "libgnutls-30.dll", installdir + "bin")
+        shutil.copy(libdir + "libhogweed-4-2.dll", installdir + "bin")
+        shutil.copy(libdir + "libnettle-6-2.dll", installdir + "bin")
+        shutil.copy(libdir + "libp11-kit-0.dll", installdir + "bin")
         return launch_win_installer_build(installdir, blast_version)                
     if platform.startswith("Linux64"):
         return launch_rpm_build(installdir, blast_version, srctarball)
     if platform == "FreeBSD32" or platform.startswith("SunOS") or \
         platform.startswith("Linux32"):
         return do_nothing(platform)
-    if platform == "IntelMAC":
+    if platform.startswith("IntelMAC"):
         return mac_post_build(installdir, blast_version)
     
     print("Unknown OS identifier:" + platform, file=sys.stderr)
diff --git a/c++/scripts/projects/blast/post_build/win/make_win.py b/c++/scripts/projects/blast/post_build/win/make_win.py
index 648b3ef..0d4b51b 100644
--- a/c++/scripts/projects/blast/post_build/win/make_win.py
+++ b/c++/scripts/projects/blast/post_build/win/make_win.py
@@ -1,6 +1,6 @@
 #! /usr/bin/env python3
 """Script to create the Windows installer for BLAST command line applications"""
-# $Id: make_win.py 495892 2016-03-22 15:02:26Z camacho $
+# $Id: make_win.py 511374 2016-08-22 13:18:52Z camacho $
 #
 # Author: Christiam camacho
 
@@ -62,7 +62,14 @@ def main():
              "blast_formatter.exe",
              "deltablast.exe",
              "legacy_blast.pl",
-             "update_blastdb.pl" ]
+             "update_blastdb.pl",
+             "libgcc_s_seh-1.dll",
+             "libgmp-10.dll",
+             "libgnutls-30.dll",
+             "libhogweed-4-2.dll",
+             "libnettle-6-2.dll",
+             "libp11-kit-0.dll"
+             ]
     
     cwd = os.getcwd()
     for app in apps:
diff --git a/c++/scripts/projects/blast/post_build/win/ncbi-blast.nsi b/c++/scripts/projects/blast/post_build/win/ncbi-blast.nsi
index 71590ba..593b76f 100755
--- a/c++/scripts/projects/blast/post_build/win/ncbi-blast.nsi
+++ b/c++/scripts/projects/blast/post_build/win/ncbi-blast.nsi
@@ -81,6 +81,12 @@ Section "DefaultSection" SecDflt
   File "blastdbcheck.exe"
   File "blast_formatter.exe"
   File "deltablast.exe"
+  File "libgcc_s_seh-1.dll"
+  File "libgmp-10.dll"
+  File "libgnutls-30.dll"
+  File "libhogweed-4-2.dll"
+  File "libnettle-6-2.dll"
+  File "libp11-kit-0.dll"
   
   SetOutPath "$INSTDIR\doc"
   File "README.txt"
@@ -124,6 +130,12 @@ Section "Uninstall"
   Delete "$INSTDIR\bin\blastdbcheck.exe"
   Delete "$INSTDIR\bin\blast_formatter.exe"
   Delete "$INSTDIR\bin\deltablast.exe"
+  Delete "$INSTDIR\bin\libgcc_s_seh-1.dll"
+  Delete "$INSTDIR\bin\libgmp-10.dll"
+  Delete "$INSTDIR\bin\libgnutls-30.dll"
+  Delete "$INSTDIR\bin\libhogweed-4-2.dll"
+  Delete "$INSTDIR\bin\libnettle-6-2.dll"
+  Delete "$INSTDIR\bin\libp11-kit-0.dll"
   Delete "$INSTDIR\doc\README.txt"
   RmDir "$INSTDIR\bin"
   RmDir "$INSTDIR\doc"
diff --git a/c++/scripts/projects/blast/project.lst b/c++/scripts/projects/blast/project.lst
index f24331e..3c97087 100644
--- a/c++/scripts/projects/blast/project.lst
+++ b/c++/scripts/projects/blast/project.lst
@@ -78,3 +78,6 @@ objtools/simple$
 -objects/.*/test
 -objects/.*/demo
 -objects/.*/unit_test
+misc$
+misc/third_party
+misc/third_party_static
diff --git a/c++/scripts/projects/cobalt/Manifest b/c++/scripts/projects/cobalt/Manifest
index fe16c00..ca06940 100644
--- a/c++/scripts/projects/cobalt/Manifest
+++ b/c++/scripts/projects/cobalt/Manifest
@@ -36,7 +36,7 @@ DEFAULT_CONFIGURATIONS: Linux32-Centos:icc Linux64-Centos:icc
 Win32_13    : plain : static  32  ReleaseMT
 Win64_13    : plain : static  64  ReleaseMT
 
-IntelMAC    : universal : GCC.sh        --without-debug --without-pcre --with-mt --with-flat-makefile --with-universal=i386,x86_64 --with-ncbi-public
+IntelMAC    : gcc : GCC.sh        --without-debug --without-pcre --with-mt --with-flat-makefile --with-ncbi-public
 
 USE_COMPONENTS
 
diff --git a/c++/scripts/projects/datatool/ChangeLog b/c++/scripts/projects/datatool/ChangeLog
index d85ed64..71b909f 100644
--- a/c++/scripts/projects/datatool/ChangeLog
+++ b/c++/scripts/projects/datatool/ChangeLog
@@ -152,6 +152,8 @@ Added mapping of certain data types to strings.
 Fixed delayed buffer in choice variants.
 Changed to print schema comments using documentation tag.
 
-
+July 21, 2016
+Version 2.16.0, CXX-8385
+Added option to distinguish BigInt and Int8 in ASN binary serialization.
 
 
diff --git a/c++/scripts/projects/datatool/Manifest b/c++/scripts/projects/datatool/Manifest
index 4172f6f..72799a7 100644
--- a/c++/scripts/projects/datatool/Manifest
+++ b/c++/scripts/projects/datatool/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 486339 2015-12-03 15:52:01Z fukanchi $
+# $Id: Manifest 508788 2016-08-01 16:12:18Z fukanchi $
 #
 # Author: Sergey Satskiy
 #
@@ -36,7 +36,7 @@ IntelMAC   : plain  : GCC.sh           --without-debug --without-mt --with-stati
 
 Win32_13   : plain : static  32  ReleaseMT
 
-XCode      : plain  : Xcode.sh 30 --without-debug --with-universal=i386,x86_64
+XCode      : plain  : Xcode.sh 30 --without-debug
 
 USE_COMPONENTS
 
diff --git a/c++/scripts/projects/dispatcher/Manifest b/c++/scripts/projects/dispatcher/Manifest
index e7e503e..d48558f 100644
--- a/c++/scripts/projects/dispatcher/Manifest
+++ b/c++/scripts/projects/dispatcher/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 486339 2015-12-03 15:52:01Z fukanchi $
+# $Id: Manifest 508788 2016-08-01 16:12:18Z fukanchi $
 #
 # Author: Sergey Satskiy
 #
@@ -36,5 +36,5 @@ POSTBUILD: [ "$platform" != "Cygwin64" ] || { cp -vp /usr/{bin/cygcheck.exe,bin/
 Linux64-Centos  : ICC   : ICC.sh         --with-local-lbsm --without-debug --without-mt --with-static --without-serial --without-runpath --with-flat-makefile
 Linux64-Centos  : GCC   : GCC.sh         --with-local-lbsm --without-debug --without-mt --with-static --without-serial --without-runpath --with-flat-makefile
 FreeBSD64       : Clang : Clang.sh       --with-local-lbsm --without-debug --without-mt --with-static --without-serial --without-runpath --with-flat-makefile
-IntelMAC        : GCC   : GCC.sh         --with-local-lbsm --without-debug --without-mt --with-static --without-serial --without-runpath --with-flat-makefile --with-universal=i386,x86_64
+IntelMAC        : GCC   : GCC.sh         --with-local-lbsm --without-debug --without-mt --with-static --without-serial --without-runpath --with-flat-makefile
 # Cygwin64        : GCC   : GCC.sh         --with-local-lbsm --without-debug --without-mt --with-static --without-serial --without-runpath --without-flat-makefile
diff --git a/c++/scripts/projects/gumbel_params/Manifest b/c++/scripts/projects/gumbel_params/Manifest
index 2428596..49e0a0b 100644
--- a/c++/scripts/projects/gumbel_params/Manifest
+++ b/c++/scripts/projects/gumbel_params/Manifest
@@ -39,6 +39,6 @@ Win64_13    : plain : static  64  ReleaseMT
 
 SunOSx86    : plain : WorkShop59.sh 64  --without-debug --without-pcre --with-mt --with-flat-makefile
 
-IntelMAC    : universal : GCC.sh        --without-debug --without-pcre --with-mt --with-flat-makefile --with-universal=i386,x86_64 --with-ncbi-public
+IntelMAC    : gcc : GCC.sh        --without-debug --without-pcre --with-mt --with-flat-makefile --with-ncbi-public
 
 # USE_COMPONENTS
diff --git a/c++/scripts/projects/igblast/ChangeLog b/c++/scripts/projects/igblast/ChangeLog
index 7937b96..b382e94 100644
--- a/c++/scripts/projects/igblast/ChangeLog
+++ b/c++/scripts/projects/igblast/ChangeLog
@@ -1,3 +1,13 @@
+Oct 26, 2016
+* Release 1.6.1
+* Added clonotype report
+
+April 25, 2016
+* Release 1.5.0
+* Added CDR3 annotation 
+* Added option for extending at 5' side
+* Default to IMGT region (was Kabat previously)
+	
 July 17, 2014
 * Release 1.4.0
 * Added capability to analyze monkey sequences.
diff --git a/c++/scripts/projects/igblast/LICENSE b/c++/scripts/projects/igblast/LICENSE
index f3577c2..b5e8446 100644
--- a/c++/scripts/projects/igblast/LICENSE
+++ b/c++/scripts/projects/igblast/LICENSE
@@ -17,3 +17,508 @@
   purpose.
 
   Please cite the author in any work or product based on this material.
+
+  ===========================================================================
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+

+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+

+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+

+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+

+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+

+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+

+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+

+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+

+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+

+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/c++/scripts/projects/igblast/Manifest b/c++/scripts/projects/igblast/Manifest
index e38fa0c..68ba277 100644
--- a/c++/scripts/projects/igblast/Manifest
+++ b/c++/scripts/projects/igblast/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 497677 2016-04-08 19:08:30Z camacho $
+# $Id: Manifest 517012 2016-10-19 21:23:41Z camacho $
 #
 # Author: Christiam Camacho
 #
@@ -16,9 +16,9 @@
 # It is allowed to have more than one of each statements
 APP: igblastp igblastn makeblastdb
 
-POSTBUILD: $srcdir/scripts/projects/igblast/post_build/make_installers.py -v $version $platform $installdir
+POSTBUILD: $srcdir/scripts/projects/igblast/post_build/make_installers.py -v $version $platform $installdir "$tarball" $bindir
 
-DEFAULT_CONFIGURE_FLAGS: --without-debug --with-strip --with-mt --with-build-root=$srcdir/ReleaseMT
+DEFAULT_CONFIGURE_FLAGS: --without-debug --with-strip --with-openmp --with-mt --without-vdb --with-build-root=$srcdir/ReleaseMT
 
 # Each line describes a single configuration
 # The format is as follows:
@@ -31,15 +31,16 @@ DEFAULT_CONFIGURE_FLAGS: --without-debug --with-strip --with-mt --with-build-roo
 # ICC gives us about 10% improvement in the core2 microarchitecture, so prefer
 # that. The build-root is needed so that rpmbuild can find the proper directories
 # to copy the binaries from
-Linux64-Centos   : icc : ICC.sh            --with-strip --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile
+Linux64-Centos   : icc : ICC.sh            --with-bin-release --with-strip --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-experimental=Int8GI --without-vdb --with-gnutls=/netopt/ncbi_tools64/gnutls-3.4.0 --without-gcrypt
 #Linux64-Centos     : gcc-debug : GCC.sh            --with-strip --with-debug --without-pcre --with-mt --with-flat-makefile
 
 DEFAULT_CONFIGURATIONS: Linux64-Centos:icc
 
-Win32    : plain : static  32  ReleaseMT
-Win64    : plain : static  64  ReleaseMT
+#Win32    : plain : static  32  ReleaseMT
+#Win64    : plain : static  64  ReleaseMT
+Win64    : plain : static  64  ReleaseDLL <ENV>NCBI_CONFIG____ENABLEDUSERREQUESTS__NCBI-INT8-GI=1</ENV>
 
-IntelMAC    : universal : Clang.sh      --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-universal=i386,x86_64 --with-ncbi-public
+IntelMAC            : clang : Clang.sh       --with-bin-release --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-ncbi-public --with-experimental=Int8GI --without-vdb --with-gnutls=/netopt/ncbi_tools/gnutls-3.4.0 --without-gcrypt
+IntelMAC-Clang36    : clang : Clang.sh 7.0.2 --with-bin-release --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-ncbi-public --with-experimental=Int8GI --without-vdb --with-gnutls=/netopt/ncbi_tools/gnutls-3.4.0 --without-gcrypt
 
 USE_COMPONENTS
-
diff --git a/c++/scripts/projects/igblast/README b/c++/scripts/projects/igblast/README
index c23b873..e3c476a 100644
--- a/c++/scripts/projects/igblast/README
+++ b/c++/scripts/projects/igblast/README
@@ -31,15 +31,16 @@ program is) or a path pointed to by IGDATA environmental variable.  Note that th
  any germline gene databases you should search (see above for how you can obtain a germline gene database).
 
 2.  Optional files (download from the release/ directory):
-This is the file to indicate germline J gene coding frame start position (position is 0-based) for each 
-sequence in your germline J sequence database.  Note that the supplied file contains only information 
-for NCBI or IMGT  germline database.   If you search your own database and if it contains different 
+This is the file to indicate germline J gene coding frame start position (position is 0-based), the J gene type, 
+and the CDR3 end position for each sequence in the germline J sequence database (Fields are tab-delimited).
+
+Note that the supplied file contains only information for NCBI or IMGT  germline gene sequence database 
+(including gene names as well as the sequences).   If you search your own database and if it contains different 
 sequences or sequence identifiers, then you need to edit that file (or supply your own file) to reflect that 
-or you won't get proper frame status information for a rearrangement (other results will still be shown).  
-The entry format has tab-delimited fields for sequence id and coding frame start position.  See 
-human_gl.aux or mouse_gl.aux for examples.  Enter -1 if the frame information is unknown (or simply 
-don't include that sequence entry at all).  You need to use -auxiliary_data option to specify your file. You 
-can directly supply a path to this file or put it under a path pointed to by IGDATA environmental variable.
+or you won't get proper frame status or CDR3 information (other results will still be shown correctly).  
+See human_gl.aux or mouse_gl.aux for examples.  Enter -1 if the frame information is unknown.  
+You need to use -auxiliary_data option to specify your file. You can directly supply a path to this file or 
+put it under a path pointed to by IGDATA environmental variable.
  
 3.  Some examples.
 1).  Searching germline gene database
diff --git a/c++/scripts/projects/igblast/components.link b/c++/scripts/projects/igblast/components.link
index e8df490..86d2dd2 100644
--- a/c++/scripts/projects/igblast/components.link
+++ b/c++/scripts/projects/igblast/components.link
@@ -1,9 +1,9 @@
 [components]
-infrastructure  17.0
-core            17.0
-dbase           17.0
-web             17.0
-objects         17.0
-objtools        17.0
-algo            17.0
-app             17.0
+infrastructure  18.0
+core            18.0
+dbase           18.0
+web             18.0
+objects         18.0
+objtools        18.0
+algo            18.0
+app             18.0
diff --git a/c++/scripts/projects/igblast/post_build/blast_utils.py b/c++/scripts/projects/igblast/post_build/blast_utils.py
index cfa22b0..ef9940d 100644
--- a/c++/scripts/projects/igblast/post_build/blast_utils.py
+++ b/c++/scripts/projects/igblast/post_build/blast_utils.py
@@ -72,7 +72,7 @@ def update_blast_version(config_file, ver):
     os.remove(fname)
 
 
-def create_new_tarball_name(platform, version):
+def create_new_tarball_name(platform, program, version):
     """ Converts the name of a platform as specified to the prepare_release 
     framework to an archive name according to BLAST release naming conventions.
     
@@ -80,17 +80,17 @@ def create_new_tarball_name(platform, version):
     more information can be found in http://mini.ncbi.nih.gov/3oo
     """
     
-    retval = "ncbi-blast-" + version + "+"
-    if platform.startswith("Win32"):
-        retval += "-ia32-win32"
-    elif platform.startswith("Win64"):
+    retval = "ncbi-" + program + "-" + version
+    if program == "blast":
+        retval += "+"
+    if platform.startswith("Win"):
         retval += "-x64-win64"
     elif platform.startswith("Linux32"):
         retval += "-ia32-linux"
     elif platform.startswith("Linux64"):
         retval += "-x64-linux"
-    elif platform == "IntelMAC":
-        retval += "-universal-macosx"
+    elif platform.startswith("IntelMAC"):
+        retval += "-x64-macosx"
     elif platform == "SunOSSparc":
         retval += "-sparc64-solaris"
     elif platform == "SunOSx86":
@@ -99,6 +99,7 @@ def create_new_tarball_name(platform, version):
         raise RuntimeError("Unknown platform: " + platform)
     return retval
 
+
 def determine_platform():
     """ Determines the platform (as defined in prepare_release) for the current
     hostname 
diff --git a/c++/scripts/projects/igblast/post_build/make_installers.py b/c++/scripts/projects/igblast/post_build/make_installers.py
index da4e560..4ac612f 100755
--- a/c++/scripts/projects/igblast/post_build/make_installers.py
+++ b/c++/scripts/projects/igblast/post_build/make_installers.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 """Driver program for post-build processing"""
-# $Id: make_installers.py 496124 2016-03-23 20:34:27Z camacho $
+# $Id: make_installers.py 517012 2016-10-19 21:23:41Z camacho $
 #
 # Author: Christiam Camacho
 #
@@ -9,21 +9,23 @@ from __future__ import print_function
 import os, sys, os.path
 from optparse import OptionParser
 import blast_utils
+import shutil
 
 VERBOSE = False
 SCRIPTS_DIR = os.path.dirname(os.path.abspath(sys.argv[0]))
 
 def main(): #IGNORE:R0911
     """ Creates installers for selected platforms. """
-    parser = OptionParser("%prog <blast_version> <platform> <installation directory>")
+    parser = OptionParser("%prog <blast_version> <platform> \
+                          <installation directory> \"<src-tarball>\"")
     parser.add_option("-v", "--verbose", action="store_true", default=False,
                       help="Show verbose output", dest="VERBOSE")
     options, args = parser.parse_args()
-    if len(args) != 3:
+    if len(args) != 5:
         parser.error("Incorrect number of arguments")
         return 1
 
-    blast_version, platform, installdir = args
+    blast_version, platform, installdir, srctarball, libdir = args
 
     global VERBOSE #IGNORE:W0603
     VERBOSE = options.VERBOSE
@@ -31,17 +33,36 @@ def main(): #IGNORE:R0911
         print("BLAST version", blast_version)
         print("Platform:", platform)
         print("Installation directory:", installdir)
+        print("Source tarball:", srctarball)
+        print("Lib directory:", libdir)
 
     if platform.startswith("Win"):
+        import glob
+        print("Files in libdir " + libdir + ":")
+        for dll in glob.glob(libdir + "/*"):
+            print(dll)
+        print("Files in install dir " + installdir + ":")
+        for dll in glob.glob(installdir + "/*"):
+            print(dll)
+
+
+    if platform.startswith("Win"):
+        shutil.copy(libdir + "libgcc_s_seh-1.dll", installdir + "bin")
+        shutil.copy(libdir + "libgmp-10.dll", installdir + "bin")
+        shutil.copy(libdir + "libgnutls-30.dll", installdir + "bin")
+        shutil.copy(libdir + "libhogweed-4-2.dll", installdir + "bin")
+        shutil.copy(libdir + "libnettle-6-2.dll", installdir + "bin")
+        shutil.copy(libdir + "libp11-kit-0.dll", installdir + "bin")
         return launch_win_installer_build(installdir, blast_version)                
-    if platform.startswith("Linux"):
+    if platform.startswith("Linux64"):
         return launch_rpm_build(installdir, blast_version)
-    if platform == "FreeBSD32" or platform.startswith("SunOS"):
+    if platform == "FreeBSD32" or platform.startswith("SunOS") or \
+        platform.startswith("Linux32"):
         return do_nothing(platform)
-    if platform == "IntelMAC":
+    if platform.startswith("IntelMAC"):
         return mac_post_build(installdir, blast_version)
     
-    print("Unknown OS identifier:", platform, file=sys.stderr)
+    print("Unknown OS identifier:" + platform, file=sys.stderr)
     print("Exiting post build script.", file=sys.stderr)
     return 2
 
diff --git a/c++/scripts/projects/igblast/post_build/win/make_win.py b/c++/scripts/projects/igblast/post_build/win/make_win.py
index e7fb633..b6d882f 100644
--- a/c++/scripts/projects/igblast/post_build/win/make_win.py
+++ b/c++/scripts/projects/igblast/post_build/win/make_win.py
@@ -1,6 +1,6 @@
 #! /usr/bin/env python3
 """Script to create the Windows installer for BLAST command line applications"""
-# $Id: make_win.py 495893 2016-03-22 15:02:30Z camacho $
+# $Id: make_win.py 516804 2016-10-18 15:15:47Z camacho $
 #
 # Author: Christiam camacho
 
@@ -41,7 +41,14 @@ def main():
     blast_version, installdir = args
     VERBOSE = options.VERBOSE
     
-    apps = [ "igblastn.exe", "igblastp.exe" ]
+    apps = [ "igblastn.exe", "igblastp.exe",
+             "libgcc_s_seh-1.dll",
+             "libgmp-10.dll",
+             "libgnutls-30.dll",
+             "libhogweed-4-2.dll",
+             "libnettle-6-2.dll",
+             "libp11-kit-0.dll"
+            ]
     
     cwd = os.getcwd()
     for app in apps:
diff --git a/c++/scripts/projects/igblast/post_build/win/ncbi-blast.nsi b/c++/scripts/projects/igblast/post_build/win/ncbi-blast.nsi
index f1adc07..4e6b716 100755
--- a/c++/scripts/projects/igblast/post_build/win/ncbi-blast.nsi
+++ b/c++/scripts/projects/igblast/post_build/win/ncbi-blast.nsi
@@ -62,6 +62,12 @@ Section "DefaultSection" SecDflt
   
   File "igblastn.exe"
   File "igblastp.exe"
+  File "libgcc_s_seh-1.dll"
+  File "libgmp-10.dll"
+  File "libgnutls-30.dll"
+  File "libhogweed-4-2.dll"
+  File "libnettle-6-2.dll"
+  File "libp11-kit-0.dll"
   
   SetOutPath "$INSTDIR\doc"
   File "README"
diff --git a/c++/scripts/projects/igblast/project.lst b/c++/scripts/projects/igblast/project.lst
index 784632e..a206abe 100644
--- a/c++/scripts/projects/igblast/project.lst
+++ b/c++/scripts/projects/igblast/project.lst
@@ -82,3 +82,6 @@ objtools/simple$
 -objects/.*/test
 -objects/.*/demo
 -objects/.*/unit_test
+misc$
+misc/third_party
+misc/third_party_static
diff --git a/c++/scripts/projects/magicblast/ChangeLog b/c++/scripts/projects/magicblast/ChangeLog
new file mode 100644
index 0000000..f1af188
--- /dev/null
+++ b/c++/scripts/projects/magicblast/ChangeLog
@@ -0,0 +1,11 @@
+August 19, 2016
+* First release
+
+November 4, 2016
+* 1.1.0 release
+Improvements:
+* -sra option connects to NCBI via HTTPS
+* Results are formatted with 'bare' accessions
+* Tabular output includes a header with column titles
+Bug fixes:
+* Fixed SAM flag values
diff --git a/c++/scripts/projects/magicblast/LICENSE b/c++/scripts/projects/magicblast/LICENSE
new file mode 100644
index 0000000..b5e8446
--- /dev/null
+++ b/c++/scripts/projects/magicblast/LICENSE
@@ -0,0 +1,524 @@
+                            PUBLIC DOMAIN NOTICE
+               National Center for Biotechnology Information
+
+  This software/database is a "United States Government Work" under the
+  terms of the United States Copyright Act.  It was written as part of
+  the author's official duties as a United States Government employee and
+  thus cannot be copyrighted.  This software/database is freely available
+  to the public for use. The National Library of Medicine and the U.S.
+  Government have not placed any restriction on its use or reproduction.
+
+  Although all reasonable efforts have been taken to ensure the accuracy
+  and reliability of the software and data, the NLM and the U.S.
+  Government do not and cannot warrant the performance or results that
+  may be obtained by using this software or data. The NLM and the U.S.
+  Government disclaim all warranties, express or implied, including
+  warranties of performance, merchantability or fitness for any particular
+  purpose.
+
+  Please cite the author in any work or product based on this material.
+
+  ===========================================================================
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+

+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+

+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+

+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+

+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+

+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+

+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+

+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+

+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+

+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/c++/scripts/projects/magicblast/Manifest b/c++/scripts/projects/magicblast/Manifest
new file mode 100644
index 0000000..73a93d8
--- /dev/null
+++ b/c++/scripts/projects/magicblast/Manifest
@@ -0,0 +1,50 @@
+#
+# Filename: Manifest
+#
+# $Id $
+#
+# Author: Christiam Camacho, Greg Boratyn
+#
+# Purpose: This file holds all the supported configurations of a package
+#          It is used by release configurator.
+#
+
+# The APP: statement describes binaries
+# The LIB: statement describes libraries
+# The DLL: statement describes shared objects
+# The ETC: statement describes configuration files
+# It is allowed to have more than one of each statements
+# NOTE: When applications are added/removed from this list, please update
+# the application listings in post_build/win/{make_win.py,ncbi-blast.nsi},
+# post_build/macosx/ncbi-blast.sh, and post_build/rpm/ncbi-blast.spec
+APP: magicblast makeblastdb
+
+POSTBUILD: $srcdir/scripts/projects/magicblast/post_build/make_installers.py -v $version $platform $installdir "$tarball" $bindir
+
+DEFAULT_CONFIGURE_FLAGS: --without-debug --with-strip --with-openmp --with-mt --with-build-root=$srcdir/ReleaseMT --with-downloaded-vdb --with-static-vdb
+
+# Each line describes a single configuration
+# The format is as follows:
+# <HardwareIdentifier> : <ReleaseSuffix> : <CompilerConfigurationScriptWithKeys>
+# Configuration script is relative to c++/compilers/unix/ .
+# Release configurator assumes that this script will eventually call standard configure script and pass all options
+# to it. So some standard options may be added by release configurator, such as --build-root-sfx, --with-projects,
+# --with-distcc, --with-action etc.
+
+# ICC gives us about 10% improvement in the core2 microarchitecture, so prefer
+# that. The build-root is needed so that rpmbuild can find the proper directories
+# to copy the binaries from
+Linux64-Centos     : icc : ICC.sh           --with-bin-release --with-strip --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-experimental=Int8GI --with-downloaded-vdb --with-static-vdb --with-gnutls=/netopt/ncbi_tools64/gnutls-3.4.0 --without-gcrypt
+#Linux64-Centos     : gcc : GCC.sh           --with-bin-release --with-strip --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-experimental=Int8GI --with-downloaded-vdb --with-static-vdb
+#Linux64-Centos     : gcc-debug : GCC.sh                        --with-strip --with-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-downloaded-vdb
+
+DEFAULT_CONFIGURATIONS: Linux64-Centos:icc
+#DEFAULT_CONFIGURATIONS: Linux64-Centos:gcc
+
+Win64         : plain : static  64  ReleaseDLL <ENV>NCBI_CONFIG____ENABLEDUSERREQUESTS__NCBI-INT8-GI=1</ENV>
+
+#IntelMAC            : gcc : GCC.sh   --with-bin-release --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-ncbi-public --with-downloaded-vdb --with-static-vdb
+IntelMAC            : clang     : Clang.sh          --with-bin-release --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-ncbi-public --with-experimental=Int8GI --with-downloaded-vdb --with-static-vdb --with-gnutls=/netopt/ncbi_tools/gnutls-3.4.0 --without-gcrypt
+IntelMAC-Clang36    : clang     : Clang.sh 7.0.2    --with-bin-release --without-debug --without-pcre --with-mt --with-openmp --with-flat-makefile --with-ncbi-public --with-experimental=Int8GI --with-downloaded-vdb --with-static-vdb --with-gnutls=/netopt/ncbi_tools/gnutls-3.4.0 --without-gcrypt
+
+USE_COMPONENTS
diff --git a/c++/scripts/projects/magicblast/README b/c++/scripts/projects/magicblast/README
new file mode 100644
index 0000000..f2e4b06
--- /dev/null
+++ b/c++/scripts/projects/magicblast/README
@@ -0,0 +1,170 @@
+Magic-BLAST is a tool for mapping large next-generation RNA or DNA sequencing
+runs against a whole genome or transcriptome. Each alignment optimizes
+a composite score, taking into account simultaneously the two reads of
+a pair, and in case of RNA-seq, locating the candidate introns and adding
+up the score of all exons. This is very different from other versions of
+BLAST, where each exon is scored as a separate hit and read-pairing is
+ignored.
+
+Magic-Blast incorporates within the NCBI BLAST code framework ideas
+developed in the NCBI Magic pipeline, in particular hit extensions by
+local walk and jump, which is faster than Smith-Waterman extension
+(http://www.ncbi.nlm.nih.gov/pubmed/26109056), and recursive clipping of
+mismatches near the edges of the reads, which avoids accumulating
+artefactual mismatches near splice sites and is needed to distinguish
+short indels from substitutions near the edges.
+
+We call the whole next generation run (from Illumina, Roche-454, ABI, or
+another sequencing platform excluding SOLiD), a query. The input reads may
+be provided as SRA accession or file in a SRA, FASTA, FASTQ, or FASTC format.
+Read pairs can be presented as parallel files, or as successive reads in a
+single file.
+
+The reference genome or transcriptome can be given as a BLAST database
+or a FASTA file. It is preferable to use BLAST database for large genomes,
+such as human, or transcript collections, such as all of RefSeq, Ensembl,
+or AceView. The procedure for creating a BLAST database is described below.
+
+The full list of options is listed when you use -help option.
+
+===================
+
+EXAMPLES:
+Use this command line to map RNA-seq reads in FASTA format to a reference
+genome in FASTA format:
+magicblast -query reads.fa -subject genome.fa
+
+Use this command line to map RNA-seq reads to a reference genome provided
+as a BLAST database:
+magicblast -query reads.fa -db genome
+
+Use this command line to map RNA-seq reads in FASTQ format:
+magicblast -query reads.fastq -db genome -infmt fastq
+
+The reads can also be provided from the standard input:
+cat reads.fa | magicblast -query - -db genome
+cat reads.fa | magicblast -db genome
+
+Magic-Blast recognizes read and reference file names with extension ".gz"
+as compressed and decompresses them automatically using gzip.
+
+Use this command line to map SRA run to a genome:
+magicblast -sra sra_accession -db genome
+
+
+
+PAIRED-READS:
+
+For paired reads presented as successive entries in a single FASTA or FASTQ
+file, i.e. read 1 and 2 of fragment 1, then read 1 and 2 of fragment 2,
+etc., simply add the parameter '-paired':
+magicblast -query reads.fa -db genome -paired
+
+If you are using fastq-dump
+(http://www.ncbi.nlm.nih.gov/Traces/sra/sra.cgi?view=toolkit_doc&f=fastq-dump)
+to download NCBI SRA data or convert SRA file to the FASTQ format, use these
+parameters for runs with paired reads to create a single merged input file
+for Magic-Blast:
+fastq-dump -I --split-spot <accession or file>
+
+For paired reads presented in two parallel files, use these options:
+magicblast -query reads.fa -query_mate mates.fa -db genome
+
+
+RNA versus DNA:
+
+By default, Magic-Blast aligns RNA reads to a genome and reports spliced
+alignments, possibly spanning several exons. To disable spliced alignments,
+use the '-splice F' option. Use the '-reftype transcriptome' option, to
+map reads to a transcriptome database. These are example command lines:
+magicblast -query reads.fa -db genome -splice F
+magicblast -query reads.fa -db genome -reftype transcriptome
+
+Magic-Blast finds alignments between a read and a genome based on initial
+common word in both. To make mapping faster we first count word occurrences
+in the genome and disregard those that occur too often. With the
+'-reftype transcripts' option the words that are frequent in the transcript
+database are used for alignment.
+
+
+MULTI-THREADING
+
+To use multiple CPUs, specify the maximal number of threads with the
+'-num_threads' parameter:
+magicblast -query reads.fa -db genome -num_threads 10
+
+
+OUTPUT:
+
+By default, results are provided to the standard output in the SAM format.
+Use '-out filename' option to redirect output to a file.
+Use '-outfmt' option to specify the output format:
+-outfmt SAM : SAM format (default)
+-outfmt tabular : exports a simple tab delimited format defined below.
+
+The output can be also compressed, using the '-gzo' flag:
+magicblast -query reads.fa -db genome -out output.gz -gzo
+
+
+CREATION OF A BLAST DATABASE:
+
+Use this command line to create a BLAST database:
+makeblastdb -in fasta_file -dbtype nucl -parse_seqids -out database_name
+-title "Database title"
+
+The -parse_seqids option is required to keep the original sequence
+identifiers. Otherwise makeblastdb will generate its own identifiers.
+
+
+TABULAR OUTPUT FORMAT
+
+The tabular output format shows one alignment per line with these tab
+delimited fields:
+1. Query/read sequence identifier
+2. Reference sequence identifier
+3. Percent identity of the alignment
+4. Not used
+5. Not used
+6. Not used
+7. Alignment start position on the query sequence
+8. Alignment stop position on the query sequence
+9. Alignment start position on the reference sequence
+10. Alignment stop position on the reference sequence
+11. Not used
+12. Not used
+13. Alignment score
+14. Query strand
+15. Reference sequence strand
+16. Query/read length
+17. Alignment as extended BTOP string
+    This is the same BTOP string as in BLAST tabular output with a
+    few extensions:
+    - a number represents this many matches,
+    - two bases represent a mismatch and show query and reference base,
+    - base and gap or gap and base, show a gap in query or reference,
+    - ^<number>^ represents an intron of this number of bases,
+    - _<number>_ represents a gap in query of this number of bases,
+    - (<number>) shows number of query bases that are shared between
+    two parts of a spliced alignment; used when proper splice sites
+    were not found
+18. Number of different alignments reported for this query sequence
+19. Information about detected splice sites, polyA tails, or adapter
+    sequences found at the edges of the alignment
+20. Compartment - a unique identifier for all alignments that belong to
+    a single fragment. These can be two alignments for a pair of reads
+    or alignments to exons that were not spliced.
+21. Reverse complemented unaligned query sequence from the beginning
+    of the query, or '-' if the query aligns to the left edge
+22. Unaligned sequence at the end of the query, or '-'
+23. Reference sequence identifier where the mate is aligned, if
+    different from the identifier in column 2, otherwise '-'
+24. Alignment start position on the reference sequence for the mate, or
+    '-' if no alignment for the mate was found; a negative number
+    denotes a divergent pair
+25. Composite alignment score for all exons that belong to the fragment
+
+Thank you for testing this code and providing us with feedback. Please,
+let us know of any desired option, problem or difficulty.
+
+E-mail boratyng at ncbi.nlm.nih.gov or blast-help at ncbi.nlm.nih.gov with
+questions or comments.
diff --git a/c++/scripts/projects/magicblast/components.link b/c++/scripts/projects/magicblast/components.link
new file mode 100644
index 0000000..86d2dd2
--- /dev/null
+++ b/c++/scripts/projects/magicblast/components.link
@@ -0,0 +1,9 @@
+[components]
+infrastructure  18.0
+core            18.0
+dbase           18.0
+web             18.0
+objects         18.0
+objtools        18.0
+algo            18.0
+app             18.0
diff --git a/c++/scripts/projects/magicblast/post_build/blast_utils.py b/c++/scripts/projects/magicblast/post_build/blast_utils.py
new file mode 100644
index 0000000..2209bef
--- /dev/null
+++ b/c++/scripts/projects/magicblast/post_build/blast_utils.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python3
+""" Various utilities/tools for BLAST """
+from __future__ import print_function
+
+__all__ = ["safe_exec", "update_blast_version"]
+
+import os
+import subprocess
+import platform
+import unittest
+import tempfile
+import re
+
+
+def safe_exec(cmd):
+    """ Executes a command and checks its return value, throwing an
+        exception if it fails.
+    """
+    try:
+        msg = "Command: '" + cmd + "' "
+        retcode = subprocess.call(cmd, shell=True)
+        if retcode < 0:
+            msg += "Termined by signal " + str(-retcode)
+            raise RuntimeError(msg)
+        elif retcode != 0:
+            msg += "Failed with exit code " + str(retcode)
+            raise RuntimeError(msg)
+    except OSError as err:
+        msg += "Execution failed: " + err
+        raise RuntimeError(msg)
+
+
+class Tester(unittest.TestCase):
+    '''Testing class for this script.'''
+    def test_one(self):
+        ver = "2.3.0"
+        line1 = "Hello BLAST"
+        with tempfile.NamedTemporaryFile(mode='w+t') as fp:
+            print(line1, file=fp)
+            print("BLAST_VERSION", file=fp)
+            print(line1, file=fp, flush=True)
+
+            update_blast_version(fp.name, ver)
+
+            fp.seek(0)
+            line = fp.readline().rstrip()
+            self.assertEqual(line1, line)
+            line = fp.readline().rstrip()
+            self.assertEqual(ver, line)
+            line = fp.readline().rstrip()
+            self.assertEqual(line1, line)
+
+
+def update_blast_version(config_file, ver):
+    """Updates the BLAST version in the specified file.
+
+    Assumes the specified file contains the string BLAST_VERSION, which will
+    be replaced by the contents of the variable passed to this function.
+    """
+    (fd, fname) = tempfile.mkstemp()
+    try:
+        with open(config_file, "r") as infile, open(fname, "w") as out:
+            for line in infile:
+                newline = re.sub("BLAST_VERSION", ver, line.rstrip())
+                print(newline, file=out)
+
+        with open(config_file, "w") as out, open(fname, "r") as infile:
+            for line in infile:
+                print(line.rstrip(), file=out)
+    finally:
+        os.close(fd)
+        os.remove(fname)
+
+
+def create_new_tarball_name(platform, program, version):
+    """ Converts the name of a platform as specified to the prepare_release
+    framework to an archive name according to BLAST release naming conventions.
+
+    Note: the platform names come from the prepare_release script conventions,
+    more information can be found in http://mini.ncbi.nih.gov/3oo
+    """
+
+    retval = "ncbi-" + program + "-" + version
+    if program == "blast":
+        retval += "+"
+    if platform.startswith("Win"):
+        retval += "-x64-win64"
+    elif platform.startswith("Linux32"):
+        retval += "-ia32-linux"
+    elif platform.startswith("Linux64"):
+        retval += "-x64-linux"
+    elif platform.startswith("IntelMAC"):
+        retval += "-x64-macosx"
+    elif platform == "SunOSSparc":
+        retval += "-sparc64-solaris"
+    elif platform == "SunOSx86":
+        retval += "-x64-solaris"
+    else:
+        raise RuntimeError("Unknown platform: " + platform)
+    return retval
+
+
+def determine_platform():
+    """ Determines the platform (as defined in prepare_release) for the current
+    hostname
+    """
+
+    p = platform.platform().lower()
+    print("PLATFORM = " + p)
+    if p.find("linux") != -1:
+        if p.find("x86_64") != -1:
+            return "Linux64"
+        else:
+            return "Linux32"
+    elif p.find("sunos") != -1:
+        if p.find("sparc") != -1:
+            return "SunOSSparc"
+        else:
+            return "SunOSx86"
+    elif p.find("windows") != -1 or p.find("cygwin") != -1:
+        if platform.architecture()[0].find("64") != -1:
+            return "Win64"
+        else:
+            return "Win32"
+    elif p.find("darwin") != -1:
+        return "IntelMAC"
+    else:
+        raise RuntimeError("Unknown platform: " + p)
diff --git a/c++/scripts/projects/magicblast/post_build/macosx/large-Blue_ncbi_logo.tiff b/c++/scripts/projects/magicblast/post_build/macosx/large-Blue_ncbi_logo.tiff
new file mode 100644
index 0000000..9408bc3
Binary files /dev/null and b/c++/scripts/projects/magicblast/post_build/macosx/large-Blue_ncbi_logo.tiff differ
diff --git a/c++/scripts/projects/magicblast/post_build/macosx/ncbi-magicblast.sh b/c++/scripts/projects/magicblast/post_build/macosx/ncbi-magicblast.sh
new file mode 100755
index 0000000..2d4bbcc
--- /dev/null
+++ b/c++/scripts/projects/magicblast/post_build/macosx/ncbi-magicblast.sh
@@ -0,0 +1,86 @@
+#!/bin/sh -xe
+
+INSTALLDIR=$1
+SCRIPTDIR=$2
+BLAST_VERSION=$3
+PRODUCT="ncbi-magicblast-$BLAST_VERSION+"
+
+INSTALL_LOCATION1=/usr/local/ncbi/magicblast
+INSTALL_LOCATION2=/etc/paths.d
+STAGE_DIR1=_stage1
+STAGE_DIR2=_stage2
+RESOURCES_DIR=Resources
+ID=gov.nlm.nih.ncbi.blast
+
+if [ $# -ne 3 ] ; then
+    echo "Usage: ncbi-magicblast.sh [installation directory] [MacOSX post-build script directory] [BLAST version]";
+    exit 1;
+fi
+
+setup()
+{
+    rm -rf $PRODUCT.dmg $PRODUCT $STAGE_DIR1 $STAGE_DIR2 $INSTALLDIR/installer $RESOURCES_DIR
+    mkdir -p $STAGE_DIR1/bin $STAGE_DIR1/doc $STAGE_DIR2 $PRODUCT
+}
+
+prep_binary_component_package() 
+{
+    BLAST_BINS="magicblast makeblastdb"
+    ALL_BINS="$BLAST_BINS"
+
+    cp $INSTALLDIR/README $STAGE_DIR1/doc/README.txt
+
+    for bin in $ALL_BINS; do
+        cp -p $INSTALLDIR/bin/$bin $STAGE_DIR1/bin
+    done
+
+    /usr/bin/pkgbuild --root $STAGE_DIR1 --identifier $ID.binaries --version \
+        $BLAST_VERSION --install-location $INSTALL_LOCATION1 binaries.pkg
+}
+
+prep_paths_component_package()
+{
+    echo /usr/local/ncbi/magicblast/bin > $STAGE_DIR2/ncbi_magicblast
+    /usr/bin/pkgbuild --root $STAGE_DIR2 --identifier $ID.paths --version \
+        $BLAST_VERSION --install-location $INSTALL_LOCATION2 paths.pkg
+}
+
+customize_distribution_xml()
+{
+    sed -i.bak '/options/i\
+    <title>NCBI Magic-BLAST Command Line Applications</title> \
+    <welcome file="welcome.txt" mime-type="text/plain"/> \
+    <license file="LICENSE" mime-type="text/plain"/> \
+    <background scaling="proportional" alignment="left" file="large-Blue_ncbi_logo.tiff" mime-type="image/tiff"/> \
+' Distribution.xml 
+}
+
+create_product_archive()
+{
+	/usr/bin/productbuild --synthesize --identifier $ID --version \
+    $BLAST_VERSION --package binaries.pkg --package paths.pkg Distribution.xml
+
+    customize_distribution_xml
+
+    mkdir $RESOURCES_DIR
+    cp -p $INSTALLDIR/LICENSE $RESOURCES_DIR
+    for f in welcome.txt large-Blue_ncbi_logo.tiff ; do
+        cp -p $SCRIPTDIR/$f $RESOURCES_DIR
+    done
+
+	/usr/bin/productbuild --resources Resources --distribution Distribution.xml $PRODUCT/$PRODUCT.pkg
+    cp -p $SCRIPTDIR/uninstall_ncbi_magicblast.zip $PRODUCT
+}
+
+create_disk_image()
+{
+	/usr/bin/hdiutil create $PRODUCT.dmg -srcfolder $PRODUCT
+    mkdir $INSTALLDIR/installer
+    mv $PRODUCT.dmg $INSTALLDIR/installer
+}
+
+setup
+prep_binary_component_package
+prep_paths_component_package
+create_product_archive
+create_disk_image
diff --git a/c++/scripts/projects/magicblast/post_build/macosx/uninstall_ncbi_magicblast.zip b/c++/scripts/projects/magicblast/post_build/macosx/uninstall_ncbi_magicblast.zip
new file mode 100644
index 0000000..679a404
Binary files /dev/null and b/c++/scripts/projects/magicblast/post_build/macosx/uninstall_ncbi_magicblast.zip differ
diff --git a/c++/scripts/projects/magicblast/post_build/macosx/welcome.txt b/c++/scripts/projects/magicblast/post_build/macosx/welcome.txt
new file mode 100644
index 0000000..3202f0d
--- /dev/null
+++ b/c++/scripts/projects/magicblast/post_build/macosx/welcome.txt
@@ -0,0 +1,2 @@
+NCBI Magic-BLAST is a specialized variant of BLAST designed for mapping
+next-generation RNA or DNA sequencing runs against a genome or transcriptome.
diff --git a/c++/scripts/projects/magicblast/post_build/make_installers.py b/c++/scripts/projects/magicblast/post_build/make_installers.py
new file mode 100755
index 0000000..c0d9b13
--- /dev/null
+++ b/c++/scripts/projects/magicblast/post_build/make_installers.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python3
+"""Driver program for post-build processing"""
+# $Id: make_installers.py 513315 2016-09-09 13:58:57Z boratyng $
+#
+# Author: Christiam Camacho
+#
+
+from __future__ import print_function
+import os, sys, os.path
+from optparse import OptionParser
+import blast_utils
+import shutil
+
+VERBOSE = False
+SCRIPTS_DIR = os.path.dirname(os.path.abspath(sys.argv[0]))
+
+def main(): #IGNORE:R0911
+    """ Creates installers for selected platforms. """
+    parser = OptionParser("%prog <blast_version> <platform> \
+                          <installation directory> \"<src-tarball>\"")
+    parser.add_option("-v", "--verbose", action="store_true", default=False,
+                      help="Show verbose output", dest="VERBOSE")
+    options, args = parser.parse_args()
+    if len(args) != 5:
+        parser.error("Incorrect number of arguments")
+        return 1
+
+    blast_version, platform, installdir, srctarball, libdir = args
+
+    global VERBOSE #IGNORE:W0603
+    VERBOSE = options.VERBOSE
+    if VERBOSE:
+        print("BLAST version", blast_version)
+        print("Platform:", platform)
+        print("Installation directory:", installdir)
+        print("Source tarball:", srctarball)
+        print("Lib directory:", libdir)
+
+    if platform.startswith("Win"):
+        import glob
+        print("Files in libdir " + libdir + ":")
+        for dll in glob.glob(libdir + "/*"):
+            print(dll)
+        print("Files in install dir " + installdir + ":")
+        for dll in glob.glob(installdir + "/*"):
+            print(dll)
+
+
+    if platform.startswith("Win"):
+        # copy ncbi-vdb-md.dll and GNUTLS libs
+        shutil.copy(libdir + "ncbi-vdb-md.dll", installdir + "bin")
+        shutil.copy(libdir + "libgcc_s_seh-1.dll", installdir + "bin")
+        shutil.copy(libdir + "libgmp-10.dll", installdir + "bin")
+        shutil.copy(libdir + "libgnutls-30.dll", installdir + "bin")
+        shutil.copy(libdir + "libhogweed-4-2.dll", installdir + "bin")
+        shutil.copy(libdir + "libnettle-6-2.dll", installdir + "bin")
+        shutil.copy(libdir + "libp11-kit-0.dll", installdir + "bin")
+        return launch_win_installer_build(installdir, blast_version)
+    if platform.startswith("Linux64"):
+        return launch_rpm_build(installdir, blast_version, srctarball)
+    if platform == "FreeBSD32" or platform.startswith("SunOS") or \
+           platform.startswith("Linux32"):
+        return do_nothing(platform)
+    if platform.startswith("IntelMAC"):
+        return mac_post_build(installdir, blast_version)
+
+    print("Unknown OS identifier:" + platform, file=sys.stderr)
+    print("Exiting post build script.", file=sys.stderr)
+    return 2
+
+def launch_win_installer_build(installdir, blast_version):
+    '''Windows post-build: create installer'''
+    if VERBOSE: 
+        print("Packaging for Windows...")
+    cmd = "python " + os.path.join(SCRIPTS_DIR, "win", "make_win.py") + " "
+    cmd += blast_version + " " + installdir
+    if VERBOSE: 
+        cmd += " -v"
+    blast_utils.safe_exec(cmd)
+    return 0
+
+def launch_rpm_build(installdir, blast_version, srctarball):
+    '''Linux post-build: create RPM'''
+    if VERBOSE: 
+        print("Packing linux RPM...")
+    cmd = "python3 " + os.path.join(SCRIPTS_DIR, "rpm", "make_rpm.py") + " "
+    cmd += blast_version + " " + installdir + " " + srctarball
+    if VERBOSE: 
+        cmd += " -v"
+    if len(srctarball) > 2:     # Skip for local builds
+        blast_utils.safe_exec(cmd)
+    return 0
+
+def mac_post_build(installdir, blast_version):
+    '''MacOSX post-build: create installer'''
+    if VERBOSE:
+        print("Packaging for MacOSX...")
+    script_dir = os.path.join(SCRIPTS_DIR, "macosx")
+    cmd = os.path.join(script_dir, "ncbi-magicblast.sh") + " "
+    cmd += installdir + " " + script_dir + " " + blast_version
+    blast_utils.safe_exec(cmd)
+    return 0
+
+def do_nothing(platform):
+    '''No op function'''
+    print("No post-build step necessary for", platform)
+    return 0
+
+# The script execution entry point
+if __name__ == "__main__":
+    sys.exit( main() )
+
diff --git a/c++/scripts/projects/magicblast/post_build/rpm/make_rpm.py b/c++/scripts/projects/magicblast/post_build/rpm/make_rpm.py
new file mode 100755
index 0000000..829ce9c
--- /dev/null
+++ b/c++/scripts/projects/magicblast/post_build/rpm/make_rpm.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python3
+"""Script to create a source/binary RPM.
+"""
+# $Id: make_rpm.py 509841 2016-08-09 16:23:05Z boratyng $
+
+from __future__ import print_function
+import sys, os, shutil
+from optparse import OptionParser
+import subprocess
+import tarfile
+SCRIPT_DIR = os.path.dirname(os.path.abspath(sys.argv[0]))
+sys.path.append(os.path.join(SCRIPT_DIR, ".."))
+from blast_utils import *   #IGNORE:W0401
+
+VERBOSE = False
+
+# Name of the temporary rpmbuild directory
+RPMBUILD_HOME = "rpmbuild"
+PACKAGE_NAME = ""
+# Name of the source TARBALL to create
+TARBALL = ""
+# Local RPM configuration file
+RPMMACROS = os.path.join(os.path.expanduser("~"), ".rpmmacros")
+
+def setup_rpmbuild():
+    """ Prepare local rpmbuild directory. """
+    cleanup_rpm()
+    os.mkdir(RPMBUILD_HOME)
+    for directory in [ 'BUILD', 'SOURCES', 'SPECS', 'SRPMS', 'tmp', 'RPMS' ]:
+        os.mkdir(os.path.join(RPMBUILD_HOME, directory))
+    cwd = os.getcwd()
+    os.chdir(os.path.join(RPMBUILD_HOME, 'RPMS'))
+    for subdir in [ 'i386', 'i586', 'i686', 'noarch', 'x86_64' ]:
+        os.mkdir(subdir)
+    os.chdir(cwd)
+
+    # Create ~/.rpmmacros
+    with open(RPMMACROS, "w") as out:
+        print("%_topdir %( echo", os.path.join(cwd, RPMBUILD_HOME), ")", file=out)
+        print("%_tmppath %( echo", end=' ', file=out) 
+        print(os.path.join(cwd, RPMBUILD_HOME, "tmp"), ")", file=out)
+        print(file=out)
+        print("%packager Christiam E. Camacho (camacho at ncbi.nlm.nih.gov)", file=out)
+        print("%debug_package %{nil}", file=out)
+        if VERBOSE: 
+            print("Created", RPMMACROS)
+
+def cleanup_rpm():
+    """ Delete rpm files """
+    if os.path.exists(RPMBUILD_HOME):
+        shutil.rmtree(RPMBUILD_HOME)
+
+    if os.path.exists(RPMMACROS):
+        os.remove(RPMMACROS)
+
+def cleanup_srctarball_contents():
+    """ Remove unnecessary directories/files from svn checkout """
+    import fnmatch
+           
+    cmd = "find " + PACKAGE_NAME + " -type d -name .svn | xargs rm -fr "
+    safe_exec(cmd) 
+        
+    os.remove(os.path.join(PACKAGE_NAME, "Makefile"))
+    for path in ["builds", "scripts"]:
+        path = os.path.join(PACKAGE_NAME, path)
+        if os.path.exists(path):
+            shutil.rmtree(path)
+            if VERBOSE: 
+                print("Deleting", path)
+               
+    projects_path = os.path.join(PACKAGE_NAME, "c++", "scripts", "projects")
+    for root, dirs, files in os.walk(projects_path): 
+        for name in files:
+            name = os.path.join(root, name)
+            if fnmatch.fnmatch(name, "*blast/*"): 
+                continue
+            if VERBOSE:
+                print("Deleting file", name)
+            os.remove(name)
+            
+        for name in dirs:
+            name = os.path.join(root, name)
+            if fnmatch.fnmatch(name, "*blast*"):
+                continue
+            if VERBOSE: 
+                print("Deleting directory", name)
+            shutil.rmtree(name)
+            
+
+def decompress_src_tarball(srctarball):
+    """Decompreses the source tarball provided"""
+    tar = tarfile.open(srctarball)
+    os.mkdir(PACKAGE_NAME)
+    cwd = os.getcwd()
+    os.chdir(os.path.join(cwd, PACKAGE_NAME))
+    tar.list()
+    tar.extractall()
+    os.chdir(cwd)
+    cleanup_srctarball_contents()
+
+def compress_sources():
+    """Compress sources to be included in source RPM"""
+    tar = tarfile.open(TARBALL, "w:bz2")
+    tar.add(PACKAGE_NAME)
+    tar.close()
+
+def cleanup():
+    """ Remove all files created. """
+    if os.path.exists(TARBALL):
+        os.remove(TARBALL)
+    if os.path.exists(PACKAGE_NAME):
+        shutil.rmtree(PACKAGE_NAME)
+
+def run_rpm(blast_version):
+    """Run the rpmbuild command"""
+    shutil.rmtree(PACKAGE_NAME)
+    shutil.move(TARBALL, os.path.join(RPMBUILD_HOME, "SOURCES"))
+    rpm_spec = "ncbi-magicblast.spec"
+    src = os.path.join(SCRIPT_DIR, rpm_spec)
+    dest = os.path.join(RPMBUILD_HOME, "SPECS", rpm_spec)
+    shutil.copyfile(src, dest)
+    update_blast_version(dest, blast_version)
+    cmd = "/usr/bin/rpmbuild -ba " + dest
+    safe_exec(cmd)
+
+def move_rpms_to_installdir(installdir):
+    """Copy the resulting RPM files into the installation directory"""
+    installer_dir = os.path.join(installdir, "installer")
+    if not os.path.exists(installer_dir):
+        os.makedirs(installer_dir)
+        
+    args = [ "find", RPMBUILD_HOME, "-name", "*.rpm" ]
+    output = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0]
+    for rpm in output.split():
+        rpm = rpm.decode('ascii')
+        if VERBOSE: 
+            print("mv", rpm, installer_dir)
+        shutil.move(rpm, installer_dir)
+
+
+def main():
+    """ Creates RPMs for linux. """
+    parser = OptionParser("%prog <blast_version> <installation directory> \
+                          \"<srctarball>\"")
+    parser.add_option("-v", "--verbose", action="store_true", default=False,
+                      help="Show verbose output", dest="VERBOSE")
+    options, args = parser.parse_args()
+    if len(args) != 3:
+        parser.error("Incorrect number of arguments")
+        return 1
+    
+    # N.B.: srctarball may be an empty argument (i.e.: "") in case of local
+    # builds, but this script shouldn't be invoked in that case
+    blast_version, installdir, srctarball = args
+    global VERBOSE, PACKAGE_NAME, TARBALL #IGNORE:W0603
+    VERBOSE = options.VERBOSE
+    if VERBOSE: 
+        print("Installing RPM to", installdir)
+        
+    PACKAGE_NAME = "ncbi-magicblast-" + blast_version
+    TARBALL = PACKAGE_NAME + ".tgz"
+    
+    setup_rpmbuild()
+    cleanup()
+    decompress_src_tarball(srctarball)
+    compress_sources()
+    run_rpm(blast_version)
+    move_rpms_to_installdir(installdir)
+    cleanup_rpm()
+    cleanup()
+    
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/c++/scripts/projects/magicblast/post_build/rpm/ncbi-magicblast.spec b/c++/scripts/projects/magicblast/post_build/rpm/ncbi-magicblast.spec
new file mode 100644
index 0000000..d7cadef
--- /dev/null
+++ b/c++/scripts/projects/magicblast/post_build/rpm/ncbi-magicblast.spec
@@ -0,0 +1,41 @@
+Name:        ncbi-magicblast
+Version:     BLAST_VERSION
+Release:     1
+Source0:     %{name}-%{version}.tgz
+Summary:     NCBI Magic-BLAST is a tool for mapping next-generation RNA or DNA sequencing runs against a genome or transcriptome. 
+Exclusiveos: linux
+Group:       NCBI/BLAST
+License:     Public Domain
+BuildArch:   i686 x86_64
+BuildRoot:   /var/tmp/%{name}-buildroot
+Prefix:      /usr
+
+Requires:    ncbi-blast
+
+%description
+NCBI Magic-BLAST is a specialized variant of BLAST designed for mapping
+next-generation RNA or DNA sequencing runs against a genome or transcriptome.
+
+%prep 
+%setup -q
+
+%build
+./configure
+cd c++/*/build
+%__make -f Makefile.flat
+
+%install
+%__mkdir_p $RPM_BUILD_ROOT/%_bindir
+%__install -m755 c++/*/bin/magicblast $RPM_BUILD_ROOT/%_bindir
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+%_bindir/*
+
+%changelog
+* Fri Aug 19 2016 <blast-help at ncbi.nlm.nih.gov>
+- See ChangeLog file
+
diff --git a/c++/scripts/projects/magicblast/post_build/win/EnvVarUpdate.nsh b/c++/scripts/projects/magicblast/post_build/win/EnvVarUpdate.nsh
new file mode 100644
index 0000000..4148114
--- /dev/null
+++ b/c++/scripts/projects/magicblast/post_build/win/EnvVarUpdate.nsh
@@ -0,0 +1,568 @@
+; Obtained from http://nsis.sourceforge.net/Path_Manipulation on 08/14/08
+!ifndef ENVVARUPDATE_FUNCTION
+!define ENVVARUPDATE_FUNCTION
+!verbose push
+!verbose 3
+!include "LogicLib.nsh"
+!include "WinMessages.NSH"
+ 
+; ---------------------------------- Macro Definitions ----------------------------------------
+!macro _EnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString
+  Push "${EnvVarName}"
+  Push "${Action}"
+  Push "${RegLoc}"
+  Push "${PathString}"
+    Call EnvVarUpdate
+  Pop "${ResultVar}"
+!macroend
+!define EnvVarUpdate '!insertmacro "_EnvVarUpdateConstructor"'
+ 
+!macro _unEnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString
+  Push "${EnvVarName}"
+  Push "${Action}"
+  Push "${RegLoc}"
+  Push "${PathString}"
+    Call un.EnvVarUpdate
+  Pop "${ResultVar}"
+!macroend
+!define un.EnvVarUpdate '!insertmacro "_unEnvVarUpdateConstructor"'
+ 
+!macro _StrTokConstructor ResultVar String Separators ResultPart SkipEmptyParts
+  Push "${String}"
+  Push "${Separators}"
+  Push "${ResultPart}"
+  Push "${SkipEmptyParts}"
+   Call ${UN}StrTok
+  Pop "${ResultVar}"
+!macroend
+!define StrTok '!insertmacro "_StrTokConstructor"'
+ 
+!macro _StrContainsConstructor OUT NEEDLE HAYSTACK
+  Push "${HAYSTACK}"
+  Push "${NEEDLE}"
+   Call ${UN}StrContains
+  Pop "${OUT}"
+!macroend
+!define StrContains '!insertmacro "_StrContainsConstructor"'
+ 
+!macro _strReplaceConstructor OUT NEEDLE NEEDLE2 HAYSTACK
+  Push "${HAYSTACK}"
+  Push "${NEEDLE}"
+  Push "${NEEDLE2}"
+   Call ${UN}StrReplace
+  Pop "${OUT}"
+!macroend
+!define StrReplace '!insertmacro "_strReplaceConstructor"'
+ 
+; ---------------------------------- Macro Definitions end-------------------------------------
+ 
+;----------------------------------- EnvVarUpdate start----------------------------------------
+!define hklm_all_users     'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
+!define hkcu_current_user  'HKCU "Environment"'
+ 
+!macro EnvVarUpdate UN
+ 
+Function ${UN}EnvVarUpdate
+ 
+  Push $0
+  Exch 4
+  Exch $1
+  Exch 3
+  Exch $2
+  Exch 2
+  Exch $3
+  Exch
+  Exch $4
+  Push $5
+  Push $6
+  Push $7
+  Push $8
+  Push $9
+  Push $R0
+ 
+  /* After this point:
+  -------------------------
+     $0 = ResultVar     (returned)
+     $1 = EnvVarName    (input)
+     $2 = Action        (input)
+     $3 = RegLoc        (input)
+     $4 = PathString    (input)
+     $5 = Orig EnvVar   (read from registry)
+     $6 = Len of $0     (temp)
+     $7 = tempstr1      (temp)
+     $8 = Entry counter (temp)
+     $9 = tempstr2      (temp)
+     $R0 = tempChar     (temp)  */
+ 
+  ; Step 1:  Read contents of EnvVarName from RegLoc
+  ;
+  ; Check for empty EnvVarName
+  ${If} $1 == ""
+    SetErrors
+    DetailPrint "ERROR: EnvVarName is blank"
+    Goto EnvVarUpdate_Restore_Vars
+  ${EndIf}
+ 
+  ; Check for valid Action
+  ${If}    $2 != "A"
+  ${AndIf} $2 != "P"
+  ${AndIf} $2 != "R"
+    SetErrors
+    DetailPrint "ERROR: Invalid Action - must be A, P, or R"
+    Goto EnvVarUpdate_Restore_Vars
+  ${EndIf}
+ 
+  ${If} $3 == HKLM
+    ReadRegStr $5 ${hklm_all_users} $1     ; Get EnvVarName from all users into $5
+  ${ElseIf} $3 == HKCU
+    ReadRegStr $5 ${hkcu_current_user} $1  ; Read EnvVarName from current user into $5
+  ${Else}
+    SetErrors
+    DetailPrint 'ERROR: Action is [$3] but must be "HKLM" or HKCU"'
+    Goto EnvVarUpdate_Restore_Vars
+  ${EndIf}
+ 
+  ; Check for empty PathString
+  ${If} $4 == ""
+    SetErrors
+    DetailPrint "ERROR: PathString is blank"
+    Goto EnvVarUpdate_Restore_Vars
+  ${EndIf}
+ 
+  ; Make sure we've got some work to do
+  ${If} $5 == ""
+  ${AndIf} $2 == "R"
+    SetErrors
+    DetailPrint "$1 is empty - Nothing to remove"
+    Goto EnvVarUpdate_Restore_Vars
+  ${EndIf}
+ 
+  ; Step 2: Scrub EnvVar
+  ;
+  StrCpy $0 $5                             ; Copy the contents to $0
+  ; Remove spaces around semicolons (NOTE: spaces before the 1st entry or
+  ; after the last one are not removed here but instead in Step 3)
+  ${If} $0 != ""                           ; If EnvVar is not empty ...
+    ${Do}
+      ${StrContains} $7 " ;" $0
+      ${If} $7 == ""
+        ${ExitDo}
+      ${EndIf}
+      ${StrReplace} $0 " ;" ";" $0         ; Remove '<space>;'
+    ${Loop}
+    ${Do}
+      ${StrContains} $7 "; " $0
+      ${If} $7 == ""
+        ${ExitDo}
+      ${EndIf}
+      ${StrReplace} $0 "; " ";" $0         ; Remove ';<space>'
+    ${Loop}
+    ${Do}
+      ${StrContains} $7 ";;" $0
+      ${If} $7 == ""
+        ${ExitDo}
+      ${EndIf}
+      ${StrReplace} $0 ";;" ";" $0
+    ${Loop}
+ 
+    ; Remove a leading or trailing semicolon from EnvVar
+    StrCpy  $7  $0 1 0
+    ${If} $7 == ";"
+      StrCpy $0  $0 "" 1                   ; Change ';<EnvVar>' to '<EnvVar>'
+    ${EndIf}
+    StrLen $6 $0
+    IntOp $6 $6 - 1
+    StrCpy $7  $0 1 $6
+    ${If} $7 == ";"
+     StrCpy $0  $0 $6                      ; Change ';<EnvVar>' to '<EnvVar>'
+    ${EndIf}
+    ; DetailPrint "Scrubbed $1: [$0]"      ; Uncomment to debug
+  ${EndIf}
+ 
+  /* Step 3. Remove all instances of the target path/string (even if "A" or "P")
+     $6 = bool flag (1 = found and removed PathString)
+     $7 = a string (e.g. path) delimited by semicolon(s)
+     $8 = entry counter starting at 0
+     $9 = copy of $0
+     $R0 = tempChar      */
+ 
+  ${If} $5 != ""                           ; If EnvVar is not empty ...
+    StrCpy $9 $0
+    StrCpy $0 ""
+    StrCpy $8 0
+    StrCpy $6 0
+ 
+    ${Do}
+      ${StrTok} $7 $9 ";" $8 "0"      ; $7 = next entry, $8 = entry counter
+ 
+      ${If} $7 == ""                       ; If we've run out of entries,
+        ${ExitDo}                          ;    were done
+      ${EndIf}                             ;
+ 
+      ; Remove leading and trailing spaces from this entry (critical step for Action=Remove)
+      ${Do}
+        StrCpy $R0  $7 1
+        ${If} $R0 != " "
+          ${ExitDo}
+        ${EndIf}
+        StrCpy $7   $7 "" 1                ;  Remove leading space
+      ${Loop}
+      ${Do}
+        StrCpy $R0  $7 1 -1
+        ${If} $R0 != " "
+          ${ExitDo}
+        ${EndIf}
+        StrCpy $7   $7 -1                  ;  Remove trailing space
+      ${Loop}
+      ${If} $7 == $4                       ; If string matches, remove it by not appending it
+        StrCpy $6 1                        ; Set 'found' flag
+      ${ElseIf} $7 != $4                   ; If string does NOT match
+      ${AndIf}  $0 == ""                   ;    and the 1st string being added to $0,
+        StrCpy $0 $7                       ;    copy it to $0 without a prepended semicolon
+      ${ElseIf} $7 != $4                   ; If string does NOT match
+      ${AndIf}  $0 != ""                   ;    and this is NOT the 1st string to be added to $0,
+        StrCpy $0 $0;$7                    ;    append path to $0 with a prepended semicolon
+      ${EndIf}                             ;
+ 
+      IntOp $8 $8 + 1                      ; Bump counter
+    ${Loop}                                ; Check for duplicates until we run out of paths
+  ${EndIf}
+ 
+  ; Step 4:  Perform the requested Action
+  ;
+  ${If} $2 != "R"                          ; If Append or Prepend
+    ${If} $6 == 1                          ; And if we found the target
+      DetailPrint "Target is already present in $1. It will be removed and"
+    ${EndIf}
+    ${If} $0 == ""                         ; If EnvVar is (now) empty
+      StrCpy $0 $4                         ;   just copy PathString to EnvVar
+      ${If} $6 == 0                        ; If found flag is either 0
+      ${OrIf} $6 == ""                     ; or blank (if EnvVarName is empty)
+        DetailPrint "$1 was empty and has been updated with the target"
+      ${EndIf}
+    ${ElseIf} $2 == "A"                    ;  If Append (and EnvVar is not empty),
+      StrCpy $0 $0;$4                      ;     append PathString
+      ${If} $6 == 1
+        DetailPrint "appended to $1"
+      ${Else}
+        DetailPrint "Target was appended to $1"
+      ${EndIf}
+    ${Else}                                ;  If Prepend (and EnvVar is not empty),
+      StrCpy $0 $4;$0                      ;     prepend PathString
+      ${If} $6 == 1
+        DetailPrint "prepended to $1"
+      ${Else}
+        DetailPrint "Target was prepended to $1"
+      ${EndIf}
+    ${EndIf}
+  ${Else}                                  ; If Action = Remove
+    ${If} $6 == 1                          ;   and we found the target
+      DetailPrint "Target was found and removed from $1"
+    ${Else}
+      DetailPrint "Target was NOT found in $1 (nothing to remove)"
+    ${EndIf}
+    ${If} $0 == ""
+      DetailPrint "$1 is now empty"
+    ${EndIf}
+  ${EndIf}
+ 
+  ; Step 5:  Update the registry at RegLoc with the updated EnvVar and announce the change
+  ;
+  ClearErrors
+  ${If} $3  == HKLM
+    WriteRegExpandStr ${hklm_all_users} $1 $0     ; Write it in all users section
+  ${ElseIf} $3 == HKCU
+    WriteRegExpandStr ${hkcu_current_user} $1 $0  ; Write it to current user section
+  ${EndIf}
+ 
+  IfErrors 0 +4
+    MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3"
+    DetailPrint "Could not write updated $1 to $3"
+    Goto EnvVarUpdate_Restore_Vars
+ 
+  ; "Export" our change
+  SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+ 
+  EnvVarUpdate_Restore_Vars:
+  ;
+  ; Restore the user's variables and return ResultVar
+  Pop $R0
+  Pop $9
+  Pop $8
+  Pop $7
+  Pop $6
+  Pop $5
+  Pop $4
+  Pop $3
+  Pop $2
+  Pop $1
+  Push $0  ; Push my $0 (ResultVar)
+  Exch
+  Pop $0   ; Restore his $0
+ 
+FunctionEnd
+ 
+!macroend   ; EnvVarUpdate UN
+!insertmacro EnvVarUpdate ""
+!insertmacro EnvVarUpdate "un."
+;----------------------------------- EnvVarUpdate end----------------------------------------
+ 
+ 
+;-------------------------------------- StrTok start ------------------------------------------
+; Written by Diego Pedroso (deguix)
+;
+!macro StrTok UN
+ 
+Function ${UN}StrTok
+ 
+/*After this point:
+  ------------------------------------------
+  $0 = SkipEmptyParts (input)
+  $1 = ResultPart (input)
+  $2 = Separators (input)
+  $3 = String (input)
+  $4 = SeparatorsLen (temp)
+  $5 = StrLen (temp)
+  $6 = StartCharPos (temp)
+  $7 = TempStr (temp)
+  $8 = CurrentLoop
+  $9 = CurrentSepChar
+  $R0 = CurrentSepCharNum  */
+ 
+  ;Get input from user
+  Exch $0
+  Exch
+  Exch $1
+  Exch
+  Exch 2
+  Exch $2
+  Exch 2
+  Exch 3
+  Exch $3
+  Exch 3
+  Push $4
+  Push $5
+  Push $6
+  Push $7
+  Push $8
+  Push $9
+  Push $R0
+ 
+  ;Parameter defaults
+  ${IfThen} $2 == `` ${|} StrCpy $2 `|` ${|}
+  ${IfThen} $1 == `` ${|} StrCpy $1 `L` ${|}
+  ${IfThen} $0 == `` ${|} StrCpy $0 `0` ${|}
+ 
+  ;Get "String" and "Separators" length
+  StrLen $4 $2
+  StrLen $5 $3
+  ;Start "StartCharPos" and "ResultPart" counters
+  StrCpy $6 0
+  StrCpy $8 -1
+ 
+  ;Loop until "ResultPart" is met, "Separators" is found or
+  ;"String" reaches its end
+  ResultPartLoop: ;"CurrentLoop" Loop
+ 
+  ;Increase "CurrentLoop" counter
+  IntOp $8 $8 + 1
+ 
+  StrSearchLoop:
+  ${Do} ;"String" Loop
+    ;Remove everything before and after the searched part ("TempStr")
+    StrCpy $7 $3 1 $6
+ 
+    ;Verify if it's the "String" end
+    ${If} $6 >= $5
+      ;If "CurrentLoop" is what the user wants, remove the part
+      ;after "TempStr" and itself and get out of here
+      ${If} $8 == $1
+      ${OrIf} $1 == `L`
+        StrCpy $3 $3 $6
+      ${Else} ;If not, empty "String" and get out of here
+        StrCpy $3 ``
+      ${EndIf}
+      StrCpy $R0 `End`
+      ${ExitDo}
+    ${EndIf}
+ 
+    ;Start "CurrentSepCharNum" counter (for "Separators" Loop)
+    StrCpy $R0 0
+ 
+    ${Do} ;"Separators" Loop
+      ;Use one "Separators" character at a time
+      ${If} $R0 <> 0
+        StrCpy $9 $2 1 $R0
+      ${Else}
+        StrCpy $9 $2 1
+      ${EndIf}
+ 
+      ;Go to the next "String" char if it's "Separators" end
+      ${IfThen} $R0 >= $4 ${|} ${ExitDo} ${|}
+ 
+      ;Or, if "TempStr" equals "CurrentSepChar", then...
+      ${If} $7 == $9
+        StrCpy $7 $3 $6
+ 
+        ;If "String" is empty because this result part doesn't
+        ;contain data, verify if "SkipEmptyParts" is activated,
+        ;so we don't return the output to user yet
+ 
+        ${If} $7 == ``
+        ${AndIf} $0 = 1 ;${TRUE}
+          IntOp $6 $6 + 1
+          StrCpy $3 $3 `` $6
+          StrCpy $6 0
+          Goto StrSearchLoop
+        ${ElseIf} $8 == $1
+          StrCpy $3 $3 $6
+          StrCpy $R0 "End"
+          ${ExitDo}
+        ${EndIf} ;If not, go to the next result part
+        IntOp $6 $6 + 1
+        StrCpy $3 $3 `` $6
+        StrCpy $6 0
+        Goto ResultPartLoop
+      ${EndIf}
+ 
+      ;Increase "CurrentSepCharNum" counter
+      IntOp $R0 $R0 + 1
+    ${Loop}
+    ${IfThen} $R0 == "End" ${|} ${ExitDo} ${|}
+ 
+    ;Increase "StartCharPos" counter
+    IntOp $6 $6 + 1
+  ${Loop}
+ 
+  /*After this point:
+  ------------------------------------------
+  $3 = ResultVar (output)*/
+ 
+  ;Return output to user
+  Pop $R0
+  Pop $9
+  Pop $8
+  Pop $7
+  Pop $6
+  Pop $5
+  Pop $4
+  Pop $0
+  Pop $1
+  Pop $2
+  Exch $3
+FunctionEnd
+ 
+!macroend ; StrTok UN
+!insertmacro StrTok ""
+!insertmacro StrTok "un."
+ 
+;----------------------------------------- StrTok end -------------------------------------------
+ 
+ 
+;---------------------------------------- StrContains start -------------------------------------
+; StrContains
+; This function does a case sensitive searches for an occurrence of a substring in a string.
+; It returns the substring if it is found; otherwise, it returns null("").
+; Usage: ${StrContains} "$result_var" "Needle" "Haystack"
+; Written by kenglish_hi
+; Adapted from StrReplace written by dandaman32
+ 
+Var STR_HAYSTACK
+Var STR_NEEDLE
+Var STR_CONTAINS_VAR_1
+Var STR_CONTAINS_VAR_2
+Var STR_CONTAINS_VAR_3
+Var STR_CONTAINS_VAR_4
+Var STR_RETURN_VAR
+ 
+!macro StrContains UN
+ 
+Function ${UN}StrContains
+ 
+  Exch $STR_NEEDLE
+  Exch
+  Exch $STR_HAYSTACK
+  ; Uncomment to debug
+  ;MessageBox MB_OK 'STR_NEEDLE = $STR_NEEDLE STR_HAYSTACK = $STR_HAYSTACK '
+    StrCpy $STR_RETURN_VAR ""
+    StrCpy $STR_CONTAINS_VAR_1 -1
+    StrLen $STR_CONTAINS_VAR_2 $STR_NEEDLE
+    StrLen $STR_CONTAINS_VAR_4 $STR_HAYSTACK
+    loop:
+      IntOp $STR_CONTAINS_VAR_1 $STR_CONTAINS_VAR_1 + 1
+      StrCpy $STR_CONTAINS_VAR_3 $STR_HAYSTACK $STR_CONTAINS_VAR_2 $STR_CONTAINS_VAR_1
+      StrCmp $STR_CONTAINS_VAR_3 $STR_NEEDLE found
+      StrCmp $STR_CONTAINS_VAR_1 $STR_CONTAINS_VAR_4 done
+      Goto loop
+    found:
+      StrCpy $STR_RETURN_VAR $STR_NEEDLE
+      Goto done
+    done:
+   Pop  $STR_HAYSTACK       ;Prevent "invalid opcode" errors and keep the stack intact
+   Exch $STR_RETURN_VAR
+FunctionEnd
+ 
+!macroend
+!insertmacro StrContains ""
+!insertmacro StrContains "un."
+;--------------------------------------- StrContains end ---------------------------------------
+ 
+ 
+;--------------------------------------- StrReplace start --------------------------------------
+; NOTE: Do not substitute 'StrReplaceV4' for this function. It will fail due to the way I call it.
+;
+; StrReplace
+; Replaces all occurences of a given needle within a haystack with another string
+; Usage: ${StrReplace} "$result_var" "SubString" "RepString" "String"
+; Written by dandaman32
+ 
+Var STR_REPLACE_VAR_0
+Var STR_REPLACE_VAR_1
+Var STR_REPLACE_VAR_2
+Var STR_REPLACE_VAR_3
+Var STR_REPLACE_VAR_4
+Var STR_REPLACE_VAR_5
+Var STR_REPLACE_VAR_6
+Var STR_REPLACE_VAR_7
+Var STR_REPLACE_VAR_8
+ 
+!macro StrReplace UN
+ 
+Function ${UN}StrReplace
+ 
+  Exch $STR_REPLACE_VAR_2
+  Exch 1
+  Exch $STR_REPLACE_VAR_1
+  Exch 2
+  Exch $STR_REPLACE_VAR_0
+    StrCpy $STR_REPLACE_VAR_3 -1
+    StrLen $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_1
+    StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
+    loop:
+      IntOp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_3 + 1
+      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_3
+      StrCmp $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_1 found
+      StrCmp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_6 done
+      Goto loop
+    found:
+      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_3
+      IntOp $STR_REPLACE_VAR_8 $STR_REPLACE_VAR_3 + $STR_REPLACE_VAR_4
+      StrCpy $STR_REPLACE_VAR_7 $STR_REPLACE_VAR_0 "" $STR_REPLACE_VAR_8
+      StrCpy $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_5$STR_REPLACE_VAR_2$STR_REPLACE_VAR_7
+      StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
+      Goto loop
+    done:
+  Pop $STR_REPLACE_VAR_1 ; Prevent "invalid opcode" errors and keep the
+  Pop $STR_REPLACE_VAR_1 ; stack as it was before the function was called
+  Exch $STR_REPLACE_VAR_0
+ 
+FunctionEnd
+ 
+!macroend   ; StrContains UN
+!insertmacro StrReplace ""
+!insertmacro StrReplace "un."
+ 
+;----------------------------------------- StrReplace end ---------------------------------------
+ 
+!verbose pop
+!endif
\ No newline at end of file
diff --git a/c++/scripts/projects/magicblast/post_build/win/make_win.py b/c++/scripts/projects/magicblast/post_build/win/make_win.py
new file mode 100644
index 0000000..86b3bad
--- /dev/null
+++ b/c++/scripts/projects/magicblast/post_build/win/make_win.py
@@ -0,0 +1,91 @@
+#! /usr/bin/env python3
+"""Script to create the Windows installer for BLAST command line applications"""
+# $Id: make_win.py 513315 2016-09-09 13:58:57Z boratyng $
+#
+# Author: Christiam camacho
+
+from __future__ import print_function
+import os, sys, os.path
+import shutil
+from optparse import OptionParser
+SCRIPT_DIR = os.path.dirname(os.path.abspath(sys.argv[0]))
+sys.path.append(os.path.join(SCRIPT_DIR, ".."))
+from blast_utils import safe_exec, update_blast_version
+
+VERBOSE = False
+    
+# NSIS Configuration file
+NSIS_CONFIG = os.path.join(SCRIPT_DIR, "ncbi-blast.nsi")
+
+def extract_installer():
+    """Extract name of the installer file from NSIS configuration file"""
+    from fileinput import FileInput
+
+    retval = "unknown"
+    for line in FileInput(NSIS_CONFIG):
+        if line.find("OutFile") != -1:
+            retval = line.split()[1]
+            return retval.strip('"')
+
+def main():
+    """ Creates NSIS installer for BLAST command line binaries """
+    global VERBOSE #IGNORE:W0603
+    parser = OptionParser("%prog <blast_version> <installation directory>")
+    parser.add_option("-v", "--verbose", action="store_true", default=False,
+                      help="Show verbose output", dest="VERBOSE")
+    options, args = parser.parse_args()
+    if len(args) != 2:
+        parser.error("Incorrect number of arguments")
+        return 1
+    
+    blast_version, installdir = args
+    VERBOSE = options.VERBOSE
+    
+    apps = [ "magicblast.exe",
+             "ncbi-vdb-md.dll",
+             "makeblastdb.exe",
+             "libgcc_s_seh-1.dll",
+             "libgmp-10.dll",
+             "libgnutls-30.dll",
+             "libhogweed-4-2.dll",
+             "libnettle-6-2.dll",
+             "libp11-kit-0.dll" ]
+    
+    cwd = os.getcwd()
+    for app in apps:
+        app = os.path.join(installdir, "bin", app)
+        if VERBOSE: 
+            print("Copying", app, "to", cwd)
+        shutil.copy(app, cwd)
+    
+    
+    update_blast_version(NSIS_CONFIG, blast_version)
+    # Copy necessary files to the current working directory
+    shutil.copy(NSIS_CONFIG, cwd)
+    license_file = os.path.join(SCRIPT_DIR, "..", "..", "LICENSE")
+    shutil.copy(license_file, cwd)
+
+    # Copy the README file from the parent directory
+    readme_file = os.path.join(SCRIPT_DIR, "..", "..", "README")
+    shutil.copy(readme_file, cwd)    
+
+    for aux_file in ("EnvVarUpdate.nsh", "ncbilogo.ico", "unix2dos.nsh"):
+        src = os.path.join(SCRIPT_DIR, aux_file)
+        if VERBOSE:
+            print("Copying", src, "to", cwd)
+        shutil.copy(src, cwd)
+        
+    # makensis is in the path of the script courtesy of the release framework
+    cmd = "makensis " + os.path.basename(NSIS_CONFIG)
+    safe_exec(cmd)
+
+    installer_dir = os.path.join(installdir, "installer")
+    if not os.path.exists(installer_dir):
+        os.makedirs(installer_dir)
+
+    installer = extract_installer()
+    shutil.copy(installer, installer_dir)
+
+if __name__ == "__main__":
+    sys.exit(main())
+
diff --git a/c++/scripts/projects/magicblast/post_build/win/ncbi-blast.nsi b/c++/scripts/projects/magicblast/post_build/win/ncbi-blast.nsi
new file mode 100755
index 0000000..0436096
--- /dev/null
+++ b/c++/scripts/projects/magicblast/post_build/win/ncbi-blast.nsi
@@ -0,0 +1,102 @@
+;NSIS Modern User Interface
+
+;--------------------------------
+;Include Modern UI
+
+  !include "MUI.nsh"
+  !include "EnvVarUpdate.nsh"
+  !include "x64.nsh"
+  !include "unix2dos.nsh"
+  
+;--------------------------------
+; Initialization function to properly set the installation directory
+Function .onInit
+  ${If} ${RunningX64}
+    StrCpy $INSTDIR "$PROGRAMFILES64\NCBI\magicblast-BLAST_VERSION"
+  ${EndIf}
+FunctionEnd
+
+;--------------------------------
+;General
+
+  ;Name and file
+  Name "NCBI Magic-BLAST BLAST_VERSION"
+  OutFile "ncbi-magicblast-BLAST_VERSION.exe"
+  ; Install/uninstall icons
+  !define MUI_ICON "ncbilogo.ico"
+  !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\nsis1-uninstall.ico"
+
+  ;Default installation folder
+  InstallDir "$PROGRAMFILES\NCBI\magicblast-BLAST_VERSION"
+  
+  ;Get installation folder from registry if available
+  InstallDirRegKey HKCU "Software\NCBI\magicblast-BLAST_VERSION" ""
+
+;--------------------------------
+;Interface Settings
+
+  !define MUI_ABORTWARNING
+
+;--------------------------------
+;Pages
+
+  !insertmacro MUI_PAGE_LICENSE "LICENSE"
+  !insertmacro MUI_PAGE_DIRECTORY
+  !insertmacro MUI_PAGE_INSTFILES
+  ;!insertmacro MUI_PAGE_FINISH
+  
+  !insertmacro MUI_UNPAGE_CONFIRM
+  !insertmacro MUI_UNPAGE_INSTFILES
+  
+;--------------------------------
+;Languages
+ 
+  !insertmacro MUI_LANGUAGE "English"
+
+;--------------------------------
+;Installer Sections
+
+Section "DefaultSection" SecDflt
+  
+  SetOutPath "$INSTDIR\bin"
+  
+  File "magicblast.exe"
+  File "ncbi-vdb-md.dll"
+  File "makeblastdb.exe"
+  File "libgcc_s_seh-1.dll"
+  File "libgmp-10.dll"
+  File "libgnutls-30.dll"
+  File "libhogweed-4-2.dll"
+  File "libnettle-6-2.dll"
+  File "libp11-kit-0.dll"
+  
+  SetOutPath "$INSTDIR\doc"
+  File "README"
+  Push "$INSTDIR\doc\README"
+  Push "$INSTDIR\doc\README.txt"
+  Call unix2dos
+
+  ;Store installation folder
+  WriteRegStr HKCU "Software\NCBI\magicblast-BLAST_VERSION" "" $INSTDIR
+  
+  ;Create uninstaller
+  WriteUninstaller "$INSTDIR\Uninstall-ncbi-magicblast-BLAST_VERSION.exe"
+  
+  ;Update PATH
+  ${EnvVarUpdate} $0 "PATH" "P" "HKCU" "$INSTDIR\bin"
+  
+SectionEnd
+
+;--------------------------------
+;Uninstaller Section
+
+Section "Uninstall"
+  Delete "$INSTDIR\Uninstall-ncbi-magicblast-BLAST_VERSION.exe"
+  RMDir /r "$INSTDIR"
+
+  DeleteRegKey /ifempty HKCU "Software\NCBI\magicblast-BLAST_VERSION"
+  
+  ; Remove installation directory from PATH
+  ${un.EnvVarUpdate} $0 "PATH" "R" "HKCU" "$INSTDIR\bin"
+
+SectionEnd
diff --git a/c++/scripts/projects/magicblast/post_build/win/ncbilogo.ico b/c++/scripts/projects/magicblast/post_build/win/ncbilogo.ico
new file mode 100644
index 0000000..247e28f
Binary files /dev/null and b/c++/scripts/projects/magicblast/post_build/win/ncbilogo.ico differ
diff --git a/c++/scripts/projects/magicblast/post_build/win/unix2dos.nsh b/c++/scripts/projects/magicblast/post_build/win/unix2dos.nsh
new file mode 100644
index 0000000..ffe2bbb
--- /dev/null
+++ b/c++/scripts/projects/magicblast/post_build/win/unix2dos.nsh
@@ -0,0 +1,56 @@
+Function unix2dos
+    ; strips all CRs
+    ; and then converts all LFs into CRLFs
+    ; (this is roughly equivalent to "cat file | dos2unix | unix2dos")
+    ;
+    ; usage:
+    ;    Push "infile"
+    ;    Push "outfile"
+    ;    Call unix2dos
+    ;
+    ; beware that this function destroys $0 $1 $2
+
+    ClearErrors
+
+    Pop $2
+    FileOpen $1 $2 w 
+
+    Pop $2
+    FileOpen $0 $2 r
+
+    Push $2 ; save name for deleting
+
+    IfErrors unix2dos_done
+
+    ; $0 = file input (opened for reading)
+    ; $1 = file output (opened for writing)
+
+unix2dos_loop:
+    ; read a byte (stored in $2)
+    FileReadByte $0 $2
+    IfErrors unix2dos_done ; EOL
+    ; skip CR
+    StrCmp $2 13 unix2dos_loop
+    ; if LF write an extra CR
+    StrCmp $2 10 unix2dos_cr unix2dos_write
+
+unix2dos_cr:
+    FileWriteByte $1 13
+
+unix2dos_write:
+    ; write byte
+    FileWriteByte $1 $2
+    ; read next byte
+    Goto unix2dos_loop
+
+unix2dos_done:
+
+    ; close files
+    FileClose $0
+    FileClose $1
+
+    ; delete original
+    Pop $0
+    Delete $0
+
+FunctionEnd
diff --git a/c++/scripts/projects/magicblast/project.lst b/c++/scripts/projects/magicblast/project.lst
new file mode 100644
index 0000000..42d8d9c
--- /dev/null
+++ b/c++/scripts/projects/magicblast/project.lst
@@ -0,0 +1,85 @@
+corelib$
+serial$
+serial/impl$
+serial/datatool
+algo$
+algo/blast$
+algo/blast/api
+algo/blast/core
+algo/blast/blastinput
+algo/blast/composition_adjustment
+algo/blast/dbindex
+algo/blast/format
+algo/blast/unit_tests
+algo/blast/igblast
+algo/dustmask$
+algo/winmask$
+algo/segmask$
+algo/blast/blastinput/unit_test
+-algo/blast/blastinput/demo
+objects
+cgi$
+cgi/impl$
+html$
+connect$
+connect/services
+-connect/services/test
+connect/ext$
+util$
+util/creaders$
+util/tables$
+util/compress$
+util/compress/bzip2$
+util/compress/zlib$
+util/compress/api
+util/regexp
+util/xregexp
+util/sequtil$
+util/bitset$
+util/math$
+util/cache$
+util/impl$
+objtools$
+objtools/alnmgr$
+objtools/readers$
+objtools/seqmasks_io$
+objtools/blast$
+objtools/blast/seqdb_reader
+objtools/blast/gene_info_reader
+objtools/blast/services
+objtools/blast/blastdb_format
+objtools/blast/seqdb_writer
+objtools/cleanup$
+objtools/edit$
+objtools/format$
+objtools/format/items$
+objtools/align_format
+dbapi$
+dbapi/driver$
+dbapi/cache$
+dbapi/driver/impl$
+dbapi/driver/odbc$
+dbapi/driver/odbc/unix_odbc$
+dbapi/driver/util$ update-only
+objmgr
+-objmgr/test
+-objmgr/util/unit_test
+objtools/data_loaders/genbank
+-objtools/data_loaders/genbank/test
+objtools/data_loaders$
+objtools/data_loaders/blastdb$
+app$
+app/blast
+app/blastdb
+objtools/simple$
+-objects/.*/test
+-objects/.*/demo
+-objects/.*/unit_test
+algo/blast/blast_sra_input
+app/magicblast
+sra/readers/sra
+sra/readers$
+sra$
+misc$
+misc/third_party
+misc/third_party_static
diff --git a/c++/scripts/projects/ncbi_applog/ChangeLog b/c++/scripts/projects/ncbi_applog/ChangeLog
index 40a0553..1b8a3a6 100644
--- a/c++/scripts/projects/ncbi_applog/ChangeLog
+++ b/c++/scripts/projects/ncbi_applog/ChangeLog
@@ -1,5 +1,20 @@
-
-1.1.0
+1.3.0 (11/29/16)
+    - Switch to HTTPS protocol for CGI mode.
+    - Added '-sid' option for 'generate' command. CXX-8809
+
+1.2.0 (06/29/16)
+    - Do not split log files by default, use .log and .perf files for /log, and single .log file for all other locations. CXX-8158
+    - Add euid to log file name when using /log. CXX-8158
+    - Fixes for 'url' command:  CXX-7846
+	- add '-appname', '-host' and '-pid' flags to allow include only necessary information to the search term;
+	- add '-std' flag to automatically imply all 3 flags above (previously default);
+	- use '-maxtime' instead of '-timestamp', add '-maxtime-delay' flag.
+
+1.1.1 (06/01/16)
+    - Add additional checks to CGI redirecting to return error code if CGI is unavailable. CXX-8117
+    - Add checking /log/logsite location for writing logs, if logsite is known, before redirecting to CGI. CXX-8117
+
+1.1.0 (03/28/16)
     - Allow to send RAW logs incrementally (for CGI redirects). CXX-7803
     - Add possibility to generate an Applog query URL on a base of token ('url' command). CXX-7846
 
@@ -20,7 +35,6 @@
     failed
 
 1.0.13 (01/13/14) - first public version 
-
     - Clog try to fallback to /log/<port> or /log/srv. CXX-3423
     - Add support for $NCBI_CONFIG_LOG_FILE, allow extracting SID from the token. CXX-3818
     - Alow to specify posting timestamp. CXX-3933
diff --git a/c++/scripts/projects/ncbi_applog/Manifest b/c++/scripts/projects/ncbi_applog/Manifest
index eb61824..7e5b261 100644
--- a/c++/scripts/projects/ncbi_applog/Manifest
+++ b/c++/scripts/projects/ncbi_applog/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 486339 2015-12-03 15:52:01Z fukanchi $
+# $Id: Manifest 519350 2016-11-15 14:55:24Z ivanov $
 #
 # Author: Alexey Rafanovich
 #
@@ -15,6 +15,7 @@ APP: ncbi_applog
 
 POSTBUILD: cp $srcdir/src/misc/clog/app/ncbi_applog.cgi $installdir/bin
 POSTBUILD: cp $srcdir/src/misc/clog/app/test_ncbi_applog.sh $installdir/bin
+POSTBUILD: cp $srcdir/src/misc/clog/app/ncbi_applog_run_app.sh $installdir/bin
 
 # The -t key prevents inclusion of the tree builder into the release
 # SVN_TAG_RELEASE_ADD_FLAGS: -t
@@ -31,9 +32,8 @@ Linux64-Centos : plain  : GCC.sh   --without-debug --without-mt --with-static --
 Linux64-Ubuntu : plain  : GCC.sh   --without-debug --with-mt    --with-static --without-runpath --with-flat-makefile
 FreeBSD64      : plain  : Clang.sh --without-debug --without-mt --with-static --without-runpath --with-flat-makefile
 IntelMAC       : plain  : GCC.sh   --without-debug --without-mt --with-static --without-runpath --with-flat-makefile
-Win32_13       : plain  : static 32 ReleaseMT
+Win64_13       : plain  : static 64 ReleaseMT
 
-#XCode      : plain  : Xcode.sh 30 --without-debug --with-universal=i386,x86_64
 
 #USE_COMPONENTS
 #
diff --git a/c++/scripts/projects/ncbi_applog/project.lst b/c++/scripts/projects/ncbi_applog/project.lst
index 45ceb63..85dc7ca 100644
--- a/c++/scripts/projects/ncbi_applog/project.lst
+++ b/c++/scripts/projects/ncbi_applog/project.lst
@@ -7,3 +7,5 @@ util/xregexp$
 misc$
 misc/clog$
 misc/clog/app$
+misc/third_party
+misc/third_party_static
diff --git a/c++/scripts/projects/ncbi_gui_base.lst b/c++/scripts/projects/ncbi_gui_base.lst
index 6cbb168..913ebd1 100644
--- a/c++/scripts/projects/ncbi_gui_base.lst
+++ b/c++/scripts/projects/ncbi_gui_base.lst
@@ -34,6 +34,7 @@ misc/hydra_client$
 misc/discrepancy$
 misc/discrepancy_report$
 misc/biosample_util$
+misc/data_loaders_util$
 objects
 objmgr
 objtools
diff --git a/c++/scripts/projects/netcache/ChangeLog b/c++/scripts/projects/netcache/ChangeLog
index 04037a5..8ec5a0b 100644
--- a/c++/scripts/projects/netcache/ChangeLog
+++ b/c++/scripts/projects/netcache/ChangeLog
@@ -162,5 +162,40 @@ March 01, 2016
 version 6.9.5 (CXX-7908)
 Changed to do blob synchronization after quorum requirement is met.
 
+June 13, 2016
+version 6.9.6 (CXX-8233)
+Corrected task scheduling.
+
+June 17, 2016
+version 6.9.7 (CXX-8248)
+Corrected periodic synchronization bugs.
+
+September 21, 2016
+version 6.9.8 (CXX-8613)
+Fixed handling of SearchOnRead setting.
+
+October 13, 2016
+version 6.10.0 (CXX-8706)
+Implemented server credentials configuration.
+Made visible log severity configurable.
+Removed unstructured information from applog.
+
+November 10, 2016
+version 6.11.0 (CXX-8801)
+Added option to re-cache blob without prolonging its life.
+Added ncbi_role info into logs.
+Added option to enumerate blobs in a given cache using various metadata filters.
+Corrected blob caching information.
+
+November 17, 2016
+version 6.11.1 (CXX-8817)
+Changed blob filtering conditions.
+Changed data separator in BLIST2 command output.
+Changed to treat cache and key names as precise matches in BLIST2 command.
+
+November 21, 2016
+version 6.11.2 (CXX-8749)
+Corrected blob list separator and filters.
+
 
 
diff --git a/c++/scripts/projects/netschedule/ChangeLog b/c++/scripts/projects/netschedule/ChangeLog
index 84aae25..d6fba5a 100644
--- a/c++/scripts/projects/netschedule/ChangeLog
+++ b/c++/scripts/projects/netschedule/ChangeLog
@@ -1,3 +1,42 @@
+Release 4.28.2 cloned from 4.28.1 (2016-10-31)
+
+Improvements:
+    * Extra '0' in STAT output (JIRA: CXX-8768)
+
+
+Release 4.28.1 cloned from 4.28.0 (2016-10-26)
+
+Improvements:
+    * netschedule socket leak (JIRA: CXX-8727)
+    * NetSchedule: tries to write into a socket when it is already closed
+      (JIRA: CXX-8740)
+    * NetSchedule: incorrect logging of the timed out connections
+      (JIRA: CXX-8754)
+
+
+Release 4.28.0 cloned from 4.27.0 (2016-10-14)
+
+Improvements:
+    * NetSchedule: new performance record Pending_Deleted (JIRA: CXX-8643)
+    * NS -- Allow to (re)run a job (JIRA: CXX-8694)
+    * NetSchedule: remove AFLS command support (JIRA: CXX-5216)
+
+
+Release 4.27.0 cloned from 4.26.0 (2016-09-19)
+
+Improvements:
+    * NetSchedule: let prioritized affinities work together with any affinity
+      flag (JIRA: CXX-8587)
+    * NetSchedule: shutdown sockets on client close (JIRA: CXX-8286)
+    * NetSchedule: extend with IServer_ConnectionHandler::OnError() callback
+      (JIRA: CXX-8287)
+    * NS -- use status code 404 (NotFound) for non-existing jobs
+      (JIRA: CXX-8251)
+    * NS -- log connection ID on establishing the connection; change method of
+      ID creation (JIRA: CXX-8253)
+    * NetSchedule: not initialized member (JIRA: CXX-8359)
+
+
 Release 4.26.0 cloned from 4.25.0 (2016-05-04)
 
 Improvements:
diff --git a/c++/scripts/projects/netschedule/Manifest b/c++/scripts/projects/netschedule/Manifest
index 9afa218..312c4b0 100644
--- a/c++/scripts/projects/netschedule/Manifest
+++ b/c++/scripts/projects/netschedule/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 472057 2015-07-06 19:39:16Z satskyse $
+# $Id: Manifest 517704 2016-10-26 20:59:02Z satskyse $
 #
 # Author: Sergey Satskiy
 #
@@ -30,9 +30,10 @@ DEFAULT_CONFIGURATIONS: Linux64-Centos:Bdb6126-O2g
 # Release configurator assumes that this script will eventually call standard configure script and pass all options
 # to it. So some standard options may be added by release configurator, such as --build-root-sfx, --with-projects,
 # --with-distcc, --with-action etc.
-Linux64-Centos : Bdb6126-Release : GCC.sh 4.8.1 --without-debug --with-mt --with-flat-makefile --with-bdb=$NCBI/BerkeleyDB-6.1.26
-Linux64-Centos : Bdb6126-Debug   : GCC.sh 4.8.1 --with-debug    --with-mt --with-flat-makefile --with-bdb=$NCBI/BerkeleyDB-6.1.26
-Linux64-Centos : Bdb6126-O2g : GCC.sh 4.8.1 --without-debug --with-symbols --with-mt --with-flat-makefile --with-bdb=$NCBI/BerkeleyDB-6.1.26
+Linux64-Centos  : Bdb6126-Release : GCC.sh 4.8.1 --without-debug --with-mt --with-flat-makefile --with-bdb=$NCBI/BerkeleyDB-6.1.26
+Linux64-Centos  : Bdb6126-Debug   : GCC.sh 4.8.1 --with-debug    --with-mt --with-flat-makefile --with-bdb=$NCBI/BerkeleyDB-6.1.26
+Linux64-Centos  : Bdb6126-O2g : GCC.sh 4.8.1 --without-debug --with-symbols --with-mt --with-flat-makefile --with-bdb=$NCBI/BerkeleyDB-6.1.26
+Linux64-Centos7 : Bdb6126-O2g : GCC.sh 4.8.1 --without-debug --with-symbols --with-mt --with-flat-makefile --with-bdb=$NCBI/BerkeleyDB-6.1.26
 
 USE_COMPONENTS
 
diff --git a/c++/scripts/projects/netstorage/Manifest b/c++/scripts/projects/netstorage/Manifest
index d088e1a..2d4a4ad 100644
--- a/c++/scripts/projects/netstorage/Manifest
+++ b/c++/scripts/projects/netstorage/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 466301 2015-04-30 18:18:56Z satskyse $
+# $Id: Manifest 521097 2016-12-05 21:32:38Z fukanchi $
 #
 # Author: Sergey Satskiy
 #
@@ -16,6 +16,8 @@
 # It is allowed to have more than one of each statements
 APP: netstoraged
 ETC: src/app/netstorage/netstoraged.ini
+APP: netstorage_gc
+ETC: src/app/netstorage/utils/netstorage_gc.ini
 
 DEFAULT_CONFIGURATIONS: Linux64-Centos:O2g
 
diff --git a/c++/scripts/projects/netstorage/components.link b/c++/scripts/projects/netstorage/components.link
index 50b59f2..9d27c5b 100644
--- a/c++/scripts/projects/netstorage/components.link
+++ b/c++/scripts/projects/netstorage/components.link
@@ -1,6 +1,5 @@
 [components]
-infrastructure  17.0
-core            17.0
-dbase           17.0
-misc            17.0
-
+infrastructure  18.0
+core            18.0
+dbase           18.0
+misc            18.0
diff --git a/c++/scripts/projects/netstorage/project.lst b/c++/scripts/projects/netstorage/project.lst
index f1e5102..c0e52ca 100644
--- a/c++/scripts/projects/netstorage/project.lst
+++ b/c++/scripts/projects/netstorage/project.lst
@@ -2,7 +2,6 @@ corelib$
 util$
 util/regexp$
 util/compress
-util/fileblobstorage$
 util/qparse$
 util/bitset$ update-only
 util/cache$ update-only
diff --git a/c++/scripts/projects/netstorage_gc/project.lst b/c++/scripts/projects/netstorage_gc/project.lst
index b50eb09..3ae078c 100644
--- a/c++/scripts/projects/netstorage_gc/project.lst
+++ b/c++/scripts/projects/netstorage_gc/project.lst
@@ -29,5 +29,14 @@ dbapi/driver/ftds64$
 dbapi/driver/ftds64/impl$
 dbapi/driver/ftds64/freetds
 dbapi/driver/ftds64/ctlib$
+dbapi/driver/ftds95$
+dbapi/driver/ftds95/freetds$
+dbapi/driver/ftds95/freetds/freetds update-only
+dbapi/driver/ftds95/freetds/replacements update-only
+dbapi/driver/ftds95/freetds/tds$
+dbapi/driver/ftds95/freetds/ctlib$
+dbapi/driver/ftds95/ctlib$
+dbapi/driver/ftds95/impl update-only
+dbapi/driver/ftds95/freetds/replacements$
 dbapi/driver/ftds-default
 dbapi/simple$
diff --git a/c++/scripts/projects/project_tree_builder/ChangeLog b/c++/scripts/projects/project_tree_builder/ChangeLog
index 1fbac9f..d9c85ee 100644
--- a/c++/scripts/projects/project_tree_builder/ChangeLog
+++ b/c++/scripts/projects/project_tree_builder/ChangeLog
@@ -302,3 +302,11 @@ Added analysis and reporting of cyclic library dependencies.
 March 09, 2016
 version 4.1.3, CXX-7917
 Added support for VS2015
+
+May 11, 2016
+version 4.1.4, CXX-8128
+Implemented library order analysis and generation.
+
+August 05, 2016
+version 4.1.5, CXX-8435
+Bug fixes.
diff --git a/c++/scripts/projects/project_tree_builder/Manifest b/c++/scripts/projects/project_tree_builder/Manifest
index 29b59ee..050db13 100644
--- a/c++/scripts/projects/project_tree_builder/Manifest
+++ b/c++/scripts/projects/project_tree_builder/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 486339 2015-12-03 15:52:01Z fukanchi $
+# $Id: Manifest 508788 2016-08-01 16:12:18Z fukanchi $
 #
 # Author: Sergey Satskiy
 #
@@ -35,11 +35,10 @@ Linux64-Ubuntu    : plain : GCC.sh           --without-debug --without-mt --with
 FreeBSD64  : plain : Clang.sh           --without-debug --without-mt --with-static --without-runpath --with-flat-makefile --without-ncbi-c --without-pcre
 
 IntelMAC   : plain : GCC.sh           --without-debug --without-mt --with-static --without-runpath --with-flat-makefile --without-ncbi-c
-#IntelMAC    : universal : GCC.sh        --without-debug --without-mt  --with-static --with-universal=i386,x86_64 --with-flat-makefile --without-ncbi-c
 
 Win32_13    : msvc-13-static-32 : static  32  ReleaseMT
 
-XCode      : plain  : Xcode.sh 30 --without-debug --with-universal=i386,x86_64 --without-ncbi-c
+XCode      : plain  : Xcode.sh 30 --without-debug --without-ncbi-c
 
 USE_COMPONENTS
 
diff --git a/c++/scripts/projects/public/Manifest b/c++/scripts/projects/public/Manifest
index aed3142..07a9485 100644
--- a/c++/scripts/projects/public/Manifest
+++ b/c++/scripts/projects/public/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 500492 2016-05-04 22:25:11Z fukanchi $
+# $Id: Manifest 521307 2016-12-07 18:54:25Z fukanchi $
 #
 # Author:
 #
@@ -24,22 +24,23 @@ TAG_PRE_COMMIT: tagprecommit/use_embedded_ptb.py
 Win32_13       : MSVC13-32 : dll    32 ReleaseDLL
 Win64_13       : MSVC13-64 : static 64 ReleaseDLL
 
-Cygwin64       : GCC       : GCC.sh --without-debug --with-mt --with-flat-makefile
+Cygwin64       : GCC       : GCC.sh --without-debug --with-mt --with-flat-makefile --without-ncbi-c
 
-Linux64-Centos : GCC481    : GCC.sh 4.8.1 --without-debug --without-flat-makefile
-Linux64-Centos : GCC493d   : GCC.sh 4.9.3 --with-debug --with-mt --with-flat-makefile
-Linux64-Centos : GCC510    : GCC.sh 5.1.0 --without-debug --with-mt --with-flat-makefile
-Linux64-Centos : GCC530    : GCC.sh 5.3.0 --without-debug --with-mt --with-flat-makefile
-Linux64-Centos : ICC150    : ICC.sh 15.0  --without-debug --with-mt --with-dll
-Linux64-Centos : ICC150d   : ICC.sh 15.0  --with-debug --with-mt --with-3psw=system
-Linux64-Centos7 : Clang    : Clang.sh 3.8.0 --with-debug --with-mt --with-flat-makefile
+Linux64-Centos : GCC481    : GCC.sh 4.8.1 --without-debug --without-flat-makefile --without-ncbi-c
+Linux64-Centos : GCC493d   : GCC.sh 4.9.3 --with-debug --with-mt --with-flat-makefile --without-ncbi-c
+Linux64-Centos : GCC510    : GCC.sh 5.1.0 --without-debug --with-mt --with-flat-makefile --without-ncbi-c
+Linux64-Centos : GCC530    : GCC.sh 5.3.0 --without-debug --with-mt --with-flat-makefile --without-ncbi-c
+Linux64-Centos : ICC150    : ICC.sh 15.0  --without-debug --with-mt --with-dll --with-runpath --without-ncbi-c
+Linux64-Centos : ICC150d   : ICC.sh 15.0  --with-debug --with-mt --with-3psw=system --with-runpath --without-ncbi-c
+Linux64-Centos7 : Clang    : Clang.sh 3.8.0 --with-debug --with-mt --with-flat-makefile --without-ncbi-c
 
-Linux64-Ubuntu : plain-GCC : GCC.sh --without-debug --with-mt --with-flat-makefile
-Linux32-Ubuntu : plain-GCC : GCC.sh --without-debug --with-mt --with-flat-makefile
+Linux64-Ubuntu : plain-GCC : GCC.sh --without-debug --with-mt --with-flat-makefile --without-ncbi-c
+Linux32-Ubuntu : plain-GCC : GCC.sh --without-debug --with-mt --with-flat-makefile --without-ncbi-c
 
-FreeBSD64      : plain     : Clang.sh --without-debug --with-mt --with-flat-makefile
+FreeBSD64      : plain     : Clang.sh --without-debug --with-mt --with-flat-makefile --with-runpath --without-ncbi-c
 
-IntelMAC       : Debug     : GCC.sh --with-debug --with-dll --with-mt --with-universal=i386,x86_64 --with-flat-makefile
-IntelMAC       : Release   : GCC.sh --without-debug --with-dll --with-mt --with-universal=i386,x86_64 --with-flat-makefile
+IntelMAC       : Debug     : GCC.sh      --with-debug    --with-dll --with-mt --with-flat-makefile --without-gcrypt --without-mysql --without-pcre --without-ncbi-c
+IntelMAC       : Release   : GCC.sh      --without-debug --with-dll --with-mt --with-flat-makefile --without-gcrypt --without-mysql --without-pcre --without-ncbi-c
+
+XCode          : plain     : Xcode.sh 30 --without-debug --with-64 --without-ncbi-c
 
-XCode          : plain     : Xcode.sh 30 --without-debug --with-64
diff --git a/c++/scripts/projects/public/components.link b/c++/scripts/projects/public/components.link
index 60b57d0..078e2e7 100644
--- a/c++/scripts/projects/public/components.link
+++ b/c++/scripts/projects/public/components.link
@@ -1,12 +1,13 @@
 [components]
-algo            17.0
-app             17.0
-core            17.0
-dbase           17.0
-infrastructure  17.0
-misc            17.0
-objects         17.0
-objtools        17.0
-sample          17.0
-sra             17.0
-web             17.0
+algo            18.0
+app             18.0
+core            18.0
+dbase           18.0
+infrastructure  18.0
+misc            18.0
+objects         18.0
+objtools        18.0
+sample          18.0
+sra             18.0
+web             18.0
+
diff --git a/c++/scripts/projects/python_ncbi_dbapi/ChangeLog b/c++/scripts/projects/python_ncbi_dbapi/ChangeLog
index 4eceb85..736734e 100644
--- a/c++/scripts/projects/python_ncbi_dbapi/ChangeLog
+++ b/c++/scripts/projects/python_ncbi_dbapi/ChangeLog
@@ -1,3 +1,11 @@
+Version 1.18.0 (2016-10-13):
+* Advance to version 18.0 of the stable C++ Toolkit components, with
+  ftds95 as default ftds and support for contacting dispd over HTTPS.
+
+Version 1.17.0 (2016-06-23):
+* Advance to version 17.0 of the stable C++ Toolkit components, complete
+  with an ftds95 driver in addition to ftds(64).
+
 Version 1.16.1 (2016-01-15):
 * Cover Python 3.4 in addition to 2.7.
 
diff --git a/c++/scripts/projects/python_ncbi_dbapi/components.link b/c++/scripts/projects/python_ncbi_dbapi/components.link
index b1e583c..33d657d 100644
--- a/c++/scripts/projects/python_ncbi_dbapi/components.link
+++ b/c++/scripts/projects/python_ncbi_dbapi/components.link
@@ -1,4 +1,4 @@
 [components]
-infrastructure  16.1
-core            16.1
-dbase           16.1
+infrastructure  18.0
+core            18.0
+dbase           18.0
diff --git a/c++/scripts/projects/python_ncbi_dbapi/project.lst b/c++/scripts/projects/python_ncbi_dbapi/project.lst
index 5d5fd66..6af5f98 100644
--- a/c++/scripts/projects/python_ncbi_dbapi/project.lst
+++ b/c++/scripts/projects/python_ncbi_dbapi/project.lst
@@ -13,10 +13,20 @@ dbapi/driver/odbc/unix_odbc$ update-only
 dbapi/driver/ctlib$
 dbapi/driver/dblib$
 dbapi/driver/ftds64$
+dbapi/driver/ftds64/impl$ update-only
 dbapi/driver/ftds64/freetds$
 dbapi/driver/ftds64/freetds/tds$
 dbapi/driver/ftds64/freetds/replacements$
 dbapi/driver/ftds64/freetds/ctlib$
 dbapi/driver/ftds64/ctlib$
+dbapi/driver/ftds95$
+dbapi/driver/ftds95/impl$ update-only
+dbapi/driver/ftds95/freetds$
+dbapi/driver/ftds95/freetds/freetds$ update-only
+dbapi/driver/ftds95/freetds/tds$
+dbapi/driver/ftds95/freetds/replacements$
+dbapi/driver/ftds95/freetds/ctlib$
+dbapi/driver/ftds95/ctlib$
+dbapi/driver/ftds-default$
 dbapi/lang_bind$
 dbapi/lang_bind/python
diff --git a/c++/scripts/projects/rmblastn/Manifest b/c++/scripts/projects/rmblastn/Manifest
index f528d2a..508bdf2 100644
--- a/c++/scripts/projects/rmblastn/Manifest
+++ b/c++/scripts/projects/rmblastn/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 483955 2015-11-05 15:16:36Z fukanchi $
+# $Id: Manifest 508788 2016-08-01 16:12:18Z fukanchi $
 #
 # Author: Christiam Camacho
 #
@@ -38,6 +38,6 @@ DEFAULT_CONFIGURE_FLAGS: --without-debug --with-strip --with-mt --with-build-roo
 Win32_13    : plain : static  32  ReleaseMT
 Win64_13    : plain : static  64  ReleaseMT
 
-IntelMAC    : universal : GCC.sh 4.0     --without-debug --without-pcre --with-mt --with-flat-makefile --with-universal=i386,x86_64 --with-ncbi-public
+IntelMAC    : plain : GCC.sh 4.0     --without-debug --without-pcre --with-mt --with-flat-makefile --with-ncbi-public
 
 USE_COMPONENTS
diff --git a/c++/scripts/projects/testres-kernel/ChangeLog b/c++/scripts/projects/testres-kernel/ChangeLog
index 36905c3..2b3bc8d 100644
--- a/c++/scripts/projects/testres-kernel/ChangeLog
+++ b/c++/scripts/projects/testres-kernel/ChangeLog
@@ -1,4 +1,3 @@
-Oct 21, 2013
-First release
-Jun 2, 2015
-Version 1.3.0. Multiple bugfixes, improvements
+Oct 21, 2013 First release
+Jun 2, 2015 Version 1.3.0 Multiple bugfixes, improvements
+Dec 1, 2016 Version 1.3.4 less resource hogging, new test modules, https transition, bugfixes
diff --git a/c++/scripts/projects/testres-kernel/Manifest b/c++/scripts/projects/testres-kernel/Manifest
index 58b2108..52a489c 100644
--- a/c++/scripts/projects/testres-kernel/Manifest
+++ b/c++/scripts/projects/testres-kernel/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 481816 2015-10-15 22:41:22Z fukanchi $
+# $Id: Manifest 520935 2016-12-02 23:17:37Z zakharov $
 #
 # Author: Mikhail Zakharov (template by Sergey Satskiy)
 #
@@ -21,7 +21,10 @@ POSTBUILD: $packagedir/copy_modules.py $srcdir $bindir $installdir
 #ini file
 COPY: $srcdir/src/internal/cppcore/testres/kernel/testres_kernel.ini $installdir/bin
 
-Linux64-Centos  : GCC481  : GCC.sh 4.8.1     --without-debug --with-mt --with-static --without-runpath --with-flat-makefile --without-ncbi-c
+Linux64-Centos : O2g : GCC.sh 4.9.3 --without-debug --with-symbols --with-mt --with-static --without-runpath --with-flat-makefile --without-ncbi-c
+
+Linux64-Centos : dbg : GCC.sh 4.9.3 --with-debug --with-symbols --with-mt --with-static --without-runpath --with-flat-makefile --without-ncbi-c
+Linux64-Centos : O2  : GCC.sh 4.9.3 --without-debug --with-mt --with-static --without-runpath --with-flat-makefile --without-ncbi-c
 
 
 
diff --git a/c++/scripts/projects/testres-kernel/components.link b/c++/scripts/projects/testres-kernel/components.link
index bbb94f0..99d5fc8 100644
--- a/c++/scripts/projects/testres-kernel/components.link
+++ b/c++/scripts/projects/testres-kernel/components.link
@@ -1,6 +1,6 @@
 [components]
 #infrastructure  16.1
 #core            16.1
-web             16.1
-misc            16.1
-app             16.1
+web             18.0
+misc            18.0
+app             18.0
diff --git a/c++/scripts/projects/testres-scheduler/ChangeLog b/c++/scripts/projects/testres-scheduler/ChangeLog
index 5841b7b..3a84301 100644
--- a/c++/scripts/projects/testres-scheduler/ChangeLog
+++ b/c++/scripts/projects/testres-scheduler/ChangeLog
@@ -2,3 +2,6 @@ Oct 21, 2013
 First release
 Jun 2, 2015
 Release 1.3.0, Multiple bugfixes, performance improvements
+Dec 1, 2016
+Release 1.3.4, make Netcache communications more efficient, multiple kernel
+management
diff --git a/c++/scripts/projects/testres-scheduler/Manifest b/c++/scripts/projects/testres-scheduler/Manifest
index b101bf5..d73148f 100644
--- a/c++/scripts/projects/testres-scheduler/Manifest
+++ b/c++/scripts/projects/testres-scheduler/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 432272 2014-04-10 20:51:27Z zakharov $
+# $Id: Manifest 520936 2016-12-02 23:17:48Z zakharov $
 #
 # Author: Mikhail Zakharov (template by Sergey Satskiy)
 #
@@ -22,6 +22,8 @@ COPY: $srcdir/src/internal/cppcore/testres/web/presenters/ $installdir
 #ini file
 COPY: $srcdir/src/internal/cppcore/testres/scheduler/testres_scheduler.ini $installdir/bin
 
-Linux64-Centos  : plain  : GCC.sh      --without-debug --with-mt --with-static --without-runpath --with-flat-makefile --without-ncbi-c
+Linux64-Centos : O2g : GCC.sh 4.9.3 --without-debug --with-symbols --with-mt --with-static --without-runpath --with-flat-makefile --without-ncbi-c
 
+Linux64-Centos : dbg  : GCC.sh 4.9.3 --with-debug --with-symbols --with-mt --with-static --without-runpath --with-flat-makefile --without-ncbi-c
+Linux64-Centos : O2   : GCC.sh 4.9.3 --without-debug --with-mt --with-static --without-runpath --with-flat-makefile --without-ncbi-c
 
diff --git a/c++/scripts/projects/testres-scheduler/components.link b/c++/scripts/projects/testres-scheduler/components.link
index bbb94f0..99d5fc8 100644
--- a/c++/scripts/projects/testres-scheduler/components.link
+++ b/c++/scripts/projects/testres-scheduler/components.link
@@ -1,6 +1,6 @@
 [components]
 #infrastructure  16.1
 #core            16.1
-web             16.1
-misc            16.1
-app             16.1
+web             18.0
+misc            18.0
+app             18.0
diff --git a/c++/scripts/projects/xmlwrapp/Manifest b/c++/scripts/projects/xmlwrapp/Manifest
index 2d8df7f..0635797 100644
--- a/c++/scripts/projects/xmlwrapp/Manifest
+++ b/c++/scripts/projects/xmlwrapp/Manifest
@@ -1,7 +1,7 @@
 #
 # Filename: Manifest
 #
-# $Id: Manifest 491986 2016-02-10 22:03:08Z fukanchi $
+# $Id: Manifest 517162 2016-10-20 22:47:37Z fukanchi $
 #
 # Author: Sergey Satskiy
 #
@@ -31,24 +31,26 @@ FreeBSD64         : plain          : Clang.sh         --without-debug --with-mt
 
 Linux64-Centos    : plain-GCC      : GCC.sh           --without-debug --with-mt    --without-runpath --with-flat-makefile
 Linux64-Centos    : GCC-nomt       : GCC.sh           --without-debug --without-mt --without-runpath --with-flat-makefile
-Linux64-Centos    : ICC-13      : ICC.sh 13.0      --without-debug --with-mt    --without-runpath --with-flat-makefile
-Linux64-Centos    : ICC-135      : ICC.sh 13.5      --without-debug --with-mt    --without-runpath --with-flat-makefile
-Linux64-Centos    : ICC-15      : ICC.sh 15.0      --without-debug --with-mt    --without-runpath --with-flat-makefile
-Linux64-Centos    : plain-ICC      : ICC.sh      --without-debug --with-mt    --without-runpath --with-flat-makefile
+Linux64-Centos    : ICC-13         : ICC.sh 13.0      --without-debug --with-mt    --without-runpath --with-flat-makefile
+Linux64-Centos    : ICC-135        : ICC.sh 13.5      --without-debug --with-mt    --without-runpath --with-flat-makefile
+Linux64-Centos    : ICC-15         : ICC.sh 15.0      --without-debug --with-mt    --without-runpath --with-flat-makefile
+Linux64-Centos    : plain-ICC      : ICC.sh           --without-debug --with-mt    --without-runpath --with-flat-makefile
 
 Linux64-Ubuntu    : plain-GCC      : GCC.sh           --without-debug --with-mt    --without-runpath --with-flat-makefile
 Linux32-Ubuntu    : plain-GCC      : GCC.sh           --without-debug --with-mt    --without-runpath --with-flat-makefile
 
 Cygwin64          : GCC            : GCC.sh           --without-debug --with-mt    --without-runpath --with-flat-makefile
 
-IntelMAC          : GCC-universal  : GCC.sh           --without-debug --with-mt    --without-runpath --with-flat-makefile --with-universal=i386,x86_64 --with-3psw=system:netopt --without-ncbi-public
+IntelMAC          : plain  : GCC.sh                   --without-debug --with-mt    --without-runpath --with-flat-makefile --with-3psw=system:netopt --without-ncbi-public
 IntelMAC          : GCC            : GCC.sh           --without-debug --with-mt    --without-runpath --with-flat-makefile
 
-Win32_13          : 13-static-32   : static 32 ReleaseDLL
+Win64_13          : 13-debug-64   : static 64 DebugDLL
 Win64_13          : 13-static-64   : static 64 ReleaseDLL
 
 XCode             : plain          : Xcode.sh 30
 
 
 
-IntelMAC-Clang36  : clang : Clang.sh           --without-debug --with-mt    --without-runpath --with-flat-makefile --with-universal=i386,x86_64 --with-3psw=system:netopt --without-ncbi-public
+IntelMAC-Clang36  : clang          : Clang.sh         --without-debug --with-mt    --without-runpath --with-flat-makefile --with-3psw=system:netopt --without-ncbi-public
+
+Linux64-Centos7    : Release       : GCC.sh           --without-debug --with-mt    --without-runpath --with-flat-makefile
diff --git a/c++/src/Makefile.in b/c++/src/Makefile.in
index 86fd134..f44cbac 100644
--- a/c++/src/Makefile.in
+++ b/c++/src/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in 500618 2016-05-05 19:15:27Z blastadm $
+# $Id: Makefile.in 521318 2016-12-07 19:37:59Z blastadm $
 
 # Master (top-level) makefile for all NCBI C++ projects
 ##################################################################
diff --git a/c++/src/algo/blast/Makefile.blast_macros.mk b/c++/src/algo/blast/Makefile.blast_macros.mk
index d9ca4a3..7870c5e 100644
--- a/c++/src/algo/blast/Makefile.blast_macros.mk
+++ b/c++/src/algo/blast/Makefile.blast_macros.mk
@@ -1,5 +1,5 @@
 #################################
-# $Id: Makefile.blast_macros.mk 457267 2015-01-21 19:46:09Z boratyng $
+# $Id: Makefile.blast_macros.mk 499473 2016-04-26 14:40:22Z camacho $
 # This file contains macro definitions for using libraries maintained by the
 # BLAST TEAM
 # Author:  Christiam Camacho (camacho at ncbi.nlm.nih.gov)
@@ -10,7 +10,7 @@ BLAST_FORMATTER_MINIMAL_LIBS = xblastformat align_format taxon1 blastdb_format \
     gene_info $(XFORMAT_LIBS) xalnmgr blastxml blastxml2 xcgi xhtml
 # BLAST_FORMATTER_LIBS = $(BLAST_FORMATTER_MINIMAL_LIBS)
 BLAST_FORMATTER_LIBS = $(BLAST_INPUT_LIBS)
-BLAST_DB_DATA_LOADER_LIBS = ncbi_xloader_blastdb ncbi_xloader_blastdb_rmt
+BLAST_DB_DATA_LOADER_LIBS = ncbi_xloader_blastdb_rmt ncbi_xloader_blastdb
 BLAST_INPUT_LIBS = blastinput \
     $(BLAST_DB_DATA_LOADER_LIBS) $(BLAST_FORMATTER_MINIMAL_LIBS)
 
@@ -19,6 +19,6 @@ BLAST_SRA_LIBS=blast_sra $(SRAXF_LIBS) vxf $(SRA_LIBS)
 
 # BLAST_FORMATTER_LIBS and BLAST_INPUT_LIBS need $BLAST_LIBS
 BLAST_LIBS = xblast xalgoblastdbindex composition_adjustment \
-		xalgodustmask xalgowinmask seqmasks_io seqdb blast_services xobjutil \
-		$(OBJREAD_LIBS) xnetblastcli xnetblast blastdb scoremat tables xalnmgr
+		xalgodustmask xalgowinmask seqmasks_io seqdb blast_services xalnmgr \
+		xobjutil $(OBJREAD_LIBS) xnetblastcli xnetblast blastdb scoremat tables
 # BLAST additionally needs xconnect $(SOBJMGR_LIBS) or $(OBJMGR_LIBS)
diff --git a/c++/src/algo/blast/Makefile.in b/c++/src/algo/blast/Makefile.in
index 14e720d..054e756 100644
--- a/c++/src/algo/blast/Makefile.in
+++ b/c++/src/algo/blast/Makefile.in
@@ -1,10 +1,10 @@
-# $Id: Makefile.in 319820 2011-07-25 20:22:28Z maning $
+# $Id: Makefile.in 507884 2016-07-22 02:13:25Z ucko $
 
 # Meta-makefile ("BLAST" project)
 #################################
 
-SUB_PROJ = composition_adjustment core dbindex dbindex_search api format blastinput \
-           igblast gumbel_params unit_tests
+SUB_PROJ = composition_adjustment core dbindex dbindex_search api format \
+           blastinput blast_sra_input igblast gumbel_params unit_tests
 
 WATCHERS = camacho madden
 
diff --git a/c++/src/algo/blast/api/Makefile.xblast.lib b/c++/src/algo/blast/api/Makefile.xblast.lib
index 18108c1..52c95d7 100644
--- a/c++/src/algo/blast/api/Makefile.xblast.lib
+++ b/c++/src/algo/blast/api/Makefile.xblast.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.xblast.lib 427427 2014-02-20 13:40:13Z gouriano $
+# $Id: Makefile.xblast.lib 504861 2016-06-20 15:45:40Z boratyng $
 
 include $(srcdir)/../core/Makefile.blast.lib
 
@@ -72,7 +72,9 @@ rpsblast_local \
 seedtop \
 cdd_pssm_input \
 deltablast_options \
-deltablast
+deltablast \
+magicblast_options \
+magicblast
 
 SRC  = $(SRC_C:%=.core_%) $(SRC_CXX)
 
diff --git a/c++/src/algo/blast/api/bioseq_extract_data_priv.cpp b/c++/src/algo/blast/api/bioseq_extract_data_priv.cpp
index 6a7e63a..baa24f5 100644
--- a/c++/src/algo/blast/api/bioseq_extract_data_priv.cpp
+++ b/c++/src/algo/blast/api/bioseq_extract_data_priv.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: bioseq_extract_data_priv.cpp 144802 2008-11-03 20:57:20Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
@@ -56,6 +52,9 @@ static char const rcsid[] =
 #include <objects/seq/Seqdesc.hpp>
 #include <objects/seqfeat/BioSource.hpp>
 #include <objects/seq/Seq_inst.hpp>
+#include <objects/general/User_object.hpp> // for has_pair
+#include <objects/general/User_field.hpp>
+#include <objects/general/Object_id.hpp>
 
 // Private BLAST API headers
 #include "blast_setup.hpp"
@@ -372,6 +371,50 @@ CBlastQuerySourceBioseqSet::GetTitle(int index) const
     return retval;
 }
 
+bool
+CBlastQuerySourceBioseqSet::IsFirstOfAPair(int index) const
+{
+    return GetSegmentInfo(index) == eFirstSegment;
+}
+
+
+int
+CBlastQuerySourceBioseqSet::GetSegmentInfo(int index) const
+{
+    // FIXME: this is a hack, a better field in Bioseq may be needed to store
+    // this information
+    CConstRef<CBioseq> bioseq = m_Bioseqs[index];
+    int retval = 0;
+    if (!bioseq->CanGetDescr()) {
+        return retval;
+    }
+    const CSeq_descr::Tdata& descr = bioseq->GetDescr().Get();
+    ITERATE(CSeq_descr::Tdata, desc, descr) {
+        if ((*desc)->Which() == CSeqdesc::e_User) {
+
+            if (!(*desc)->GetUser().IsSetType() ||
+                !(*desc)->GetUser().GetType().IsStr() ||
+                (*desc)->GetUser().GetType().GetStr() != "Mapping") {
+                continue;
+            }
+
+            if (!(*desc)->GetUser().HasField("has_pair")) {
+                break;
+            }
+
+            const CUser_field& field = (*desc)->GetUser().GetField("has_pair");
+            if (!field.GetData().IsInt()) {
+                break;
+            }
+
+            retval = field.GetData().GetInt();
+        }
+    }
+
+    return retval;
+}
+
+
 void 
 CBlastQuerySourceBioseqSet::x_BioseqSanityCheck(const objects::CBioseq& bs) 
 {
diff --git a/c++/src/algo/blast/api/bioseq_extract_data_priv.hpp b/c++/src/algo/blast/api/bioseq_extract_data_priv.hpp
index b7fd381..35364bd 100644
--- a/c++/src/algo/blast/api/bioseq_extract_data_priv.hpp
+++ b/c++/src/algo/blast/api/bioseq_extract_data_priv.hpp
@@ -1,4 +1,4 @@
-/*  $Id: bioseq_extract_data_priv.hpp 144802 2008-11-03 20:57:20Z camacho $
+/*  $Id: bioseq_extract_data_priv.hpp 517499 2016-10-25 17:20:41Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -179,6 +179,13 @@ public:
     /// @param index index of the sequence in the sequence container [in]
     virtual string GetTitle(int index) const;
 
+    /// Is this sequence followed by a mate (for mapping short reads)
+    NCBI_DEPRECATED virtual bool IsFirstOfAPair(int index) const;
+
+    /// Get segment information (for mapping paired short reads)
+    virtual int GetSegmentInfo(int index) const;
+
+
 private:
     /// True if the data contained in this object is protein
     bool m_IsProt;
diff --git a/c++/src/algo/blast/api/blast_aux.cpp b/c++/src/algo/blast/api/blast_aux.cpp
index 1d74083..956d0b9 100644
--- a/c++/src/algo/blast/api/blast_aux.cpp
+++ b/c++/src/algo/blast/api/blast_aux.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_aux.cpp 437219 2014-06-04 13:04:32Z camacho $
+/*  $Id: blast_aux.cpp 509279 2016-08-04 16:02:34Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -53,6 +53,11 @@
 #include "blast_setup.hpp"
 #include "blast_aux_priv.hpp"
 
+#include <objects/seq/Seq_ext.hpp>
+#include <objects/seq/Delta_seq.hpp>
+#include <objects/seq/Delta_ext.hpp>
+#include <objmgr/seq_map_ci.hpp>
+
 #include <algorithm>
 #include <sstream>
 
@@ -686,6 +691,7 @@ string EProgramToTaskName(EProgram p)
     case ePHIBlastn:        retval.assign("phiblastn"); break;
     case eDeltaBlast:       retval.assign("deltablast"); break;
     case eVecScreen:        retval.assign("vecscreen"); break;
+    case eMapper:           retval.assign("mapr2g"); break;
     default:
         cerr << "Invalid EProgram value: " << (int)p << endl;
         abort();
@@ -707,6 +713,9 @@ EProgramToEBlastProgramType(EProgram p)
     case eDiscMegablast:
     case eVecScreen:
         return eBlastTypeBlastn;
+
+    case eMapper:
+        return eBlastTypeMapping;
         
     case eBlastp:
         return eBlastTypeBlastp;
@@ -784,6 +793,16 @@ EProgram ProgramNameToEnum(const std::string& program_name)
         return eDeltaBlast;
     } else if (lowercase_program_name == "vecscreen") {
         return eVecScreen;
+    // FIXME: mapper is used in core as a single program name for all tasks,
+    // we may need a better approach to mapping tasks with fewer program names
+    } else if (lowercase_program_name == "mapper") {
+        return eMapper;
+    } else if (lowercase_program_name == "mapr2g") {
+        return eMapper;
+    } else if (lowercase_program_name == "mapr2r") {
+        return eMapper;
+    } else if (lowercase_program_name == "mapg2g") {
+        return eMapper;
     } else {
         NCBI_THROW(CBlastException, eNotSupported, 
                    "Program type '" + program_name + "' not supported");
@@ -898,7 +917,7 @@ Blast_GetSeqLocInfoVector(EBlastProgramType program,
         NCBI_THROW(CBlastException, eInvalidArgument, msg);
     }
 
-    if (program == eBlastTypeBlastn) {
+    if (program == eBlastTypeBlastn || program == eBlastTypeMapping) {
         s_ConvertBlastnMasks(query_intervals, mask, mask_v);
         return;
     }
@@ -1087,6 +1106,51 @@ IsLocalId(const objects::CSeq_id* seqid)
     return retval;
 }
 
+void
+LoadSequencesToScope(CScope::TIds& ids, vector<TSeqRange>& ranges, CRef<CScope> & scope)
+{
+	CScope::TBioseqHandles bhs = scope->GetBioseqHandles(ids);
+
+    // Per Eugene Vasilchenko's suggestion, via email on 6/8/10:
+    // "With the current API you can make artificial delta sequence
+    // referencing several other sequences and use its CSeqMap to load them
+    // all in one call. There is no straightforward way to do this, sorry."
+
+    // Create virtual delta sequence
+	CRef<CBioseq> top_seq(new CBioseq);
+    CSeq_inst& inst = top_seq->SetInst();
+    inst.SetRepr(CSeq_inst::eRepr_virtual);
+    inst.SetMol(CSeq_inst::eMol_not_set);
+    CDelta_ext& delta = inst.SetExt().SetDelta();
+    int i = 0;
+    ITERATE(CScope::TBioseqHandles, it, bhs) {
+    	CRef<CDelta_seq> seq(new CDelta_seq);
+	    CSeq_interval& interval = seq->SetLoc().SetInt();
+	    interval.SetId(*SerialClone(*it->GetAccessSeq_id_Handle().GetSeqId()));
+	    if (ranges[i].GetFrom() > ranges[i].GetToOpen()) {
+	    	TSeqPos length = it->GetBioseqLength();
+	        interval.SetFrom(length - ranges[i].GetFrom());
+	        interval.SetTo(length - ranges[i].GetTo());
+	    } else {
+	        interval.SetFrom(ranges[i].GetFrom());
+	        interval.SetTo(ranges[i].GetTo());
+	    }
+	    i++;
+	    delta.Set().push_back(seq);
+    }
+
+    // Add it to the scope
+    CBioseq_Handle top_bh = scope->AddBioseq(*top_seq);
+
+    // prepare selector. SetLinkUsedTSE() is necessary for batch loading
+	SSeqMapSelector sel(CSeqMap::fFindAnyLeaf, kInvalidSeqPos);
+	sel.SetLinkUsedTSE(top_bh.GetTSE_Handle());
+
+	// and get all sequence data in batch mode
+	_TRACE("Fetching " << ids.size() << " sequences");
+	top_bh.GetSeqMap().CanResolveRange(&*scope, sel);
+}
+
 END_SCOPE(blast)
 END_NCBI_SCOPE
 
diff --git a/c++/src/algo/blast/api/blast_aux_priv.cpp b/c++/src/algo/blast/api/blast_aux_priv.cpp
index d2382cb..8e4be3e 100644
--- a/c++/src/algo/blast/api/blast_aux_priv.cpp
+++ b/c++/src/algo/blast/api/blast_aux_priv.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_aux_priv.cpp 443924 2014-08-20 15:03:37Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
@@ -173,11 +169,12 @@ BlastSetupPreliminarySearchEx(CRef<IQueryFactory> qf,
     // 4. Create the BlastScoreBlk
     BlastSeqLoc* lookup_segments = NULL;
     BlastScoreBlk* sbp = NULL;
+    bool is_mapper = (options->GetProgram() == eMapper);
     try {
     	sbp =
         CSetupFactory::CreateScoreBlock(opts_memento.get(), query_data, 
                                         &lookup_segments, retval->m_Messages, 
-                                        &retval->m_Masks, 
+                                        (is_mapper ? NULL : &retval->m_Masks), 
                                         retval->m_InternalData->m_RpsData);
     } catch (CBlastException & e) {
     	const string  kCatchThisError (kBlastErrMsg_CantCalculateUngappedKAParams);
@@ -229,6 +226,7 @@ BlastSetupPreliminarySearchEx(CRef<IQueryFactory> qf,
         CSetupFactory::CreateHspStream(opts_memento.get(),
                                        query_data->GetNumQueries(),
         CSetupFactory::CreateHspWriter(opts_memento.get(),
+                                       retval->m_InternalData->m_Queries,
                                        query_data->GetQueryInfo()));
     
     if (is_multi_threaded) 
diff --git a/c++/src/algo/blast/api/blast_mtlock.cpp b/c++/src/algo/blast/api/blast_mtlock.cpp
index bedea6e..286e89d 100644
--- a/c++/src/algo/blast/api/blast_mtlock.cpp
+++ b/c++/src/algo/blast/api/blast_mtlock.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_mtlock.cpp 103491 2007-05-04 17:18:18Z kazimird $
+/*  $Id: blast_mtlock.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Initialization for the mutex locking interface. 
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_mtlock.cpp 103491 2007-05-04 17:18:18Z kazimird $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbimtx.hpp>
 #include <algo/blast/api/blast_mtlock.hpp>
diff --git a/c++/src/algo/blast/api/blast_nucl_options.cpp b/c++/src/algo/blast/api/blast_nucl_options.cpp
index 2d1f83a..c3754b2 100644
--- a/c++/src/algo/blast/api/blast_nucl_options.cpp
+++ b/c++/src/algo/blast/api/blast_nucl_options.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_nucl_options.cpp 456407 2015-01-12 15:47:18Z fongah2 $
+/*  $Id: blast_nucl_options.cpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -139,6 +139,7 @@ CBlastNucleotideOptionsHandle::SetLookupTableDefaults()
     SetLookupTableType(eNaLookupTable);
     SetWordSize(BLAST_WORDSIZE_NUCL);
     m_Opts->SetWordThreshold(BLAST_WORD_THRESHOLD_BLASTN);
+    m_Opts->SetLookupTableStride(0);
 }
 
 void 
@@ -147,6 +148,7 @@ CBlastNucleotideOptionsHandle::SetMBLookupTableDefaults()
     SetLookupTableType(eMBLookupTable);
     SetWordSize(BLAST_WORDSIZE_MEGABLAST);
     m_Opts->SetWordThreshold(BLAST_WORD_THRESHOLD_MEGABLAST);
+    m_Opts->SetLookupTableStride(0);
 }
 
 void
diff --git a/c++/src/algo/blast/api/blast_objmgr_priv.hpp b/c++/src/algo/blast/api/blast_objmgr_priv.hpp
index 9a71445..d0b7f0c 100644
--- a/c++/src/algo/blast/api/blast_objmgr_priv.hpp
+++ b/c++/src/algo/blast/api/blast_objmgr_priv.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_objmgr_priv.hpp 151315 2009-02-03 18:13:26Z camacho $
+/*  $Id: blast_objmgr_priv.hpp 517499 2016-10-25 17:20:41Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -149,6 +149,17 @@ public:
     /// Return the title of a sequence
     /// @param index index of the sequence in the sequence container [in]
     virtual string GetTitle(int index) const;
+
+    /// Is this sequence followed by a mate (for mapping short reads)
+    NCBI_DEPRECATED virtual bool IsFirstOfAPair(int index) const
+    { NCBI_THROW(CException, eInvalid, "Function "
+                 "CBlasyQuerySourceOM::IsFirstOfAPair was not implemented");}
+
+    /// Get segment information (for mapping paired short reads)
+    virtual int GetSegmentInfo(int index) const
+    { NCBI_THROW(CException, eInvalid, "Function "
+                 "CBlasyQuerySourceOM::GetSegmentInfo was not implemented");}
+
     
 protected:
     /// Reference to input CBlastQueryVector (or empty if not used)
diff --git a/c++/src/algo/blast/api/blast_objmgr_tools.cpp b/c++/src/algo/blast/api/blast_objmgr_tools.cpp
index 200f216..45f84d1 100644
--- a/c++/src/algo/blast/api/blast_objmgr_tools.cpp
+++ b/c++/src/algo/blast/api/blast_objmgr_tools.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_objmgr_tools.cpp 495292 2016-03-16 14:52:49Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
diff --git a/c++/src/algo/blast/api/blast_options_builder.cpp b/c++/src/algo/blast/api/blast_options_builder.cpp
index 97b701a..e80995b 100644
--- a/c++/src/algo/blast/api/blast_options_builder.cpp
+++ b/c++/src/algo/blast/api/blast_options_builder.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_options_builder.cpp 482563 2015-10-23 20:19:28Z fongah2 $
+/*  $Id: blast_options_builder.cpp 513039 2016-09-06 19:42:59Z fukanchi $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -109,6 +109,9 @@ CBlastOptionsBuilder::ComputeProgram(const string & program,
             p = "psitblastn";
             found = true;
         }
+        if ((s == "sra") || (s == "wgs")) {
+        	found = true;
+        }
     } else if (p == "tblastx") {
         found = true;
     } else if (p == "blastx") {
@@ -258,7 +261,17 @@ x_ProcessOneOption(CBlastOptionsHandle        & opts,
         	}
         	m_GiList = gi_list;
             #elif defined(NCBI_INT8_GI)
-                m_GiList = v.GetBig_integer_list();
+		if(v.IsBig_integer_list()) {
+                	m_GiList = v.GetBig_integer_list();
+		}
+		else {
+			const list<int>& int_list = v.GetInteger_list();
+        		list<TGi> gi_list;
+        		ITERATE ( list<int>, it, int_list ) {
+        			gi_list.push_back(GI_FROM(int, *it));
+        		}
+        		m_GiList = gi_list;
+		}
 	    #else
             m_GiList = v.GetInteger_list();
 	    #endif
@@ -364,7 +377,17 @@ x_ProcessOneOption(CBlastOptionsHandle        & opts,
         	}
         	m_NegativeGiList = gi_list;
             #elif defined(NCBI_INT8_GI)
-            	m_NegativeGiList = v.GetBig_integer_list();
+		if (v.IsBig_integer_list()) {
+            		m_NegativeGiList = v.GetBig_integer_list();
+		}
+		else {
+			const list<int>& int_list = v.GetInteger_list();
+        		list<TGi> gi_list;
+        		ITERATE ( list<int>, it, int_list ) {
+        			gi_list.push_back(GI_FROM(int, *it));
+        		}
+        		m_NegativeGiList = gi_list;
+		}
 	    #else
             m_NegativeGiList = v.GetInteger_list();
 	    #endif
diff --git a/c++/src/algo/blast/api/blast_options_cxx.cpp b/c++/src/algo/blast/api/blast_options_cxx.cpp
index e6bf3a1..2f9f845 100644
--- a/c++/src/algo/blast/api/blast_options_cxx.cpp
+++ b/c++/src/algo/blast/api/blast_options_cxx.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_options_cxx.cpp 456407 2015-01-12 15:47:18Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
@@ -919,6 +915,37 @@ CBlastOptions::SetWordSize(int ws)
     }
 }
 
+Uint4 CBlastOptions::GetLookupTableStride() const
+{
+	if (!m_Local) {
+        x_Throwx("Error: GetLookupTableStride not available.");
+	}
+    return m_Local->GetLookupTableStride();
+}
+void CBlastOptions::SetLookupTableStride(Uint4 val)
+{
+	if (!m_Local) {
+        x_Throwx("Error: SetLookupTableStride not available.");
+	}
+    m_Local->SetLookupTableStride(val);
+}
+
+bool CBlastOptions::GetLookupDbFilter() const
+{
+	if (!m_Local) {
+        x_Throwx("Error: GetLookupDbFilter not available.");
+	}
+    return m_Local->GetLookupDbFilter();
+}
+
+void CBlastOptions::SetLookupDbFilter(bool val)
+{
+	if (!m_Local) {
+        x_Throwx("Error: SetLookupDbFilter not yet available.");
+	}
+    m_Local->SetLookupDbFilter(val);
+}
+
 /// Megablast only lookup table options
 unsigned char 
 CBlastOptions::GetMBTemplateLength() const
@@ -1583,6 +1610,49 @@ CBlastOptions::SetUnifiedP(int u)
       m_Remote->SetValue(eBlastOpt_UnifiedP, u);
    }
 }
+
+int
+CBlastOptions::GetMaxMismatches() const
+{
+    if (! m_Local) {
+        x_Throwx("Error: GetMaxMismatches() not available.");
+    }
+
+    return m_Local->GetMaxMismatches();
+}
+
+void
+CBlastOptions::SetMaxMismatches(int m)
+{
+    if (m_Local) {
+	m_Local->SetMaxMismatches(m);
+    }
+    else {
+        x_Throwx("Error: GetMaxMismatches() not supported for remote searches");
+    }
+}
+
+
+int
+CBlastOptions::GetMismatchWindow() const
+{
+    if (! m_Local) {
+        x_Throwx("Error: GetMismatchWindow() not available.");
+    }
+
+    return m_Local->GetMismatchWindow();
+}
+
+void
+CBlastOptions::SetMismatchWindow(int w)
+{
+    if (m_Local) {
+	m_Local->SetMismatchWindow(w);
+    }
+    else {
+        x_Throwx("Error: GetMismatchWindow() not supported for remote searches");
+    }
+}
  
 
 /******************* Hit saving options *************************/
@@ -1913,6 +1983,47 @@ CBlastOptions::SetLowScorePerc(double p)
 }
 
 
+bool
+CBlastOptions::GetPaired() const
+{
+    if (! m_Local) {
+        x_Throwx("Error: GetPaired() not available.");
+    }
+    return m_Local->GetPaired();
+}
+
+void
+CBlastOptions::SetPaired(bool p)
+{
+    if (m_Local) {
+        m_Local->SetPaired(p);
+    }
+    else {
+        x_Throwx("Error: SetPaired() not available.");
+    }
+}
+
+
+bool
+CBlastOptions::GetSpliceAlignments() const
+{
+    if (! m_Local) {
+        x_Throwx("Error: GetSplice() not available.");
+    }
+    return m_Local->GetSplice();
+}
+
+void
+CBlastOptions::SetSpliceAlignments(bool s)
+{
+    if (m_Local) {
+        m_Local->SetSplice(s);
+    }
+    else {
+        x_Throwx("Error: SetSplice() not available.");
+    }
+}
+
 
 /************************ Scoring options ************************/
 const char* 
diff --git a/c++/src/algo/blast/api/blast_options_handle.cpp b/c++/src/algo/blast/api/blast_options_handle.cpp
index 0a0bd1e..1845678 100644
--- a/c++/src/algo/blast/api/blast_options_handle.cpp
+++ b/c++/src/algo/blast/api/blast_options_handle.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_options_handle.cpp 442215 2014-07-31 14:00:16Z fongah2 $
+/*  $Id: blast_options_handle.cpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -47,6 +47,7 @@
 #include <algo/blast/api/phiblast_nucl_options.hpp>
 #include <algo/blast/api/phiblast_prot_options.hpp>
 #include <algo/blast/api/deltablast_options.hpp>
+#include <algo/blast/api/magicblast_options.hpp>
 
 /** @addtogroup AlgoBlast
  *
@@ -186,6 +187,10 @@ CBlastOptionsFactory::Create(EProgram program, EAPILocality locality)
         break;
 	}
 
+    case eMapper:
+        retval = new CMagicBlastOptionsHandle(locality);
+        break;
+
     case eBlastNotSet:
         NCBI_THROW(CBlastException, eInvalidArgument,
                    "eBlastNotSet may not be used as argument");
@@ -233,6 +238,13 @@ CBlastOptionsFactory::GetTasks(ETaskSets choice /* = eAll */)
         retval.insert("tblastx");
     }
 
+    if (choice == eMapping || choice == eAll) {
+        retval.insert("mapper");
+        retval.insert("mapr2g");
+        retval.insert("mapr2r");
+        retval.insert("mapg2g");
+    }
+
     return retval;
 }
 
@@ -298,6 +310,14 @@ CBlastOptionsFactory::GetDocumentation(const string& task_name)
     } else if (task == "deltablast") {
         retval.assign("DELTA-BLAST builds profile using conserved domain ");
         retval += "and uses this profile to search protein database";
+    } else if (task == "mapper") {
+        retval.assign("Map short reads to a genome");
+    } else if (task == "mapr2g") {
+        retval.assign("Map RNA-seq sequence to a genome");
+    } else if (task == "mapr2r") {
+        retval.assign("Map RNA-seq sequences to an mRNA database");
+    } else if (task == "mapg2g") {
+        retval.assign("Map genomic reads to a genome");
     } else {
         retval.assign("Unknown task");
     }
@@ -424,6 +444,27 @@ CBlastOptionsFactory::CreateTask(string task, EAPILocality locality)
     {
          retval = CBlastOptionsFactory::Create(eDeltaBlast, locality);
     }
+    else if (!NStr::CompareNocase(task, "mapper") ||
+             !NStr::CompareNocase(task, "mapr2g") ||
+             !NStr::CompareNocase(task, "mapr2r") ||
+             !NStr::CompareNocase(task, "mapg2g")) {
+
+        CMagicBlastOptionsHandle* opts =
+            dynamic_cast<CMagicBlastOptionsHandle*>
+            (CBlastOptionsFactory::Create(eMapper, locality));
+
+        if (!NStr::CompareNocase(task, "mapr2g")) {
+            opts->SetRNAToGenomeDefaults();
+        }
+        else if (!NStr::CompareNocase(task, "mapr2r")) {
+            opts->SetRNAToRNADefaults();
+        }
+        else {
+            opts->SetGenomeToGenomeDefaults();
+        }
+
+        retval = opts;
+    }
     else
     {
         abort();    // should never get here
diff --git a/c++/src/algo/blast/api/blast_options_local_priv.cpp b/c++/src/algo/blast/api/blast_options_local_priv.cpp
index 4603df7..1c38b5c 100644
--- a/c++/src/algo/blast/api/blast_options_local_priv.cpp
+++ b/c++/src/algo/blast/api/blast_options_local_priv.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_options_local_priv.cpp 463310 2015-03-26 17:00:09Z boukn $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
@@ -383,7 +379,8 @@ CBlastOptionsLocal::Validate() const
     else
         // Index validation.
         if( m_UseMBIndex && 
-                (m_Program != eMegablast && m_Program != eBlastn) ) {
+                (m_Program != eMegablast && m_Program != eBlastn
+                 && m_Program != eMapper) ) {
             NCBI_THROW(CBlastException, eInvalidOptions, 
                     "Database index can be used only with contiguous megablast." );
         }
diff --git a/c++/src/algo/blast/api/blast_options_local_priv.hpp b/c++/src/algo/blast/api/blast_options_local_priv.hpp
index 4c40d0a..38e2277 100644
--- a/c++/src/algo/blast/api/blast_options_local_priv.hpp
+++ b/c++/src/algo/blast/api/blast_options_local_priv.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_options_local_priv.hpp 460349 2015-02-26 16:10:16Z fongah2 $
+/*  $Id: blast_options_local_priv.hpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -87,6 +87,11 @@ public:
     int GetWordSize() const;
     void SetWordSize(int ws);
 
+    /// Skip words after each collected one while creating a lookup table
+    /// (currently only for megablast)
+    Uint4 GetLookupTableStride() const;
+    void SetLookupTableStride(Uint4 val);
+
     /// Megablast only lookup table options
     unsigned char GetMBTemplateLength() const;
     void SetMBTemplateLength(unsigned char len);
@@ -94,6 +99,9 @@ public:
     unsigned char GetMBTemplateType() const;
     void SetMBTemplateType(unsigned char type);
 
+    bool GetLookupDbFilter(void) const;
+    void SetLookupDbFilter(bool val);
+
     /******************* Query setup options ************************/
     char* GetFilterString() const;
     void SetFilterString(const char* f);
@@ -175,6 +183,12 @@ public:
     int GetUnifiedP() const;
     void SetUnifiedP(int u = 0);
 
+    int GetMaxMismatches() const;
+    void SetMaxMismatches(int m);
+
+    int GetMismatchWindow() const;
+    void SetMismatchWindow(int w);
+
     /******************* Hit saving options *************************/
     int GetHitlistSize() const;
     void SetHitlistSize(int s);
@@ -230,6 +244,14 @@ public:
     double GetLowScorePerc() const;
     void SetLowScorePerc(double p = 0.0);
 
+    // Paired reads only if set to true
+    bool GetPaired() const;
+    void SetPaired(bool p);
+
+    /// Splice HSPs for each query
+    bool GetSplice() const;
+    void SetSplice(bool p);
+
     /// Returns true if cross_match-like complexity adjusted
     //  scoring is required, false otherwise. -RMH-
     bool GetComplexityAdjMode() const;
@@ -572,6 +594,18 @@ CBlastOptionsLocal::SetWordSize(int ws)
 	m_LutOpts->lut_type = eCompressedAaLookupTable;
 }
 
+inline Uint4
+CBlastOptionsLocal::GetLookupTableStride() const
+{
+    return m_LutOpts->stride;
+}
+
+inline void
+CBlastOptionsLocal::SetLookupTableStride(Uint4 val)
+{
+    m_LutOpts->stride = val;
+}
+
 inline unsigned char
 CBlastOptionsLocal::GetMBTemplateLength() const
 {
@@ -596,6 +630,18 @@ CBlastOptionsLocal::SetMBTemplateType(unsigned char type)
     m_LutOpts->mb_template_type = type;
 }
 
+inline bool
+CBlastOptionsLocal::GetLookupDbFilter(void) const
+{
+    return m_LutOpts->db_filter;
+}
+
+inline void
+CBlastOptionsLocal::SetLookupDbFilter(bool val)
+{
+    m_LutOpts->db_filter = val;
+}
+
 /******************* Query setup options ************************/
 
 inline char*
@@ -638,7 +684,8 @@ CBlastOptionsLocal::SetFilterString(const char* f)
    }
 
    // Repeat filtering is only allowed for blastn.
-   if (GetProgramType() != eBlastTypeBlastn && 
+   if (GetProgramType() != eBlastTypeBlastn &&
+       GetProgramType() != eBlastTypeMapping && 
        m_QueryOpts->filtering_options->repeatFilterOptions)
        m_QueryOpts->filtering_options->repeatFilterOptions =
            SRepeatFilterOptionsFree(m_QueryOpts->filtering_options->repeatFilterOptions);
@@ -1077,6 +1124,30 @@ CBlastOptionsLocal::SetUnifiedP(int u)
    m_ExtnOpts->unifiedP = u;
 }
 
+inline int
+CBlastOptionsLocal::GetMaxMismatches() const
+{
+    return m_ExtnOpts->max_mismatches;
+}
+
+inline void
+CBlastOptionsLocal::SetMaxMismatches(int m)
+{
+    m_ExtnOpts->max_mismatches = m;
+}
+
+inline int
+CBlastOptionsLocal::GetMismatchWindow() const
+{
+    return m_ExtnOpts->mismatch_window;
+}
+
+inline void
+CBlastOptionsLocal::SetMismatchWindow(int w)
+{
+    m_ExtnOpts->mismatch_window = w;
+}
+
 /******************* Hit saving options *************************/
 inline int
 CBlastOptionsLocal::GetHitlistSize() const
@@ -1335,6 +1406,30 @@ CBlastOptionsLocal::SetLowScorePerc(double p)
     m_HitSaveOpts->low_score_perc = p;
 }
 
+inline bool
+CBlastOptionsLocal::GetPaired() const
+{
+    return m_HitSaveOpts->paired;
+}
+
+inline void
+CBlastOptionsLocal::SetPaired(bool p)
+{
+    m_HitSaveOpts->paired = p;
+}
+
+inline bool
+CBlastOptionsLocal::GetSplice() const
+{
+    return m_HitSaveOpts->splice;
+}
+
+inline void
+CBlastOptionsLocal::SetSplice(bool s)
+{
+    m_HitSaveOpts->splice = s;
+}
+
 /* Flag to indicate if cross_match-like complexity adjusted
    scoring is in use. Currently only used by RMBlastN. -RMH- */
 inline bool
diff --git a/c++/src/algo/blast/api/blast_results.cpp b/c++/src/algo/blast/api/blast_results.cpp
index 04f695b..3e06e35 100644
--- a/c++/src/algo/blast/api/blast_results.cpp
+++ b/c++/src/algo/blast/api/blast_results.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_results.cpp 475845 2015-08-12 14:12:44Z fongah2 $
+/*  $Id: blast_results.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  * search
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_results.cpp 475845 2015-08-12 14:12:44Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/api/blast_results.hpp>
 #include <objects/seqalign/Seq_align.hpp>
diff --git a/c++/src/algo/blast/api/blast_seqalign.cpp b/c++/src/algo/blast/api/blast_seqalign.cpp
index 0276ad2..ce423ca 100644
--- a/c++/src/algo/blast/api/blast_seqalign.cpp
+++ b/c++/src/algo/blast/api/blast_seqalign.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_seqalign.cpp 499810 2016-04-28 15:43:25Z ivanov $
+/*  $Id: blast_seqalign.cpp 520431 2016-11-28 18:26:12Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -41,8 +41,10 @@
 #include <objects/seqloc/Seq_interval.hpp>
 #include <objects/seqalign/seqalign__.hpp>
 #include <objects/general/Object_id.hpp>
+#include <objects/general/User_object.hpp>
 #include <serial/iterator.hpp>
 #include <objmgr/util/seq_align_util.hpp>
+#include "../core/jumper.h"
 
 #include <algorithm>
 
@@ -393,6 +395,123 @@ s_CorrectUASequence(BlastHSP* hsp)
     return;
 }
 
+
+void MakeSplicedSeg(CSpliced_seg& spliced_seg,
+                    CRef<CSeq_id> product_id,
+                    CRef<CSeq_id> genomic_id,
+                    int product_length,
+                    const BlastHSPChain* chain)
+{
+    spliced_seg.SetProduct_id(*product_id);
+    spliced_seg.SetGenomic_id(*genomic_id);
+    
+    _ASSERT(chain->num_hsps > 0);
+    _ASSERT(chain->hsp_array[0]);
+    ENa_strand product_strand = s_Frame2Strand(chain->hsp_array[0]->query.frame);
+    ENa_strand genomic_strand = s_Frame2Strand(
+                                        chain->hsp_array[0]->subject.frame);
+
+    spliced_seg.SetProduct_type(CSpliced_seg::eProduct_type_transcript);
+    spliced_seg.SetProduct_length(product_length);
+
+    CSpliced_seg::TExons& exons = spliced_seg.SetExons();
+    const Uint1 kGap = 15; // Gap in BLASTNA
+
+    for (int k=0;k < chain->num_hsps;k++) {
+        BlastHSP* hsp = chain->hsp_array[k];
+        _ASSERT(hsp);
+
+        _ASSERT(hsp->gap_info->size > 1 ||
+                hsp->query.end - hsp->query.offset ==
+                hsp->subject.end - hsp->subject.offset);
+
+        CRef<CSpliced_exon> exon(new CSpliced_exon);
+        exon->SetProduct_start().SetNucpos(hsp->query.offset);
+        exon->SetProduct_end().SetNucpos(hsp->query.end - 1);
+        exon->SetGenomic_start(hsp->subject.offset);
+        exon->SetGenomic_end(hsp->subject.end - 1);
+
+        exon->SetProduct_strand(product_strand);
+        exon->SetGenomic_strand(genomic_strand);
+
+        const JumperEditsBlock* hsp_edits = hsp->map_info->edits;
+        int query_pos = hsp->query.offset;
+        int subject_pos = hsp->subject.offset;
+        int num_matches = 0;
+
+        // save splice signal before next exon
+        if (hsp->map_info->left_edge & MAPPER_SPLICE_SIGNAL) {
+            CSpliced_exon::TAcceptor_before_exon::TBases l_bases(2u, ' ');
+            l_bases[0] = BLASTNA_TO_IUPACNA[
+                   (int)((hsp->map_info->left_edge >> 2) & 3)];
+            l_bases[1] = BLASTNA_TO_IUPACNA[
+                   (int)(hsp->map_info->left_edge & 3)];
+            exon->SetAcceptor_before_exon().SetBases(l_bases);
+        }
+
+        // save splice signal after exon
+        if (hsp->map_info->right_edge & MAPPER_SPLICE_SIGNAL) {
+            CSpliced_exon::TDonor_after_exon::TBases r_bases(2u, ' ');
+            r_bases[0] = BLASTNA_TO_IUPACNA[
+                (int)((hsp->map_info->right_edge >> 2) & 3)];
+            r_bases[1] = BLASTNA_TO_IUPACNA[
+                (int)(hsp->map_info->right_edge & 3)];
+            exon->SetDonor_after_exon().SetBases(r_bases);
+        }
+
+        for (int i=0;i < hsp_edits->num_edits;i++) {
+            num_matches = hsp_edits->edits[i].query_pos - query_pos;
+            query_pos += num_matches;
+            subject_pos += num_matches;
+            _ASSERT(num_matches >= 0);
+            if (num_matches > 0) {
+                // record number of matches
+                CRef<CSpliced_exon_chunk> chunk(new CSpliced_exon_chunk);
+                chunk->SetMatch(num_matches);
+                exon->SetParts().push_back(chunk);
+            }
+
+            // record mismatch or gap
+            CRef<CSpliced_exon_chunk> chunk(new CSpliced_exon_chunk);
+            _ASSERT(hsp_edits->edits[i].query_base != kGap ||
+                    hsp_edits->edits[i].subject_base != kGap);
+
+            if (hsp_edits->edits[i].query_base == kGap) {
+                chunk->SetGenomic_ins(1);
+                subject_pos++;
+            }
+            else if (hsp_edits->edits[i].subject_base == kGap) {
+                chunk->SetProduct_ins(1);
+                query_pos++;
+            }
+            else {
+                chunk->SetMismatch(1);
+                query_pos++;
+                subject_pos++;
+            }
+
+            exon->SetParts().push_back(chunk);
+        }
+
+        num_matches = MAX(hsp->query.end - query_pos, 0);
+        _ASSERT(hsp->query.end - query_pos >= -1);
+        // an HSP may end with a mismatch or a gap, if a splice signal was
+        // found and HSP extent was updated (mapping reads to a genome)
+        _ASSERT(num_matches >= 0);
+        if (num_matches > 0) {
+            CRef<CSpliced_exon_chunk> chunk(new CSpliced_exon_chunk);
+            chunk->SetMatch(num_matches);
+            exon->SetParts().push_back(chunk);
+        }
+
+        exons.push_back(exon);
+    }
+
+#if _DEBUG
+    spliced_seg.Validate(true);
+#endif
+}
+
 /// Creates a Seq-align for a single HSP from precalculated vectors of start 
 /// positions, lengths and strands of segments, sequence identifiers and other 
 /// information.
@@ -528,8 +647,11 @@ s_BlastHSP2SeqAlign(EBlastProgramType program, BlastHSP* hsp,
                               strands, query_length, subject_length,
                               translate1, translate2);
 
-        return s_CreateSeqAlign(id1, id2, starts, lengths, strands,
-                                translate1, translate2);
+        CRef<CSeq_align> retval =  s_CreateSeqAlign(id1, id2, starts, lengths,
+                                                    strands, translate1,
+                                                    translate2);
+
+        return retval;
     }
 }
 
@@ -889,9 +1011,9 @@ s_MakeScore(const string& ident_string, double d, int i, bool is_integer)
 /// Computes the exact size of a CSeq_align::TScore for a given HSP
 /// @param hsp HSP for which the score objects will be built, must be non-NULL
 /// [in]
-/// @param gi_list list of GIs associated with this HSP [in]
+/// @param seqid_list list of IDs associated with this HSP [in]
 static size_t 
-s_CalculateScoreVectorSize(const BlastHSP* hsp, const vector<int>  & gi_list)
+s_CalculateScoreVectorSize(const BlastHSP* hsp, const vector<string>  & seqid_list)
 {
     _ASSERT(hsp);
     // query coverage hsp
@@ -926,8 +1048,8 @@ s_CalculateScoreVectorSize(const BlastHSP* hsp, const vector<int>  & gi_list)
     	retval++;
     }
 
-    if ( !gi_list.empty() ) {
-        retval += gi_list.size();
+    if ( !seqid_list.empty() ) {
+        retval += seqid_list.size();
     }
     return retval;
 }
@@ -935,17 +1057,17 @@ s_CalculateScoreVectorSize(const BlastHSP* hsp, const vector<int>  & gi_list)
 /// Creates a list of score objects for a Seq-align, given an HSP structure.
 /// @param hsp Structure containing HSP information [in]
 /// @param scores Linked list of score objects to put into a Seq-align [out]
-/// @param gi_list List of GIs for the subject sequence.
+/// @param seqid_list List of GIs for the subject sequence.
 static void
 s_BuildScoreList(const BlastHSP     * hsp,
                  CSeq_align::TScore & scores,
-                 const vector<int>  & gi_list,
+                 const vector<string>  & seqid_list,
                  Int4 query_length)
 {
     if (!hsp)
         return;
 
-    scores.reserve(s_CalculateScoreVectorSize(hsp, gi_list));
+    scores.reserve(s_CalculateScoreVectorSize(hsp, seqid_list));
 
     if (hsp->score) {
         static const string kScore("score");
@@ -985,10 +1107,9 @@ s_BuildScoreList(const BlastHSP     * hsp,
                                      hsp->comp_adjustment_method, true));
     }
     
-    if ( !gi_list.empty() ) {
-        static const string kUseThisGi("use_this_gi");
-        ITERATE(vector<int>, gi, gi_list) {
-            scores.push_back(s_MakeScore(kUseThisGi, 0.0, *gi, true));
+    if ( !seqid_list.empty() ) {
+        ITERATE(vector<string>, sid, seqid_list) { 
+            scores.push_back(s_MakeScore(*sid, 0.0, 0, true));
         }
     }
     
@@ -1005,6 +1126,22 @@ s_BuildScoreList(const BlastHSP     * hsp,
     return;
 }
 
+/// Produce UserObject with Seq-ids to limit formatting to ("use_this_gi")
+/// @param seqalign Seq-align object to fill in [in][out]
+/// @param seqid_list list of strings with seqids [in]
+static void
+s_AddUserObjectToSeqAlign(CRef<CSeq_align>  & seqalign, 
+		const vector<string> & seqid_list)
+{
+	if (seqid_list.empty())
+		return;
+
+	CRef<CUser_object> userObject(new CUser_object());
+	userObject->SetType().SetStr("use_this_seqid");
+	userObject->AddField("SEQIDS", seqid_list);
+	seqalign->SetExt().push_back(userObject);
+}
+
 
 /// Given an HSP structure, creates a list of scores and inserts them into 
 /// a Seq-align.
@@ -1014,12 +1151,12 @@ s_BuildScoreList(const BlastHSP     * hsp,
 static void
 s_AddScoresToSeqAlign(CRef<CSeq_align>  & seqalign,
                       const BlastHSP    * hsp,
-                      const vector<int> & gi_list,
+                      const vector<string> & seqid_list,
                       Int4 query_length)
 {
     // Add the scores for this HSP
     CSeq_align::TScore& score_list = seqalign->SetScore();
-    s_BuildScoreList(hsp, score_list, gi_list, query_length);
+    s_BuildScoreList(hsp, score_list, seqid_list, query_length);
 }
 
 
@@ -1036,7 +1173,7 @@ CRef<CDense_diag>
 x_UngappedHSPToDenseDiag(BlastHSP* hsp, CRef<CSeq_id> query_id, 
                          CRef<CSeq_id> subject_id,
                          Int4 query_length, Int4 subject_length,
-                         const vector<int> & gi_list)
+                         const vector<string> & seqid_list)
 {
     CRef<CDense_diag> retval(new CDense_diag());
     
@@ -1068,7 +1205,7 @@ x_UngappedHSPToDenseDiag(BlastHSP* hsp, CRef<CSeq_id> query_id,
     }
 
     CSeq_align::TScore& score_list = retval->SetScores();
-    s_BuildScoreList(hsp, score_list, gi_list, query_length);
+    s_BuildScoreList(hsp, score_list, seqid_list, query_length);
 
     return retval;
 }
@@ -1086,7 +1223,7 @@ CRef<CStd_seg>
 x_UngappedHSPToStdSeg(BlastHSP* hsp, CRef<CSeq_id> query_id, 
                       CRef<CSeq_id> subject_id,
                       Int4 query_length, Int4 subject_length,
-                      const vector<int> & gi_list)
+                      const vector<string> & seqid_list)
 {
     CRef<CStd_seg> retval(new CStd_seg());
 
@@ -1142,7 +1279,7 @@ x_UngappedHSPToStdSeg(BlastHSP* hsp, CRef<CSeq_id> query_id,
     retval->SetLoc().push_back(subject_loc);
 
     CSeq_align::TScore& score_list = retval->SetScores();
-    s_BuildScoreList(hsp, score_list, gi_list, query_length);
+    s_BuildScoreList(hsp, score_list, seqid_list, query_length);
 
     return retval;
 }
@@ -1162,7 +1299,7 @@ BLASTUngappedHspListToSeqAlign(EBlastProgramType program,
                                CRef<CSeq_id> subject_id, 
                                Int4 query_length,
                                Int4 subject_length,
-                               const vector<int> & gi_list,
+                               const vector<string> & seqid_list,
                                vector<CRef<CSeq_align > > & sa_vector)
 {
     CRef<CSeq_align> seqalign(new CSeq_align()); 
@@ -1175,6 +1312,7 @@ BLASTUngappedHspListToSeqAlign(EBlastProgramType program,
 
     hsp_array = hsp_list->hsp_array;
 
+    vector<string> emptyList;  // FIXME: change prototypes below.
     /* All HSPs are put in one seqalign, containing a list of 
      * DenseDiag for same molecule search, or StdSeg for translated searches.
      */
@@ -1189,7 +1327,7 @@ BLASTUngappedHspListToSeqAlign(EBlastProgramType program,
                                          subject_id, 
                                          query_length,
                                          subject_length,
-                                         gi_list));
+                                         emptyList));
         }
     } else { // Translated search
         for (index=0; index<hsp_list->hspcnt; index++) { 
@@ -1200,9 +1338,10 @@ BLASTUngappedHspListToSeqAlign(EBlastProgramType program,
                                       subject_id, 
 		                              query_length,
                                       subject_length,
-                                      gi_list));
+                                      emptyList));
         }
     }
+    s_AddUserObjectToSeqAlign(seqalign, seqid_list);
     sa_vector.push_back(seqalign);
     return;
 }
@@ -1221,7 +1360,7 @@ void
 BLASTHspListToSeqAlign(EBlastProgramType program, BlastHSPList* hsp_list, 
                        CRef<CSeq_id> query_id, CRef<CSeq_id> subject_id, 
                        Int4 query_length, Int4 subject_length, bool is_ooframe,
-                       const vector<int> & gi_list,
+                       const vector<string> & seqid_list,
                        vector<CRef<CSeq_align > > & sa_vector)
 {
     // Process the list of HSPs corresponding to one subject sequence and
@@ -1231,6 +1370,7 @@ BLASTHspListToSeqAlign(EBlastProgramType program, BlastHSPList* hsp_list,
 
     sa_vector.clear();
     sa_vector.reserve(hsp_list->hspcnt);
+    vector<string> emptyList;
 
     for (int index = 0; index < hsp_list->hspcnt; index++) { 
         BlastHSP* hsp = hsp_array[index];
@@ -1253,14 +1393,17 @@ BLASTHspListToSeqAlign(EBlastProgramType program, BlastHSPList* hsp_list,
         	if(hsp->num_ident == 0)
         		hsp->num_ident = -1;
         }
-        s_AddScoresToSeqAlign(seqalign, hsp, gi_list, query_length);
+	// Pass in empty list until removed.
+        s_AddScoresToSeqAlign(seqalign, hsp, emptyList, query_length);
+	
+	s_AddUserObjectToSeqAlign(seqalign, seqid_list);
         sa_vector.push_back(seqalign);
     }
     
     return;
 }
 
-CRef<CSeq_align_set> CreateEmptySeq_align_set()
+CRef<CSeq_align_set> CreateEmptySeq_align_set(void)
 {
     CRef<CSeq_align_set> retval(new CSeq_align_set);
     retval->Set().clear();
@@ -1348,9 +1491,9 @@ BlastHitList2SeqAlign_OMF(const BlastHitList     * hit_list,
             subj_masks.push_back(masks);
         }
 
-        // Get GIs for entrez query restriction.
-        vector<int> gi_list;
-        GetFilteredRedundantGis(*seqinfo_src, hsp_list->oid, gi_list);
+        // Get SeqIds for entrez query restriction.
+	vector<string> seqid_list;
+        GetFilteredRedundantSeqids(*seqinfo_src, hsp_list->oid, seqid_list, subject_id->IsGi());
         
         // stores a CSeq_align for each matching sequence
         vector<CRef<CSeq_align > > hit_align;
@@ -1362,7 +1505,7 @@ BlastHitList2SeqAlign_OMF(const BlastHitList     * hit_list,
                                        query_length,
                                        subj_length,
                                        is_ooframe,
-                                       gi_list,
+                                       seqid_list,
                                        hit_align);
         } else {
                 BLASTUngappedHspListToSeqAlign(prog,
@@ -1371,7 +1514,7 @@ BlastHitList2SeqAlign_OMF(const BlastHitList     * hit_list,
                                                subject_id,
                                                query_length,
                                                subj_length,
-                                               gi_list,
+                                               seqid_list,
                                                hit_align);
         }
 
@@ -1477,7 +1620,8 @@ static void s_AdjustNegativeSubjFrameInBlastn(ENa_strand subj_strand,
                                      BlastHSPList* hsp_list)
 {
     _ASSERT(hsp_list);
-    if (subj_strand != eNa_strand_minus || program != eBlastTypeBlastn)
+    if (subj_strand != eNa_strand_minus ||
+        (program != eBlastTypeBlastn && program != eBlastTypeMapping))
         return;
 
     for (int index = 0; index < hsp_list->hspcnt; index++) { 
@@ -1556,8 +1700,9 @@ s_BLAST_OneSubjectResults2CSeqAlign(const BlastHSPResults* results,
             TSeqPos query_length = query_data.GetSeqLength(qindex); 
             s_AdjustNegativeSubjFrameInBlastn(kSubjStrand, prog, hsp_list);
             
-            vector<int> gi_list;
-            GetFilteredRedundantGis(seqinfo_src, hsp_list->oid, gi_list);
+	    vector<string> seqid_list;
+            GetFilteredRedundantSeqids(seqinfo_src, hsp_list->oid, seqid_list, subject_id->IsGi());
+        
 
             // Union subject sequence ranges
             vector <TSeqRange> ranges;
@@ -1585,7 +1730,7 @@ s_BLAST_OneSubjectResults2CSeqAlign(const BlastHSPResults* results,
                                            query_length, 
                                            subj_length,
                                            is_ooframe,
-                                           gi_list,
+                                           seqid_list,
                                            hit_align);
             } else {
                     BLASTUngappedHspListToSeqAlign(prog,
@@ -1594,7 +1739,7 @@ s_BLAST_OneSubjectResults2CSeqAlign(const BlastHSPResults* results,
                                                    subject_id,
                                                    query_length,
                                                    subj_length,
-                                                   gi_list,
+                                                   seqid_list,
                                                    hit_align);
             }
             seq_aligns.Reset(new CSeq_align_set());
@@ -1791,7 +1936,7 @@ CRef<CStd_seg>
 x_NonTranslatedHSPToStdSeg(BlastHSP* hsp, CRef<CSeq_id> query_id,
                       	   CRef<CSeq_id> subject_id,
                       	   Int4 query_length, Int4 subject_length,
-                      	   const vector<int> & gi_list)
+                      	   const vector<string> & seqid_list)
 {
     CRef<CStd_seg> retval(new CStd_seg());
 
@@ -1832,7 +1977,7 @@ x_NonTranslatedHSPToStdSeg(BlastHSP* hsp, CRef<CSeq_id> query_id,
     retval->SetLoc().push_back(subject_loc);
 
     CSeq_align::TScore& score_list = retval->SetScores();
-    s_BuildScoreList(hsp, score_list, gi_list, query_length);
+    s_BuildScoreList(hsp, score_list, seqid_list, query_length);
 
     return retval;
 }
@@ -1854,7 +1999,7 @@ BLASTPrelminSearchHitListToStdSeg(EBlastProgramType 	   program,
 
 	CRef<CStd_seg>
 	(*fun_ptr) (BlastHSP* , CRef<CSeq_id> , CRef<CSeq_id> , Int4 , Int4 ,
-	                      	   const vector<int> & ) = NULL;
+	                      	   const vector<string> & ) = NULL;
 
 	if((TRANSLATED_QUERY_MASK | TRANSLATED_SUBJECT_MASK) & program )
 		fun_ptr = x_UngappedHSPToStdSeg;
@@ -1871,12 +2016,11 @@ BLASTPrelminSearchHitListToStdSeg(EBlastProgramType 	   program,
 
 	if(hsp_list->hspcnt > 0)
 	{
-            const Uint4 oid = hsp_list->oid;
        	    TSeqPos subject_length = 0;
        	    CRef<CSeq_id> subject_id;
-       	    vector<int> gi_list;
-       	    GetFilteredRedundantGis(*subject_seqinfo, oid, gi_list);
-       	    GetSequenceLengthAndId(subject_seqinfo, oid, subject_id, &subject_length);
+	    vector<string> seqid_list;
+       	    GetSequenceLengthAndId(subject_seqinfo, hsp_list->oid, subject_id, &subject_length);
+            GetFilteredRedundantSeqids(*subject_seqinfo, hsp_list->oid, seqid_list, subject_id->IsGi());
 
             for (int j = 0; j < hsp_list->hspcnt; j++)
             {
@@ -1886,7 +2030,7 @@ BLASTPrelminSearchHitListToStdSeg(EBlastProgramType 	   program,
         	    continue;
 
                	seg_list.push_back((*fun_ptr) (hsp, query_id, subject_id, 
-                                               query_length, subject_length, gi_list));
+                                               query_length, subject_length, seqid_list));
 	    }
         }
     }
diff --git a/c++/src/algo/blast/api/blast_seqalign.hpp b/c++/src/algo/blast/api/blast_seqalign.hpp
index 86f803d..efcbf3c 100644
--- a/c++/src/algo/blast/api/blast_seqalign.hpp
+++ b/c++/src/algo/blast/api/blast_seqalign.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_seqalign.hpp 358152 2012-03-29 14:42:07Z fongah2 $
+/*  $Id: blast_seqalign.hpp 520431 2016-11-28 18:26:12Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -67,8 +67,8 @@ RemapToQueryLoc(CRef<CSeq_align> sar, const CSeq_loc & query);
 /// @param sas Pointer to a Seq-align-set, to which new object should be 
 ///            appended (if not NULL).
 /// @return Resulting Seq-align-set. 
-CSeq_align_set*
-CreateEmptySeq_align_set(CSeq_align_set* sas);
+CRef<CSeq_align_set>
+CreateEmptySeq_align_set(void);
 
 void
 BLASTHspListToSeqAlign(EBlastProgramType program, 
@@ -78,7 +78,7 @@ BLASTHspListToSeqAlign(EBlastProgramType program,
                        Int4 query_length, 
                        Int4 subject_length,
                        bool is_ooframe,
-                       const vector<int> & gi_list,
+                       const vector<string> & seqid_list,
                        vector<CRef<CSeq_align > > & sa_vector);
 
 void
@@ -88,7 +88,7 @@ BLASTUngappedHspListToSeqAlign(EBlastProgramType program,
                                CRef<CSeq_id> subject_id, 
                                Int4 query_length, 
                                Int4 subject_length,
-                               const vector<int> & gi_list,
+                               const vector<string> & seqid_list,
                                vector<CRef<CSeq_align > > & sa_vector);
 
 /// Convert traceback output into Seq-align format.
@@ -150,6 +150,19 @@ BLASTPrelminSearchHitListToStdSeg(EBlastProgramType 	   program,
                      	 	 	  const IBlastSeqInfoSrc * subject_seqinfo,
                      	 	 	  list<CRef<CStd_seg > > & seg_list);
 
+
+/// Convert a spliced alignmeny in BlastHSPChain into Spliced_seg
+/// @param spliced_seg Spliced_seg object [in] [out]
+/// @param product_id Sequence id of a read/query [in]
+/// @param genomic_id Sequence id a genome/subject [in]
+/// @param chain Alignment to be converted [in]
+void MakeSplicedSeg(CSpliced_seg& spliced_seg,
+                    CRef<CSeq_id> product_id,
+                    CRef<CSeq_id> genomic_id,
+                    int product_length,
+                    const BlastHSPChain* chain);
+
+
 END_SCOPE(blast)
 END_NCBI_SCOPE
 
diff --git a/c++/src/algo/blast/api/blast_seqinfosrc_aux.cpp b/c++/src/algo/blast/api/blast_seqinfosrc_aux.cpp
index 95b1cca..941b099 100644
--- a/c++/src/algo/blast/api/blast_seqinfosrc_aux.cpp
+++ b/c++/src/algo/blast/api/blast_seqinfosrc_aux.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_seqinfosrc_aux.cpp 440917 2014-07-17 21:22:41Z rackerst $
+/*  $Id: blast_seqinfosrc_aux.cpp 520431 2016-11-28 18:26:12Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -68,7 +68,7 @@ void GetSequenceLengthAndId(const blast::IBlastSeqInfoSrc * seqinfo_src,
 
 void GetFilteredRedundantGis(const IBlastSeqInfoSrc & seqinfo_src,
                              int                      oid,
-                             vector<int>            & gis)
+                             vector<TGi>            & gis)
 {
     gis.resize(0);
     
@@ -81,13 +81,52 @@ void GetFilteredRedundantGis(const IBlastSeqInfoSrc & seqinfo_src,
     
     ITERATE(list< CRef<CSeq_id> >, id, seqid_list) {
         if ((**id).IsGi()) {
-            gis.push_back(GI_TO(int, (**id).GetGi()));
+            gis.push_back((**id).GetGi());
         }
     }
 
 	sort(gis.begin(), gis.end());
 }
 
+void GetFilteredRedundantSeqids(const IBlastSeqInfoSrc & seqinfo_src,
+                             int                      oid,
+                             vector<string>            & seqids,
+			     bool			use_gi)
+{
+    seqids.resize(0);
+    
+    if (! seqinfo_src.HasGiList()) {
+        return;
+    }
+    
+    list< CRef<CSeq_id> > seqid_list = seqinfo_src.GetId(oid);
+    
+    ITERATE(list< CRef<CSeq_id> >, id, seqid_list) {
+	if (use_gi)
+	{
+        	if ((**id).IsGi())
+		{
+			string sid_string = "gi:" + (*id)->GetSeqIdString(true);
+			seqids.push_back(sid_string);
+		}
+	}
+	else
+	{
+		const CTextseq_id* tsid = (*id)->GetTextseq_Id();
+		if (tsid && tsid->IsSetAccession())
+		{
+			string sid_string = "seqid:" + (*id)->GetSeqIdString(true);
+			seqids.push_back(sid_string);
+		}
+		else if ((*id)->IsPdb())
+		{
+			string sid_string = "seqid:" + (*id)->GetSeqIdString(true);
+			seqids.push_back(sid_string);
+		}
+	}
+    }
+}
+
 END_SCOPE(blast)
 END_NCBI_SCOPE
 
diff --git a/c++/src/algo/blast/api/blast_setup.hpp b/c++/src/algo/blast/api/blast_setup.hpp
index 9641c26..36d5c50 100644
--- a/c++/src/algo/blast/api/blast_setup.hpp
+++ b/c++/src/algo/blast/api/blast_setup.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_setup.hpp 144802 2008-11-03 20:57:20Z camacho $
+/*  $Id: blast_setup.hpp 517499 2016-10-25 17:20:41Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -156,6 +156,12 @@ public:
     /// @param index index of the sequence in the sequence container [in]
     /// @return the sequence title or kEmptyStr if not available
     virtual string GetTitle(int index) const = 0;
+
+    /// Is this sequence followed by a mate (for mapping short reads)
+    NCBI_DEPRECATED virtual bool IsFirstOfAPair(int index) const = 0;
+
+    /// Get segment information (for mapping paired short reads)
+    virtual int GetSegmentInfo(int index) const = 0;
 };
 
 /// Choose between a Seq-loc specified query strand and the strand obtained
diff --git a/c++/src/algo/blast/api/blast_setup_cxx.cpp b/c++/src/algo/blast/api/blast_setup_cxx.cpp
index 9f44c7b..06fc926 100644
--- a/c++/src/algo/blast/api/blast_setup_cxx.cpp
+++ b/c++/src/algo/blast/api/blast_setup_cxx.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_setup_cxx.cpp 500367 2016-05-04 12:06:01Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
@@ -136,7 +132,8 @@ s_AdjustFirstContext(BlastQueryInfo* query_info,
     _ASSERT(query_info);
 
 #if _DEBUG      /* to eliminate compiler warning in release mode */
-    bool is_na = (prog == eBlastTypeBlastn) ? true : false;
+    bool is_na = (prog == eBlastTypeBlastn || prog == eBlastTypeMapping)
+        ? true : false;
 #endif
 	bool translate = Blast_QueryIsTranslated(prog) ? true : false;
 
@@ -165,7 +162,9 @@ SetupQueryInfo_OMF(const IBlastQuerySource& queries,
     }
 
     const unsigned int kNumContexts = GetNumberOfContexts(prog);
-    bool is_na = (prog == eBlastTypeBlastn) ? true : false;
+    bool is_na = (prog == eBlastTypeBlastn || prog == eBlastTypeMapping)
+        ? true : false;
+
 	bool translate = Blast_QueryIsTranslated(prog) ? true : false;
 
     if (is_na || translate) {
@@ -177,6 +176,7 @@ SetupQueryInfo_OMF(const IBlastQuerySource& queries,
     unsigned int ctx_index = 0; // index into BlastQueryInfo::contexts array
     // Longest query length, to be saved in the query info structure
     Uint4 max_length = 0;
+    Uint4 min_length = INT4_MAX;
 
     for(TSeqPos j = 0; j < queries.Size(); j++) {
         TSeqPos length = 0;
@@ -194,6 +194,7 @@ SetupQueryInfo_OMF(const IBlastQuerySource& queries,
                 unsigned int prot_length = 
                     BLAST_GetTranslatedProteinLength(length, i);
                 max_length = MAX(max_length, prot_length);
+                min_length = MIN(min_length, prot_length);
                 
                 Uint4 ctx_len(0);
                 
@@ -201,11 +202,15 @@ SetupQueryInfo_OMF(const IBlastQuerySource& queries,
                 case eNa_strand_plus:
                     ctx_len = (i<3) ? prot_length : 0;
                     s_QueryInfo_SetContext(query_info, ctx_index + i, ctx_len);
+                    // the missing frame is present in query_info as
+                    // zero-lenghth context
+                    min_length = 0;
                     break;
 
                 case eNa_strand_minus:
                     ctx_len = (i<3) ? 0 : prot_length;
                     s_QueryInfo_SetContext(query_info, ctx_index + i, ctx_len);
+                    min_length = 0;
                     break;
 
                 case eNa_strand_both:
@@ -220,17 +225,22 @@ SetupQueryInfo_OMF(const IBlastQuerySource& queries,
             }
         } else {
             max_length = MAX(max_length, length);
+            min_length = MIN(min_length, length);
             
             if (is_na) {
                 switch (strand) {
                 case eNa_strand_plus:
                     s_QueryInfo_SetContext(query_info, ctx_index, length);
                     s_QueryInfo_SetContext(query_info, ctx_index+1, 0);
+                    // the missing strand is present in query_info as
+                    // zero-lenghth context
+                    min_length = 0;
                     break;
 
                 case eNa_strand_minus:
                     s_QueryInfo_SetContext(query_info, ctx_index, 0);
                     s_QueryInfo_SetContext(query_info, ctx_index+1, length);
+                    min_length = 0;
                     break;
 
                 case eNa_strand_both:
@@ -246,9 +256,19 @@ SetupQueryInfo_OMF(const IBlastQuerySource& queries,
                 s_QueryInfo_SetContext(query_info, ctx_index, length);
             }
         }
+
+        // mark queries that have pairs (for mapping)
+        if (Blast_ProgramIsMapping(prog)) {
+            _ASSERT(!translate);
+
+            int seg_flags = queries.GetSegmentInfo(j);
+            query_info->contexts[ctx_index].segment_flags = seg_flags;
+            query_info->contexts[ctx_index + 1].segment_flags = seg_flags;
+        }
         ctx_index += kNumContexts;
     }
     query_info->max_length = max_length;
+    query_info->min_length = min_length;
     *qinfo = query_info.Release();
 }
 
@@ -485,7 +505,9 @@ SetupQueries_OMF(IBlastQuerySource& queries,
                    "Query sequence buffer");
     }
 
-    bool is_na = (prog == eBlastTypeBlastn) ? true : false;
+    bool is_na = (prog == eBlastTypeBlastn || prog == eBlastTypeMapping)
+        ? true : false;
+
 	bool translate = Blast_QueryIsTranslated(prog) ? true : false;
 
     unsigned int ctx_index = 0;      // index into context_offsets array
@@ -863,15 +885,8 @@ GetSequenceProtein(IBlastSeqVector& sv, string* warnings = 0)
     safe_buf.reset(buf);
     *buf_var++ = GetSentinelByte(eBlastEncodingProtein);
     for (i = 0; i < sv.size(); i++) {
-        // Silently change Selenocysteine (U) to Cysteine (C)
-        // This is needed because composition based stats works with 20 amino
-        // acids, and computes residue frequencies for a query before
-        // converting U to C.
-        if (sv[i] == AMINOACID_TO_NCBISTDAA[(int)'U']) {
-            *buf_var++ = AMINOACID_TO_NCBISTDAA[(int)'C'];
-
         // Change unsupported residues to X
-        } else if (sv[i] == AMINOACID_TO_NCBISTDAA[(int)'O']) {
+        if (sv[i] == AMINOACID_TO_NCBISTDAA[(int)'O']) {
             replaced_residues.push_back(i);
             *buf_var++ = AMINOACID_TO_NCBISTDAA[(int)'X'];
         } else if (!s_IsValidResidue(sv[i])) {
@@ -896,7 +911,7 @@ GetSequenceProtein(IBlastSeqVector& sv, string* warnings = 0)
 
     *buf_var++ = GetSentinelByte(eBlastEncodingProtein);
     if (warnings && replaced_residues.size() > 0) {
-        *warnings += "One or more U or O characters replaced by X for ";
+        *warnings += "One or more O characters replaced by X for ";
         *warnings += "alignment score calculations at positions ";
         *warnings += NStr::IntToString(replaced_residues[0]);
         for (i = 1; i < min(kMaxResiduesToWarnAbout, replaced_residues.size()); 
@@ -1072,6 +1087,7 @@ GetQueryEncoding(EBlastProgramType program)
     switch (program) {
     case eBlastTypeBlastn:
     case eBlastTypePhiBlastn: 
+    case eBlastTypeMapping:
         retval = eBlastEncodingNucleotide; 
         break;
 
@@ -1104,6 +1120,7 @@ GetSubjectEncoding(EBlastProgramType program)
 
     switch (program) {
     case eBlastTypeBlastn: 
+    case eBlastTypeMapping:
         retval = eBlastEncodingNucleotide; 
         break;
 
@@ -1407,10 +1424,12 @@ FindBlastDbPath(const char* dbname, bool is_prot)
     }
 
     // Obtain the matrix path from the ncbi configuration file
-    CMetaRegistry::SEntry sentry;
-    sentry = CMetaRegistry::Load("ncbi", CMetaRegistry::eName_RcOrIni);
-    string path = 
-        sentry.registry ? sentry.registry->Get("BLAST", "BLASTDB") : "";
+    string path;
+    if (app) {
+        const CNcbiRegistry& registry = app->GetConfig();
+        if (registry.HasEntry("BLAST", "BLASTDB"))
+            CDirEntry::NormalizePath(registry.Get("BLAST", "BLASTDB"), eFollowLinks);
+    }
 
     full_path = CFile::MakePath(path, database);
     if (BlastDbFileExists(full_path, is_prot)) {
@@ -1641,6 +1660,7 @@ void CBlastQueryFilteredFrames::x_VerifyFrame(int frame)
         break;
         
     case eBlastTypeBlastn:
+    case eBlastTypeMapping:
         if ((frame != CSeqLocInfo::eFramePlus1) &&
             (frame != CSeqLocInfo::eFrameMinus1)) {
             okay = false;
@@ -1689,6 +1709,7 @@ bool CBlastQueryFilteredFrames::QueryHasMultipleFrames() const
     case eBlastTypeBlastx:
     case eBlastTypeTblastx:
     case eBlastTypeRpsTblastn:
+    case eBlastTypeMapping:
         return true;
         
     default:
@@ -1703,7 +1724,9 @@ void CBlastQueryFilteredFrames::AddSeqLoc(const objects::CSeq_interval & intv,
                                           int frame)
 {
     _ASSERT( m_Frames.empty() );
-    if ((frame == 0) && (m_Program == eBlastTypeBlastn)) {
+    if ((frame == 0) && (m_Program == eBlastTypeBlastn
+                         || m_Program == eBlastTypeMapping)) {
+
         x_VerifyFrame(CSeqLocInfo::eFramePlus1);
         x_VerifyFrame(CSeqLocInfo::eFrameMinus1);
         static const CSeqLocInfo::ETranslationFrame kFrames[] = {
diff --git a/c++/src/algo/blast/api/cdd_pssm_input.cpp b/c++/src/algo/blast/api/cdd_pssm_input.cpp
index 04aee13..591e719 100644
--- a/c++/src/algo/blast/api/cdd_pssm_input.cpp
+++ b/c++/src/algo/blast/api/cdd_pssm_input.cpp
@@ -1,8 +1,5 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: cdd_pssm_input.cpp 347562 2011-12-19 19:26:47Z boratyng $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-/* ===========================================================================
+/*  $Id: cdd_pssm_input.cpp 500404 2016-05-04 14:59:01Z camacho $
+ * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
@@ -34,7 +31,6 @@ static char const rcsid[] =
  * Implementation of the concrete strategy to obtain PSSM input data for
  * PSI-BLAST.
  */
-
 #include <ncbi_pch.hpp>
 
 // BLAST includes
diff --git a/c++/src/algo/blast/api/deltablast.cpp b/c++/src/algo/blast/api/deltablast.cpp
index 64c045a..4c855dd 100644
--- a/c++/src/algo/blast/api/deltablast.cpp
+++ b/c++/src/algo/blast/api/deltablast.cpp
@@ -1,8 +1,5 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-/* ===========================================================================
+/*  $Id: deltablast.cpp 500404 2016-05-04 14:59:01Z camacho $
+ * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
@@ -33,7 +30,6 @@ static char const rcsid[] =
 /** @file deltablast.cpp
  * Implementation of CDeltaBlast.
  */
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/api/psiblast.hpp>
 #include <algo/blast/api/psibl2seq.hpp>
@@ -54,7 +50,7 @@ static char const rcsid[] =
 
 BEGIN_NCBI_SCOPE
 USING_SCOPE(objects);
-BEGIN_SCOPE(blast);
+BEGIN_SCOPE(blast)
 
 CDeltaBlast::CDeltaBlast(CRef<IQueryFactory> query_factory,
                          CRef<CLocalDbAdapter> blastdb,
diff --git a/c++/src/algo/blast/api/dust_filter.cpp b/c++/src/algo/blast/api/dust_filter.cpp
index 9165118..927e1cc 100644
--- a/c++/src/algo/blast/api/dust_filter.cpp
+++ b/c++/src/algo/blast/api/dust_filter.cpp
@@ -1,4 +1,4 @@
-/*  $Id: dust_filter.cpp 500379 2016-05-04 13:50:05Z ivanov $
+/*  $Id: dust_filter.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
 
 /// @file dust_filter.cpp
 /// Calls sym dust lib in algo/dustmask and returns CSeq_locs for use by BLAST.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: dust_filter.cpp 500379 2016-05-04 13:50:05Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "dust_filter.hpp"
 #include <serial/iterator.hpp>
diff --git a/c++/src/algo/blast/api/local_blast.cpp b/c++/src/algo/blast/api/local_blast.cpp
index 1ecbe88..384923b 100644
--- a/c++/src/algo/blast/api/local_blast.cpp
+++ b/c++/src/algo/blast/api/local_blast.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: local_blast.cpp 500119 2016-05-02 16:12:14Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -71,6 +67,7 @@ SplitQuery_GetChunkSize(EProgram program)
             break;
         case eMegablast:
         case eDiscMegablast:
+        case eMapper:
             retval = 5000000;
             break;
         case eTblastn:
diff --git a/c++/src/algo/blast/api/local_db_adapter.cpp b/c++/src/algo/blast/api/local_db_adapter.cpp
index e00919d..11db59c 100644
--- a/c++/src/algo/blast/api/local_db_adapter.cpp
+++ b/c++/src/algo/blast/api/local_db_adapter.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: local_db_adapter.cpp 478540 2015-09-10 12:56:25Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/local_search.cpp b/c++/src/algo/blast/api/local_search.cpp
index f97e03c..5a19681 100644
--- a/c++/src/algo/blast/api/local_search.cpp
+++ b/c++/src/algo/blast/api/local_search.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: local_search.cpp 327673 2011-07-28 14:30:03Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/magicblast.cpp b/c++/src/algo/blast/api/magicblast.cpp
new file mode 100644
index 0000000..2836779
--- /dev/null
+++ b/c++/src/algo/blast/api/magicblast.cpp
@@ -0,0 +1,346 @@
+/* $Id: magicblast.cpp 505553 2016-06-27 14:10:27Z boratyng $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  Greg Boratyn
+ *
+ */
+
+/** @file magicblast.cpp
+ * Implementation of CMagicBlast.
+ */
+
+#include <ncbi_pch.hpp>
+#include <objects/general/User_object.hpp>
+#include <algo/blast/api/prelim_stage.hpp>
+#include <algo/blast/api/magicblast.hpp>
+
+#include "blast_seqalign.hpp"
+#include "blast_aux_priv.hpp"
+#include "../core/jumper.h"
+
+/** @addtogroup AlgoBlast
+ *
+ * @{
+ */
+
+BEGIN_NCBI_SCOPE
+USING_SCOPE(objects);
+BEGIN_SCOPE(blast);
+
+CMagicBlast::CMagicBlast(CRef<IQueryFactory> query_factory,
+                         CRef<CLocalDbAdapter> blastdb,
+                         CRef<CMagicBlastOptionsHandle> options)
+    : m_Queries(query_factory),
+      m_LocalDbAdapter(blastdb),
+      m_Options(&options->SetOptions())
+{
+    x_Validate();
+}
+
+
+CRef<CSeq_align_set> CMagicBlast::Run(void)
+{
+    CRef<CBlastPrelimSearch> prelim_search(new CBlastPrelimSearch(m_Queries,
+                                                            m_Options,
+                                                            m_LocalDbAdapter));
+
+    int status = prelim_search->CheckInternalData();
+    if (status != 0)
+    {
+         // Search was not run, but we send back an empty CSearchResultSet.
+         CRef<ILocalQueryData> local_query_data =
+             m_Queries->MakeLocalQueryData(m_Options);
+
+         vector< CConstRef<objects::CSeq_id> > seqid_vec;
+         vector< CRef<CBlastAncillaryData> > ancill_vec;
+         TSeqAlignVector sa_vec;
+         size_t index;
+         unsigned int num_subjects = 0;
+         if (m_LocalDbAdapter.NotEmpty() && !m_LocalDbAdapter->IsBlastDb() &&
+             !m_LocalDbAdapter->IsDbScanMode()) {
+
+             IBlastSeqInfoSrc *  subject_infosrc =
+                 m_LocalDbAdapter->MakeSeqInfoSrc();
+
+             if(subject_infosrc != NULL) {
+            	 num_subjects = subject_infosrc->Size();
+             }
+         }
+         TSearchMessages msg_vec;
+         for (index=0; index<local_query_data->GetNumQueries(); index++)
+         {
+              CConstRef<objects::CSeq_id> query_id(
+                                 local_query_data->GetSeq_loc(index)->GetId());
+
+              TQueryMessages q_msg;
+              local_query_data->GetQueryMessages(index, q_msg);
+              msg_vec.push_back(q_msg);
+              seqid_vec.push_back(query_id);
+              CRef<objects::CSeq_align_set> tmp_align;
+              sa_vec.push_back(tmp_align);
+              pair<double, double> tmp_pair(-1.0, -1.0);
+              CRef<CBlastAncillaryData>  tmp_ancillary_data(
+                             new CBlastAncillaryData(tmp_pair, tmp_pair,
+                                                     tmp_pair, 0));
+
+              ancill_vec.push_back(tmp_ancillary_data);
+
+              for(unsigned int i=1; i < num_subjects; i++) {
+            	  TQueryMessages msg;
+                  msg_vec.push_back(msg);
+                  seqid_vec.push_back(query_id);
+                  CRef<objects::CSeq_align_set> tmp_align;
+                  sa_vec.push_back(tmp_align);
+           	      CRef<CBlastAncillaryData>  tmp_ancillary_data(
+                     new CBlastAncillaryData(tmp_pair, tmp_pair, tmp_pair, 0));
+           	      ancill_vec.push_back(tmp_ancillary_data);
+              }
+         }
+         msg_vec.Combine(prelim_search->GetSearchMessages());
+
+         // FIXME: Report search messages
+    }
+
+    try {
+        prelim_search->SetNumberOfThreads(GetNumberOfThreads());
+        // do mapping
+        m_InternalData = prelim_search->Run();
+
+	}
+    catch( CIndexedDbException & ) {
+	    throw;
+	}
+    catch (CBlastException & e) {
+		if(e.GetErrCode() == CBlastException::eCoreBlastError) {
+			throw;
+		}
+    }
+    catch (...) {
+
+    }
+
+    // close HSP stream and create internal results structure
+    BlastMappingResults* results = Blast_MappingResultsNew();
+    CRef< CStructWrapper<BlastMappingResults> > wrapped_results;
+    wrapped_results.Reset(WrapStruct(results, Blast_MappingResultsFree));
+
+    BlastHSPStreamMappingClose(m_InternalData->m_HspStream->GetPointer(),
+                               results);
+
+    // create and return results as ASN.1 objects
+    return x_CreateSeqAlignSet(results);
+}
+
+
+void CMagicBlast::x_Validate(void)
+{
+    if (m_Options.Empty()) {
+        NCBI_THROW(CBlastException, eInvalidArgument, "Missing options");
+    }
+
+    if (m_Queries.Empty()) {
+        NCBI_THROW(CBlastException, eInvalidArgument, "Missing query");
+    }
+
+    if (m_LocalDbAdapter.Empty()) {
+        NCBI_THROW(CBlastException, eInvalidArgument,
+                   "Missing database or subject sequences");
+    }
+}
+
+// Compute BTOP string and percent identity from JumperEdits structure that
+// contains base mismatch infotmation
+static void s_ComputeBtopAndIdentity(const BlastHSPChain* chain,
+                                     string& btop,
+                                     double& perc_id)
+{
+    _ASSERT(chain);
+    _ASSERT(chain->hsp_array[0]);
+    const Uint1 kGap = 15;
+    
+    int num_identical = 0;
+    int len = 0;
+    for (int k=0;k < chain->num_hsps;k++) {
+        const BlastHSP* hsp = chain->hsp_array[k];
+        const JumperEditsBlock* hsp_edits = hsp->map_info->edits;
+
+        if (k > 0) {
+            const BlastHSP* prev = chain->hsp_array[k - 1];
+            int intron = hsp->subject.offset - prev->subject.end;
+            if (intron > 0) {
+                btop += (string)"^" + NStr::IntToString(intron) + "^";
+            }
+
+            int query_gap = hsp->query.offset - prev->query.end;
+            if (query_gap > 0) {
+                btop += (string)"_" + NStr::IntToString(query_gap) + "_";
+            }
+            else if (query_gap < 0) {
+                btop += (string)"(" + NStr::IntToString(-query_gap) + ")";
+            }
+
+            // gap in query on exon edge
+            if (hsp->query.offset > prev->query.end) {
+                btop += (string)"_" +
+                    NStr::IntToString(hsp->query.offset - prev->query.end) +
+                    "_";
+
+                len += hsp->query.offset - prev->query.end;
+            }
+        }        
+
+        int query_pos = hsp->query.offset;
+        int num_matches = 0;
+        for (int i=0;i < hsp_edits->num_edits;i++) {
+            num_matches = hsp_edits->edits[i].query_pos - query_pos;
+            query_pos += num_matches;
+            
+            _ASSERT(num_matches >= 0);
+            num_identical += num_matches;
+            if (num_matches > 0) {
+                btop += NStr::IntToString(num_matches);
+            }
+
+            char buff[3];
+            buff[0] = BLASTNA_TO_IUPACNA[(int)hsp_edits->edits[i].query_base];
+            buff[1] = BLASTNA_TO_IUPACNA[(int)hsp_edits->edits[i].subject_base];
+            buff[2] = 0;
+            btop += (string)buff;
+            len++;
+            if (hsp_edits->edits[i].query_base != kGap) {
+                query_pos++;
+            }
+        }
+        num_matches = hsp->query.end - query_pos;
+        num_identical += num_matches;
+        if (num_matches > 0) {
+            btop += NStr::IntToString(num_matches);
+        }
+    }
+    len += num_identical;
+
+    perc_id = (double)(num_identical * 100) / (double)len;
+}
+
+
+static CRef<CSeq_align> s_CreateSeqAlign(const BlastHSPChain* chain,
+                                         CRef<ILocalQueryData>& qdata,
+                                         CRef<IBlastSeqInfoSrc>& seqinfo_src)
+{
+    CRef<CSeq_align> align(new CSeq_align);
+    align->SetType(CSeq_align::eType_partial);
+    align->SetDim(2);
+
+    CConstRef<CSeq_loc> query_loc = qdata->GetSeq_loc(chain->query_index);
+    CRef<CSeq_id> query_id(new CSeq_id);
+    SerialAssign(*query_id, CSeq_loc_CI(*query_loc).GetSeq_id());
+    _ASSERT(query_id);
+    TSeqPos query_length = qdata->GetSeqLength(chain->query_index);
+
+    CRef<CSeq_id> subject_id;
+    TSeqPos subj_length;
+    GetSequenceLengthAndId(seqinfo_src, chain->oid, subject_id,
+                           &subj_length);
+
+
+    MakeSplicedSeg(align->SetSegs().SetSpliced(), query_id, subject_id,
+                   query_length, chain);
+
+    // alignment score
+    align->SetNamedScore(CSeq_align::eScore_Score, chain->score);
+
+    // user objec stores auxiliary information needed for various output
+    // formats
+    CRef<CUser_object> user_object(new CUser_object);
+    user_object->SetType().SetStr("Mapper Info");
+    align->SetExt().push_back(user_object);
+    // for SAM
+    // context is needed mostly for printing query sequences, mostly for
+    // convinience and fast lookup
+    user_object->AddField("context", chain->hsp_array[0]->context);
+    user_object->AddField("num_hits", chain->multiplicity);
+
+    // for tabular
+    string btop;
+    double perc_id;
+    s_ComputeBtopAndIdentity(chain, btop, perc_id);
+    user_object->AddField("btop", btop);
+    align->SetNamedScore(CSeq_align::eScore_PercentIdentity_Gapped,
+                         perc_id);
+
+    return align;
+}
+
+CRef<CSeq_align_set> CMagicBlast::x_CreateSeqAlignSet(
+                                                BlastMappingResults* results)
+{
+    CRef<CSeq_align_set> seq_aligns = CreateEmptySeq_align_set();
+
+    CRef<ILocalQueryData> qdata = m_Queries->MakeLocalQueryData(m_Options);
+    
+    CRef<IBlastSeqInfoSrc> seqinfo_src;
+    seqinfo_src.Reset(m_LocalDbAdapter->MakeSeqInfoSrc());
+    _ASSERT(seqinfo_src);
+    seqinfo_src->GarbageCollect();
+
+    for (int i=0;i < results->num_results;i++) {
+        // single spliced alignment
+        BlastHSPChain* chain = results->chain_array[i];
+
+        // mate pairs are processed together when the first one is encountered,
+        // so skip the second of the pair
+        if (chain->pair && chain->query_index > chain->pair->query_index) {
+            continue;
+        }
+
+        CRef<CSeq_align> align;
+
+        // pairs are reported as disc seg alignment composed of two
+        // spliced segs
+        if (chain->pair) {
+            align.Reset(new CSeq_align);
+            align->SetType(CSeq_align::eType_partial);
+            align->SetDim(2);
+
+            CSeq_align::TSegs::TDisc& disc = align->SetSegs().SetDisc();
+            disc.Set().push_back(s_CreateSeqAlign(chain, qdata, seqinfo_src));
+            disc.Set().push_back(s_CreateSeqAlign(chain->pair, qdata,
+                                                  seqinfo_src));
+        }
+        else {
+            align = s_CreateSeqAlign(chain, qdata, seqinfo_src);
+        }
+
+        seq_aligns->Set().push_back(align);
+    }
+
+    return seq_aligns;
+}
+
+
+END_SCOPE(blast)
+END_NCBI_SCOPE
+
+/* @} */
diff --git a/c++/src/algo/blast/api/magicblast_options.cpp b/c++/src/algo/blast/api/magicblast_options.cpp
new file mode 100644
index 0000000..dabfb74
--- /dev/null
+++ b/c++/src/algo/blast/api/magicblast_options.cpp
@@ -0,0 +1,224 @@
+/*  $Id: magicblast_options.cpp 506101 2016-07-01 15:47:17Z boratyng $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Authors:  Greg Boratyn
+ *
+ */
+
+/// @file blast_mapper_options.cpp
+/// Implements the CMagicBlastOptionsHandle class.
+
+#include <ncbi_pch.hpp>
+//#include <algo/blast/core/blast_encoding.h>
+#include <algo/blast/api/magicblast_options.hpp>
+//#include <objects/seqloc/Na_strand.hpp>
+//#include "blast_setup.hpp"
+
+/** @addtogroup AlgoBlast
+ *
+ * @{
+ */
+
+
+BEGIN_NCBI_SCOPE
+BEGIN_SCOPE(blast)
+
+CMagicBlastOptionsHandle::CMagicBlastOptionsHandle(EAPILocality locality)
+    : CBlastOptionsHandle(locality)
+{
+    SetDefaults();
+}
+
+
+CMagicBlastOptionsHandle::CMagicBlastOptionsHandle(CRef<CBlastOptions> opt)
+    : CBlastOptionsHandle(opt)
+{
+}
+
+
+void
+CMagicBlastOptionsHandle::SetDefaults()
+{
+    m_Opts->SetDefaultsMode(true);
+    SetRNAToGenomeDefaults();
+    m_Opts->SetDefaultsMode(false);
+}
+
+void
+CMagicBlastOptionsHandle::SetRNAToGenomeDefaults()
+{
+    m_Opts->SetDefaultsMode(true);
+    m_Opts->SetProgram(eMapper);
+    SetLookupTableDefaults();
+    SetQueryOptionDefaults();
+    SetInitialWordOptionsDefaults();
+    SetGappedExtensionDefaults();
+    SetScoringOptionsDefaults();
+    SetHitSavingOptionsDefaults();
+    SetEffectiveLengthsOptionsDefaults();
+    SetSubjectSequenceOptionsDefaults();
+    m_Opts->SetDefaultsMode(false);
+}
+
+void
+CMagicBlastOptionsHandle::SetRNAToRNADefaults()
+{
+    m_Opts->SetDefaultsMode(true);
+    m_Opts->SetProgram(eMapper);
+    SetLookupTableDefaults();
+    SetQueryOptionDefaults();
+    SetInitialWordOptionsDefaults();
+    SetGappedExtensionDefaults();
+    SetScoringOptionsDefaults();
+    SetHitSavingOptionsDefaults();
+    SetEffectiveLengthsOptionsDefaults();
+    SetSubjectSequenceOptionsDefaults();
+
+    SetMismatchPenalty(-4);
+    SetGapExtensionCost(4);
+    SetLookupDbFilter(false);
+    SetSpliceAlignments(false);
+    SetWordSize(30);
+    SetCutoffScore(70);
+
+    m_Opts->SetDefaultsMode(false);
+}
+
+
+void
+CMagicBlastOptionsHandle::SetGenomeToGenomeDefaults()
+{
+    m_Opts->SetDefaultsMode(true);
+    m_Opts->SetProgram(eMapper);
+    SetLookupTableDefaults();
+    SetQueryOptionDefaults();
+    SetInitialWordOptionsDefaults();
+    SetGappedExtensionDefaults();
+    SetScoringOptionsDefaults();
+    SetHitSavingOptionsDefaults();
+    SetEffectiveLengthsOptionsDefaults();
+    SetSubjectSequenceOptionsDefaults();
+
+    SetMismatchPenalty(-4);
+    SetGapExtensionCost(4);
+    SetLookupDbFilter(true);
+    SetSpliceAlignments(false);
+    SetWordSize(28);
+    SetCutoffScore(70);
+
+    m_Opts->SetDefaultsMode(false);
+}
+
+void 
+CMagicBlastOptionsHandle::SetLookupTableDefaults()
+{
+    if (getenv("MAPPER_MB_LOOKUP")) {
+        m_Opts->SetLookupTableType(eMBLookupTable);
+    }
+    else {
+        m_Opts->SetLookupTableType(eNaHashLookupTable);
+    }
+    SetWordSize(BLAST_WORDSIZE_MAPPER);
+    m_Opts->SetWordThreshold(BLAST_WORD_THRESHOLD_BLASTN);
+    SetLookupTableStride(0);
+}
+
+
+void
+CMagicBlastOptionsHandle::SetQueryOptionDefaults()
+{
+    m_Opts->SetDustFiltering(false);
+    m_Opts->SetMaskAtHash(false);
+    m_Opts->SetStrandOption(objects::eNa_strand_both);
+    SetLookupDbFilter(true);
+    SetPaired(false);
+}
+
+void
+CMagicBlastOptionsHandle::SetInitialWordOptionsDefaults()
+{
+}
+
+void
+CMagicBlastOptionsHandle::SetGappedExtensionDefaults()
+{
+    m_Opts->SetGapExtnAlgorithm(eJumperWithTraceback);
+    m_Opts->SetMaxMismatches(5);
+    m_Opts->SetMismatchWindow(10);
+    SetSpliceAlignments(true);
+}
+
+
+void
+CMagicBlastOptionsHandle::SetScoringOptionsDefaults()
+{
+    m_Opts->SetMatrixName(NULL);
+    SetGapOpeningCost(BLAST_GAP_OPEN_MAPPER);
+    SetGapExtensionCost(BLAST_GAP_EXTN_MAPPER);
+    m_Opts->SetMatchReward(BLAST_REWARD_MAPPER);
+    SetMismatchPenalty(BLAST_PENALTY_MAPPER);
+    m_Opts->SetGappedMode();
+    m_Opts->SetComplexityAdjMode(false);
+
+    // set out-of-frame options to invalid? values
+    m_Opts->SetOutOfFrameMode(false);
+    m_Opts->SetFrameShiftPenalty(INT2_MAX);
+}
+
+void
+CMagicBlastOptionsHandle::SetHitSavingOptionsDefaults()
+{
+    m_Opts->SetHitlistSize(500);
+    m_Opts->SetEvalueThreshold(BLAST_EXPECT_VALUE);
+    m_Opts->SetPercentIdentity(0);
+    // set some default here, allow INT4MAX to mean infinity
+    m_Opts->SetMaxNumHspPerSequence(0); 
+    m_Opts->SetMaxHspsPerSubject(0);
+    SetCutoffScore(20);
+    SetLongestIntronLength(2000);
+
+    // do not compute each query's ungapped alignment score threshold to
+    // trigger gapped alignment
+    m_Opts->SetLowScorePerc(0.0);
+    m_Opts->SetQueryCovHspPerc(0);
+}
+
+void
+CMagicBlastOptionsHandle::SetEffectiveLengthsOptionsDefaults()
+{
+    m_Opts->SetDbLength(0);
+    m_Opts->SetDbSeqNum(0);
+    m_Opts->SetEffectiveSearchSpace(0);
+}
+
+void
+CMagicBlastOptionsHandle::SetSubjectSequenceOptionsDefaults()
+{}
+
+END_SCOPE(blast)
+END_NCBI_SCOPE
+
+
+/* @} */
diff --git a/c++/src/algo/blast/api/msa_pssm_input.cpp b/c++/src/algo/blast/api/msa_pssm_input.cpp
index f749013..6887ab4 100644
--- a/c++/src/algo/blast/api/msa_pssm_input.cpp
+++ b/c++/src/algo/blast/api/msa_pssm_input.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: msa_pssm_input.cpp 483145 2015-10-28 17:43:30Z boratyng $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/objmgr_query_data.cpp b/c++/src/algo/blast/api/objmgr_query_data.cpp
index 7fb8cbf..3f7e0f5 100644
--- a/c++/src/algo/blast/api/objmgr_query_data.cpp
+++ b/c++/src/algo/blast/api/objmgr_query_data.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: objmgr_query_data.cpp 382043 2012-12-03 13:33:06Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
diff --git a/c++/src/algo/blast/api/objmgrfree_query_data.cpp b/c++/src/algo/blast/api/objmgrfree_query_data.cpp
index 78d728c..365d778 100644
--- a/c++/src/algo/blast/api/objmgrfree_query_data.cpp
+++ b/c++/src/algo/blast/api/objmgrfree_query_data.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: objmgrfree_query_data.cpp 103491 2007-05-04 17:18:18Z kazimird $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
diff --git a/c++/src/algo/blast/api/prelim_search_runner.hpp b/c++/src/algo/blast/api/prelim_search_runner.hpp
index c906c54..9832644 100644
--- a/c++/src/algo/blast/api/prelim_search_runner.hpp
+++ b/c++/src/algo/blast/api/prelim_search_runner.hpp
@@ -1,4 +1,4 @@
-/*  $Id: prelim_search_runner.hpp 369355 2012-07-18 17:07:15Z morgulis $
+/*  $Id: prelim_search_runner.hpp 516335 2016-10-12 17:31:18Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -113,23 +113,30 @@ public:
         : m_InternalData(internal_data), m_OptsMemento(opts_memento)
     {
         // The following fields need to be copied to ensure MT-safety
-        BlastSeqSrc* seqsrc = 
+        BlastSeqSrc* seqsrc =
             BlastSeqSrcCopy(m_InternalData.m_SeqSrc->GetPointer());
-        m_InternalData.m_SeqSrc.Reset(new TBlastSeqSrc(seqsrc, 
+        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 = 
+            SBlastProgress* bp =
                 SBlastProgressNew(m_InternalData.m_ProgressMonitor->Get()->user_data);
             m_InternalData.m_ProgressMonitor.Reset(new CSBlastProgress(bp));
         }
+        // The BlastQueryInfo field needs to be copied to silence Thread
+        // Sanitizer warnings, and probably to ensure MT-safety too.
+        BlastQueryInfo* queryInfo =
+                BlastQueryInfoDup(m_InternalData.m_QueryInfo);
+        m_InternalData.m_QueryInfo = queryInfo;
     }
 
 protected:
-    virtual ~CPrelimSearchThread(void) {}
+    virtual ~CPrelimSearchThread(void) {
+        BlastQueryInfoFree(m_InternalData.m_QueryInfo);
+    }
 
     virtual void* Main(void) {
-        return (void*) 
+        return (void*)
             ((intptr_t) CPrelimSearchRunner(m_InternalData, m_OptsMemento)());
     }
 
diff --git a/c++/src/algo/blast/api/prelim_stage.cpp b/c++/src/algo/blast/api/prelim_stage.cpp
index 32ad399..a357550 100644
--- a/c++/src/algo/blast/api/prelim_stage.cpp
+++ b/c++/src/algo/blast/api/prelim_stage.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: prelim_stage.cpp 479444 2015-09-21 13:43:44Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/psi_pssm_input.cpp b/c++/src/algo/blast/api/psi_pssm_input.cpp
index 28007f4..c8346c3 100644
--- a/c++/src/algo/blast/api/psi_pssm_input.cpp
+++ b/c++/src/algo/blast/api/psi_pssm_input.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: psi_pssm_input.cpp 347205 2011-12-14 20:08:44Z boratyng $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/psibl2seq.cpp b/c++/src/algo/blast/api/psibl2seq.cpp
index 2dd285b..89c6763 100644
--- a/c++/src/algo/blast/api/psibl2seq.cpp
+++ b/c++/src/algo/blast/api/psibl2seq.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: psibl2seq.cpp 413493 2013-09-16 17:55:21Z boratyng $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/psiblast.cpp b/c++/src/algo/blast/api/psiblast.cpp
index cfb9c50..248997d 100644
--- a/c++/src/algo/blast/api/psiblast.cpp
+++ b/c++/src/algo/blast/api/psiblast.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: psiblast.cpp 219104 2011-01-06 13:31:19Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/psiblast_aux_priv.cpp b/c++/src/algo/blast/api/psiblast_aux_priv.cpp
index 14b117a..e88e4c7 100644
--- a/c++/src/algo/blast/api/psiblast_aux_priv.cpp
+++ b/c++/src/algo/blast/api/psiblast_aux_priv.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: psiblast_aux_priv.cpp 488748 2016-01-05 16:40:40Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
diff --git a/c++/src/algo/blast/api/psiblast_impl.cpp b/c++/src/algo/blast/api/psiblast_impl.cpp
index 2e3d4c0..afbd5b0 100644
--- a/c++/src/algo/blast/api/psiblast_impl.cpp
+++ b/c++/src/algo/blast/api/psiblast_impl.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: psiblast_impl.cpp 327673 2011-07-28 14:30:03Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
diff --git a/c++/src/algo/blast/api/psiblast_iteration.cpp b/c++/src/algo/blast/api/psiblast_iteration.cpp
index 863d87a..f6e5181 100644
--- a/c++/src/algo/blast/api/psiblast_iteration.cpp
+++ b/c++/src/algo/blast/api/psiblast_iteration.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: psiblast_iteration.cpp 161402 2009-05-27 17:35:47Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
diff --git a/c++/src/algo/blast/api/pssm_engine.cpp b/c++/src/algo/blast/api/pssm_engine.cpp
index 4a15780..884ccd7 100644
--- a/c++/src/algo/blast/api/pssm_engine.cpp
+++ b/c++/src/algo/blast/api/pssm_engine.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: pssm_engine.cpp 347205 2011-12-14 20:08:44Z boratyng $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/query_data.cpp b/c++/src/algo/blast/api/query_data.cpp
index 4ae2e5d..b225f58 100644
--- a/c++/src/algo/blast/api/query_data.cpp
+++ b/c++/src/algo/blast/api/query_data.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: query_data.cpp 315260 2011-07-22 13:48:03Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
diff --git a/c++/src/algo/blast/api/remote_blast.cpp b/c++/src/algo/blast/api/remote_blast.cpp
index 6746517..a2bc58c 100644
--- a/c++/src/algo/blast/api/remote_blast.cpp
+++ b/c++/src/algo/blast/api/remote_blast.cpp
@@ -1,4 +1,4 @@
-/*  $Id: remote_blast.cpp 495288 2016-03-16 14:51:11Z ivanov $ 
+/*  $Id: remote_blast.cpp 505424 2016-06-24 16:19:35Z merezhuk $ 
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -34,6 +34,7 @@
 #include <ncbi_pch.hpp>
 #include <corelib/ncbi_system.hpp>
 #include <corelib/ncbitime.hpp>
+#include <corelib/stream_utils.hpp>
 #include <serial/iterator.hpp>
 #include <algo/blast/api/remote_blast.hpp>
 #include <algo/blast/api/blast_options_builder.hpp>
@@ -2493,11 +2494,9 @@ CRemoteBlast::x_GetSearchResultsHTTP(void)
 	bool l_cached_ok = true;
 
     auto_ptr<fstream> tmp_stream( CDirEntry::CreateTmpFile() );
-
     do{
-		ios.readsome(incoming_buffer, read_max);
-		n_read = ios.gcount();
-		if( n_read >= 0 ){
+		n_read = CStreamUtils::Readsome(ios,incoming_buffer, read_max);
+		if( n_read > 0 ){
 			l_total_bytes += n_read;
 			try{
 				tmp_stream->write(incoming_buffer,n_read);
@@ -2513,10 +2512,11 @@ CRemoteBlast::x_GetSearchResultsHTTP(void)
 				LOG_POST(Error << "CRemoteBlast::x_GetSearchResultsHTTP CAN'T WRITE CACHED DATA: "<<err.what() );
 				l_cached_ok = false;
 				m_disk_cache_error_msg = err.what();	
+				break;
 			}
 		}
     }
-    while( ios);
+    while( ios );
 	swatch.Stop();
     
 	if(!l_cached_ok ){
@@ -2530,13 +2530,18 @@ CRemoteBlast::x_GetSearchResultsHTTP(void)
     tmp_stream->seekg(0);
     // read cached answer
 	swatch.Restart();
-    {
+    try {
 		auto_ptr<CObjectIStream> 
 	    in_stream( CObjectIStream::Open(eSerial_AsnBinary,  *tmp_stream) );
 		in_stream->Read(ObjectInfo(*one_reply), CObjectIStream::eNoFileHeader);
 
     }
-    
+    catch(...){
+		LOG_POST(Info << "CRemoteBlast::x_GetSearchResultsHTTP: DISABLE CACHE, CAN'T READ CACHED FILE, RE-READ");
+		m_use_disk_cache = false;
+		m_disk_cache_error_flag = true;
+		return x_GetSearchResults();	
+   }
 	swatch.Stop();
 	
     return one_reply ;
diff --git a/c++/src/algo/blast/api/remote_search.cpp b/c++/src/algo/blast/api/remote_search.cpp
index dea41f1..ebec454 100644
--- a/c++/src/algo/blast/api/remote_search.cpp
+++ b/c++/src/algo/blast/api/remote_search.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: remote_search.cpp 481634 2015-10-14 15:21:43Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/repeats_filter_cxx.cpp b/c++/src/algo/blast/api/repeats_filter_cxx.cpp
index 443a68f..da3d3ed 100644
--- a/c++/src/algo/blast/api/repeats_filter_cxx.cpp
+++ b/c++/src/algo/blast/api/repeats_filter_cxx.cpp
@@ -1,4 +1,4 @@
-/*  $Id: repeats_filter_cxx.cpp 378639 2012-10-23 15:05:33Z camacho $
+/*  $Id: repeats_filter_cxx.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -35,11 +35,6 @@
 
 /// @file repeats_filter_cxx.cpp
 /// C++ version of repeats filtering
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: repeats_filter_cxx.cpp 378639 2012-10-23 15:05:33Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <serial/iterator.hpp>
 #include <objects/seqloc/Seq_loc.hpp>
diff --git a/c++/src/algo/blast/api/rps_aux.cpp b/c++/src/algo/blast/api/rps_aux.cpp
index 3ed17a0..cea4c25 100644
--- a/c++/src/algo/blast/api/rps_aux.cpp
+++ b/c++/src/algo/blast/api/rps_aux.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: rps_aux.cpp 382056 2012-12-03 15:31:14Z boratyng $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/rpstblastn_options.cpp b/c++/src/algo/blast/api/rpstblastn_options.cpp
index 7e7c7c4..699bb8a 100644
--- a/c++/src/algo/blast/api/rpstblastn_options.cpp
+++ b/c++/src/algo/blast/api/rpstblastn_options.cpp
@@ -1,4 +1,4 @@
-/*  $Id: rpstblastn_options.cpp 440360 2014-07-11 17:28:33Z madden $
+/*  $Id: rpstblastn_options.cpp 505234 2016-06-23 13:16:57Z fongah2 $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -54,14 +54,12 @@ void
 CRPSTBlastnOptionsHandle::SetGappedExtensionDefaults()
 {
     CBlastRPSOptionsHandle::SetGappedExtensionDefaults();
-    SetCompositionBasedStats(false);
 }
 
 
 void
 CRPSTBlastnOptionsHandle::SetQueryOptionDefaults()
 {
-    SetSegFiltering(true);
     m_Opts->SetQueryGeneticCode(BLAST_GENETIC_CODE);
 }
 
diff --git a/c++/src/algo/blast/api/seedtop.cpp b/c++/src/algo/blast/api/seedtop.cpp
index 3e16f4b..cec7ec2 100644
--- a/c++/src/algo/blast/api/seedtop.cpp
+++ b/c++/src/algo/blast/api/seedtop.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seedtop.cpp 442850 2014-08-07 17:34:09Z camacho $
+/*  $Id: seedtop.cpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -86,7 +86,7 @@ void CSeedTop::x_MakeLookupTable()
     // Lookup segments, scoreblk, and rps info arguments are irrelevant 
     // and passed as NULL.
     LookupTableWrapInit(NULL, lookup_options, NULL, NULL, 
-                        m_ScoreBlk, &m_Lookup, NULL, NULL);
+                        m_ScoreBlk, &m_Lookup, NULL, NULL, NULL);
 }
 
 void CSeedTop::x_MakeScoreBlk()
diff --git a/c++/src/algo/blast/api/seqinfosrc_bioseq.cpp b/c++/src/algo/blast/api/seqinfosrc_bioseq.cpp
index dbefe01..bc4a1b9 100644
--- a/c++/src/algo/blast/api/seqinfosrc_bioseq.cpp
+++ b/c++/src/algo/blast/api/seqinfosrc_bioseq.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: seqinfosrc_bioseq.cpp 170794 2009-09-16 18:53:03Z maning $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/seqinfosrc_bioseq.hpp b/c++/src/algo/blast/api/seqinfosrc_bioseq.hpp
index 1f6e70b..35b4a61 100644
--- a/c++/src/algo/blast/api/seqinfosrc_bioseq.hpp
+++ b/c++/src/algo/blast/api/seqinfosrc_bioseq.hpp
@@ -1,7 +1,7 @@
 #ifndef ALGO_BLAST_API__SEQINFOSRC_BIOSEQ__HPP
 #define ALGO_BLAST_API__SEQINFOSRC_BIOSEQ__HPP
 
-/*  $Id: seqinfosrc_bioseq.hpp 499810 2016-04-28 15:43:25Z ivanov $
+/*  $Id: seqinfosrc_bioseq.hpp 499693 2016-04-27 17:19:56Z madden $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/seqinfosrc_seqdb.cpp b/c++/src/algo/blast/api/seqinfosrc_seqdb.cpp
index 483222a..a220381 100644
--- a/c++/src/algo/blast/api/seqinfosrc_seqdb.cpp
+++ b/c++/src/algo/blast/api/seqinfosrc_seqdb.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: seqinfosrc_seqdb.cpp 315260 2011-07-22 13:48:03Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/seqinfosrc_seqvec.cpp b/c++/src/algo/blast/api/seqinfosrc_seqvec.cpp
index a4c5f31..4d3e285 100644
--- a/c++/src/algo/blast/api/seqinfosrc_seqvec.cpp
+++ b/c++/src/algo/blast/api/seqinfosrc_seqvec.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: seqinfosrc_seqvec.cpp 435182 2014-05-14 14:05:21Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/seqsrc_seqdb.cpp b/c++/src/algo/blast/api/seqsrc_seqdb.cpp
index 92054bc..e4b0a9a 100644
--- a/c++/src/algo/blast/api/seqsrc_seqdb.cpp
+++ b/c++/src/algo/blast/api/seqsrc_seqdb.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqsrc_seqdb.cpp 481634 2015-10-14 15:21:43Z fongah2 $
+/*  $Id: seqsrc_seqdb.cpp 510159 2016-08-11 11:28:47Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -56,44 +56,46 @@ struct SSeqDB_SeqSrc_Data {
         : copied(false)
     {
     }
-    
+
     /// Constructor.
     SSeqDB_SeqSrc_Data(CSeqDB * ptr, int id, ESubjectMaskingType type)
-        : seqdb((CSeqDBExpert*) ptr), 
+        : seqdb((CSeqDBExpert*) ptr),
           mask_algo_id(id),
           mask_type(type),
-          copied(false)
+          copied(false),
+          isProtein(seqdb->GetSequenceType() == CSeqDB::eProtein)
     {
     }
-    
+
     /// Make a copy of this object, sharing the same SeqDB object.
     SSeqDB_SeqSrc_Data * clone()
     {
         return new SSeqDB_SeqSrc_Data(&* seqdb, mask_algo_id, mask_type);
     }
-    
+
     /// Convenience to allow datap->method to use SeqDB methods.
     CSeqDBExpert * operator->()
     {
         _ASSERT(! seqdb.Empty());
         return &*seqdb;
     }
-    
+
     /// Convenience to allow datap->method to use SeqDB methods.
     CSeqDBExpert & operator*()
     {
         _ASSERT(! seqdb.Empty());
         return *seqdb;
     }
-    
+
     /// SeqDB object.
     CRef<CSeqDBExpert> seqdb;
-    
+
     /// Algorithm ID and type for mask data fetching.
     int mask_algo_id;
     ESubjectMaskingType mask_type;
     bool copied;
-    
+    bool isProtein;
+
 #if ((!defined(NCBI_COMPILER_WORKSHOP) || (NCBI_COMPILER_VERSION  > 550)) && \
      (!defined(NCBI_COMPILER_MIPSPRO)) )
     /// Ranges of the sequence to include (for masking).
@@ -111,9 +113,9 @@ static Blast_GiList*
 s_SeqDbGetGiList(void* seqdb_handle, void* args)
 {
     CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
-    
+
     Int4* oid = (Int4*) args;
-    
+
     if (!datap || !oid)
        return NULL;
 
@@ -131,7 +133,7 @@ s_SeqDbGetGiList(void* seqdb_handle, void* args)
 
 /// Retrieves the length of the longest sequence in the BlastSeqSrc.
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
-static Int4 
+static Int4
 s_SeqDbGetMaxLength(void* seqdb_handle, void*)
 {
     CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
@@ -140,7 +142,7 @@ s_SeqDbGetMaxLength(void* seqdb_handle, void*)
 
 /// Retrieves the length of the shortest sequence in the BlastSeqSrc.
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
-static Int4 
+static Int4
 s_SeqDbGetMinLength(void* seqdb_handle, void*)
 {
     CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
@@ -158,7 +160,7 @@ s_SeqDbSetNumberOfThreads(void* seqdb_handle, int n)
 
 /// Retrieves the number of sequences in the BlastSeqSrc.
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
-static Int4 
+static Int4
 s_SeqDbGetNumSeqs(void* seqdb_handle, void*)
 {
     CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
@@ -168,7 +170,7 @@ s_SeqDbGetNumSeqs(void* seqdb_handle, void*)
 /// Retrieves the number of sequences from alias file to be used for
 //  search-space calculations.
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
-static Int4 
+static Int4
 s_SeqDbGetNumSeqsStats(void* seqdb_handle, void*)
 {
     CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
@@ -177,7 +179,7 @@ s_SeqDbGetNumSeqsStats(void* seqdb_handle, void*)
 
 /// Retrieves the total length of all sequences in the BlastSeqSrc.
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
-static Int8 
+static Int8
 s_SeqDbGetTotLen(void* seqdb_handle, void*)
 {
     CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
@@ -187,17 +189,17 @@ s_SeqDbGetTotLen(void* seqdb_handle, void*)
 /// Retrieves the total length of all sequences from alias file
 // to be used for search space calculations.
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
-static Int8 
+static Int8
 s_SeqDbGetTotLenStats(void* seqdb_handle, void*)
 {
     CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
-    return seqdb.GetTotalLengthStats();  
+    return seqdb.GetTotalLengthStats();
 }
 
 /// Retrieves the average length of sequences in the BlastSeqSrc.
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
 /// @param ignoreme Unused by this implementation [in]
-static Int4 
+static Int4
 s_SeqDbGetAvgLength(void* seqdb_handle, void* ignoreme)
 {
    Int8 total_length = s_SeqDbGetTotLen(seqdb_handle, ignoreme);
@@ -208,7 +210,7 @@ s_SeqDbGetAvgLength(void* seqdb_handle, void* ignoreme)
 
 /// Retrieves the name of the BLAST database.
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
-static const char* 
+static const char*
 s_SeqDbGetName(void* seqdb_handle, void*)
 {
     CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
@@ -218,27 +220,29 @@ s_SeqDbGetName(void* seqdb_handle, void*)
 /// Checks whether database is protein or nucleotide.
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
 /// @return TRUE if database is protein, FALSE if nucleotide.
-static Boolean 
+static Boolean
 s_SeqDbGetIsProt(void* seqdb_handle, void*)
 {
-    CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
+    TSeqDBData * datap = (TSeqDBData *) seqdb_handle;
 
-    return (seqdb.GetSequenceType() == CSeqDB::eProtein);
+    return datap->isProtein;
 }
 
 /// Determine if partial fetching should be enabled
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
 static Boolean
-s_SeqDbGetSupportsPartialFetching(void* seqdb_handle, void*) 
+s_SeqDbGetSupportsPartialFetching(void* seqdb_handle, void*)
 {
-    CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
-    
-    if (seqdb.GetSequenceType() != CSeqDB::eNucleotide) {
+    TSeqDBData * datap = (TSeqDBData *) seqdb_handle;
+
+    if (datap->isProtein == true) {
        // don't bother doing this for proteins as the sequences are
        // never long enough to cause performance degredation
        return false;
     }
 
+    CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
+
     // If longest sequence is below this we quit
     static const int kMaxLengthCutoff = 5000;
     if (seqdb.GetMaxLength() < kMaxLengthCutoff) {
@@ -266,7 +270,7 @@ s_SeqDbSetRanges(void* seqdb_handle, BlastSeqSrcSetRangesArg* args)
     if (!seqdb_handle || !args) return;
 
     CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
-        
+
     CSeqDB::TRangeList ranges;
     for (int i=0; i< args->num_ranges; ++i) {
         ranges.insert(pair<int,int> (args->ranges[i*2], args->ranges[i*2+1]));
@@ -279,118 +283,117 @@ s_SeqDbSetRanges(void* seqdb_handle, BlastSeqSrcSetRangesArg* args)
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
 /// @param args Pointer to BlastSeqSrcGetSeqArg structure [in]
 /// @return return codes defined in blast_seqsrc.h
-static Int2 
+static Int2
 s_SeqDbGetSequence(void* seqdb_handle, BlastSeqSrcGetSeqArg* args)
 {
     Int4 oid = -1, len = 0;
     Boolean has_sentinel_byte;
-    
+
     if (!seqdb_handle || !args)
         return BLAST_SEQSRC_ERROR;
-    
+
     TSeqDBData * datap = (TSeqDBData *) seqdb_handle;
-    
+
     CSeqDBExpert & seqdb = **datap;
-    
+
     oid = args->oid;
 
     // If we are asked to check for OID exclusion, and if the database
     // has a GI list, then we check whether all the seqids have been
     // removed by filtering.  If so we return an error.  The traceback
     // code will exclude this HSP list.
-    
+
     if (args->check_oid_exclusion) {
         if (! seqdb.GetIdSet().Blank()) {
             list< CRef<CSeq_id> > seqids = seqdb.GetSeqIDs(oid);
-            
+
             if (seqids.empty()) {
                 return BLAST_SEQSRC_EXCLUDED;
             }
         }
     }
-    
+
 #if ((!defined(NCBI_COMPILER_WORKSHOP) || (NCBI_COMPILER_VERSION  > 550)) && \
      (!defined(NCBI_COMPILER_MIPSPRO)) )
-    if (datap->mask_type != eNoSubjMasking) { 
+    if (datap->mask_type != eNoSubjMasking) {
         ASSERT(datap->mask_algo_id != -1);
         seqdb.GetMaskData(oid, datap->mask_algo_id, datap->seq_ranges);
     }
 #endif
 
     datap->copied = false;
-    
-    if ( args->encoding == eBlastEncodingNucleotide 
-      || args->encoding == eBlastEncodingNcbi4na 
-      || (datap->mask_type == eHardSubjMasking 
+
+    if ( args->encoding == eBlastEncodingNucleotide
+      || args->encoding == eBlastEncodingNcbi4na
+      || (datap->mask_type == eHardSubjMasking
               && !(datap->seq_ranges.empty())
               && args->check_oid_exclusion))  datap->copied = true;
 
     has_sentinel_byte = (args->encoding == eBlastEncodingNucleotide);
-    
+
     /* free buffers if necessary */
     if (args->seq) BlastSequenceBlkClean(args->seq);
-    
+
     /* This occurs if the pre-selected partial sequence in the traceback stage
      * was too small to perform the traceback. Only do this for nucleotide
      * sequences as proteins are not long enough to be of significance */
-    if (args->reset_ranges && seqdb.GetSequenceType() == CSeqDB::eNucleotide) {
+    if (args->reset_ranges && datap->isProtein == false)
         seqdb.RemoveOffsetRanges(oid);
-    }
-    
+
     const char *buf;
-    len = (datap->copied) 
+    len = (datap->copied)
            /* This will consume and clear datap->seq_ranges */
-        ?  seqdb.GetAmbigSeqAlloc(oid, 
-                                  const_cast<char **>(&buf), 
-                                  has_sentinel_byte, 
+        ?  seqdb.GetAmbigSeqAlloc(oid,
+                                  const_cast<char **>(&buf),
+                                  has_sentinel_byte,
                                   eMalloc,
                                   ((datap->mask_type == eHardSubjMasking) ?
                                        &(datap->seq_ranges) : NULL))
         :  seqdb.GetSequence(oid, &buf);
-    
+
     if (len <= 0) return BLAST_SEQSRC_ERROR;
-    
+
     BlastSetUp_SeqBlkNew((Uint1*)buf, len, &args->seq, datap->copied);
-    
+
     /* If there is no sentinel byte, and buffer is allocated, i.e. this is
-       the traceback stage of a translated search, set "sequence" to the same 
+       the traceback stage of a translated search, set "sequence" to the same
        position as "sequence_start". */
     if (datap->copied && !has_sentinel_byte)
         args->seq->sequence = args->seq->sequence_start;
-    
+
     /* For preliminary stage, even though sequence buffer points to a memory
        mapped location, we still need to call ReleaseSequence. This can only be
        guaranteed by making the engine believe tat sequence is allocated.
     */
     if (!datap->copied) args->seq->sequence_allocated = TRUE;
-    
+
     args->seq->oid = oid;
 
 #if ((!defined(NCBI_COMPILER_WORKSHOP) || (NCBI_COMPILER_VERSION  > 550)) && \
      (!defined(NCBI_COMPILER_MIPSPRO)) )
     /* If masks have not been consumed (scanning phase), pass on to engine */
     if (datap->mask_type != eNoSubjMasking) {
-        if (BlastSeqBlkSetSeqRanges(args->seq, 
+        if (BlastSeqBlkSetSeqRanges(args->seq,
                                 (SSeqRange*) datap->seq_ranges.get_data(),
                                 datap->seq_ranges.size() + 1, false, datap->mask_type) != 0) {
             return BLAST_SEQSRC_ERROR;
         }
     }
 #endif
-    
+
     return BLAST_SEQSRC_SUCCESS;
 }
 
-/// Returns the memory allocated for the sequence buffer to the CSeqDB 
+/// Returns the memory allocated for the sequence buffer to the CSeqDB
 /// interface.
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
-/// @param args Pointer to the BlastSeqSrcGetSeqArgs structure, 
+/// @param args Pointer to the BlastSeqSrcGetSeqArgs structure,
 /// containing sequence block with the buffer that needs to be deallocated. [in]
 static void
 s_SeqDbReleaseSequence(void* seqdb_handle, BlastSeqSrcGetSeqArg* args)
 {
     TSeqDBData * datap = (TSeqDBData *) seqdb_handle;
-    
+
     CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
 
     _ASSERT(seqdb_handle);
@@ -398,8 +401,7 @@ s_SeqDbReleaseSequence(void* seqdb_handle, BlastSeqSrcGetSeqArg* args)
     _ASSERT(args->seq);
 
     if (args->seq->sequence_start_allocated) {
-        ASSERT (datap->copied);
-        sfree(args->seq->sequence_start);
+        if (datap->copied) sfree(args->seq->sequence_start);
         args->seq->sequence_start_allocated = FALSE;
         args->seq->sequence_start = NULL;
     }
@@ -415,7 +417,7 @@ s_SeqDbReleaseSequence(void* seqdb_handle, BlastSeqSrcGetSeqArg* args)
 /// @param seqdb_handle Pointer to initialized CSeqDB object [in]
 /// @param args Pointer to integer indicating ordinal id [in]
 /// @return Length of the database sequence or BLAST_SEQSRC_ERROR.
-static Int4 
+static Int4
 s_SeqDbGetSeqLen(void* seqdb_handle, void* args)
 {
     Int4* oid = (Int4*) args;
@@ -428,23 +430,23 @@ s_SeqDbGetSeqLen(void* seqdb_handle, void* args)
 }
 
 /// Assigns next chunk of the database to the sequence source iterator.
-/// @param seqdb_handle Reference to the database object, cast to void* to 
+/// @param seqdb_handle Reference to the database object, cast to void* to
 ///                     satisfy the signature requirement. [in]
 /// @param itr Iterator over the database sequence source. [in|out]
-static Int2 
+static Int2
 s_SeqDbGetNextChunk(void* seqdb_handle, BlastSeqSrcIterator* itr)
 {
     if (!seqdb_handle || !itr)
         return BLAST_SEQSRC_ERROR;
-    
+
     CSeqDB & seqdb = **(TSeqDBData *) seqdb_handle;
-    
+
     vector<int> oid_list;
 
-    CSeqDB::EOidListType chunk_type = 
-        seqdb.GetNextOIDChunk(itr->oid_range[0], itr->oid_range[1], 
+    CSeqDB::EOidListType chunk_type =
+        seqdb.GetNextOIDChunk(itr->oid_range[0], itr->oid_range[1],
                               itr->chunk_sz, oid_list);
-    
+
     if (itr->oid_range[1] <= itr->oid_range[0])
         return BLAST_SEQSRC_EOF;
 
@@ -457,7 +459,7 @@ s_SeqDbGetNextChunk(void* seqdb_handle, BlastSeqSrcIterator* itr)
         if (new_sz > 0) {
             itr->current_pos = 0;
             Uint4 index;
-            if (itr->chunk_sz < new_sz) { 
+            if (itr->chunk_sz < new_sz) {
                 sfree(itr->oid_list);
                 itr->oid_list = (int *) malloc (new_sz * sizeof(int));
             }
@@ -473,11 +475,11 @@ s_SeqDbGetNextChunk(void* seqdb_handle, BlastSeqSrcIterator* itr)
 }
 
 /// Finds the next not searched ordinal id in the iteration over BLAST database.
-/// @param seqdb_handle Reference to the database object, cast to void* to 
+/// @param seqdb_handle Reference to the database object, cast to void* to
 ///                     satisfy the signature requirement. [in]
 /// @param itr Iterator of the BlastSeqSrc pointed by ptr. [in]
 /// @return Next ordinal id.
-static Int4 
+static Int4
 s_SeqDbIteratorNext(void* seqdb_handle, BlastSeqSrcIterator* itr)
 {
     Int4 retval = BLAST_SEQSRC_EOF;
@@ -486,7 +488,7 @@ s_SeqDbIteratorNext(void* seqdb_handle, BlastSeqSrcIterator* itr)
     _ASSERT(seqdb_handle);
     _ASSERT(itr);
 
-    /* If internal iterator is uninitialized/invalid, retrieve the next chunk 
+    /* If internal iterator is uninitialized/invalid, retrieve the next chunk
        from the BlastSeqSrc */
     if (itr->current_pos == UINT4_MAX) {
         status = s_SeqDbGetNextChunk(seqdb_handle, itr);
@@ -518,7 +520,7 @@ s_SeqDbIteratorNext(void* seqdb_handle, BlastSeqSrcIterator* itr)
 }
 
 /// Resets CSeqDB's internal chunk bookmark
-/// @param seqdb_handle Reference to the database object, cast to void* to 
+/// @param seqdb_handle Reference to the database object, cast to void* to
 ///                     satisfy the signature requirement. [in]
 static void
 s_SeqDbResetChunkIterator(void* seqdb_handle)
@@ -541,9 +543,9 @@ public:
     /// Constructor
     CSeqDbSrcNewArgs(const string& db, bool is_prot,
                      Uint4 first_oid = 0, Uint4 final_oid = 0,
-                     Int4 mask_algo_id = -1, 
+                     Int4 mask_algo_id = -1,
                      ESubjectMaskingType mask_type = eNoSubjMasking)
-        : m_DbName(db), m_IsProtein(is_prot), 
+        : m_DbName(db), m_IsProtein(is_prot),
           m_FirstDbSeq(first_oid), m_FinalDbSeq(final_oid),
           m_MaskAlgoId(mask_algo_id), m_MaskType(mask_type)
     {}
@@ -576,15 +578,15 @@ extern "C" {
 /// SeqDb sequence source destructor: frees its internal data structure
 /// @param seq_src BlastSeqSrc structure to free [in]
 /// @return NULL
-static BlastSeqSrc* 
+static BlastSeqSrc*
 s_SeqDbSrcFree(BlastSeqSrc* seq_src)
 {
-    if (!seq_src) 
+    if (!seq_src)
         return NULL;
-    
+
     TSeqDBData * datap = static_cast<TSeqDBData*>
         (_BlastSeqSrcImpl_GetDataStructure(seq_src));
-    
+
     delete datap;
     return NULL;
 }
@@ -593,30 +595,30 @@ s_SeqDbSrcFree(BlastSeqSrc* seq_src)
 /// and copies the rest of the BlastSeqSrc structure.
 /// @param seq_src BlastSeqSrc structure to copy [in]
 /// @return Pointer to the new BlastSeqSrc.
-static BlastSeqSrc* 
+static BlastSeqSrc*
 s_SeqDbSrcCopy(BlastSeqSrc* seq_src)
 {
-    if (!seq_src) 
+    if (!seq_src)
         return NULL;
-    
+
     TSeqDBData * datap = static_cast<TSeqDBData*>
         (_BlastSeqSrcImpl_GetDataStructure(seq_src));
-    
+
     _BlastSeqSrcImpl_SetDataStructure(seq_src, (void*) datap->clone());
-    
+
     return seq_src;
 }
 
-/// Initializes the data structure and function pointers in a SeqDb based 
+/// Initializes the data structure and function pointers in a SeqDb based
 /// BlastSeqSrc.
 /// @param retval Structure to populate [in] [out]
 /// @param seqdb Reference to a CSeqDB object [in]
-static void 
+static void
 s_InitNewSeqDbSrc(BlastSeqSrc* retval, TSeqDBData * datap)
 {
     _ASSERT(retval);
     _ASSERT(datap);
-    
+
     /* Initialize the BlastSeqSrc structure fields with user-defined function
      * pointers and seqdb */
     _BlastSeqSrcImpl_SetDeleteFnPtr   (retval, & s_SeqDbSrcFree);
@@ -644,53 +646,54 @@ s_InitNewSeqDbSrc(BlastSeqSrc* retval, TSeqDBData * datap)
 #endif /* KAPPA_PRINT_DIAGNOSTICS */
 }
 
-/// Populates a BlastSeqSrc, creating a new reference to the already existing 
+/// Populates a BlastSeqSrc, creating a new reference to the already existing
 /// SeqDb object.
 /// @param retval Original BlastSeqSrc [in]
 /// @param args Pointer to a reference to CSeqDB object [in]
 /// @return retval
-static BlastSeqSrc* 
+static BlastSeqSrc*
 s_SeqDbSrcSharedNew(BlastSeqSrc* retval, void* args)
 {
     _ASSERT(retval);
     _ASSERT(args);
-    
+
     TSeqDBData * datap = (TSeqDBData *) args;
-    
+
     s_InitNewSeqDbSrc(retval, datap->clone());
-    
+
     return retval;
 }
 
-/// SeqDb sequence source constructor 
+/// SeqDb sequence source constructor
 /// @param retval BlastSeqSrc structure (already allocated) to populate [in]
 /// @param args Pointer to internal CSeqDbSrcNewArgs structure (@sa
 /// CSeqDbSrcNewArgs) [in]
 /// @return Updated seq_src structure (with all function pointers initialized
-static BlastSeqSrc* 
+static BlastSeqSrc*
 s_SeqDbSrcNew(BlastSeqSrc* retval, void* args)
 {
     _ASSERT(retval);
     _ASSERT(args);
-    
+
     CSeqDbSrcNewArgs* seqdb_args = (CSeqDbSrcNewArgs*) args;
     _ASSERT(seqdb_args);
-    
+
     TSeqDBData * datap = new TSeqDBData;
-    
+
     try {
         bool is_protein = (seqdb_args->GetDbType() == 'p');
-        
+
         datap->seqdb.Reset(new CSeqDBExpert(seqdb_args->GetDbName(),
                                             (is_protein
                                              ? CSeqDB::eProtein
                                              : CSeqDB::eNucleotide)));
-        
+
         datap->seqdb->SetIterationRange(seqdb_args->GetFirstOid(),
                                         seqdb_args->GetFinalOid());
-        
+
         datap->mask_algo_id = seqdb_args->GetMaskAlgoId();
         datap->mask_type = seqdb_args->GetMaskType();
+        datap->isProtein = is_protein;
 
         // Validate that the masking algorithm is supported
         if (datap->mask_algo_id > 0) {
@@ -701,8 +704,8 @@ s_SeqDbSrcNew(BlastSeqSrc* retval, void* args)
                      datap->mask_algo_id) == supported_algorithms.end()) {
                 CNcbiOstrstream oss;
                 oss << "Masking algorithm ID " << datap->mask_algo_id << " is "
-                    << "not supported in " << 
-                    (is_protein ? "protein" : "nucleotide") << " '" 
+                    << "not supported in " <<
+                    (is_protein ? "protein" : "nucleotide") << " '"
                     << seqdb_args->GetDbName() << "' BLAST database";
                 string msg = CNcbiOstrstreamToString(oss);
                 throw runtime_error(msg);
@@ -710,27 +713,27 @@ s_SeqDbSrcNew(BlastSeqSrc* retval, void* args)
         }
 
     } catch (const ncbi::CException& e) {
-        _BlastSeqSrcImpl_SetInitErrorStr(retval, 
+        _BlastSeqSrcImpl_SetInitErrorStr(retval,
                         strdup(e.ReportThis(eDPF_ErrCodeExplanation).c_str()));
     } catch (const std::exception& e) {
         _BlastSeqSrcImpl_SetInitErrorStr(retval, strdup(e.what()));
     } catch (...) {
-        _BlastSeqSrcImpl_SetInitErrorStr(retval, 
+        _BlastSeqSrcImpl_SetInitErrorStr(retval,
              strdup("Caught unknown exception from CSeqDB constructor"));
     }
-    
+
     /* Initialize the BlastSeqSrc structure fields with user-defined function
      * pointers and seqdb */
-    
+
     s_InitNewSeqDbSrc(retval, datap);
-    
+
     return retval;
 }
 
 }
 
-BlastSeqSrc* 
-SeqDbBlastSeqSrcInit(const string& dbname, bool is_prot, 
+BlastSeqSrc*
+SeqDbBlastSeqSrcInit(const string& dbname, bool is_prot,
                  Uint4 first_seq, Uint4 last_seq,
                  Int4 mask_algo_id, ESubjectMaskingType mask_type)
 {
@@ -745,7 +748,7 @@ SeqDbBlastSeqSrcInit(const string& dbname, bool is_prot,
     return seq_src;
 }
 
-BlastSeqSrc* 
+BlastSeqSrc*
 SeqDbBlastSeqSrcInit(CSeqDB * seqdb,
                      Int4 mask_algo_id,
                      ESubjectMaskingType mask_type)
diff --git a/c++/src/algo/blast/api/setup_factory.cpp b/c++/src/algo/blast/api/setup_factory.cpp
index 46cc54a..80338d8 100644
--- a/c++/src/algo/blast/api/setup_factory.cpp
+++ b/c++/src/algo/blast/api/setup_factory.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: setup_factory.cpp 458896 2015-02-11 15:05:08Z boratyng $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -59,8 +55,10 @@ static char const rcsid[] =
 #include <algo/blast/core/hspfilter_collector.h>
 #include <algo/blast/core/hspfilter_besthit.h>
 #include <algo/blast/core/hspfilter_culling.h>
+#include <algo/blast/core/hspfilter_mapper.h>
 
 #include <sstream>
+#include "../core/jumper.h"
 
 /** @addtogroup AlgoBlast
  *
@@ -219,7 +217,8 @@ CSetupFactory::CreateLookupTable(CRef<ILocalQueryData> query_data,
                                       score_blk,
                                       &retval,
                                       rps_info ? (*rps_info)() : 0,
-                                      &blast_msg);
+                                      &blast_msg,
+                                      seqsrc);
     if (status != 0) {
          TSearchMessages search_messages;
          Blast_Message2TSearchMessages(blast_msg.Get(), 
@@ -294,6 +293,7 @@ CSetupFactory::CreateHspStream(const CBlastOptionsMemento* opts_memento,
 
 BlastHSPWriter*
 CSetupFactory::CreateHspWriter(const CBlastOptionsMemento* opts_memento,
+                               BLAST_SequenceBlk* query,
                                BlastQueryInfo* query_info)
 {
     BlastHSPWriterInfo* writer_info = NULL;
@@ -304,8 +304,16 @@ CSetupFactory::CreateHspWriter(const CBlastOptionsMemento* opts_memento,
     	//We want to only do score edge in prelimiary stage, skip if score edge in 0
     	filt_opts = NULL;
     }
-    if (filt_opts) {
-        bool hsp_writer_found = false;
+
+    if (Blast_ProgramIsMapping(opts_memento->m_ProgramType)) {
+
+        BlastHSPMapperParams* params =
+            BlastHSPMapperParamsNew(opts_memento->m_HitSaveOpts,
+                                    opts_memento->m_ScoringOpts);
+
+        writer_info = BlastHSPMapperInfoNew(params);
+    }
+    else if (filt_opts) {
         if (filt_opts->best_hit && (filt_opts->best_hit_stage & ePrelimSearch))
         {
             BlastHSPBestHitParams* params = 
@@ -316,21 +324,17 @@ CSetupFactory::CreateHspWriter(const CBlastOptionsMemento* opts_memento,
             // Disable overhang in prelimiary stage
             params->overhang = 0;
             writer_info = BlastHSPBestHitInfoNew(params);
-            hsp_writer_found = true;
         }
         else if (filt_opts->culling_opts && 
                  (filt_opts->culling_stage & ePrelimSearch))
         {
-            _ASSERT(hsp_writer_found == false);
             BlastHSPCullingParams* params = 
                 BlastHSPCullingParamsNew(opts_memento->m_HitSaveOpts,
                      filt_opts->culling_opts,
                      opts_memento->m_ExtnOpts->compositionBasedStats,
                      opts_memento->m_ScoringOpts->gapped_calculation);
             writer_info = BlastHSPCullingInfoNew(params);
-            hsp_writer_found = true;
         }
-        (void)hsp_writer_found; /* to pacify compiler warning */
     } else {
         /* Use the collector filtering algorithm as the default */
         BlastHSPCollectorParams * params = 
@@ -340,7 +344,7 @@ CSetupFactory::CreateHspWriter(const CBlastOptionsMemento* opts_memento,
         writer_info = BlastHSPCollectorInfoNew(params);
     }
     
-    BlastHSPWriter* retval = BlastHSPWriterNew(&writer_info, query_info);
+    BlastHSPWriter* retval = BlastHSPWriterNew(&writer_info, query_info, query);
     _ASSERT(writer_info == NULL);
     return retval;
 }
@@ -420,7 +424,8 @@ CSetupFactory::InitializeMegablastDbIndex(CRef<CBlastOptions> options)
     string errstr = "";
     bool partial( false );
 
-    if( options->GetProgramType() != eBlastTypeBlastn ) {
+    if( options->GetProgramType() != eBlastTypeBlastn
+        && options->GetProgramType() != eBlastTypeMapping) {
         errstr = "Database indexing is available for blastn only.";
     }
     else if( options->GetMBTemplateLength() > 0 ) {
diff --git a/c++/src/algo/blast/api/split_query_aux_priv.cpp b/c++/src/algo/blast/api/split_query_aux_priv.cpp
index 01e1841..e8bbfa6 100644
--- a/c++/src/algo/blast/api/split_query_aux_priv.cpp
+++ b/c++/src/algo/blast/api/split_query_aux_priv.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: split_query_aux_priv.cpp 458701 2015-02-09 15:05:54Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -82,6 +78,10 @@ SplitQuery_ShouldSplit(EBlastProgramType program,
     // TODO: need to model mem usage and when it's advantageous to split
     bool retval = true;
 
+    if (program == eBlastTypeMapping) {
+        return false;
+    }
+
     // if ((concatenated_query_length <= chunk_size+SplitQuery_GetOverlapChunkSize(program)) ||
    //  if ((concatenated_query_length <= chunk_size) ||
         // do not split RPS-BLAST
diff --git a/c++/src/algo/blast/api/split_query_blk.cpp b/c++/src/algo/blast/api/split_query_blk.cpp
index 126ea28..655b1fd 100644
--- a/c++/src/algo/blast/api/split_query_blk.cpp
+++ b/c++/src/algo/blast/api/split_query_blk.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: split_query_blk.cpp 195768 2010-06-25 17:12:38Z maning $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/split_query_cxx.cpp b/c++/src/algo/blast/api/split_query_cxx.cpp
index 55afcb8..64ebcaf 100644
--- a/c++/src/algo/blast/api/split_query_cxx.cpp
+++ b/c++/src/algo/blast/api/split_query_cxx.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: split_query_cxx.cpp 442852 2014-08-07 17:41:12Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 /* ===========================================================================
  *
diff --git a/c++/src/algo/blast/api/traceback_stage.cpp b/c++/src/algo/blast/api/traceback_stage.cpp
index 83f0dc5..5032a03 100644
--- a/c++/src/algo/blast/api/traceback_stage.cpp
+++ b/c++/src/algo/blast/api/traceback_stage.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: traceback_stage.cpp 459518 2015-02-19 13:53:19Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/uniform_search.cpp b/c++/src/algo/blast/api/uniform_search.cpp
index 3c44368..c1edc5e 100644
--- a/c++/src/algo/blast/api/uniform_search.cpp
+++ b/c++/src/algo/blast/api/uniform_search.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: uniform_search.cpp 481634 2015-10-14 15:21:43Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/api/winmask_filter.cpp b/c++/src/algo/blast/api/winmask_filter.cpp
index d63303e..3bc6fa6 100644
--- a/c++/src/algo/blast/api/winmask_filter.cpp
+++ b/c++/src/algo/blast/api/winmask_filter.cpp
@@ -1,4 +1,4 @@
-/*  $Id: winmask_filter.cpp 463952 2015-04-02 16:08:53Z camacho $
+/*  $Id: winmask_filter.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -34,11 +34,6 @@
 
 /// @file winmask_filter.cpp
 /// Blast wrappers for WindowMasker filtering.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: winmask_filter.cpp 463952 2015-04-02 16:08:53Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "winmask_filter.hpp"
 #include <sstream>
diff --git a/c++/src/algo/blast/blastinput/Makefile.blastinput.lib b/c++/src/algo/blast/blastinput/Makefile.blastinput.lib
index 96ea05b..4008d13 100644
--- a/c++/src/algo/blast/blastinput/Makefile.blastinput.lib
+++ b/c++/src/algo/blast/blastinput/Makefile.blastinput.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.blastinput.lib 441606 2014-07-25 14:36:47Z fongah2 $
+# $Id: Makefile.blastinput.lib 514850 2016-09-26 17:23:32Z ivanov $
 
 SRC_CXX = \
 blast_input \
@@ -18,7 +18,10 @@ rpsblast_args \
 rpstblastn_args \
 igblastn_args \
 igblastp_args \
-deltablast_args
+deltablast_args \
+magicblast_args \
+kblastp_args \
+blast_asn1_input
 
 SRC  = $(SRC_CXX)
 
@@ -34,7 +37,7 @@ CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS)
 CXXFLAGS = $(FAST_CXXFLAGS)
 LDFLAGS  = $(FAST_LDFLAGS)
 
-WATCHERS = madden camacho fongah2
+WATCHERS = madden camacho fongah2 boratyng
 
 
 USES_LIBRARIES =  \
diff --git a/c++/src/algo/blast/blastinput/Makefile.in b/c++/src/algo/blast/blastinput/Makefile.in
index d7d08c7..ab9e5ab 100644
--- a/c++/src/algo/blast/blastinput/Makefile.in
+++ b/c++/src/algo/blast/blastinput/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in 134303 2008-07-17 17:42:49Z camacho $
+# $Id: Makefile.in 507863 2016-07-21 20:15:31Z boratyng $
 
 # Meta-makefile("ALGO" project)
 #################################
diff --git a/c++/src/algo/blast/blastinput/blast_args.cpp b/c++/src/algo/blast/blastinput/blast_args.cpp
index ca39587..948c922 100644
--- a/c++/src/algo/blast/blastinput/blast_args.cpp
+++ b/c++/src/algo/blast/blastinput/blast_args.cpp
@@ -1,4 +1,4 @@
-/* $Id: blast_args.cpp 499246 2016-04-25 11:32:24Z ivanov $
+/* $Id: blast_args.cpp 516396 2016-10-13 12:26:43Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -35,11 +35,6 @@ Author: Jason Papadopoulos
  * convert blast-related command line
  * arguments into blast options
 */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: blast_args.cpp 499246 2016-04-25 11:32:24Z ivanov $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/api/version.hpp>
 #include <algo/blast/blastinput/blast_args.hpp>
@@ -132,10 +127,11 @@ CGenericSearchArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
                      CArgDescriptions::eDouble,
                      NStr::DoubleToString(1.0));
     } else {
+        //igblastn
         arg_desc.AddDefaultKey(kArgEvalue, "evalue", 
                      "Expectation value (E) threshold for saving hits ",
                      CArgDescriptions::eDouble,
-                     NStr::DoubleToString(1e-15));
+                     NStr::DoubleToString(20.0));
     }
 
     // word size
@@ -228,7 +224,7 @@ void
 CGenericSearchArgs::ExtractAlgorithmOptions(const CArgs& args, 
                                             CBlastOptions& opt)
 {
-    if (args[kArgEvalue]) {
+    if (args.Exist(kArgEvalue) && args[kArgEvalue]) {
         opt.SetEvalueThreshold(args[kArgEvalue].AsDouble());
     }
 
@@ -251,7 +247,7 @@ CGenericSearchArgs::ExtractAlgorithmOptions(const CArgs& args,
         opt.SetGapExtensionCost(gap_extend);
     }
 
-    if (args[kArgUngappedXDropoff]) {
+    if (args.Exist(kArgUngappedXDropoff) && args[kArgUngappedXDropoff]) {
         opt.SetXDropoff(args[kArgUngappedXDropoff].AsDouble());
     }
 
@@ -269,7 +265,7 @@ CGenericSearchArgs::ExtractAlgorithmOptions(const CArgs& args,
         opt.SetWordSize(args[kArgWordSize].AsInteger());
     }
 
-    if (args[kArgEffSearchSpace]) {
+    if (args.Exist(kArgEffSearchSpace) && args[kArgEffSearchSpace]) {
         CNcbiEnvironment env;
         env.Set("OLD_FSC", "true");
         opt.SetEffectiveSearchSpace(args[kArgEffSearchSpace].AsInt8());
@@ -283,7 +279,7 @@ CGenericSearchArgs::ExtractAlgorithmOptions(const CArgs& args,
         opt.SetQueryCovHspPerc(args[kArgQueryCovHspPerc].AsDouble());
     }
 
-    if (args[kArgMaxHSPsPerSubject]) {
+    if (args.Exist(kArgMaxHSPsPerSubject) && args[kArgMaxHSPsPerSubject]) {
         opt.SetMaxHspsPerSubject(args[kArgMaxHSPsPerSubject].AsInteger());
     }
 
@@ -638,14 +634,15 @@ void
 CNuclArgs::ExtractAlgorithmOptions(const CArgs& cmd_line_args,
                                    CBlastOptions& options)
 {
-    if (cmd_line_args[kArgMismatch]) {
+    if (cmd_line_args.Exist(kArgMismatch) && cmd_line_args[kArgMismatch]) {
         options.SetMismatchPenalty(cmd_line_args[kArgMismatch].AsInteger());
     }
-    if (cmd_line_args[kArgMatch]) {
+    if (cmd_line_args.Exist(kArgMatch) && cmd_line_args[kArgMatch]) {
         options.SetMatchReward(cmd_line_args[kArgMatch].AsInteger());
     }
 
-    if (cmd_line_args[kArgNoGreedyExtension]) {
+    if (cmd_line_args.Exist(kArgNoGreedyExtension) &&
+        cmd_line_args[kArgNoGreedyExtension]) {
         options.SetGapExtnAlgorithm(eDynProgScoreOnly);
         options.SetGapTracebackAlgorithm(eDynProgTbck);
     }
@@ -794,7 +791,7 @@ s_SetCompositionBasedStats(CBlastOptions& opt,
     const EProgram program = opt.GetProgram();
     if (program == eBlastp || program == eTblastn || 
         program == ePSIBlast || program == ePSITblastn ||
-        program == eRPSBlast ||
+        program == eRPSBlast || program == eRPSTblastn ||
         program == eBlastx  ||  program == eDeltaBlast) {
 
         ECompoAdjustModes compo_mode = eNoCompositionBasedStats;
@@ -807,7 +804,7 @@ s_SetCompositionBasedStats(CBlastOptions& opt,
                 compo_mode = eCompositionBasedStats;
                 break;
             case 'D': case 'd':
-                if (program == eRPSBlast) {
+                if ((program == eRPSBlast) || (program == eRPSTblastn)) {
                     compo_mode = eNoCompositionBasedStats;
                 }
                 else if (program == eDeltaBlast) {
@@ -824,7 +821,7 @@ s_SetCompositionBasedStats(CBlastOptions& opt,
                 compo_mode = eCompoForceFullMatrixAdjust;
                 break;
             case 'T': case 't':
-                compo_mode = (program == eRPSBlast || program == eDeltaBlast) ?
+                compo_mode = (program == eRPSBlast || program == eRPSTblastn || program == eDeltaBlast) ?
                     eCompositionBasedStats : eCompositionMatrixAdjust;
                 break;
         } 
@@ -1370,6 +1367,35 @@ CPhiBlastArgs::ExtractAlgorithmOptions(const CArgs& args,
     }
 }
 
+void 
+CKBlastpArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
+{
+   arg_desc.SetCurrentGroup("KBLASTP options");
+   arg_desc.AddDefaultKey(kArgJDistance, "threshold", "Jaccard Distance", 
+			CArgDescriptions::eDouble, kDfltArgJDistance);
+   arg_desc.AddDefaultKey(kArgMinHits, "minhits", "minimal number of LSH matches", 
+			CArgDescriptions::eInteger, kDfltArgMinHits);
+   arg_desc.AddDefaultKey(kArgKIndex, "dbk", "index of kmers", 
+			CArgDescriptions::eString, kDfltArgKIndex);
+   arg_desc.AddDefaultKey(kArgTargetSeqs, "targetseqs", "Number of target sequences to process with BLAST", 
+			CArgDescriptions::eInteger, kDfltArgTargetSeqs);
+}
+
+void 
+CKBlastpArgs::ExtractAlgorithmOptions(const CArgs& args,
+                                         CBlastOptions& opt)
+{
+	if (args.Exist(kArgJDistance)) 
+		m_JDistance = args[kArgJDistance].AsDouble();
+	if (args.Exist(kArgMinHits))
+		m_MinHits = args[kArgMinHits].AsInteger();
+	if (args.Exist(kArgKIndex))
+		m_DbIndex = args[kArgKIndex].AsString();
+	if (args.Exist(kArgTargetSeqs))
+		m_TargetSeqs = args[kArgTargetSeqs].AsInteger();
+}
+
+
 void
 CDeltaBlastArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
 {
@@ -1399,6 +1425,64 @@ CDeltaBlastArgs::ExtractAlgorithmOptions(const CArgs& args,
 }
 
 void
+CMappingArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
+{
+
+    arg_desc.SetCurrentGroup("Mapping options");
+    arg_desc.AddOptionalKey(kArgScore, "num", "Cutoff score for accepting a "
+                            "single non-spliced alignment",
+                            CArgDescriptions::eInteger);
+    arg_desc.AddOptionalKey(kArgSplice, "TF", "Search for spliced alignments",
+                            CArgDescriptions::eBoolean);
+    arg_desc.AddDefaultKey(kArgRefType, "type", "Type of the reference: "
+                           "genome or transcriptome",
+                           CArgDescriptions::eString, "genome");
+    arg_desc.SetConstraint(kArgRefType,
+                        &(*new CArgAllow_Strings, "genome", "transcriptome"));
+
+    arg_desc.SetCurrentGroup("Query filtering options");
+    arg_desc.AddOptionalKey(kArgLimitLookup, "TF", "Remove word seeds with "
+                            "high frequency in the searched database",
+                            CArgDescriptions::eBoolean);
+    arg_desc.AddDefaultKey(kArgLookupStride, "num", "Number of words to skip "
+			    "after collecting one while creating a lookup table",
+                 CArgDescriptions::eInteger, "0");
+
+    arg_desc.SetCurrentGroup("");
+}
+
+
+void
+CMappingArgs::ExtractAlgorithmOptions(const CArgs& args,
+                                      CBlastOptions& opt)
+{
+    if (args.Exist(kArgScore) && args[kArgScore]) {
+        opt.SetCutoffScore(args[kArgScore].AsInteger());
+    }
+
+    if (args.Exist(kArgSplice) && args[kArgSplice]) {
+        opt.SetSpliceAlignments(args[kArgSplice].AsBoolean());
+    }
+
+    string ref_type = "genome";
+    if (args.Exist(kArgRefType) && args[kArgRefType]) {
+        ref_type = args[kArgRefType].AsString();
+    }
+
+    if (args.Exist(kArgLimitLookup) && args[kArgLimitLookup]) {
+        opt.SetLookupDbFilter(args[kArgLimitLookup].AsBoolean());
+    }
+    else {
+        opt.SetLookupDbFilter(ref_type == "genome");
+    }
+
+    if (args.Exist(kArgLookupStride) && args[kArgLookupStride]) {
+        opt.SetLookupTableStride(args[kArgLookupStride].AsInteger());
+    }
+}
+
+
+void
 CIgBlastArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
 {
     arg_desc.SetCurrentGroup("Ig-BLAST options");
@@ -1454,6 +1538,16 @@ CIgBlastArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
 
         arg_desc.SetConstraint(kArgDPenalty, 
                                new CArgAllowValuesBetween(-6, 0));
+
+        arg_desc.AddDefaultKey(kArgNumClonotype, "num_clonotype",
+                                "Number of top clonotypes to show ",
+                               CArgDescriptions::eInteger, "100");
+        arg_desc.SetConstraint(kArgNumClonotype, 
+                               new CArgAllowValuesGreaterThanOrEqual(0));
+        
+        arg_desc.AddOptionalKey(kArgClonotypeFile, "clonotype_out", 
+                                "Output file name for clonotype info",
+                               CArgDescriptions::eOutputFile);
        
     }
 
@@ -1480,8 +1574,17 @@ CIgBlastArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
     arg_desc.AddDefaultKey(kArgMinVLength, "Min_V_Length",
                            "Minimal required V gene length",
                            CArgDescriptions::eInteger, "9");
+
     arg_desc.SetConstraint(kArgMinVLength, 
                            new CArgAllowValuesGreaterThanOrEqual(9));
+
+    arg_desc.AddDefaultKey(kArgMinJLength, "Min_J_Length",
+                           "Minimal required J gene length",
+                           CArgDescriptions::eInteger, "0");
+
+    arg_desc.SetConstraint(kArgMinJLength, 
+                           new CArgAllowValuesGreaterThanOrEqual(0));
+    
     
     if (! m_IsProtein) {
         arg_desc.AddFlag(kArgTranslate, "Show translated alignments", true);
@@ -1510,12 +1613,12 @@ CIgBlastArgs::ExtractAlgorithmOptions(const CArgs& args,
 {
     string paths[3];
     CNcbiEnvironment env;
-    CMetaRegistry::SEntry sentry = 
-            CMetaRegistry::Load("ncbi", CMetaRegistry::eName_RcOrIni);
     paths[0] = CDirEntry::NormalizePath(CDir::GetCwd(), eFollowLinks);
     paths[1] = CDirEntry::NormalizePath(env.Get("IGDATA"), eFollowLinks);
-    if (sentry.registry) {
-       paths[2] = CDirEntry::NormalizePath(sentry.registry->Get("BLAST","IGDATA"), eFollowLinks);
+    CNcbiApplication* app = CNcbiApplication::Instance();
+    if (app) {
+        const CNcbiRegistry& registry = app->GetConfig();
+        paths[2] = CDirEntry::NormalizePath(registry.Get("BLAST","IGDATA"), eFollowLinks);
     } else {
 #if defined(NCBI_OS_DARWIN)
        paths[2] = "/usr/local/ncbi/igblast/data";
@@ -1536,6 +1639,7 @@ CIgBlastArgs::ExtractAlgorithmOptions(const CArgs& args,
     m_IgOptions->m_FocusV = args.Exist(kArgGLFocusV) ? args[kArgGLFocusV] : false;
     m_IgOptions->m_ExtendAlign = args.Exist(kArgExtendAlign) ? args[kArgExtendAlign] : false;
     m_IgOptions->m_MinVLength = args[kArgMinVLength].AsInteger();
+    m_IgOptions->m_MinJLength = args[kArgMinJLength].AsInteger();
    
     m_IgOptions->m_Translate = args.Exist(kArgTranslate) ? args[kArgTranslate] : false;
     if (!m_IsProtein) {
@@ -1671,11 +1775,11 @@ CQueryOptionsArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
                             "(Format: start-stop)",
                             CArgDescriptions::eString);
 
-    if ( !m_QueryCannotBeNucl ) {
+    if ( !m_QueryCannotBeNucl) {
         // search strands
         arg_desc.AddDefaultKey(kArgStrand, "strand", 
-                         "Query strand(s) to search against database/subject",
-                         CArgDescriptions::eString, kDfltArgStrand);
+                     "Query strand(s) to search against database/subject",
+                               CArgDescriptions::eString, kDfltArgStrand);
         arg_desc.SetConstraint(kArgStrand, &(*new CArgAllow_Strings, 
                                              kDfltArgStrand, "plus", "minus"));
     }
@@ -1695,37 +1799,164 @@ CQueryOptionsArgs::ExtractAlgorithmOptions(const CArgs& args,
     {
         m_Strand = eNa_strand_unknown;
 
-        if (!Blast_QueryIsProtein(opt.GetProgramType()) && args[kArgStrand]) {
-            const string& kStrand = args[kArgStrand].AsString();
-            if (kStrand == "both") {
+        if (!Blast_QueryIsProtein(opt.GetProgramType())) {
+
+            if (args.Exist(kArgStrand) && args[kArgStrand]) {
+                const string& kStrand = args[kArgStrand].AsString();
+                if (kStrand == "both") {
+                    m_Strand = eNa_strand_both;
+                } else if (kStrand == "plus") {
+                    m_Strand = eNa_strand_plus;
+                } else if (kStrand == "minus") {
+                    m_Strand = eNa_strand_minus;
+                } else {
+                    abort();
+                }
+            }
+            else {
                 m_Strand = eNa_strand_both;
-            } else if (kStrand == "plus") {
-                m_Strand = eNa_strand_plus;
-            } else if (kStrand == "minus") {
-                m_Strand = eNa_strand_minus;
-            } else {
-                abort();
             }
         }
     }
 
     // set the sequence range
-    if (args[kArgQueryLocation]) {
+    if (args.Exist(kArgQueryLocation) && args[kArgQueryLocation]) {
         m_Range = ParseSequenceRange(args[kArgQueryLocation].AsString(), 
                                      "Invalid specification of query location");
     }
 
-    m_UseLCaseMask = static_cast<bool>(args[kArgUseLCaseMasking]);
-    m_ParseDeflines = static_cast<bool>(args[kArgParseDeflines]);
+    m_UseLCaseMask = args.Exist(kArgUseLCaseMasking) &&
+        static_cast<bool>(args[kArgUseLCaseMasking]);
+    m_ParseDeflines = args.Exist(kArgParseDeflines) &&
+        static_cast<bool>(args[kArgParseDeflines]);
+}
+
+void
+CMapperQueryOptionsArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
+{
+
+    arg_desc.SetCurrentGroup("Query filtering options");
+    // lowercase masking
+    arg_desc.AddFlag(kArgUseLCaseMasking, 
+                     "Use lower case filtering in subject sequence(s)?", true);
+    arg_desc.AddDefaultKey(kArgQualityFilter, "TF", "Reject low quality "
+                           "sequences ", CArgDescriptions::eBoolean, "true");
+
+    arg_desc.SetCurrentGroup("Input query options");
+    arg_desc.AddDefaultKey(kArgInputFormat, "format", "Input format for "
+                           "sequences", CArgDescriptions::eString, "fasta");
+    arg_desc.SetConstraint(kArgInputFormat, &(*new CArgAllow_Strings,
+                                              "fasta", "fastc", "fastq",
+                                              "asn1", "asn1b"));
+    arg_desc.AddFlag(kArgPaired, "Input query sequences are paired", true);
+    arg_desc.AddOptionalKey(kArgQueryMate, "infile", "FASTA file with "
+                            "mates for query sequences (if given in "
+                            "another file)", CArgDescriptions::eInputFile);
+    arg_desc.SetDependency(kArgQueryMate, CArgDescriptions::eRequires,
+                           kArgQuery);
+
+    arg_desc.AddOptionalKey(kArgSraAccession, "accession",
+                            "Comma-separated SRA accessions",
+                            CArgDescriptions::eString);
+    arg_desc.SetDependency(kArgSraAccession, CArgDescriptions::eExcludes,
+                           kArgQuery);
+    arg_desc.SetDependency(kArgSraAccession, CArgDescriptions::eExcludes,
+                          kArgInputFormat);
+
+    arg_desc.SetCurrentGroup("Miscellaneous options");
+    arg_desc.AddDefaultKey(kArgParseDeflines, "TF", "Should the query and "
+                           "subject defline(s) be parsed?",
+                           CArgDescriptions::eBoolean, "true");
+
+    arg_desc.SetCurrentGroup("");
+}
+
+void
+CMapperQueryOptionsArgs::ExtractAlgorithmOptions(const CArgs& args,
+                                                 CBlastOptions& opt)
+{
+    CQueryOptionsArgs::ExtractAlgorithmOptions(args, opt);
+
+    if (args.Exist(kArgPaired) && args[kArgPaired]) {
+        opt.SetPaired(true);
+        m_IsPaired = true;
+    }
+
+    if (args.Exist(kArgInputFormat) && args[kArgInputFormat]) {
+        if (args[kArgInputFormat].AsString() == "fasta") {
+            m_InputFormat = eFasta;
+        }
+        else if (args[kArgInputFormat].AsString() == "fastc") {
+            m_InputFormat = eFastc;
+        }
+        else if (args[kArgInputFormat].AsString() == "fastq") {
+            m_InputFormat = eFastq;
+        }
+        else if (args[kArgInputFormat].AsString() == "asn1") {
+            m_InputFormat = eASN1text;
+        }
+        else if (args[kArgInputFormat].AsString() == "asn1b") {
+            m_InputFormat = eASN1bin;
+        }
+        else {
+            NCBI_THROW(CInputException, eInvalidInput,
+                       "Unexpected input format: " +
+                       args[kArgInputFormat].AsString());
+        }
+    }
+
+    if (m_InputFormat == eFastc) {
+        // FASTC format always has pairs in a single file
+        opt.SetPaired(true);
+        m_IsPaired = true;
+    }
+
+    if (args.Exist(kArgQualityFilter) && args[kArgQualityFilter]) {
+        m_QualityFilter = args[kArgQualityFilter].AsBoolean();
+    }
+
+    if (args.Exist(kArgQueryMate) && args[kArgQueryMate]) {
+        // create a decompress stream is the file is compressed
+        // (the primary query file is handeled by CStdCmdLieArgs object)
+        if (NStr::EndsWith(args[kArgQueryMate].AsString(), ".gz",
+                           NStr::eNocase)) {
+            m_DecompressIStream.reset(new CDecompressIStream(
+                                            args[kArgQueryMate].AsInputFile(),
+                                            CDecompressIStream::eGZipFile));
+            m_MateInputStream = m_DecompressIStream.get();
+        }
+        else {
+            m_MateInputStream = &args[kArgQueryMate].AsInputFile();
+        }
+
+        // queries have pairs in the mate stream
+        opt.SetPaired(true);
+        m_IsPaired = true;
+    }
+
+    if (args.Exist(kArgSraAccession) && args[kArgSraAccession]) {
+        NStr::Split((CTempString)args[kArgSraAccession].AsString(), ",",
+                    m_SraAccessions);
+
+        m_InputFormat = eSra;
+        // assume SRA input is paired, that information for each read is in
+        // SRA database, this option will trigger checking for pairs
+        opt.SetPaired(true);
+        m_IsPaired = true;
+    }
 }
 
+
+
 CBlastDatabaseArgs::CBlastDatabaseArgs(bool request_mol_type /* = false */,
                                        bool is_rpsblast /* = false */,
-                                       bool is_igblast  /* = false */)
+                                       bool is_igblast  /* = false */,
+                                       bool is_mapper   /* = false */)
     : m_RequestMoleculeType(request_mol_type), 
       m_IsRpsBlast(is_rpsblast),
       m_IsIgBlast(is_igblast),
       m_IsProtein(true), 
+      m_IsMapper(is_mapper),
       m_SupportsDatabaseMasking(false)
 {}
 
@@ -1767,10 +1998,12 @@ CBlastDatabaseArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
     }
 
     // DB size
-    arg_desc.SetCurrentGroup("Statistical options");
-    arg_desc.AddOptionalKey(kArgDbSize, "num_letters", 
-                            "Effective length of the database ",
-                            CArgDescriptions::eInt8);
+    if (!m_IsMapper) {
+        arg_desc.SetCurrentGroup("Statistical options");
+        arg_desc.AddOptionalKey(kArgDbSize, "num_letters", 
+                                "Effective length of the database ",
+                                CArgDescriptions::eInt8);
+    }
 
     arg_desc.SetCurrentGroup("Restrict search or results");
     // GI list
@@ -1805,13 +2038,15 @@ CBlastDatabaseArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
     }
 
     // Entrez Query
-    arg_desc.AddOptionalKey(kArgEntrezQuery, "entrez_query", 
-                            "Restrict search with the given Entrez query",
-                            CArgDescriptions::eString);
+    if (!m_IsMapper) {
+        arg_desc.AddOptionalKey(kArgEntrezQuery, "entrez_query", 
+                                "Restrict search with the given Entrez query",
+                                CArgDescriptions::eString);
 
-    // Entrez query currently requires the -remote option
-    arg_desc.SetDependency(kArgEntrezQuery, CArgDescriptions::eRequires, 
-                           kArgRemote);
+        // Entrez query currently requires the -remote option
+        arg_desc.SetDependency(kArgEntrezQuery, CArgDescriptions::eRequires, 
+                               kArgRemote);
+    }
 
 
 #if ((!defined(NCBI_COMPILER_WORKSHOP) || (NCBI_COMPILER_VERSION  > 550)) && \
@@ -1906,7 +2141,19 @@ CBlastDatabaseArgs::ExtractAlgorithmOptions(const CArgs& args,
 #endif
     } else if (args.Exist(kArgSubject) && args[kArgSubject]) {
 
-        CNcbiIstream& subj_input_stream = args[kArgSubject].AsInputFile();
+        CNcbiIstream* subj_input_stream = NULL;
+        auto_ptr<CDecompressIStream> decompress_stream;
+        if (m_IsMapper &&
+            NStr::EndsWith(args[kArgSubject].AsString(), ".gz", NStr::eNocase)) {
+            decompress_stream.reset(
+                        new CDecompressIStream(args[kArgSubject].AsInputFile(),
+                        CDecompressIStream::eGZipFile));
+            subj_input_stream = decompress_stream.get();
+        }
+        else {
+            subj_input_stream = &args[kArgSubject].AsInputFile();
+        }
+
         TSeqRange subj_range;
         if (args.Exist(kArgSubjectLocation) && args[kArgSubjectLocation]) {
             subj_range = 
@@ -1915,15 +2162,15 @@ CBlastDatabaseArgs::ExtractAlgorithmOptions(const CArgs& args,
         }
 
         const bool parse_deflines = args.Exist(kArgParseDeflines) 
-	    ? bool(args[kArgParseDeflines])
+            ? args[kArgParseDeflines].AsBoolean()
             : kDfltArgParseDeflines;
         const bool use_lcase_masks = args.Exist(kArgUseLCaseMasking)
 	    ? bool(args[kArgUseLCaseMasking])
             : kDfltArgUseLCaseMasking;
         CRef<blast::CBlastQueryVector> subjects;
-        m_Scope = ReadSequencesToBlast(subj_input_stream, IsProtein(),
+        m_Scope = ReadSequencesToBlast(*subj_input_stream, IsProtein(),
                                        subj_range, parse_deflines,
-                                       use_lcase_masks, subjects);
+                                       use_lcase_masks, subjects, m_IsMapper);
         m_Subjects.Reset(new blast::CObjMgr_QueryFactory(*subjects));
 
     } else if (!m_IsIgBlast){
@@ -1937,7 +2184,7 @@ CBlastDatabaseArgs::ExtractAlgorithmOptions(const CArgs& args,
         return;
     }
 
-    if (args[kArgDbSize]) {
+    if (args.Exist(kArgDbSize) && args[kArgDbSize]) {
         opts.SetDbLength(args[kArgDbSize].AsInt8());
     }
 
@@ -1967,10 +2214,13 @@ CFormattingArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
     " 14 = Multiple-file BLAST XML2,\n"
     " 15 = Single-file BLAST JSON,\n"
     " 16 = Single-file BLAST XML2");
-
+    
     if(m_FormatFlags & eIsSAM) {
-    	kOutputFormatDescription +=
-    			",\n 17 = Sequence Alignment/Map (SAM)\n\n"
+    	kOutputFormatDescription += ",\n 17 = Sequence Alignment/Map (SAM)";                
+    }    
+    kOutputFormatDescription += ",\n 18 = Organism Report\n\n";
+    if(m_FormatFlags & eIsSAM) {
+    	kOutputFormatDescription +=    			
                 "Options 6, 7, 10 and 17 "
     			"can be additionally configured to produce\n"
     		    "a custom format specified by space delimited format specifiers.\n"
@@ -1978,11 +2228,12 @@ CFormattingArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
     }
     else {
     	kOutputFormatDescription +=
-    			"\n\nOptions 6, 7 and 10 "
+    			"Options 6, 7 and 10 "
     			"can be additionally configured to produce\n"
     		    "a custom format specified by space delimited format specifiers.\n"
     		    "The supported format specifiers are:\n";
     }
+
     kOutputFormatDescription += DescribeTabularOutputFormatSpecifiers() +  string("\n");
 
     if(m_FormatFlags & eIsSAM) {
@@ -1991,6 +2242,7 @@ CFormattingArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
         		DescribeSAMOutputFormatSpecifiers();
     }
 
+
     int dft_outfmt = kDfltArgOutputFormat;
 
     // Igblast shows extra column of gaps
@@ -2047,6 +2299,7 @@ CFormattingArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
     if(!m_IsIgBlast){
         arg_desc.AddFlag(kArgProduceHtml, "Produce HTML output?", true);
     }
+
     /// Hit list size, listed here for convenience only
     arg_desc.SetCurrentGroup("Restrict search or results");
     arg_desc.AddOptionalKey(kArgMaxTargetSequences, "num_sequences",
@@ -2139,7 +2392,8 @@ CFormattingArgs::ExtractAlgorithmOptions(const CArgs& args,
     // we need to increase the  num_ descriptions and num_alignemtns
     if(hitlist_size > BLAST_HITLIST_SIZE )
     {
-    	if(!args[kArgNumDescriptions] && !args[kArgNumAlignments] &&
+    	if((!args.Exist(kArgNumDescriptions) || !args[kArgNumDescriptions]) &&
+           (!args.Exist(kArgNumAlignments) || !args[kArgNumAlignments]) &&
     	   (m_OutputFormat <= eFlatQueryAnchoredNoIdentities)) {
     		m_NumDescriptions = hitlist_size;
     		m_NumAlignments = hitlist_size/ 2;
@@ -2148,7 +2402,7 @@ CFormattingArgs::ExtractAlgorithmOptions(const CArgs& args,
     }
 
     if(m_OutputFormat <= eFlatQueryAnchoredNoIdentities) {
-    	 if (args[kArgMaxTargetSequences]) {
+        if (args.Exist(kArgMaxTargetSequences) && args[kArgMaxTargetSequences]) {
     		 ERR_POST(Warning << "The parameter -max_target_seqs is ignored for "
     				    "output formats, 0,1,2,3. Use -num_descriptions "
     				    "and -num_alignments to control output");
@@ -2157,18 +2411,20 @@ CFormattingArgs::ExtractAlgorithmOptions(const CArgs& args,
     	 m_NumDescriptions = m_DfltNumDescriptions;
     	 m_NumAlignments = m_DfltNumAlignments;
 
-    	 if (args[kArgNumDescriptions]) {
+    	 if (args.Exist(kArgNumDescriptions) && args[kArgNumDescriptions]) {
     	    m_NumDescriptions = args[kArgNumDescriptions].AsInteger();
     	 }
 
-    	if (args[kArgNumAlignments]) {
+         if (args.Exist(kArgNumAlignments) && args[kArgNumAlignments]) {
     		m_NumAlignments = args[kArgNumAlignments].AsInteger();
     	}
 
     	// The If clause is for handling import_search_strategy hitlist size < 500
     	// We want to preserve the hitlist size in iss if no formatting input is entered in cmdline
     	// If formmating option(s) is entered than the iss hitlist size is overridden.
-    	if (args[kArgNumDescriptions] || args[kArgNumAlignments]) {
+         // FIXME: does this work with import search strategies?
+         if ((args.Exist(kArgNumDescriptions) && args[kArgNumDescriptions]) ||
+             (args.Exist(kArgNumAlignments) && args[kArgNumAlignments])) {
     		hitlist_size = max(m_NumDescriptions, m_NumAlignments);
     	}
 
@@ -2178,7 +2434,7 @@ CFormattingArgs::ExtractAlgorithmOptions(const CArgs& args,
     }
     else
     {
-    	if (args[kArgNumDescriptions]) {
+    	if (args.Exist(kArgNumDescriptions) && args[kArgNumDescriptions]) {
    		 ERR_POST(Warning << "The parameter -num_descriptions is ignored for "
    				    		 "output formats > 4 . Use -max_target_seqs "
    				             "to control output");
@@ -2189,10 +2445,10 @@ CFormattingArgs::ExtractAlgorithmOptions(const CArgs& args,
    				    		 "output formats > 4 .");
     	}
 
-    	if (args[kArgMaxTargetSequences]) {
+    	if (args.Exist(kArgMaxTargetSequences) && args[kArgMaxTargetSequences]) {
     		hitlist_size = args[kArgMaxTargetSequences].AsInteger();
     	}
-    	else if (args[kArgNumAlignments]) {
+    	else if (args.Exist(kArgNumAlignments) && args[kArgNumAlignments]) {
     		hitlist_size = args[kArgNumAlignments].AsInteger();
     	}
 
@@ -2485,6 +2741,10 @@ CStdCmdLineArgs::SetArgumentDescriptions(CArgDescriptions& arg_desc)
                    "Output file name",
                    CArgDescriptions::eOutputFile, "-");
 
+    if (m_GzipEnabled) {
+        arg_desc.AddFlag(kArgOutputGzip, "Output will be compressed");
+    }
+
     arg_desc.SetCurrentGroup("");
 }
 
@@ -2494,9 +2754,28 @@ CStdCmdLineArgs::ExtractAlgorithmOptions(const CArgs& args,
 {
     if (args.Exist(kArgQuery) && args[kArgQuery].HasValue() &&
         m_InputStream == NULL) {
-        m_InputStream = &args[kArgQuery].AsInputFile();
+
+        if (m_GzipEnabled &&
+            NStr::EndsWith(args[kArgQuery].AsString(), ".gz", NStr::eNocase)) {
+            m_DecompressIStream.reset(new CDecompressIStream(
+                                               args[kArgQuery].AsInputFile(),
+                                               CDecompressIStream::eGZipFile));
+            m_InputStream = m_DecompressIStream.get();
+        }
+        else {
+            m_InputStream = &args[kArgQuery].AsInputFile();
+        }
+    }
+
+    if (args.Exist(kArgOutputGzip) && args[kArgOutputGzip]) {
+        m_CompressOStream.reset(new CCompressOStream(
+                                              args[kArgOutput].AsOutputFile(),
+                                              CCompressOStream::eGZipFile));
+        m_OutputStream = m_CompressOStream.get();
+    }
+    else {
+        m_OutputStream = &args[kArgOutput].AsOutputFile();
     }
-    m_OutputStream = &args[kArgOutput].AsOutputFile();
 }
 
 CNcbiIstream&
@@ -2556,7 +2835,8 @@ CNcbiIstream*
 CSearchStrategyArgs::GetImportStream(const CArgs& args) const
 {
     CNcbiIstream* retval = NULL;
-    if (args[kArgInputSearchStrategy].HasValue()) {
+    if (args.Exist(kArgInputSearchStrategy) &&
+        args[kArgInputSearchStrategy].HasValue()) {
         retval = &args[kArgInputSearchStrategy].AsInputFile();
     }
     return retval;
@@ -2566,7 +2846,8 @@ CNcbiOstream*
 CSearchStrategyArgs::GetExportStream(const CArgs& args) const
 {
     CNcbiOstream* retval = NULL;
-    if (args[kArgOutputSearchStrategy].HasValue()) {
+    if (args.Exist(kArgOutputSearchStrategy) &&
+        args[kArgOutputSearchStrategy].HasValue()) {
         retval = &args[kArgOutputSearchStrategy].AsOutputFile();
     }
     return retval;
diff --git a/c++/src/algo/blast/blastinput/blast_asn1_input.cpp b/c++/src/algo/blast/blastinput/blast_asn1_input.cpp
new file mode 100644
index 0000000..db1dfce
--- /dev/null
+++ b/c++/src/algo/blast/blastinput/blast_asn1_input.cpp
@@ -0,0 +1,365 @@
+/*  $Id: blast_asn1_input.cpp 517499 2016-10-25 17:20:41Z ivanov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  Greg Boratyn
+ *
+ */
+
+/** @file blast_asn1_input.cpp
+ * Convert ASN1-formatted files into blast sequence input
+ */
+
+#include <ncbi_pch.hpp>
+#include <objmgr/util/sequence.hpp>
+
+#include <objects/seq/Bioseq.hpp>
+#include <objects/seq/Seq_descr.hpp>
+#include <objects/general/User_object.hpp>
+
+#include <algo/blast/blastinput/blast_input_aux.hpp>
+#include <algo/blast/blastinput/blast_asn1_input.hpp>
+#include <util/sequtil/sequtil_convert.hpp>
+
+BEGIN_NCBI_SCOPE
+BEGIN_SCOPE(blast)
+USING_SCOPE(objects);
+
+
+CASN1InputSourceOMF::CASN1InputSourceOMF(CNcbiIstream& infile,
+                                         TSeqPos num_seqs,
+                                         bool is_bin,
+                                         bool is_paired,
+                                         bool validate)
+    : m_NumSeqsInBatch(num_seqs),
+      m_InputStream(&infile),
+      m_SecondInputStream(NULL),
+      m_IsPaired(is_paired),
+      m_Validate(validate),
+      m_IsBinary(is_bin)
+{}
+
+CASN1InputSourceOMF::CASN1InputSourceOMF(CNcbiIstream& infile1,
+                                         CNcbiIstream& infile2,
+                                         TSeqPos num_seqs,
+                                         bool is_bin,
+                                         bool validate)
+    : m_NumSeqsInBatch(num_seqs),
+      m_InputStream(&infile1),
+      m_SecondInputStream(&infile2),
+      m_IsPaired(true),
+      m_Validate(validate),
+      m_IsBinary(is_bin)
+{}
+
+
+void
+CASN1InputSourceOMF::GetNextNumSequences(CBioseq_set& bioseq_set,
+                                         TSeqPos /* num_seqs */)
+{
+    // preallocate memory for sequences to be read
+    m_Entries.clear();
+
+    // +1 in case we need to read one more sequence so that a pair is not
+    // broken
+    m_Entries.resize(m_NumSeqsInBatch + 1);
+
+    if (m_SecondInputStream) {
+        x_ReadFromTwoFiles(bioseq_set);
+    }
+    else {
+        x_ReadFromSingleFile(bioseq_set);
+    }
+
+    // detach CRefs in m_Entries from objects in bioseq_set for thread safety
+    m_Entries.clear();
+}
+
+
+int
+CASN1InputSourceOMF::x_ReadOneSeq(CNcbiIstream& instream)
+{
+    CTempString line;
+    CTempString id;
+    int retval = -1;
+
+    CRef<CSeq_entry> seq_entry(new CSeq_entry);
+    try {
+        if (m_IsBinary) {
+            instream >> MSerial_AsnBinary >> *seq_entry;
+        }
+        else {
+            instream >> MSerial_AsnText >> *seq_entry;
+        }
+    }
+    catch (...) {
+        if (instream.eof()) {
+            return -1;
+        }
+
+        NCBI_THROW(CInputException, eInvalidInput, "Problem reading ASN1 entry");
+    }
+
+    if (!m_Validate ||
+        x_ValidateSequence(seq_entry->GetSeq().GetInst().GetSeq_data(),
+                           seq_entry->GetSeq().GetInst().GetLength())) {
+
+        m_Entries[m_Index] = seq_entry;
+        retval = m_Index;
+        m_Index++;
+    }
+
+    return retval;
+}
+
+
+bool
+CASN1InputSourceOMF::x_ReadFromSingleFile(CBioseq_set& bioseq_set)
+{
+    int current_read = 0;
+    bool first_added = false;
+
+    // tags to indicate paired sequences
+    CRef<CSeqdesc> seqdesc_first(new CSeqdesc);
+    seqdesc_first->SetUser().SetType().SetStr("Mapping");
+    seqdesc_first->SetUser().AddField("has_pair", eFirstSegment);
+
+    CRef<CSeqdesc> seqdesc_last(new CSeqdesc);
+    seqdesc_last->SetUser().SetType().SetStr("Mapping");
+    seqdesc_last->SetUser().AddField("has_pair", eLastSegment);
+
+    CRef<CSeqdesc> seqdesc_first_partial(new CSeqdesc);
+    seqdesc_first_partial->SetUser().SetType().SetStr("Mapping");
+    seqdesc_first_partial->SetUser().AddField("has_pair",
+                                              fFirstSegmentFlag | fPartialFlag);
+
+    CRef<CSeqdesc> seqdesc_last_partial(new CSeqdesc);
+    seqdesc_last_partial->SetUser().SetType().SetStr("Mapping");
+    seqdesc_last_partial->SetUser().AddField("has_pair",
+                                             fLastSegmentFlag | fPartialFlag);
+
+    m_Index = 0;
+    while (m_Index < (int)m_NumSeqsInBatch && !m_InputStream->eof()) {
+        int index = x_ReadOneSeq(*m_InputStream);
+
+        if (index >= 0) {
+
+            if (m_IsPaired && (current_read & 1) == 0) {
+                first_added = true;
+            }
+
+            if (m_IsPaired && (current_read & 1) == 1) {
+                if (first_added) {
+                    bioseq_set.SetSeq_set().back()->SetSeq().SetDescr().Set().
+                        push_back(seqdesc_first);
+                    m_Entries[index]->SetSeq().SetDescr().Set().push_back(seqdesc_last);
+                }
+                else {
+                    m_Entries[index]->SetSeq().SetDescr().Set().push_back(
+                                                        seqdesc_last_partial);
+                }
+                first_added = false;
+            }
+
+            bioseq_set.SetSeq_set().push_back(m_Entries[index]);
+        }
+        else {
+            if (first_added) {
+                bioseq_set.SetSeq_set().back()->SetSeq().SetDescr().Set().
+                    push_back(seqdesc_first_partial);
+            }
+            first_added = false;
+        }
+        current_read++;
+    }
+
+    return true;
+}
+
+
+bool
+CASN1InputSourceOMF::x_ReadFromTwoFiles(CBioseq_set& bioseq_set)
+{
+    // tags to indicate paired sequences
+    CRef<CSeqdesc> seqdesc_first(new CSeqdesc);
+    seqdesc_first->SetUser().SetType().SetStr("Mapping");
+    seqdesc_first->SetUser().AddField("has_pair", eFirstSegment);
+
+    CRef<CSeqdesc> seqdesc_last(new CSeqdesc);
+    seqdesc_last->SetUser().SetType().SetStr("Mapping");
+    seqdesc_last->SetUser().AddField("has_pair", eLastSegment);
+
+    CRef<CSeqdesc> seqdesc_first_partial(new CSeqdesc);
+    seqdesc_first_partial->SetUser().SetType().SetStr("Mapping");
+    seqdesc_first_partial->SetUser().AddField("has_pair",
+                                              fFirstSegmentFlag | fPartialFlag);
+
+    CRef<CSeqdesc> seqdesc_last_partial(new CSeqdesc);
+    seqdesc_last_partial->SetUser().SetType().SetStr("Mapping");
+    seqdesc_last_partial->SetUser().AddField("has_pair",
+                                             fLastSegmentFlag | fPartialFlag);
+
+    int index1;
+    int index2;
+    m_Index = 0;
+    while (m_Index < (int)m_NumSeqsInBatch && !m_InputStream->eof() &&
+           !m_SecondInputStream->eof()) {
+
+        index1 = x_ReadOneSeq(*m_InputStream); 
+        index2 = x_ReadOneSeq(*m_SecondInputStream);
+
+        // if both sequences were read, the pair in the first one
+        if (index1 >= 0 && index2 >= 0) {
+            m_Entries[index1]->SetSeq().SetDescr().Set().push_back(
+                                                             seqdesc_first);
+
+            m_Entries[index2]->SetSeq().SetDescr().Set().push_back(
+                                                              seqdesc_last);
+
+            bioseq_set.SetSeq_set().push_back(m_Entries[index1]);
+            bioseq_set.SetSeq_set().push_back(m_Entries[index2]);
+        }
+        else {
+            // otherwise mark incomplete pair for the sequence that was read
+            if (index1 >= 0) {
+                m_Entries[index1]->SetSeq().SetDescr().Set().push_back(
+                                                       seqdesc_first_partial);
+                bioseq_set.SetSeq_set().push_back(m_Entries[index1]);
+            }
+
+            if (index2 >= 0) {
+                m_Entries[index2]->SetSeq().SetDescr().Set().push_back(
+                                                        seqdesc_last_partial);
+                bioseq_set.SetSeq_set().push_back(m_Entries[index2]);
+            }
+        }
+    }
+
+    return true;
+}
+
+
+bool CASN1InputSourceOMF::x_ValidateSequence(const CSeq_data& seq_data,
+                                             int length)
+{
+    string sequence;
+    int entropy;
+
+    switch (seq_data.Which()) {
+
+    case CSeq_data::e_Ncbi2na:
+        // Ncbi2na format does not have ambiguous bases, hence only compute
+        // entropy and exit
+        entropy = x_FindDimerEntropy2NA(seq_data.GetNcbi2na().Get(), length);
+        return entropy > 16;
+
+
+    case CSeq_data::e_Ncbi4na:
+        // convert sequence to Iupac
+        CSeqConvert::Convert(seq_data.GetNcbi4na().Get(),
+                             CSeqUtil::e_Ncbi4na, 0, length,
+                             sequence, CSeqUtil::e_Iupacna);
+        break;
+            
+    case CSeq_data::e_Ncbi8na:
+        // convert sequence to Iupac
+        CSeqConvert::Convert(seq_data.GetNcbi8na().Get(),
+                             CSeqUtil::e_Ncbi8na, 0, length,
+                             sequence, CSeqUtil::e_Iupacna);
+        break;
+
+    case CSeq_data::e_Iupacna:
+        sequence.resize(length);
+        memcpy(&sequence[0], seq_data.GetIupacna().Get().c_str(),
+               length * sizeof(Uint1));
+        break;
+
+    default:
+        NCBI_THROW(CInputException, eInvalidInput, "Encoding not handled "
+                   "for input sequences");
+
+    };
+
+    // find number of ambiguous bases
+    const char* s = sequence.c_str();
+    const int kNBase = (int)'N';
+    const double kMaxFractionAmbiguousBases = 0.5;
+    int num = 0;
+    for (int i=0;i < length;i++) {
+        num += (toupper((int)s[i]) == kNBase);
+    }
+
+    if ((double)num / length > kMaxFractionAmbiguousBases) {
+        return false;
+    }
+
+    // find dimer entropy
+    entropy = FindDimerEntropy(sequence.c_str(), length);
+    return entropy > 16;
+}
+
+
+int CASN1InputSourceOMF::x_FindDimerEntropy2NA(const vector<char>& sequence,
+                                               int length)
+{
+    const int kNumDimers = 1 << 4;
+    int counts[kNumDimers];
+    memset(counts, 0, kNumDimers * sizeof(int));
+    int num = 0;
+    Uint1 mask = 0xc0;
+    Uint1 base;
+    int dimer;
+    int k = 0;
+    int i = 0;
+
+    // count dimers
+    dimer = (sequence[i] & (mask >> k)) >> (2*(3 - k));
+    k++;
+    num++;
+    while (num < length) {
+        _ASSERT(i < (int)sequence.size());
+        for (;k < 4;k++) {
+            base = (sequence[i] & (mask >> k)) >> (2*(3 - k));
+            dimer = ((dimer << 2) | base) & 0xf;
+            counts[dimer]++;
+            num++;
+        }
+        k = 0;
+        i++;
+    }
+
+    // compute amount of information in the sequence
+    double sum = 0.0;
+    for (int i=0;i < kNumDimers;i++) {
+        if (counts[i]) {
+            sum += (double)counts[i] * log((double)counts[i] / num);
+        }
+    }
+
+    return -sum * (1.0 /(log(16.0))) + 0.5;
+}
+
+
+END_SCOPE(blast)
+END_NCBI_SCOPE
diff --git a/c++/src/algo/blast/blastinput/blast_fasta_input.cpp b/c++/src/algo/blast/blastinput/blast_fasta_input.cpp
index 1fba5b7..90d49e7 100644
--- a/c++/src/algo/blast/blastinput/blast_fasta_input.cpp
+++ b/c++/src/algo/blast/blastinput/blast_fasta_input.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_fasta_input.cpp 489949 2016-01-20 12:32:48Z madden $
+/*  $Id: blast_fasta_input.cpp 517821 2016-10-27 19:13:57Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Convert FASTA-formatted files into blast sequence input
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_fasta_input.cpp 489949 2016-01-20 12:32:48Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <serial/iterator.hpp>
 #include <objmgr/util/sequence.hpp>
@@ -47,6 +42,7 @@ static char const rcsid[] =
 #include <objects/general/Dbtag.hpp>
 #include <objects/general/Object_id.hpp>
 
+#include <algo/blast/core/blast_query_info.h>
 #include <algo/blast/blastinput/blast_fasta_input.hpp>
 #include <algo/blast/blastinput/blast_input_aux.hpp>
 
@@ -236,10 +232,40 @@ private:
 
 };
 
+/// Stream line reader that converts gaps to Ns before returning each line
+class CStreamLineReaderConverter : public CStreamLineReader
+{
+public:
+
+    CStreamLineReaderConverter(CNcbiIstream& instream)
+        : CStreamLineReader(instream) {}
+
+    CStreamLineReaderConverter& operator++(void){
+        CStreamLineReader::operator++();
+        CTempString line = CStreamLineReader::operator*();
+        if (NStr::StartsWith(line, ">")) {
+            m_ConvLine = line;
+        }
+        else {
+            m_ConvLine = NStr::Replace(line, "-", "N");
+        }
+        return *this;
+    }
+
+    CTempString operator*(void) const {
+        return CTempString(m_ConvLine);
+    }
+
+private:
+    string m_ConvLine;
+};
+
 CBlastFastaInputSource::CBlastFastaInputSource(CNcbiIstream& infile,
                                        const CBlastInputSourceConfig& iconfig)
     : m_Config(iconfig),
-      m_LineReader(new CStreamLineReader(infile)),
+      m_LineReader(iconfig.GetConvertGapsToNs() ?
+                   new CStreamLineReaderConverter(infile) :
+                   new CStreamLineReader(infile)),
       m_ReadProteins(iconfig.IsProteinInput())
 {
     x_InitInputReader();
@@ -298,6 +324,7 @@ CBlastFastaInputSource::x_InitInputReader()
 
     m_InputReader->IgnoreProblem(ILineError::eProblem_ModifierFoundButNoneExpected);
     m_InputReader->IgnoreProblem(ILineError::eProblem_TooLong);
+    m_InputReader->IgnoreProblem(ILineError::eProblem_TooManyAmbiguousResidues);
     //m_InputReader->IgnoreProblem(ILineError::eProblem_InvalidResidue);
     //m_InputReader->IgnoreProblem(ILineError::eProblem_IgnoredResidue);
 
@@ -442,5 +469,698 @@ CBlastFastaInputSource::GetNextSequence(CScope& scope)
         (new CBlastSearchQuery(*seqloc, scope, masks_in_query));
 }
 
+
+CShortReadFastaInputSource::CShortReadFastaInputSource(CNcbiIstream& infile,
+                               TSeqPos num_seqs,
+                               CShortReadFastaInputSource::EInputFormat format,
+                               bool paired,
+                               bool validate)
+    : m_NumSeqsInBatch(num_seqs),
+      m_SeqBuffLen(550),
+      m_LineReader(new CStreamLineReader(infile)),
+      m_IsPaired(paired),
+      m_Validate(validate),
+      m_NumRejected(0),
+      m_Format(format)
+{
+    // allocate sequence buffer
+    m_Sequence.reserve(m_SeqBuffLen + 1);
+
+    // read the first line for FASTA input
+    if (m_Format == eFasta) {
+        do {
+            ++(*m_LineReader);
+            m_Line = **m_LineReader;
+        } while (m_Line.empty() && !m_LineReader->AtEOF());
+
+        if (m_Line[0] != '>') {
+            NCBI_THROW(CInputException, eInvalidInput, "FASTA parse error: "
+                       "defline expected");
+        }
+    }
+}
+
+CShortReadFastaInputSource::CShortReadFastaInputSource(CNcbiIstream& infile1,
+                               CNcbiIstream& infile2,
+                               TSeqPos num_seqs,
+                               CShortReadFastaInputSource::EInputFormat format,
+                               bool validate)
+    : m_NumSeqsInBatch(num_seqs),
+      m_SeqBuffLen(550),
+      m_LineReader(new CStreamLineReader(infile1)),
+      m_SecondLineReader(new CStreamLineReader(infile2)),
+      m_IsPaired(true),
+      m_Validate(validate),
+      m_NumRejected(0),
+      m_Format(format)
+{
+    if (m_Format == eFastc) {
+        m_LineReader.Reset();
+        m_SecondLineReader.Reset();
+
+        NCBI_THROW(CInputException, eInvalidInput, "FASTC format cannot be "
+                   "used with two input files");
+    }
+
+    // allocate sequence buffer
+    m_Sequence.reserve(m_SeqBuffLen + 1);
+
+    // read the first line for FASTA input
+    if (m_Format == eFasta) {
+        CTempString line;
+        do {
+            ++(*m_LineReader);
+            line = **m_LineReader;
+        } while (line.empty() && !m_LineReader->AtEOF());
+
+        if (line[0] != '>') {
+            NCBI_THROW(CInputException, eInvalidInput, "FASTA parse error: "
+                       "defline expected");
+        }
+    
+        do {
+            ++(*m_SecondLineReader);
+            line = **m_SecondLineReader;
+        } while (line.empty() && !m_SecondLineReader->AtEOF());
+
+        if (line[0] != '>') {
+            NCBI_THROW(CInputException, eInvalidInput, "FASTA parse error: "
+                       "defline expected");
+        }
+    }
+}
+
+void
+CShortReadFastaInputSource::GetNextNumSequences(CBioseq_set& bioseq_set,
+                                                TSeqPos /* num_seqs */)
+{
+    // preallocate and initialize objects for sequences to be read
+    m_SeqIds.clear();
+    m_Entries.clear();
+
+    // +1 in case we need to read one more sequence so that a pair is not
+    // broken
+    m_SeqIds.resize(m_NumSeqsInBatch + 1);
+    m_Entries.resize(m_NumSeqsInBatch + 1);
+
+    // allocate seq_id and seq_entry objects, they will be reused to minimize
+    // time spent on memory management
+    for (TSeqPos i=0;i < m_NumSeqsInBatch + 1;i++) {
+        m_SeqIds[i].Reset(new CSeq_id);
+        m_Entries[i].Reset(new CSeq_entry);
+        m_Entries[i]->SetSeq().SetInst().SetMol(CSeq_inst::eMol_na);
+        m_Entries[i]->SetSeq().SetInst().SetRepr(CSeq_inst::eRepr_raw);
+    }
+
+    // read sequernces
+    switch (m_Format) {
+    case eFasta:
+        if (m_SecondLineReader.NotEmpty()) {
+            x_ReadFromTwoFiles(bioseq_set, m_Format);
+        }
+        else {
+            x_ReadFasta(bioseq_set);
+        }
+        break;
+
+    case eFastq:
+        if (m_SecondLineReader.NotEmpty()) {
+            x_ReadFromTwoFiles(bioseq_set, m_Format);
+        }
+        else {
+            x_ReadFastq(bioseq_set);
+        }
+        break;
+
+    case eFastc:
+        x_ReadFastc(bioseq_set);
+        break;
+
+    default:
+        NCBI_THROW(CInputException, eInvalidInput, "Unexpected input format");
+
+    };
+
+    // detach CRefs from in m_Entries and m_SeqIds from objects in bioseq_set
+    // for thread safety
+    m_Entries.clear();
+    m_SeqIds.clear();
+}
+
+void
+CShortReadFastaInputSource::x_ReadFasta(CBioseq_set& bioseq_set)
+{
+    TSeqPos index = 0;
+    int start = 0;
+    // parse the last read defline
+    CTempString id = x_ParseDefline(m_Line);
+    m_SeqIds[0]->Set(CSeq_id::e_Local, id);
+    int current_read = 0;
+    bool first_added = false;
+
+    // tags to indicate paired sequences
+    CRef<CSeqdesc> seqdesc_first(new CSeqdesc);
+    seqdesc_first->SetUser().SetType().SetStr("Mapping");
+    seqdesc_first->SetUser().AddField("has_pair", eFirstSegment);
+
+    CRef<CSeqdesc> seqdesc_last(new CSeqdesc);
+    seqdesc_last->SetUser().SetType().SetStr("Mapping");
+    seqdesc_last->SetUser().AddField("has_pair", eLastSegment);
+
+    CRef<CSeqdesc> seqdesc_first_partial(new CSeqdesc);
+    seqdesc_first_partial->SetUser().SetType().SetStr("Mapping");
+    seqdesc_first_partial->SetUser().AddField("has_pair",
+                                              fFirstSegmentFlag | fPartialFlag);
+
+    CRef<CSeqdesc> seqdesc_last_partial(new CSeqdesc);
+    seqdesc_last_partial->SetUser().SetType().SetStr("Mapping");
+    seqdesc_last_partial->SetUser().AddField("has_pair",
+                                             fLastSegmentFlag | fPartialFlag);
+
+    while (index < m_NumSeqsInBatch && !m_LineReader->AtEOF()) {
+        ++(*m_LineReader);
+        m_Line = **m_LineReader;
+
+        // ignore empty lines
+        if (m_Line.empty()) {
+            continue;
+        }
+
+        // if defline
+        if (m_Line[0] == '>') {
+
+            // set up sequence
+            if (!m_Validate || x_ValidateSequence(m_Sequence.data(), start)) {
+                CBioseq& bioseq = m_Entries[index]->SetSeq();
+                bioseq.SetId().clear();
+                bioseq.SetId().push_back(m_SeqIds[index]);
+                bioseq.SetInst().SetLength(start);
+                m_Sequence[start] = 0;
+                bioseq.SetInst().SetSeq_data().SetIupacna(CIUPACna(
+                                                            &m_Sequence[0]));
+
+                if (m_IsPaired && (current_read & 1) == 0) {
+                    first_added = true;
+                }
+
+                if (m_IsPaired && (current_read & 1) == 1) {
+                    if (first_added) {
+                        // set paired tags: both sequences of the pair passed
+                        // validation
+                        bioseq_set.SetSeq_set().back()->SetSeq().SetDescr().
+                            Set().push_back(seqdesc_first);
+
+                        m_Entries[index]->SetSeq().SetDescr().Set().push_back(
+                                                               seqdesc_last);
+                    }
+                    else {
+                        // only the second sequence of the pair passed
+                        // validation
+                        m_Entries[index]->SetSeq().SetDescr().Set().push_back(
+                                                       seqdesc_last_partial);
+                    }
+                    first_added = false;
+                }
+
+                // add a sequence to the batch
+                bioseq_set.SetSeq_set().push_back(m_Entries[index]);
+
+                index++;
+            }
+            else {
+                if (first_added) {
+                    // only the first sequence of the pair passed validation
+                    bioseq_set.SetSeq_set().back()->SetSeq().SetDescr().
+                        Set().push_back(seqdesc_first_partial);
+                    
+                }
+
+                m_NumRejected++;
+                first_added = false;
+            }
+            current_read++;
+
+            start = 0;
+
+            // set sequence id for the new sequence
+            if (index < m_NumSeqsInBatch) {
+                id = x_ParseDefline(m_Line);
+                m_SeqIds[index]->Set(CSeq_id::e_Local, id);
+            }
+        }
+        else {
+            // otherwise copy the sequence
+            // increase the sequence buffer if necessary
+            if (start + m_Line.length() + 1 > m_SeqBuffLen) {
+                string tmp;
+                m_SeqBuffLen = 2 * (start + m_Line.length() + 1);
+                tmp.reserve(m_SeqBuffLen);
+                memcpy(&tmp[0], &m_Sequence[0], start);
+                m_Sequence.swap(tmp);
+            }
+            memcpy(&m_Sequence[start], m_Line.data(), m_Line.length());
+            start += m_Line.length();
+        }
+    }
+
+    if (!m_LineReader->AtEOF()) {
+        return;
+    }
+
+    if (m_Validate && (!x_ValidateSequence(m_Sequence.data(), start))) {
+        m_NumRejected++;
+        if (m_IsPaired) { 
+            if (first_added && (current_read & 1)  == 1) {
+                bioseq_set.SetSeq_set().back()->SetSeq().SetDescr().Set().
+                    push_back(seqdesc_first_partial);
+            }
+        }
+
+        return;
+    }
+
+    if (m_IsPaired && (current_read & 1) == 1 && first_added) {
+        // add the tag for paired reads
+        bioseq_set.SetSeq_set().back()->SetSeq().SetDescr().Set().
+            push_back(seqdesc_first);
+    }
+
+    // set up the last sequence read
+    CBioseq& bioseq = m_Entries[index]->SetSeq();
+    bioseq.SetId().clear();
+    bioseq.SetId().push_back(m_SeqIds[index]);
+    bioseq.SetInst().SetLength(start);
+    m_Sequence[start] = 0;
+    bioseq.SetInst().SetSeq_data().SetIupacna(CIUPACna(&m_Sequence[0]));
+    bioseq_set.SetSeq_set().push_back(m_Entries[index]);    
+
+    if (m_IsPaired && (current_read & 1) == 1) {
+        bioseq_set.SetSeq_set().back()->SetSeq().SetDescr().Set().
+            push_back(first_added ? seqdesc_last : seqdesc_last_partial);
+    }
+}
+
+
+void
+CShortReadFastaInputSource::x_ReadFastc(CBioseq_set& bioseq_set)
+{
+    TSeqPos index = 0;
+    string id;
+
+    // tags to indicate paired sequences
+    CRef<CSeqdesc> seqdesc_first(new CSeqdesc);
+    seqdesc_first->SetUser().SetType().SetStr("Mapping");
+    seqdesc_first->SetUser().AddField("has_pair", eFirstSegment);
+
+    CRef<CSeqdesc> seqdesc_last(new CSeqdesc);
+    seqdesc_last->SetUser().SetType().SetStr("Mapping");
+    seqdesc_last->SetUser().AddField("has_pair", eLastSegment);
+
+    while (index < m_NumSeqsInBatch && !m_LineReader->AtEOF()) {
+        ++(*m_LineReader);
+        m_Line = **m_LineReader;
+
+        // ignore empty lines
+        if (m_Line.empty()) {
+            continue;
+        }
+
+        // if defline
+        if (m_Line[0] == '>') {
+            id = x_ParseDefline(m_Line);
+        }
+        else {
+            // otherwise sequence
+
+            // make sure that a defline was read first
+            if (id.empty()) {
+                NCBI_THROW(CInputException, eInvalidInput,
+                           (string)"Missing defline before line: " +
+                           NStr::IntToString(m_LineReader->GetLineNumber()));
+            }
+
+            // find '><' that separate reads of a pair
+            size_t p = m_Line.find('>');
+            if (p == CTempString::npos || m_Line[p + 1] != '<') {
+
+                NCBI_THROW(CInputException, eInvalidInput,
+                           (string)"FASTC parse error: Sequence separator '><'"
+                           " was not found in line: " +
+                           NStr::IntToString(m_LineReader->GetLineNumber()));
+            }
+
+            // set up reads, there are two sequences in the same line separated
+            char* first = (char*)m_Line.data();
+            char* second = (char*)m_Line.data() + p + 2;
+            size_t first_len = p;
+            size_t second_len = m_Line.length() - p - 2;
+
+            // FIXME: Both reads are rejected if only one fails validation
+            if (x_ValidateSequence(first, first_len) &&
+                x_ValidateSequence(second, second_len)) {
+
+                {{
+                    CBioseq& bioseq = m_Entries[index]->SetSeq();
+                    bioseq.SetId().clear();
+                    m_SeqIds[index]->Set(CSeq_id::e_Local, id + ".1");
+                    bioseq.SetId().push_back(m_SeqIds[index]);
+                    bioseq.SetInst().SetLength(first_len);
+                    first[first_len] = 0;
+                    bioseq.SetInst().SetSeq_data().SetIupacna(CIUPACna(first));
+
+                    bioseq.SetDescr().Set().push_back(seqdesc_first);
+                }}
+                // add a sequence to the batch
+                bioseq_set.SetSeq_set().push_back(m_Entries[index]);
+                index++;
+
+                {{
+                    CBioseq& bioseq = m_Entries[index]->SetSeq();
+                    bioseq.SetId().clear();
+                    m_SeqIds[index]->Set(CSeq_id::e_Local, id + ".2");
+                    bioseq.SetId().push_back(m_SeqIds[index]);
+                    bioseq.SetInst().SetLength(second_len);
+                    second[second_len] = 0;
+                    bioseq.SetInst().SetSeq_data().SetIupacna(CIUPACna(second));
+
+                    bioseq.SetDescr().Set().push_back(seqdesc_last);
+                }}
+                // add a sequence to the batch
+                bioseq_set.SetSeq_set().push_back(m_Entries[index]);
+                index++;
+            }
+            else {
+                m_NumRejected++;
+            }
+            id.clear();
+        }
+    }
+}
+
+
+void
+CShortReadFastaInputSource::x_ReadFastq(CBioseq_set& bioseq_set)
+{
+    int current_read = 0;
+    bool first_added = false;
+
+    // tags to indicate paired sequences
+    CRef<CSeqdesc> seqdesc_first(new CSeqdesc);
+    seqdesc_first->SetUser().SetType().SetStr("Mapping");
+    seqdesc_first->SetUser().AddField("has_pair", eFirstSegment);
+
+    CRef<CSeqdesc> seqdesc_last(new CSeqdesc);
+    seqdesc_last->SetUser().SetType().SetStr("Mapping");
+    seqdesc_last->SetUser().AddField("has_pair", eLastSegment);
+
+    CRef<CSeqdesc> seqdesc_first_partial(new CSeqdesc);
+    seqdesc_first_partial->SetUser().SetType().SetStr("Mapping");
+    seqdesc_first_partial->SetUser().AddField("has_pair",
+                                              fFirstSegmentFlag | fPartialFlag);
+
+    CRef<CSeqdesc> seqdesc_last_partial(new CSeqdesc);
+    seqdesc_last_partial->SetUser().SetType().SetStr("Mapping");
+    seqdesc_last_partial->SetUser().AddField("has_pair",
+                                             fLastSegmentFlag | fPartialFlag);
+
+    m_Index = 0;
+    while (m_Index < (int)m_NumSeqsInBatch && !m_LineReader->AtEOF()) {
+        int index = x_ReadFastqOneSeq(m_LineReader);
+
+        if (index >= 0) {
+
+            if (m_IsPaired && (current_read & 1) == 0) {
+                first_added = true;
+            }
+
+            if (m_IsPaired && (current_read & 1) == 1) {
+                if (first_added) {
+                    // this field indicates that this sequence has a pair
+                    bioseq_set.SetSeq_set().back()->SetSeq().SetDescr().Set().
+                        push_back(seqdesc_first);
+
+                    m_Entries[index]->SetSeq().SetDescr().Set().push_back(
+                                                                seqdesc_last);
+                }
+                else {
+                    m_Entries[index]->SetSeq().SetDescr().Set().push_back(
+                                                        seqdesc_last_partial);
+                }
+                first_added = false;
+            }
+
+            bioseq_set.SetSeq_set().push_back(m_Entries[index]);
+        }
+        else {
+            if (first_added) {
+                bioseq_set.SetSeq_set().back()->SetSeq().SetDescr().Set().
+                    push_back(seqdesc_first_partial);
+            }
+
+            m_NumRejected++;
+            first_added = false;
+        }
+        current_read++;
+    }
+
+}
+
+
+int
+CShortReadFastaInputSource::x_ReadFastaOneSeq(CRef<ILineReader> line_reader)
+{
+    int start = 0;
+    // parse the last read defline
+    CTempString line = **line_reader;
+    CTempString id = x_ParseDefline(line);
+    m_SeqIds[m_Index]->Set(CSeq_id::e_Local, id);
+    ++(*line_reader);
+    line = **line_reader;
+    while (line[0] != '>') {
+
+        // ignore empty lines
+        if (line.empty() && !line_reader->AtEOF()) {
+            ++(*line_reader);
+            line = **line_reader;
+            continue;
+        }
+
+        // copy the sequence
+        // increase the sequence buffer if necessary
+        if (start + line.length() + 1 > m_SeqBuffLen) {
+            string tmp;
+            m_SeqBuffLen = 2 * (start + line.length() + 1);
+            tmp.reserve(m_SeqBuffLen);
+            memcpy(&tmp[0], &m_Sequence[0], start);
+            m_Sequence.swap(tmp);
+        }
+        memcpy(&m_Sequence[start], line.data(), line.length());
+        start += line.length();
+
+        if (line_reader->AtEOF()) {
+            break;
+        }
+
+        // read next line
+        ++(*line_reader);
+        line = **line_reader;
+    }
+
+    // set up sequence
+    if (!m_Validate || x_ValidateSequence(m_Sequence.data(), start)) {
+
+        CBioseq& bioseq = m_Entries[m_Index]->SetSeq();
+        bioseq.SetId().clear();
+        bioseq.SetId().push_back(m_SeqIds[m_Index]);
+        bioseq.SetInst().SetLength(start);
+        m_Sequence[start] = 0;
+        bioseq.SetInst().SetSeq_data().SetIupacna(CIUPACna(&m_Sequence[0]));
+
+        m_Index++;
+        return m_Index - 1;
+    }
+
+    return -1;
+}
+
+
+int
+CShortReadFastaInputSource::x_ReadFastqOneSeq(CRef<ILineReader> line_reader)
+{
+    CTempString line;
+    CTempString id;
+    int retval = -1;
+
+    // first read defline
+    ++(*line_reader);
+    line = **line_reader;
+
+    // skip empty lines
+    while (!line_reader->AtEOF() && line.empty()) {
+        ++(*line_reader);
+        line = **line_reader;
+    }
+
+    if (line[0] != '@') {
+        NCBI_THROW(CInputException, eInvalidInput, (string)"FASTQ parse error:"
+                   " defline expected at line: " +
+                   NStr::IntToString(line_reader->GetLineNumber()));
+    }
+
+    id = x_ParseDefline(line);
+    m_SeqIds[m_Index]->Set(CSeq_id::e_Local, id);
+
+    // read sequence
+    ++(*line_reader);
+    line = **line_reader;
+    // skip empty lines
+    while (!line_reader->AtEOF() && line.empty()) {
+        ++(*line_reader);
+        line = **line_reader;
+    }
+
+    // set up sequence
+    if (!m_Validate || x_ValidateSequence(line.data(), line.length())) {
+
+        CBioseq& bioseq = m_Entries[m_Index]->SetSeq();
+        bioseq.SetId().clear();
+        bioseq.SetId().push_back(m_SeqIds[m_Index]);
+        bioseq.SetInst().SetLength(line.length());
+        bioseq.SetInst().SetSeq_data().SetIupacna(CIUPACna(line.data()));
+
+        m_Index++;
+        retval =  m_Index - 1;
+    }
+    
+    // read and skip second defline
+    ++(*line_reader);
+    line = **line_reader;
+    // skip empty lines
+    while (!line_reader->AtEOF() && line.empty()) {
+        ++(*line_reader);
+        line = **line_reader;
+    }
+
+    if (line[0] != '+') {
+        NCBI_THROW(CInputException, eInvalidInput, (string)"FASTQ parse error:"
+                   " defline expected at line: " +
+                   NStr::IntToString(line_reader->GetLineNumber()));
+    }
+
+    // read and skip quality scores
+    ++(*line_reader);
+    line = **line_reader;
+    // skip empty lines
+    while (!line_reader->AtEOF() && line.empty()) {
+        ++(*line_reader);
+        line = **line_reader;
+    }
+
+    return retval;
+}
+
+
+bool
+CShortReadFastaInputSource::x_ReadFromTwoFiles(CBioseq_set& bioseq_set,
+                            CShortReadFastaInputSource::EInputFormat format)
+{
+    if (format == eFastc) {
+        NCBI_THROW(CInputException, eInvalidInput, "FASTC format cannot be "
+                   "used with two files");
+    }
+
+    // tags to indicate paired sequences
+    CRef<CSeqdesc> seqdesc_first(new CSeqdesc);
+    seqdesc_first->SetUser().SetType().SetStr("Mapping");
+    seqdesc_first->SetUser().AddField("has_pair", eFirstSegment);
+
+    CRef<CSeqdesc> seqdesc_last(new CSeqdesc);
+    seqdesc_last->SetUser().SetType().SetStr("Mapping");
+    seqdesc_last->SetUser().AddField("has_pair", eLastSegment);
+
+    CRef<CSeqdesc> seqdesc_first_partial(new CSeqdesc);
+    seqdesc_first_partial->SetUser().SetType().SetStr("Mapping");
+    seqdesc_first_partial->SetUser().AddField("has_pair",
+                                              fFirstSegmentFlag | fPartialFlag);
+
+    CRef<CSeqdesc> seqdesc_last_partial(new CSeqdesc);
+    seqdesc_last_partial->SetUser().SetType().SetStr("Mapping");
+    seqdesc_last_partial->SetUser().AddField("has_pair",
+                                             fLastSegmentFlag | fPartialFlag);
+
+    int index1;
+    int index2;
+    m_Index = 0;
+    while (m_Index < (int)m_NumSeqsInBatch && !m_LineReader->AtEOF() &&
+           !m_SecondLineReader->AtEOF()) {
+
+        if (format == eFasta) {
+            index1 = x_ReadFastaOneSeq(m_LineReader); 
+            index2 = x_ReadFastaOneSeq(m_SecondLineReader);
+        }
+        else {
+            index1 = x_ReadFastqOneSeq(m_LineReader);
+            index2 = x_ReadFastqOneSeq(m_SecondLineReader);
+        }
+
+        if (index1 >= 0) {
+            if (index2 >= 0) {
+                m_Entries[index1]->SetSeq().SetDescr().Set().push_back(
+                                                              seqdesc_first);
+            }
+            else {
+                m_Entries[index1]->SetSeq().SetDescr().Set().push_back(
+                                                      seqdesc_first_partial);
+            }
+            bioseq_set.SetSeq_set().push_back(m_Entries[index1]);
+        }
+
+        if (index2 >= 0) {
+            if (index1 >= 0) {
+                m_Entries[index2]->SetSeq().SetDescr().Set().push_back(
+                                                               seqdesc_last);
+            }
+            else {
+                m_Entries[index2]->SetSeq().SetDescr().Set().push_back(
+                                                       seqdesc_last_partial);
+            }
+            bioseq_set.SetSeq_set().push_back(m_Entries[index2]);
+        }
+    }
+
+    return true;
+}
+
+
+CTempString CShortReadFastaInputSource::x_ParseDefline(CTempString& line)
+{
+    // set local sequence id for the new sequence as the string between '>'
+    // and the first space
+    size_t begin = 1;
+    size_t end = line.find(' ', 1);
+    CTempString id = line.substr(begin, end - begin);
+    return id;
+}
+
+
+bool CShortReadFastaInputSource::x_ValidateSequence(const char* sequence,
+                                                    int length)
+{
+    const char* s = sequence;
+    const int kNBase = (int)'N';
+    const double kMaxFractionAmbiguousBases = 0.5;
+    int num = 0;
+    for (int i=0;i < length;i++) {
+        num += (toupper((int)s[i]) == kNBase);
+    }
+
+    if ((double)num / length > kMaxFractionAmbiguousBases) {
+        return false;
+    }
+
+    int entropy = FindDimerEntropy(sequence, length);
+    return entropy > 16;
+}
+
 END_SCOPE(blast)
 END_NCBI_SCOPE
diff --git a/c++/src/algo/blast/blastinput/blast_input.cpp b/c++/src/algo/blast/blastinput/blast_input.cpp
index 2daf968..1b17150 100644
--- a/c++/src/algo/blast/blastinput/blast_input.cpp
+++ b/c++/src/algo/blast/blastinput/blast_input.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_input.cpp 458462 2015-02-05 14:10:55Z camacho $
+/*  $Id: blast_input.cpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Convert sources of sequence data into blast sequence input
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_input.cpp 458462 2015-02-05 14:10:55Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objects/seqloc/Seq_loc.hpp>
 #include <objmgr/util/sequence.hpp>
@@ -63,7 +58,8 @@ CBlastInputSourceConfig::CBlastInputSourceConfig
   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_SeqLenThreshold2Guess(seqlen_thresh2guess),
+  m_GapsToNs(false)
 {
     // Set an appropriate default for the strand
     if (m_Strand == eNa_strand_other) {
@@ -280,5 +276,28 @@ CBlastBioseqMaker::IsEmptyBioseq(const CBioseq& bioseq)
 
 }
 
+CBlastInputOMF::CBlastInputOMF(CRef<CBlastInputSourceOMF> source,
+                               TSeqPos num_seqs)
+    : m_Source(source),
+      m_NumSeqsInBatch(num_seqs),
+      m_BioseqSet(new CBioseq_set)
+    
+{}
+
+void
+CBlastInputOMF::GetNextSeqBatch(CBioseq_set& bioseq_set)
+{
+    m_Source->GetNextNumSequences(bioseq_set, m_NumSeqsInBatch);
+}
+
+CRef<CBioseq_set>
+CBlastInputOMF::GetNextSeqBatch(void)
+{
+    m_BioseqSet->SetSeq_set().clear();
+    m_Source->GetNextNumSequences(*m_BioseqSet, m_NumSeqsInBatch);
+    return m_BioseqSet;
+}
+
+
 END_SCOPE(blast)
 END_NCBI_SCOPE
diff --git a/c++/src/algo/blast/blastinput/blast_input_aux.cpp b/c++/src/algo/blast/blastinput/blast_input_aux.cpp
index b216490..07df8ce 100644
--- a/c++/src/algo/blast/blastinput/blast_input_aux.cpp
+++ b/c++/src/algo/blast/blastinput/blast_input_aux.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_input_aux.cpp 489109 2016-01-08 15:13:42Z fongah2 $
+/*  $Id: blast_input_aux.cpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  *  Auxiliary functions for BLAST input library
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_input_aux.cpp 489109 2016-01-08 15:13:42Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/blast_input_aux.hpp>
 #include <algo/blast/api/blast_exception.hpp>
@@ -110,6 +105,7 @@ GetQueryBatchSize(EProgram program, bool is_ungapped /* = false */,
 	retval = 500000;
 	break;
     case eMegablast:
+    case eMapper:
         retval = 5000000;
         break;
     case eTblastn:
@@ -217,7 +213,8 @@ ReadSequencesToBlast(CNcbiIstream& in,
                      const TSeqRange& range, 
                      bool parse_deflines,
                      bool use_lcase_masking,
-                     CRef<CBlastQueryVector>& sequences)
+                     CRef<CBlastQueryVector>& sequences,
+                     bool gaps_to_Ns /* = false */)
 {
     SDataLoaderConfig dlconfig(read_proteins);
     dlconfig.OptimizeForWholeLargeSequenceRetrieval();
@@ -227,6 +224,9 @@ ReadSequencesToBlast(CNcbiIstream& in,
     iconfig.SetBelieveDeflines(parse_deflines);
     iconfig.SetLowercaseMask(use_lcase_masking);
     iconfig.SetSubjectLocalIdMode();
+    if (!read_proteins && gaps_to_Ns) {
+        iconfig.SetConvertGapsToNs(true);
+    }
 
     CRef<CBlastFastaInputSource> fasta(new CBlastFastaInputSource(in, iconfig));
     CRef<CBlastInput> input(new CBlastInput(fasta));
@@ -426,5 +426,36 @@ CheckForEmptySequences(CRef<CBioseq_set> sequences, string& warnings)
     }
 }
 
+// compute enrtopy of 2-mers in a IUPACNA sequence
+int FindDimerEntropy(const char* sequence, int length)
+{
+    const int kNumDimers = 1 << 4;
+    int counts[kNumDimers];
+    memset(counts, 0, kNumDimers * sizeof(int));
+    int num = 0;
+    // count dimers
+    for (int i=0;i < length - 1;i++) {
+        Uint1 base_1 = IUPACNA_TO_BLASTNA[toupper((int)sequence[i])];
+        Uint1 base_2 = IUPACNA_TO_BLASTNA[toupper((int)sequence[i + 1])];
+        if ((base_1 & 0xfc) == 0 && (base_2 & 0xfc) == 0) {
+            int dimer = (base_1 << 2) | base_2;
+            counts[dimer]++;
+            num++;
+        }
+    }
+
+    // compute amount of information in the sequence
+    double sum = 0.0;
+    for (int i=0;i < kNumDimers;i++) {
+        if (counts[i]) {
+            sum += (double)counts[i] * log((double)counts[i] / num);
+        }
+    }
+
+    return -sum * (1.0 /(log(16.0))) + 0.5;
+}
+
+
+
 END_SCOPE(blast)
 END_NCBI_SCOPE
diff --git a/c++/src/algo/blast/blastinput/blast_scope_src.cpp b/c++/src/algo/blast/blastinput/blast_scope_src.cpp
index 563e515..b7517df 100644
--- a/c++/src/algo/blast/blastinput/blast_scope_src.cpp
+++ b/c++/src/algo/blast/blastinput/blast_scope_src.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_scope_src.cpp 445894 2014-09-09 15:49:42Z boratyng $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -68,21 +64,21 @@ SDataLoaderConfig::x_Init(SDataLoaderConfig::EConfigOpts options,
     }
     m_IsLoadingProteins = load_proteins;
 
-    CMetaRegistry::SEntry sentry =
-        CMetaRegistry::Load("ncbi", CMetaRegistry::eName_RcOrIni);
-    x_LoadDataLoadersConfig(sentry);
-    x_LoadBlastDbDataLoaderConfig(sentry);
+    CNcbiApplication* app = CNcbiApplication::Instance();
+    if (app) {
+        const CNcbiRegistry& registry = app->GetConfig();
+        x_LoadDataLoadersConfig(registry);
+        x_LoadBlastDbDataLoaderConfig(registry);
+    }
 }
 
 void
-SDataLoaderConfig::x_LoadDataLoadersConfig(const CMetaRegistry::SEntry& sentry)
+SDataLoaderConfig::x_LoadDataLoadersConfig(const CNcbiRegistry& registry)
 {
     static const string kDataLoadersConfig("DATA_LOADERS");
 
-    if (sentry.registry && 
-        sentry.registry->HasEntry("BLAST", kDataLoadersConfig)) {
-        const string& kLoaders = sentry.registry->Get("BLAST",
-                                                      kDataLoadersConfig);
+    if (registry.HasEntry("BLAST", kDataLoadersConfig)) {
+        const string& kLoaders = registry.Get("BLAST", kDataLoadersConfig);
         if (NStr::FindNoCase(kLoaders, "blastdb") == NPOS) {
             m_UseBlastDbs = false;
         }
@@ -99,8 +95,7 @@ SDataLoaderConfig::x_LoadDataLoadersConfig(const CMetaRegistry::SEntry& sentry)
 }
 
 void
-SDataLoaderConfig::x_LoadBlastDbDataLoaderConfig
-    (const CMetaRegistry::SEntry& sentry)
+SDataLoaderConfig::x_LoadBlastDbDataLoaderConfig(const CNcbiRegistry& registry)
 {
     if ( !m_UseBlastDbs ) {
         m_BlastDbName.clear();
@@ -119,8 +114,8 @@ SDataLoaderConfig::x_LoadBlastDbDataLoaderConfig
         ? kProtBlastDbLoaderConfig 
         : kNuclBlastDbLoaderConfig;
 
-    if (sentry.registry && sentry.registry->HasEntry("BLAST", config_param)) {
-        m_BlastDbName = sentry.registry->Get("BLAST", config_param);
+    if (registry.HasEntry("BLAST", config_param)) {
+        m_BlastDbName = registry.Get("BLAST", config_param);
     } else {
         _ASSERT(m_BlastDbName.empty());
         m_BlastDbName = m_IsLoadingProteins 
diff --git a/c++/src/algo/blast/blastinput/blastn_args.cpp b/c++/src/algo/blast/blastinput/blastn_args.cpp
index 6169370..12be18e 100644
--- a/c++/src/algo/blast/blastinput/blastn_args.cpp
+++ b/c++/src/algo/blast/blastinput/blastn_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastn_args.cpp 474565 2015-07-29 19:26:43Z fongah2 $
+/*  $Id: blastn_args.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Implementation of the BLASTN command line arguments
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] 
-    = "$Id: blastn_args.cpp 474565 2015-07-29 19:26:43Z fongah2 $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/blastn_args.hpp>
 #include <algo/blast/api/disc_nucl_options.hpp>
diff --git a/c++/src/algo/blast/blastinput/blastp_args.cpp b/c++/src/algo/blast/blastinput/blastp_args.cpp
index 2d1ee42..75f2d03 100644
--- a/c++/src/algo/blast/blastinput/blastp_args.cpp
+++ b/c++/src/algo/blast/blastinput/blastp_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastp_args.cpp 448376 2014-10-06 09:52:42Z mcelhany $
+/*  $Id: blastp_args.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /** @file blastp_args.cpp
  * Implementation of the BLASTP command line arguments
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: blastp_args.cpp 448376 2014-10-06 09:52:42Z mcelhany $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/blastp_args.hpp>
 #include <algo/blast/api/blast_advprot_options.hpp>
diff --git a/c++/src/algo/blast/blastinput/blastx_args.cpp b/c++/src/algo/blast/blastinput/blastx_args.cpp
index fc2e07e..9f67704 100644
--- a/c++/src/algo/blast/blastinput/blastx_args.cpp
+++ b/c++/src/algo/blast/blastinput/blastx_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastx_args.cpp 448376 2014-10-06 09:52:42Z mcelhany $
+/*  $Id: blastx_args.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Implementation of the BLASTX command line arguments
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] 
-    = "$Id: blastx_args.cpp 448376 2014-10-06 09:52:42Z mcelhany $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/blastx_args.hpp>
 #include <algo/blast/api/blastx_options.hpp>
diff --git a/c++/src/algo/blast/blastinput/cmdline_flags.cpp b/c++/src/algo/blast/blastinput/cmdline_flags.cpp
index c5f5744..bf3659b 100644
--- a/c++/src/algo/blast/blastinput/cmdline_flags.cpp
+++ b/c++/src/algo/blast/blastinput/cmdline_flags.cpp
@@ -1,4 +1,4 @@
-/*  $Id: cmdline_flags.cpp 499246 2016-04-25 11:32:24Z ivanov $
+/*  $Id: cmdline_flags.cpp 514854 2016-09-26 17:24:36Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  *  Constant definitions for command line arguments for BLAST programs
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: cmdline_flags.cpp 499246 2016-04-25 11:32:24Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 
 #ifndef SKIP_DOXYGEN_PROCESSING
@@ -187,6 +182,9 @@ const string kArgGLDomainSystem("domain_system");
 const string kArgGLFocusV("focus_on_V_segment");
 const string kArgExtendAlign("extend_align5end");
 const string kArgMinVLength("min_V_length");
+const string kArgMinJLength("min_J_length");
+const string kArgNumClonotype("num_clonotype");
+const string kArgClonotypeFile("clonotype_out");
 const string kArgTranslate("show_translation");
 const string kArgMinDMatch("min_D_match");
 const string kArgDPenalty("D_penalty");
@@ -215,12 +213,33 @@ const string kDfltArgRpsDb("cdd_delta");
 const string kArgDomainInclusionEThreshold("domain_inclusion_ethresh");
 const string kArgShowDomainHits("show_domain_hits");
 
+const string kArgJDistance("thresh");
+const string kDfltArgJDistance("0.05");
+const string kArgMinHits("min_hits");
+const string kDfltArgMinHits("0");
+const string kArgKIndex("dbk");
+const string kDfltArgKIndex("nr");
+const string kArgTargetSeqs("target_seqs");
+const string kDfltArgTargetSeqs("5000");
+
 const string kArgRid("rid");
 const string kArgArchive("archive");
 
 const string kArgQueryCovHspPerc("qcov_hsp_perc");
 const string kArgLineLength("line_length");
 
+const string kArgPaired("paired");
+const string kArgScore("score");
+const string kArgLimitLookup("limit_lookup");
+const string kArgSplice("splice");
+const string kArgLookupStride("lookup_stride");
+const string kArgInputFormat("infmt");
+const string kArgQualityFilter("validate_seqs");
+const string kArgQueryMate("query_mate");
+const string kArgRefType("reftype");
+const string kArgOutputGzip("gzo");
+const string kArgSraAccession("sra");
+
 END_SCOPE(blast)
 END_NCBI_SCOPE
 
diff --git a/c++/src/algo/blast/blastinput/deltablast_args.cpp b/c++/src/algo/blast/blastinput/deltablast_args.cpp
index fb7c457..dafc199 100644
--- a/c++/src/algo/blast/blastinput/deltablast_args.cpp
+++ b/c++/src/algo/blast/blastinput/deltablast_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: deltablast_args.cpp 483573 2015-11-02 17:48:31Z boratyng $
+/*  $Id: deltablast_args.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /** @file deltablast_args.cpp
  * Implementation of the DELTA-BLAST command line arguments
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: deltablast_args.cpp 483573 2015-11-02 17:48:31Z boratyng $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/deltablast_args.hpp>
 #include <algo/blast/api/deltablast_options.hpp>
diff --git a/c++/src/algo/blast/blastinput/igblastn_args.cpp b/c++/src/algo/blast/blastinput/igblastn_args.cpp
index 4ced77f..94a048b 100644
--- a/c++/src/algo/blast/blastinput/igblastn_args.cpp
+++ b/c++/src/algo/blast/blastinput/igblastn_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: igblastn_args.cpp 431056 2014-04-01 15:13:51Z camacho $
+/*  $Id: igblastn_args.cpp 514849 2016-09-26 17:23:09Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Implementation of the IGBLASTN command line arguments
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] 
-    = "$Id: igblastn_args.cpp 431056 2014-04-01 15:13:51Z camacho $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/igblastn_args.hpp>
 #include <algo/blast/api/disc_nucl_options.hpp>
@@ -142,7 +137,7 @@ CIgBlastnAppArgs::x_CreateOptionsHandle(CBlastOptions::EAPILocality locality,
     CBlastOptions &opts = retval->SetOptions();
     opts.SetMatchReward(1);
     opts.SetMismatchPenalty(-1);
-    opts.SetWordSize(11);
+    opts.SetWordSize(9);
     opts.SetGapOpeningCost(4);
     opts.SetGapExtensionCost(1);
 
diff --git a/c++/src/algo/blast/blastinput/igblastp_args.cpp b/c++/src/algo/blast/blastinput/igblastp_args.cpp
index 8ea11ce..401c268 100644
--- a/c++/src/algo/blast/blastinput/igblastp_args.cpp
+++ b/c++/src/algo/blast/blastinput/igblastp_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: igblastp_args.cpp 431056 2014-04-01 15:13:51Z camacho $
+/*  $Id: igblastp_args.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Implementation of the IGBLASTP command line arguments
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] 
-    = "$Id: igblastp_args.cpp 431056 2014-04-01 15:13:51Z camacho $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/igblastp_args.hpp>
 #include <algo/blast/api/disc_nucl_options.hpp>
diff --git a/c++/src/algo/blast/blastinput/kblastp_args.cpp b/c++/src/algo/blast/blastinput/kblastp_args.cpp
new file mode 100644
index 0000000..3bcbb55
--- /dev/null
+++ b/c++/src/algo/blast/blastinput/kblastp_args.cpp
@@ -0,0 +1,105 @@
+/*  $Id: kblastp_args.cpp 514853 2016-09-26 17:24:14Z ivanov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author: Tom Madden
+ *
+ */
+
+/** @file kblastp_args.cpp
+ * Implementation of the BLASTP command line arguments
+ */
+#include <ncbi_pch.hpp>
+#include <algo/blast/blastinput/kblastp_args.hpp>
+#include <algo/blast/api/blast_advprot_options.hpp>
+#include <algo/blast/api/blast_exception.hpp>
+#include <algo/blast/blastinput/blast_input_aux.hpp>
+#include <algo/blast/api/version.hpp>
+
+BEGIN_NCBI_SCOPE
+BEGIN_SCOPE(blast)
+USING_SCOPE(objects);
+
+CKBlastpAppArgs::CKBlastpAppArgs()
+{
+    CRef<IBlastCmdLineArgs> arg;
+    static const string kProgram("kblastp");
+    arg.Reset(new CProgramDescriptionArgs(kProgram, "Protein-Protein BLAST"));
+    const bool kQueryIsProtein = true;
+    bool const kFilterByDefault = false;
+    m_Args.push_back(arg);
+    m_ClientId = kProgram + " " + CBlastVersion().Print();
+
+    // m_BlastDbArgs.Reset(new CBlastDatabaseArgs);
+    // m_BlastDbArgs->SetDatabaseMaskingSupport(false);
+    // arg.Reset(m_BlastDbArgs);
+    // m_Args.push_back(arg);
+
+    m_StdCmdLineArgs.Reset(new CStdCmdLineArgs);
+    arg.Reset(m_StdCmdLineArgs);
+    m_Args.push_back(arg);
+
+    arg.Reset(new CGenericSearchArgs(kQueryIsProtein));
+    m_Args.push_back(arg);
+
+    // arg.Reset(new CFilteringArgs(kQueryIsProtein, kFilterByDefault));
+    // m_Args.push_back(arg);
+
+    m_QueryOptsArgs.Reset(new CQueryOptionsArgs(kQueryIsProtein));
+    arg.Reset(m_QueryOptsArgs);
+    m_Args.push_back(arg);
+
+    m_FormattingArgs.Reset(new CFormattingArgs);
+    arg.Reset(m_FormattingArgs);
+    m_Args.push_back(arg);
+
+    m_MTArgs.Reset(new CMTArgs);
+    arg.Reset(m_MTArgs);
+    m_Args.push_back(arg);
+
+    m_KBlastpArgs.Reset(new CKBlastpArgs);
+    arg.Reset(m_KBlastpArgs);
+    m_Args.push_back(arg);
+
+    m_DebugArgs.Reset(new CDebugArgs);
+    arg.Reset(m_DebugArgs);
+    m_Args.push_back(arg);
+}
+
+CRef<CBlastOptionsHandle> 
+CKBlastpAppArgs::x_CreateOptionsHandle(CBlastOptions::EAPILocality locality, 
+                                      const CArgs& args)
+{
+    return CRef<CBlastOptionsHandle>(new CBlastProteinOptionsHandle(locality));
+}
+
+int
+CKBlastpAppArgs::GetQueryBatchSize() const
+{
+    return 10000;
+}
+
+END_SCOPE(blast)
+END_NCBI_SCOPE
+
diff --git a/c++/src/algo/blast/blastinput/magicblast_args.cpp b/c++/src/algo/blast/blastinput/magicblast_args.cpp
new file mode 100644
index 0000000..3e6f5ec
--- /dev/null
+++ b/c++/src/algo/blast/blastinput/magicblast_args.cpp
@@ -0,0 +1,278 @@
+/*  $Id: magicblast_args.cpp 517510 2016-10-25 17:24:24Z ivanov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author: Greg Boratyn
+ *
+ */
+
+/** @file blastmapper_args.cpp
+ * Implementation of the BLASTMAPPER command line arguments
+ */
+
+#include <ncbi_pch.hpp>
+#include <algo/blast/blastinput/magicblast_args.hpp>
+#include <algo/blast/api/blast_exception.hpp>
+#include <algo/blast/blastinput/blast_fasta_input.hpp>
+#include <algo/blast/blastinput/blast_input_aux.hpp>
+//#include <algo/blast/api/version.hpp>
+#include <algo/blast/api/magicblast_options.hpp>
+
+BEGIN_NCBI_SCOPE
+BEGIN_SCOPE(blast)
+USING_SCOPE(objects);
+
+/// Special generic search arguments for blastmapper
+class CMapperGenericSearchArgs : public CGenericSearchArgs
+{
+public:
+    CMapperGenericSearchArgs(void) : CGenericSearchArgs(false) {}
+
+    virtual void SetArgumentDescriptions(CArgDescriptions& arg_desc) {
+
+        arg_desc.SetCurrentGroup("General search options");
+
+        arg_desc.AddOptionalKey(kArgWordSize, "int_value", "Word size for "
+                                "wordfinder algorithm (length of best perfect "
+                                "match)", CArgDescriptions::eInteger);
+
+        arg_desc.SetConstraint(kArgWordSize,
+                               new CArgAllowValuesGreaterThanOrEqual(12));
+
+
+        // gap open penalty
+        arg_desc.AddOptionalKey(kArgGapOpen, "open_penalty",
+                                "Cost to open a gap",
+                                CArgDescriptions::eInteger);
+
+        // gap extend penalty
+        arg_desc.AddOptionalKey(kArgGapExtend, "extend_penalty",
+                               "Cost to extend a gap", 
+                               CArgDescriptions::eInteger);
+
+        // FIXME: not sure if this one is needed
+        arg_desc.SetCurrentGroup("Restrict search or results");
+        arg_desc.AddOptionalKey(kArgPercentIdentity, "float_value",
+                                "Percent identity",
+                                CArgDescriptions::eDouble);
+        arg_desc.SetConstraint(kArgPercentIdentity,
+                               new CArgAllow_Doubles(0.0, 100.0));
+    }
+};
+
+/// Nucleotide args with no reward score
+class CMapperNuclArgs : public CNuclArgs
+{
+public:
+    CMapperNuclArgs(void) : CNuclArgs() {}
+
+    virtual void SetArgumentDescriptions(CArgDescriptions& arg_desc) {
+        arg_desc.SetCurrentGroup("General search options");
+        // blastn mismatch penalty
+        arg_desc.AddOptionalKey(kArgMismatch, "penalty", 
+                                "Penalty for a nucleotide mismatch", 
+                                CArgDescriptions::eInteger);
+        arg_desc.SetConstraint(kArgMismatch, 
+                               new CArgAllowValuesLessThanOrEqual(0));
+        arg_desc.SetCurrentGroup("");
+    }
+};
+
+/// Formatting args advertising only SAM and fast tabular formats
+class CMapperFormattingArgs : public CFormattingArgs
+{
+public:
+
+    CMapperFormattingArgs(void) : CFormattingArgs() {}
+
+    virtual void SetArgumentDescriptions(CArgDescriptions& arg_desc) {
+        arg_desc.SetCurrentGroup("Formatting options");
+        string kOutputFormatDescription = string(
+        "alignment view options:\n"
+        "sam = SAM format,\n"
+        "tabular = Tabular format,\n"
+        "asn = text ASN.1\n");
+
+        arg_desc.AddDefaultKey(align_format::kArgOutputFormat, "format", 
+                               kOutputFormatDescription,
+                               CArgDescriptions::eString, 
+                               "sam");
+
+        set<string> allowed_formats = {"sam", "tabular", "asn"};
+        arg_desc.SetConstraint(align_format::kArgOutputFormat,
+                               new CArgAllowStringSet(allowed_formats));
+
+        arg_desc.SetCurrentGroup("");
+    }
+
+    virtual void ExtractAlgorithmOptions(const CArgs& args, CBlastOptions& opt) {
+        if (args.Exist(align_format::kArgOutputFormat)) {
+            string fmt_choice = args[align_format::kArgOutputFormat].AsString();
+            if (fmt_choice == "sam") {
+                m_OutputFormat = eSAM;
+            }
+            else if (fmt_choice == "tabular") {
+                m_OutputFormat = eTabular;
+            }
+            else if (fmt_choice == "asn") {
+                m_OutputFormat = eAsnText;
+            }
+            else {
+                CNcbiOstrstream os;
+                os << "'" << fmt_choice << "' is not a valid output format";
+                string msg = CNcbiOstrstreamToString(os);
+                NCBI_THROW(CInputException, eInvalidInput, msg);
+            }
+        }
+
+        m_ShowGis = true;
+        m_Html = false;
+
+        // only the fast tabular format is able to show merged HSPs with
+        // common query bases
+        if (m_OutputFormat != eTabular) {
+            // FIXME: This is a hack. Merging should be done by the formatter,
+            // but is currently done by HSP stream writer. This is an easy
+            // switch until merging is implemented properly.
+            CNcbiEnvironment().Set("MAPPER_NO_OVERLAPPED_HSP_MERGE", "1");
+        }
+    }
+
+    virtual bool ArchiveFormatRequested(const CArgs& args) const {
+        return false;
+    }
+};
+
+/// Longest intron size with non-zero defalut value
+class CMapperLargestIntronSizeArgs : public CLargestIntronSizeArgs
+{
+public:
+    virtual void SetArgumentDescriptions(CArgDescriptions& arg_desc) {
+        arg_desc.SetCurrentGroup("General search options");
+        // largest intron length
+        arg_desc.AddDefaultKey(kArgMaxIntronLength, "length", 
+                    "Length of the largest intron allowed in a translated "
+                    "nucleotide sequence when linking multiple distinct "
+                    "alignments",
+                    CArgDescriptions::eInteger,
+                    NStr::IntToString(2000));
+        arg_desc.SetConstraint(kArgMaxIntronLength,
+                               new CArgAllowValuesGreaterThanOrEqual(0));
+        arg_desc.SetCurrentGroup("");
+    }
+};
+
+/// RemoteArgs with no option for remote
+class CMapperRemoteArgs : public CRemoteArgs
+{
+public:
+    virtual void SetArgumentDescriptions(CArgDescriptions& arg_desc) {}    
+};
+
+
+/// Program description without BLAST+ version
+class CMapperProgramDescriptionArgs : public CProgramDescriptionArgs
+{
+public:
+    CMapperProgramDescriptionArgs(const string& program_name,
+                                  const string& program_desc)
+        : CProgramDescriptionArgs(program_name, program_desc) {}
+
+    virtual void SetArgumentDescriptions(CArgDescriptions& arg_desc) {
+        arg_desc.SetUsageContext(m_ProgName, m_ProgDesc);
+    }
+};
+
+CMagicBlastAppArgs::CMagicBlastAppArgs()
+{
+    // remove search strategy args added in parent class constructor
+    m_Args.clear();
+
+    CRef<IBlastCmdLineArgs> arg;
+    static const char kProgram[] = "magicblast";
+    arg.Reset(new CMapperProgramDescriptionArgs(kProgram, "Short read mapper"));
+    m_Args.push_back(arg);
+
+    m_BlastDbArgs.Reset(new CBlastDatabaseArgs(false, false, false, true));
+    m_BlastDbArgs->SetDatabaseMaskingSupport(true);
+    arg.Reset(m_BlastDbArgs);
+    m_Args.push_back(arg);
+
+    m_StdCmdLineArgs.Reset(new CStdCmdLineArgs);
+    m_StdCmdLineArgs->SetGzipEnabled(true);
+    arg.Reset(m_StdCmdLineArgs);
+    m_Args.push_back(arg);
+
+    arg.Reset(new CMapperGenericSearchArgs);
+    m_Args.push_back(arg);
+
+    arg.Reset(new CMapperNuclArgs);
+    m_Args.push_back(arg);
+
+    m_QueryOptsArgs.Reset(new CMapperQueryOptionsArgs);
+    arg.Reset(m_QueryOptsArgs);
+    m_Args.push_back(arg);
+
+    arg.Reset(new CMapperFormattingArgs);
+    m_FormattingArgs.Reset(dynamic_cast<CFormattingArgs*>(
+                                           arg.GetNonNullPointer()));
+    m_Args.push_back(arg);
+
+    m_MTArgs.Reset(new CMTArgs);
+    arg.Reset(m_MTArgs);
+    m_Args.push_back(arg);
+
+    m_RemoteArgs.Reset(new CMapperRemoteArgs);
+    arg.Reset(m_RemoteArgs);
+    m_Args.push_back(arg);
+
+    m_DebugArgs.Reset(new CDebugArgs);
+    arg.Reset(m_DebugArgs);
+    m_Args.push_back(arg);
+
+    arg.Reset(new CMapperLargestIntronSizeArgs);
+    m_Args.push_back(arg);
+
+    arg.Reset(new CMappingArgs);
+    m_Args.push_back(arg);
+}
+
+CRef<CBlastOptionsHandle> 
+CMagicBlastAppArgs::x_CreateOptionsHandle(
+                                         CBlastOptions::EAPILocality locality,
+                                         const CArgs& args)
+{
+    return CRef<CBlastOptionsHandle>(new CMagicBlastOptionsHandle(locality));
+}
+
+int
+CMagicBlastAppArgs::GetQueryBatchSize() const
+{
+    bool is_remote = (m_RemoteArgs.NotEmpty() && m_RemoteArgs->ExecuteRemotely());
+    return blast::GetQueryBatchSize(ProgramNameToEnum(GetTask()), m_IsUngapped, is_remote, false);
+}
+
+END_SCOPE(blast)
+END_NCBI_SCOPE
+
diff --git a/c++/src/algo/blast/blastinput/psiblast_args.cpp b/c++/src/algo/blast/blastinput/psiblast_args.cpp
index 3146f82..ee7e91e 100644
--- a/c++/src/algo/blast/blastinput/psiblast_args.cpp
+++ b/c++/src/algo/blast/blastinput/psiblast_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: psiblast_args.cpp 483345 2015-10-30 14:04:13Z boratyng $
+/*  $Id: psiblast_args.cpp 516795 2016-10-18 14:21:21Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /** @file psiblast_args.cpp
  * Implementation of the PSI-BLAST command line arguments
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: psiblast_args.cpp 483345 2015-10-30 14:04:13Z boratyng $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/psiblast_args.hpp>
 #include <algo/blast/api/psiblast_options.hpp>
@@ -53,7 +48,7 @@ CPsiBlastAppArgs::CPsiBlastAppArgs()
     static const string kProgram("psiblast");
     CRef<IBlastCmdLineArgs> arg;
     arg.Reset(new CProgramDescriptionArgs(kProgram,
-                                          "Position-Specific Initiated BLAST"));
+                                          "Position-Specific Iterated BLAST"));
     m_Args.push_back(arg);
     m_ClientId = kProgram + " " + CBlastVersion().Print();
 
diff --git a/c++/src/algo/blast/blastinput/rmblastn_args.cpp b/c++/src/algo/blast/blastinput/rmblastn_args.cpp
index c5ebd7c..b869f66 100644
--- a/c++/src/algo/blast/blastinput/rmblastn_args.cpp
+++ b/c++/src/algo/blast/blastinput/rmblastn_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: rmblastn_args.cpp 431056 2014-04-01 15:13:51Z camacho $
+/*  $Id: rmblastn_args.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -16,11 +16,6 @@
  */
 
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] 
-    = "$Id: rmblastn_args.cpp 431056 2014-04-01 15:13:51Z camacho $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/rmblastn_args.hpp>
 #include <algo/blast/api/disc_nucl_options.hpp>
diff --git a/c++/src/algo/blast/blastinput/rpsblast_args.cpp b/c++/src/algo/blast/blastinput/rpsblast_args.cpp
index 1a54173..677f1b2 100644
--- a/c++/src/algo/blast/blastinput/rpsblast_args.cpp
+++ b/c++/src/algo/blast/blastinput/rpsblast_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: rpsblast_args.cpp 448376 2014-10-06 09:52:42Z mcelhany $
+/*  $Id: rpsblast_args.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /** @file rpsblast_args.cpp
  * Implementation of the RPSBLAST command line arguments
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: rpsblast_args.cpp 448376 2014-10-06 09:52:42Z mcelhany $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/rpsblast_args.hpp>
 #include <algo/blast/api/blast_rps_options.hpp>
diff --git a/c++/src/algo/blast/blastinput/rpstblastn_args.cpp b/c++/src/algo/blast/blastinput/rpstblastn_args.cpp
index 624d0fa..98ae1ab 100644
--- a/c++/src/algo/blast/blastinput/rpstblastn_args.cpp
+++ b/c++/src/algo/blast/blastinput/rpstblastn_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: rpstblastn_args.cpp 448376 2014-10-06 09:52:42Z mcelhany $
+/*  $Id: rpstblastn_args.cpp 505234 2016-06-23 13:16:57Z fongah2 $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Implementation of the RPSTBLASTN command line arguments
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] 
-    = "$Id: rpstblastn_args.cpp 448376 2014-10-06 09:52:42Z mcelhany $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/rpstblastn_args.hpp>
 #include <algo/blast/api/rpstblastn_options.hpp>
@@ -49,11 +44,13 @@ USING_SCOPE(objects);
 CRPSTBlastnAppArgs::CRPSTBlastnAppArgs()
 {
     CRef<IBlastCmdLineArgs> arg;
+    bool const kFilterByDefault = false;
     static const string kProgram("rpstblastn");
     arg.Reset(new CProgramDescriptionArgs(kProgram,
                                "Translated Reverse Position Specific BLAST"));
     const bool kQueryIsProtein = false;
     const bool kIsRpsBlast = true;
+    const bool kIsCBS2and3Supported = false;
     m_Args.push_back(arg);
     m_ClientId = kProgram + " " + CBlastVersion().Print();
 
@@ -78,7 +75,7 @@ CRPSTBlastnAppArgs::CRPSTBlastnAppArgs()
 
     // N.B.: query is not protein because the filtering is applied on the 
     // translated query
-    arg.Reset(new CFilteringArgs( !kQueryIsProtein ));
+    arg.Reset(new CFilteringArgs( !kQueryIsProtein, kFilterByDefault));
     m_Args.push_back(arg);
 
     arg.Reset(new CWindowSizeArg);
@@ -106,6 +103,10 @@ CRPSTBlastnAppArgs::CRPSTBlastnAppArgs()
     m_DebugArgs.Reset(new CDebugArgs);
     arg.Reset(m_DebugArgs);
     m_Args.push_back(arg);
+
+    arg.Reset(new CCompositionBasedStatsArgs(kIsCBS2and3Supported, kDfltArgCompBasedStatsRPS ));
+    m_Args.push_back(arg);
+
 }
 
 CRef<CBlastOptionsHandle> 
diff --git a/c++/src/algo/blast/blastinput/tblastn_args.cpp b/c++/src/algo/blast/blastinput/tblastn_args.cpp
index a4ec8a0..c1bac5a 100644
--- a/c++/src/algo/blast/blastinput/tblastn_args.cpp
+++ b/c++/src/algo/blast/blastinput/tblastn_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: tblastn_args.cpp 448376 2014-10-06 09:52:42Z mcelhany $
+/*  $Id: tblastn_args.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Implementation of the TBLASTN command line arguments
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] 
-    = "$Id: tblastn_args.cpp 448376 2014-10-06 09:52:42Z mcelhany $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/tblastn_args.hpp>
 #include <algo/blast/api/tblastn_options.hpp>
diff --git a/c++/src/algo/blast/blastinput/tblastx_args.cpp b/c++/src/algo/blast/blastinput/tblastx_args.cpp
index a14a977..8158a53 100644
--- a/c++/src/algo/blast/blastinput/tblastx_args.cpp
+++ b/c++/src/algo/blast/blastinput/tblastx_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: tblastx_args.cpp 448376 2014-10-06 09:52:42Z mcelhany $
+/*  $Id: tblastx_args.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Implementation of the TBLASTX command line arguments
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] 
-    = "$Id: tblastx_args.cpp 448376 2014-10-06 09:52:42Z mcelhany $";
-#endif
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/blastinput/tblastx_args.hpp>
 #include <algo/blast/api/tblastx_options.hpp>
diff --git a/c++/src/algo/blast/blastinput/unit_test/Makefile.blastinput_unit_test.app b/c++/src/algo/blast/blastinput/unit_test/Makefile.blastinput_unit_test.app
index 7cbc124..7c22364 100644
--- a/c++/src/algo/blast/blastinput/unit_test/Makefile.blastinput_unit_test.app
+++ b/c++/src/algo/blast/blastinput/unit_test/Makefile.blastinput_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.blastinput_unit_test.app 435839 2014-05-21 13:36:09Z camacho $
+# $Id: Makefile.blastinput_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = blastinput_unit_test
 SRC = blastinput_unit_test blast_scope_src_unit_test
@@ -8,7 +8,7 @@ CPPFLAGS = $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
 ENTREZ_LIBS = entrez2cli entrez2
 
 LIB_ = test_boost $(ENTREZ_LIBS) $(BLAST_INPUT_LIBS) \
-    ncbi_xloader_blastdb_rmt $(BLAST_LIBS) $(OBJMGR_LIBS)
+       $(BLAST_LIBS) $(OBJMGR_LIBS)
 LIB = $(LIB_:%=%$(STATIC))
 
 LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
diff --git a/c++/src/algo/blast/blastinput/unit_test/blast_input_unit_test_aux.hpp b/c++/src/algo/blast/blastinput/unit_test/blast_input_unit_test_aux.hpp
index 845c2ca..c395743 100644
--- a/c++/src/algo/blast/blastinput/unit_test/blast_input_unit_test_aux.hpp
+++ b/c++/src/algo/blast/blastinput/unit_test/blast_input_unit_test_aux.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_input_unit_test_aux.hpp 424465 2014-01-16 14:02:06Z camacho $
+/*  $Id: blast_input_unit_test_aux.hpp 516396 2016-10-13 12:26:43Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -56,8 +56,13 @@ public:
 
     typedef blast::SDataLoaderConfig::EConfigOpts EConfigOpts;
 
-    CAutoNcbiConfigFile(EConfigOpts opts = blast::SDataLoaderConfig::eDefault) {
-        m_Sentry = CMetaRegistry::Load("ncbi", CMetaRegistry::eName_RcOrIni);
+    CAutoNcbiConfigFile(EConfigOpts opts = blast::SDataLoaderConfig::eDefault)
+        : m_App(CNcbiApplication::Instance()), m_Registry(0)
+    {
+        _ASSERT(m_App);
+        m_App->ReloadConfig(CMetaRegistry::fAlwaysReload);
+        m_Registry = &m_App->GetConfig();
+        _ASSERT(m_Registry);
 
         string value;
         if (opts & blast::SDataLoaderConfig::eUseBlastDbDataLoader) {
@@ -69,33 +74,39 @@ public:
         if (opts & blast::SDataLoaderConfig::eUseNoDataLoaders) {
             value += "none";
         }
-        m_Sentry.registry->Set(kSection, kDataLoaders, value);
+        m_Registry->Set(kSection, kDataLoaders, value);
     }
 
     void SetProteinBlastDbDataLoader(const string& prot_db_name) {
-        m_Sentry.registry->Set(kSection, kProtBlastDbDataLoader, prot_db_name);
+        m_Registry->Set(kSection, kProtBlastDbDataLoader, prot_db_name);
     }
 
     void SetNucleotideBlastDbDataLoader(const string& nucl_db_name) {
-        m_Sentry.registry->Set(kSection, kNuclBlastDbDataLoader, nucl_db_name);
+        m_Registry->Set(kSection, kNuclBlastDbDataLoader, nucl_db_name);
     }
 
     void RemoveBLASTDBEnvVar() {
-        m_BlastDb = m_Sentry.registry->Get(kSection, "BLASTDB");
-        m_Sentry.registry->Set(kSection, "BLASTDB", "/dev/null");
+        m_BlastDb = m_Registry->Get(kSection, "BLASTDB");
+        m_Registry->Set(kSection, "BLASTDB", "/dev/null");
     }
 
     ~CAutoNcbiConfigFile() {
-        m_Sentry.registry->Set(kSection, kDataLoaders, kEmptyStr);
-        m_Sentry.registry->Set(kSection, kProtBlastDbDataLoader, kEmptyStr);
-        m_Sentry.registry->Set(kSection, kNuclBlastDbDataLoader, kEmptyStr);
+        m_App->ReloadConfig(CMetaRegistry::fAlwaysReload);
+        m_Registry->Set(kSection, kDataLoaders, kEmptyStr);
+        m_Registry->Set(kSection, kProtBlastDbDataLoader, kEmptyStr);
+        m_Registry->Set(kSection, kNuclBlastDbDataLoader, kEmptyStr);
         if ( !m_BlastDb.empty() ) {
-            m_Sentry.registry->Set(kSection, "BLASTDB", m_BlastDb);
+            m_Registry->Set(kSection, "BLASTDB", m_BlastDb);
         }
     }
+
 private:
-    CMetaRegistry::SEntry m_Sentry;
+    CNcbiApplication* m_App;
+    CNcbiRegistry* m_Registry;
     string m_BlastDb;
+
+    CAutoNcbiConfigFile(const CAutoNcbiConfigFile&) = delete;
+    CAutoNcbiConfigFile& operator=(const CAutoNcbiConfigFile&) = delete;
 };
 
 /// RAII class for the CBlastScopeSource. It revokes the BLAST database data
diff --git a/c++/src/algo/blast/blastinput/unit_test/blast_scope_src_unit_test.cpp b/c++/src/algo/blast/blastinput/unit_test/blast_scope_src_unit_test.cpp
index 23c5063..7039430 100644
--- a/c++/src/algo/blast/blastinput/unit_test/blast_scope_src_unit_test.cpp
+++ b/c++/src/algo/blast/blastinput/unit_test/blast_scope_src_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_scope_src_unit_test.cpp 481294 2015-10-08 14:03:49Z grichenk $
+/*  $Id: blast_scope_src_unit_test.cpp 516396 2016-10-13 12:26:43Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -393,14 +393,6 @@ BOOST_AUTO_TEST_CASE(ForceRemoteBlastDbLoader) {
     acf.RemoveBLASTDBEnvVar();
     acf.SetProteinBlastDbDataLoader(SDataLoaderConfig::kDefaultProteinBlastDb);
 
-    // Make sure to post warnings
-    CDiagRestorer diag_restorer;
-    SetDiagPostLevel(eDiag_Info);
-
-    // Redirect the output warnings
-    CNcbiOstrstream error_stream;
-    SetDiagStream(&error_stream); 
-
     const CSeq_id seqid(CSeq_id::e_Gi, 129295);
 
     SDataLoaderConfig dlconfig(true);
@@ -415,10 +407,6 @@ BOOST_AUTO_TEST_CASE(ForceRemoteBlastDbLoader) {
     const TSeqPos kExpectedLength = 232;
     BOOST_CHECK_EQUAL(kExpectedLength, length);
 
-    const string kWarnings = CNcbiOstrstreamToString(error_stream);
-    const string kExpectedMsg("Error initializing local BLAST database data");
-    BOOST_CHECK(kWarnings.find(kExpectedMsg) != NPOS);
-
     string data_loader_name("REMOTE_BLASTDB_");
     data_loader_name += string(SDataLoaderConfig::kDefaultProteinBlastDb);
     data_loader_name += "Protein";
diff --git a/c++/src/algo/blast/blastinput/unit_test/blastinput_unit_test.cpp b/c++/src/algo/blast/blastinput/unit_test/blastinput_unit_test.cpp
index 47a0896..f7d01ee 100644
--- a/c++/src/algo/blast/blastinput/unit_test/blastinput_unit_test.cpp
+++ b/c++/src/algo/blast/blastinput/unit_test/blastinput_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastinput_unit_test.cpp 489949 2016-01-20 12:32:48Z madden $
+/*  $Id: blastinput_unit_test.cpp 517499 2016-10-25 17:20:41Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -40,13 +40,16 @@
 #include <objects/seqloc/PDB_seq_id.hpp>
 #include <objects/seq/Seq_data.hpp>
 #include <objects/seq/NCBIeaa.hpp>
+#include <objects/seqset/Bioseq_set.hpp>
 
 #include <corelib/ncbienv.hpp>
 #include <objtools/readers/reader_exception.hpp>
 #include <algo/blast/api/sseqloc.hpp>
+#include <algo/blast/core/blast_query_info.h>
 #include <algo/blast/blastinput/blast_input.hpp>
 #include <algo/blast/blastinput/blast_input_aux.hpp>
 #include <algo/blast/blastinput/blast_fasta_input.hpp>
+#include <algo/blast/blastinput/blast_asn1_input.hpp>
 #include <objmgr/util/sequence.hpp>
 #include <objmgr/seq_vector.hpp>
 
@@ -59,6 +62,8 @@
 #include <algo/blast/blastinput/rpsblast_args.hpp>
 #include "blast_input_unit_test_aux.hpp"
 
+#include <unordered_map>
+
 #undef NCBI_BOOST_NO_AUTO_TEST_MAIN
 #include <corelib/test_boost.hpp>
 
@@ -998,7 +1003,7 @@ BOOST_AUTO_TEST_CASE(ReadSingleAccession_RetrieveLargeSequence)
 
     BOOST_REQUIRE(ssl.seqloc->GetInt().IsSetId() == true);
     BOOST_REQUIRE_EQUAL(CSeq_id::e_Gi, ssl.seqloc->GetInt().GetId().Which());
-    BOOST_REQUIRE_EQUAL(GI_FROM(TIntId, kGi), ssl.seqloc->GetInt().GetId().GetGi());
+    BOOST_REQUIRE_EQUAL(GI_CONST(kGi), ssl.seqloc->GetInt().GetId().GetGi());
 
     BOOST_REQUIRE(!ssl.mask);
 
@@ -1013,7 +1018,7 @@ BOOST_AUTO_TEST_CASE(ReadSingleAccession_RetrieveLargeSequence)
     bool found_gi = false, found_accession = false;
     ITERATE(CBioseq::TId, id, b.GetId()) {
         if ((*id)->Which() == CSeq_id::e_Gi) {
-            BOOST_REQUIRE_EQUAL(GI_FROM(TIntId, kGi), (*id)->GetGi());
+            BOOST_REQUIRE_EQUAL(GI_CONST(kGi), (*id)->GetGi());
             found_gi = true;
         } else if ((*id)->Which() == CSeq_id::e_Other) {
             CNcbiOstrstream os;
@@ -1249,7 +1254,7 @@ BOOST_AUTO_TEST_CASE(ReadSingleGi)
 
     BOOST_REQUIRE(ssl.seqloc->GetInt().IsSetId() == true);
     BOOST_REQUIRE_EQUAL(CSeq_id::e_Gi, ssl.seqloc->GetInt().GetId().Which());
-    const TGi gi = GI_FROM(TIntId, 89161185);
+    const TGi gi = GI_CONST(89161185);
     BOOST_REQUIRE_EQUAL(gi, ssl.seqloc->GetInt().GetId().GetGi());
 
     BOOST_REQUIRE(!ssl.mask);
@@ -1710,7 +1715,7 @@ BOOST_AUTO_TEST_CASE(ReadGiNuclWithFlankingSpacesIntoBuffer_Single)
     BOOST_REQUIRE(ssl.seqloc->GetInt().IsSetId() == true);
     BOOST_REQUIRE( !blast::IsLocalId(ssl.seqloc->GetId()) );
     BOOST_REQUIRE_EQUAL(CSeq_id::e_Gi, ssl.seqloc->GetInt().GetId().Which());
-    const TGi gi = GI_FROM(TIntId, 1945386);
+    const TGi gi = GI_CONST(1945386);
     BOOST_REQUIRE_EQUAL(gi, ssl.seqloc->GetInt().GetId().GetGi());
 
     BOOST_REQUIRE(!ssl.mask);
@@ -1721,8 +1726,11 @@ BOOST_AUTO_TEST_CASE(ReadGiNuclWithFlankingSpacesIntoBuffer_Single)
     BOOST_REQUIRE(bioseqs->GetSeq_set().front()->IsSeq());
     const CBioseq& b = bioseqs->GetSeq_set().front()->GetSeq();
     BOOST_REQUIRE(b.IsNa());
-    BOOST_REQUIRE_EQUAL(CSeq_id::e_Gi, b.GetId().front()->Which());
-    BOOST_REQUIRE_EQUAL(gi, b.GetId().front()->GetGi());
+
+    CRef<CSeq_id> id = FindBestChoice(b.GetId(), CSeq_id::BestRank);
+    BOOST_REQUIRE(id.NotNull());
+    BOOST_REQUIRE_EQUAL(CSeq_id::e_Gi, id->Which());
+    BOOST_REQUIRE_EQUAL(gi, id->GetGi());
     BOOST_REQUIRE_EQUAL(CSeq_inst::eRepr_raw, b.GetInst().GetRepr());
     BOOST_REQUIRE(CSeq_inst::IsNa(b.GetInst().GetMol()));
     BOOST_REQUIRE_EQUAL(length, b.GetInst().GetLength());
@@ -1761,7 +1769,7 @@ BOOST_AUTO_TEST_CASE(ReadAccessionNuclWithFlankingSpacesIntoBuffer_Single)
     BOOST_REQUIRE( !blast::IsLocalId(ssl.seqloc->GetId()) );
     BOOST_REQUIRE_EQUAL(CSeq_id::e_Gi, ssl.seqloc->GetInt().GetId().Which());
     const string accession("X65215.1");
-    BOOST_REQUIRE_EQUAL(GI_FROM(TIntId, 555), ssl.seqloc->GetInt().GetId().GetGi());
+    BOOST_REQUIRE_EQUAL(GI_CONST(555), ssl.seqloc->GetInt().GetId().GetGi());
 
     BOOST_REQUIRE(!ssl.mask);
 
@@ -1774,7 +1782,7 @@ BOOST_AUTO_TEST_CASE(ReadAccessionNuclWithFlankingSpacesIntoBuffer_Single)
     bool found_gi = false, found_accession = false;
     ITERATE(CBioseq::TId, id, b.GetId()) {
         if ((*id)->Which() == CSeq_id::e_Gi) {
-            BOOST_REQUIRE_EQUAL(GI_FROM(TIntId, 555), (*id)->GetGi());
+            BOOST_REQUIRE_EQUAL(GI_CONST(555), (*id)->GetGi());
             found_gi = true;
         } else if ((*id)->Which() == CSeq_id::e_Embl) {
             CNcbiOstrstream os;
@@ -1975,7 +1983,7 @@ BOOST_AUTO_TEST_CASE(ParseDefline)
     CRef<CBlastInput> source(s_DeclareBlastInput(infile, iconfig));
     CScope scope(*CObjectManager::GetInstance());
 
-    const TGi gi = GI_FROM(TIntId, 129295);
+    const TGi gi = GI_CONST(129295);
     blast::SSeqLoc ssl = source->GetNextSeqLocBatch(scope).front();
     BOOST_REQUIRE_EQUAL(CSeq_id::e_Gi, ssl.seqloc->GetId()->Which());
     BOOST_REQUIRE_EQUAL(gi, ssl.seqloc->GetId()->GetGi());
@@ -2222,7 +2230,7 @@ BOOST_AUTO_TEST_CASE(MultiBatch)
     v = source->GetNextSeqLocBatch(scope);
     BOOST_REQUIRE_EQUAL((size_t)7, v.size());
     BOOST_REQUIRE_EQUAL((TSeqPos)530, v[0].seqloc->GetInt().GetTo());
-    gi = GI_FROM(TIntId, 1346057);
+    gi = GI_CONST(1346057);
     BOOST_REQUIRE( !blast::IsLocalId(v[0].seqloc->GetId()) );
     BOOST_REQUIRE_EQUAL(gi, v[0].seqloc->GetInt().GetId().GetGi());
     BOOST_REQUIRE_EQUAL(gi, v[0].seqloc->GetId()->GetGi());
@@ -2230,7 +2238,7 @@ BOOST_AUTO_TEST_CASE(MultiBatch)
     v = source->GetNextSeqLocBatch(scope);
     BOOST_REQUIRE_EQUAL((size_t)8, v.size());
     BOOST_REQUIRE_EQUAL((TSeqPos)445, v[0].seqloc->GetInt().GetTo());
-    gi = GI_FROM(TIntId, 1170625);
+    gi = GI_CONST(1170625);
     BOOST_REQUIRE( !blast::IsLocalId(v[0].seqloc->GetId()) );
     BOOST_REQUIRE_EQUAL(gi, v[0].seqloc->GetInt().GetId().GetGi());
     BOOST_REQUIRE_EQUAL(gi, v[0].seqloc->GetId()->GetGi());
@@ -2238,7 +2246,7 @@ BOOST_AUTO_TEST_CASE(MultiBatch)
     v = source->GetNextSeqLocBatch(scope);
     BOOST_REQUIRE_EQUAL((size_t)4, v.size());
     BOOST_REQUIRE_EQUAL((TSeqPos)688, v[0].seqloc->GetInt().GetTo());
-    gi = GI_FROM(TIntId, 114152);
+    gi = GI_CONST(114152);
     BOOST_REQUIRE( !blast::IsLocalId(v[0].seqloc->GetId()) );
     BOOST_REQUIRE_EQUAL(gi, v[0].seqloc->GetInt().GetId().GetGi());
     BOOST_REQUIRE_EQUAL(gi, v[0].seqloc->GetId()->GetGi());
@@ -2664,8 +2672,300 @@ BOOST_AUTO_TEST_CASE(FetchGiFromAccessionInput)
     }
 }
 
+
 BOOST_AUTO_TEST_SUITE_END() // end of blastinput test suite
 
+
+BOOST_AUTO_TEST_SUITE(short_reads)
+
+static int s_GetSegmentFlags(const CBioseq& bioseq)
+{
+    int retval = 0;
+
+    BOOST_REQUIRE(bioseq.IsSetDescr());
+    for (auto desc : bioseq.GetDescr().Get()) {
+        if (desc->Which() == CSeqdesc::e_User) {
+
+            if (!desc->GetUser().IsSetType() ||
+                !desc->GetUser().GetType().IsStr() ||
+                desc->GetUser().GetType().GetStr() != "Mapping") {
+                continue;
+            }
+
+            BOOST_REQUIRE(desc->GetUser().HasField("has_pair"));
+            const CUser_field& field = desc->GetUser().GetField("has_pair");
+            BOOST_REQUIRE(field.GetData().IsInt());
+
+            retval = field.GetData().GetInt();
+        }
+    }
+
+    return retval;
+}
+
+BOOST_AUTO_TEST_CASE(TestFlagsForPairedReadsFromFasta) {
+
+    CNcbiIfstream istr("data/paired_reads.fa");
+    BOOST_REQUIRE(istr);
+    unordered_map<string, int> ref_flags = {
+        {"lcl|pair1", eFirstSegment},
+        {"lcl|pair2", eLastSegment},
+        {"lcl|incomplete1.1", fFirstSegmentFlag | fPartialFlag},
+        {"lcl|incomplete2.2", fLastSegmentFlag | fPartialFlag}
+    };
+    
+    CShortReadFastaInputSource input_source(istr, 1000,
+                                         CShortReadFastaInputSource::eFasta,
+                                         true, true);
+
+    CRef<CBioseq_set> queries(new CBioseq_set);
+    input_source.GetNextNumSequences(*queries, 0);
+    // input file contains six sequences, but two should have been rejected
+    // in screening
+    BOOST_REQUIRE_EQUAL(queries->GetSeq_set().size(), 4u);
+
+    size_t count = 0;
+    for (auto it : queries->GetSeq_set()) {
+        string id = it->GetSeq().GetFirstId()->AsFastaString();
+        int flags = s_GetSegmentFlags(it->GetSeq());
+        int expected = ref_flags.at(id);
+
+        BOOST_REQUIRE_MESSAGE(flags == expected, (string)"Segment flag for " +
+                id + " is different from expected " +
+                NStr::IntToString(flags) + " != " +
+                NStr::IntToString(expected));
+        count++;
+    }
+
+    BOOST_REQUIRE_EQUAL(ref_flags.size(), count);
+}
+
+BOOST_AUTO_TEST_CASE(TestPairedFlagsForPairedReadsFromTwoFastaFiles) {
+
+    CNcbiIfstream istr1("data/paired_reads_1.fa");
+    CNcbiIfstream istr2("data/paired_reads_2.fa");
+    BOOST_REQUIRE(istr1);
+    BOOST_REQUIRE(istr2);
+    unordered_map<string, int> ref_flags = {
+        {"lcl|pair1", eFirstSegment},
+        {"lcl|pair2", eLastSegment},
+        {"lcl|incomplete1.1", fFirstSegmentFlag | fPartialFlag},
+        {"lcl|incomplete2.2", fLastSegmentFlag | fPartialFlag}
+    };
+    
+    CShortReadFastaInputSource input_source(istr1, istr2, 1000,
+                                         CShortReadFastaInputSource::eFasta,
+                                         true);
+
+    CRef<CBioseq_set> queries(new CBioseq_set);
+    input_source.GetNextNumSequences(*queries, 0);
+    // input file contains six sequences, but two should have been rejected
+    // in screening
+    BOOST_REQUIRE_EQUAL(queries->GetSeq_set().size(), 4u);
+
+    size_t count = 0;
+    for (auto it : queries->GetSeq_set()) {
+        string id = it->GetSeq().GetFirstId()->AsFastaString();
+        int flags = s_GetSegmentFlags(it->GetSeq());
+        int expected = ref_flags.at(id);
+
+        BOOST_REQUIRE_MESSAGE(flags == expected, (string)"Segment flag for " +
+                id + " is different from expected " +
+                NStr::IntToString(flags) + " != " +
+                NStr::IntToString(expected));
+        count++;
+    }
+
+    BOOST_REQUIRE_EQUAL(ref_flags.size(), count);
+}
+
+BOOST_AUTO_TEST_CASE(TestPairedFlagsForSingleReadsFromFasta) {
+
+    CNcbiIfstream istr("data/paired_reads.fa");
+    CShortReadFastaInputSource input_source(istr, 1000,
+                                         CShortReadFastaInputSource::eFasta,
+                                         false, true);
+
+    CRef<CBioseq_set> queries(new CBioseq_set);
+    input_source.GetNextNumSequences(*queries, 0);
+    // input file contains six sequences, but two should have been rejected
+    // in screening
+    BOOST_REQUIRE_EQUAL(queries->GetSeq_set().size(), 4u);
+
+    size_t count = 0;
+    for (auto it : queries->GetSeq_set()) {
+        if (it->GetSeq().IsSetDescr()) {
+
+            string id = it->GetSeq().GetFirstId()->AsFastaString();
+            int flags = s_GetSegmentFlags(it->GetSeq());
+            int expected = 0;
+
+            BOOST_REQUIRE_MESSAGE(flags == expected,
+                                  (string)"Segment flag for " +
+                                  id + " is different from expected " +
+                                  NStr::IntToString(flags) + " != " +
+                                  NStr::IntToString(expected));
+        }
+        count++;
+    }
+
+    BOOST_REQUIRE_EQUAL(4u, count);
+}
+
+BOOST_AUTO_TEST_CASE(TestFlagsForPairedReadsFromFastQ) {
+
+    CNcbiIfstream istr("data/paired_reads.fastq");
+    BOOST_REQUIRE(istr);
+    unordered_map<string, int> ref_flags = {
+        {"lcl|pair1", eFirstSegment},
+        {"lcl|pair2", eLastSegment},
+        {"lcl|incomplete1.1", fFirstSegmentFlag | fPartialFlag},
+        {"lcl|incomplete2.2", fLastSegmentFlag | fPartialFlag}
+    };
+    
+    CShortReadFastaInputSource input_source(istr, 1000,
+                                         CShortReadFastaInputSource::eFastq,
+                                         true, true);
+
+    CRef<CBioseq_set> queries(new CBioseq_set);
+    input_source.GetNextNumSequences(*queries, 0);
+    // input file contains six sequences, but two should have been rejected
+    // in screening
+    BOOST_REQUIRE_EQUAL(queries->GetSeq_set().size(), 4u);
+
+    size_t count = 0;
+    for (auto it : queries->GetSeq_set()) {
+        string id = it->GetSeq().GetFirstId()->AsFastaString();
+        int flags = s_GetSegmentFlags(it->GetSeq());
+        int expected = ref_flags.at(id);
+
+        BOOST_REQUIRE_MESSAGE(flags == expected, (string)"Segment flag for " +
+                id + " is different from expected " +
+                NStr::IntToString(flags) + " != " +
+                NStr::IntToString(expected));
+        count++;
+    }
+
+    BOOST_REQUIRE_EQUAL(ref_flags.size(), count);
+}
+
+BOOST_AUTO_TEST_CASE(TestPairedFlagsForPairedReadsFromTwoFastQFiles) {
+
+    CNcbiIfstream istr1("data/paired_reads_1.fastq");
+    CNcbiIfstream istr2("data/paired_reads_2.fastq");
+    BOOST_REQUIRE(istr1);
+    BOOST_REQUIRE(istr2);
+    unordered_map<string, int> ref_flags = {
+        {"lcl|pair1", eFirstSegment},
+        {"lcl|pair2", eLastSegment},
+        {"lcl|incomplete1.1", fFirstSegmentFlag | fPartialFlag},
+        {"lcl|incomplete2.2", fLastSegmentFlag | fPartialFlag}
+    };
+    
+    CShortReadFastaInputSource input_source(istr1, istr2, 1000,
+                                         CShortReadFastaInputSource::eFastq,
+                                         true);
+
+    CRef<CBioseq_set> queries(new CBioseq_set);
+    input_source.GetNextNumSequences(*queries, 0);
+    // input file contains six sequences, but two should have been rejected
+    // in screening
+    BOOST_REQUIRE_EQUAL(queries->GetSeq_set().size(), 4u);
+
+    size_t count = 0;
+    for (auto it : queries->GetSeq_set()) {
+        string id = it->GetSeq().GetFirstId()->AsFastaString();
+        int flags = s_GetSegmentFlags(it->GetSeq());
+        int expected = ref_flags.at(id);
+
+        BOOST_REQUIRE_MESSAGE(flags == expected, (string)"Segment flag for " +
+                id + " is different from expected " +
+                NStr::IntToString(flags) + " != " +
+                NStr::IntToString(expected));
+        count++;
+    }
+
+    BOOST_REQUIRE_EQUAL(ref_flags.size(), count);
+}
+
+
+
+
+BOOST_AUTO_TEST_CASE(TestFlagsForPairedReadsFromASN1) {
+
+    CNcbiIfstream istr("data/paired_reads.asn");
+    BOOST_REQUIRE(istr);
+    unordered_map<string, int> ref_flags = {
+        {"lcl|pair1", eFirstSegment},
+        {"lcl|pair2", eLastSegment},
+        {"lcl|incomplete1.1", fFirstSegmentFlag | fPartialFlag},
+        {"lcl|incomplete2.2", fLastSegmentFlag | fPartialFlag}
+    };
+    
+    CASN1InputSourceOMF input_source(istr, 1000, false, true, true);
+
+    CRef<CBioseq_set> queries(new CBioseq_set);
+    input_source.GetNextNumSequences(*queries, 0);
+    // input file contains six sequences, but two should have been rejected
+    // in screening
+    BOOST_REQUIRE_EQUAL(queries->GetSeq_set().size(), 4u);
+
+    size_t count = 0;
+    for (auto it : queries->GetSeq_set()) {
+        string id = it->GetSeq().GetFirstId()->AsFastaString();
+        int flags = s_GetSegmentFlags(it->GetSeq());
+        int expected = ref_flags.at(id);
+
+        BOOST_REQUIRE_MESSAGE(flags == expected, (string)"Segment flag for " +
+                id + " is different from expected " +
+                NStr::IntToString(flags) + " != " +
+                NStr::IntToString(expected));
+        count++;
+    }
+
+    BOOST_REQUIRE_EQUAL(ref_flags.size(), count);
+}
+
+BOOST_AUTO_TEST_CASE(TestPairedFlagsForPairedReadsFromTwoASN1Files) {
+
+    CNcbiIfstream istr1("data/paired_reads_1.asn");
+    CNcbiIfstream istr2("data/paired_reads_2.asn");
+    BOOST_REQUIRE(istr1);
+    BOOST_REQUIRE(istr2);
+    unordered_map<string, int> ref_flags = {
+        {"lcl|pair1", eFirstSegment},
+        {"lcl|pair2", eLastSegment},
+        {"lcl|incomplete1.1", fFirstSegmentFlag | fPartialFlag},
+        {"lcl|incomplete2.2", fLastSegmentFlag | fPartialFlag}
+    };
+    
+    CASN1InputSourceOMF input_source(istr1, istr2, 1000, false, true);
+
+    CRef<CBioseq_set> queries(new CBioseq_set);
+    input_source.GetNextNumSequences(*queries, 0);
+    // input file contains six sequences, but two should have been rejected
+    // in screening
+    BOOST_REQUIRE_EQUAL(queries->GetSeq_set().size(), 4u);
+
+    size_t count = 0;
+    for (auto it : queries->GetSeq_set()) {
+        string id = it->GetSeq().GetFirstId()->AsFastaString();
+        int flags = s_GetSegmentFlags(it->GetSeq());
+        int expected = ref_flags.at(id);
+
+        BOOST_REQUIRE_MESSAGE(flags == expected, (string)"Segment flag for " +
+                id + " is different from expected " +
+                NStr::IntToString(flags) + " != " +
+                NStr::IntToString(expected));
+        count++;
+    }
+
+    BOOST_REQUIRE_EQUAL(ref_flags.size(), count);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // end of short_reads test suite
+
+
 BOOST_AUTO_TEST_SUITE(blastargs)
 
 /// Auxiliary class to convert a string into an argument count and vector
diff --git a/c++/src/algo/blast/blastinput/unit_test/data/paired_reads.asn b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads.asn
new file mode 100644
index 0000000..e984b26
--- /dev/null
+++ b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads.asn
@@ -0,0 +1,84 @@
+Seq-entry ::= seq {
+  id {
+    local str "pair1"
+  },
+  descr {
+    title "HWI-ST330:273:C19UAACXX:1:1307:6147:73672"
+  },
+  inst {
+    repr raw,
+    mol na,
+    length 67,
+    seq-data iupacna "GAATGTCCGTCTGGGTCTCCTTGTGCTGCGGTCCTGGCAACTCGTAGAATTTCTTACCAAAGTATCG"
+  }
+}
+Seq-entry ::= seq {
+  id {
+    local str "pair2"
+  },
+  descr {
+    title "HWI-ST330:273:C19UAACXX:1:1307:6147:73672"
+  },
+  inst {
+    repr raw,
+    mol na,
+    length 67,
+    seq-data iupacna "GAATGTCCGTCTGGGTCTCCTTGTGCTGCGGTCCTGGCAACTCGTAGAATTTCTTACCAAAGTATCG"
+  }
+}
+Seq-entry ::= seq {
+  id {
+    local str "incomplete1.1"
+  },
+  descr {
+    title "HWI-ST330:273:C19UAACXX:1:1307:6147:73672"
+  },
+  inst {
+    repr raw,
+    mol na,
+    length 67,
+    seq-data iupacna "GAATGTCCGTCTGGGTCTCCTTGTGCTGCGGTCCTGGCAACTCGTAGAATTTCTTACCAAAGTATCG"
+  }
+}
+Seq-entry ::= seq {
+  id {
+    local str "incomplete1.2"
+  },
+  descr {
+    title "HWI-ST330:273:C19UAACXX:1:1307:6147:73672"
+  },
+  inst {
+    repr raw,
+    mol na,
+    length 66,
+    seq-data iupacna "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
+  }
+}
+Seq-entry ::= seq {
+  id {
+    local str "incomplete2.1"
+  },
+  descr {
+    title "HWI-ST330:273:C19UAACXX:1:1307:6147:73672"
+  },
+  inst {
+    repr raw,
+    mol na,
+    length 66,
+    seq-data iupacna "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
+  }
+}
+Seq-entry ::= seq {
+  id {
+    local str "incomplete2.2"
+  },
+  descr {
+    title "HWI-ST330:273:C19UAACXX:1:1307:6147:73672"
+  },
+  inst {
+    repr raw,
+    mol na,
+    length 67,
+    seq-data iupacna "GAATGTCCGTCTGGGTCTCCTTGTGCTGCGGTCCTGGCAACTCGTAGAATTTCTTACCAAAGTATCG"
+  }
+}
diff --git a/c++/src/algo/blast/blastinput/unit_test/data/paired_reads.fa b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads.fa
new file mode 100644
index 0000000..491555f
--- /dev/null
+++ b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads.fa
@@ -0,0 +1,12 @@
+>pair1  (both are read)
+GAATGTCCGTCTGGGTCTCCTTGTGCTGCGGTCCTGGCAACTCGTAGAATTTCTTACCAAAGTATCGATCCGGGAGATAGTACGATGGATACTCCGCCCTCAGCCTCTCG
+>pair2
+ATGTTTTCCGATCCCGCCCAGGAGTCGGTTGCCACGCAGACGGAGGCACAACCGGTTCCGTCGCCCATCTGCACCCCACTGCTGATGGTGGACGAGGATGGACGAAAGCG
+>incomplete1.1  (only the first is accepted)
+ATGTTTTCCGATCCCGCCCAGGAGTCGGTTGCCACGCAGACGGAGGCACAACCGGTTCCGTCGCCCATCTGCACCCCACTGCTGATGGTGGACGAGGATGGACGAAAGCG
+>incomplete1.2
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+>incomplete2.1   (only the second is accepted)
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+>incomplete2.2
+ATGTTTTCCGATCCCGCCCAGGAGTCGGTTGCCACGCAGACGGAGGCACAACCGGTTCCGTCGCCCATCTGCACCCCACTGCTGATGGTGGACGAGGATGGACGAAAGCG
diff --git a/c++/src/algo/blast/blastinput/unit_test/data/paired_reads.fastq b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads.fastq
new file mode 100644
index 0000000..74c1c40
--- /dev/null
+++ b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads.fastq
@@ -0,0 +1,24 @@
+ at pair1  (both are read)
+GAATGTCCGTCTGGGTCTCCTTGTGCTGCGGTCCTGGCAACTCGTAGAATTTCTTACCAAAGTATCGATCCGGGAGATAGTACGATGGATACTCCGCCCTCAGCCTCTCG
++pair1
+BBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFF<FFFFFFFFFFFFFFFFBFFFFF<FFFFFFFFFFFFFFFFFFFFFFFF
+ at pair2
+ATGTTTTCCGATCCCGCCCAGGAGTCGGTTGCCACGCAGACGGAGGCACAACCGGTTCCGTCGCCCATCTGCACCCCACTGCTGATGGTGGACGAGGATGGACGAAAGCG
++pair2
+BBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFF<FFFFFFFFFFFFFFFFBFFFFF<FFFFFFFFFFFFFFFFFFFFFFFF
+ at incomplete1.1  (only the first is accepted)
+ATGTTTTCCGATCCCGCCCAGGAGTCGGTTGCCACGCAGACGGAGGCACAACCGGTTCCGTCGCCCATCTGCACCCCACTGCTGATGGTGGACGAGGATGGACGAAAGCG
++incomplete1.1
+BBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFF<FFFFFFFFFFFFFFFFBFFFFF<FFFFFFFFFFFFFFFFFFFFFFFF
+ at incomplete1.2
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
++incomplete1.2
+BBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFF<FFFFFFFFFFFFFFFFBFFFFFF
+ at incomplete2.1   (only the second is accepted)
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
++incomplete2.1
+BBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFF<FFFFFFFFFFFFFFFFBFFFFFF
+ at incomplete2.2
+ATGTTTTCCGATCCCGCCCAGGAGTCGGTTGCCACGCAGACGGAGGCACAACCGGTTCCGTCGCCCATCTGCACCCCACTGCTGATGGTGGACGAGGATGGACGAAAGCG
++incomplete2.2
+BBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFF<FFFFFFFFFFFFFFFFBFFFFF<FFFFFFFFFFFFFFFFFFFFFFFF
diff --git a/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_1.asn b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_1.asn
new file mode 100644
index 0000000..f1936ce
--- /dev/null
+++ b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_1.asn
@@ -0,0 +1,42 @@
+Seq-entry ::= seq {
+  id {
+    local str "pair1"
+  },
+  descr {
+    title "HWI-ST330:273:C19UAACXX:1:1307:6147:73672"
+  },
+  inst {
+    repr raw,
+    mol na,
+    length 67,
+    seq-data iupacna "GAATGTCCGTCTGGGTCTCCTTGTGCTGCGGTCCTGGCAACTCGTAGAATTTCTTACCAAAGTATCG"
+  }
+}
+Seq-entry ::= seq {
+  id {
+    local str "incomplete1.1"
+  },
+  descr {
+    title "HWI-ST330:273:C19UAACXX:1:1307:6147:73672"
+  },
+  inst {
+    repr raw,
+    mol na,
+    length 67,
+    seq-data iupacna "GAATGTCCGTCTGGGTCTCCTTGTGCTGCGGTCCTGGCAACTCGTAGAATTTCTTACCAAAGTATCG"
+  }
+}
+Seq-entry ::= seq {
+  id {
+    local str "incomplete2.1"
+  },
+  descr {
+    title "HWI-ST330:273:C19UAACXX:1:1307:6147:73672"
+  },
+  inst {
+    repr raw,
+    mol na,
+    length 66,
+    seq-data iupacna "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
+  }
+}
diff --git a/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_1.fa b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_1.fa
new file mode 100644
index 0000000..506fb11
--- /dev/null
+++ b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_1.fa
@@ -0,0 +1,6 @@
+>pair1  (both are read)
+GAATGTCCGTCTGGGTCTCCTTGTGCTGCGGTCCTGGCAACTCGTAGAATTTCTTACCAAAGTATCGATCCGGGAGATAGTACGATGGATACTCCGCCCTCAGCCTCTCG
+>incomplete1.1  (only the first is accepted)
+ATGTTTTCCGATCCCGCCCAGGAGTCGGTTGCCACGCAGACGGAGGCACAACCGGTTCCGTCGCCCATCTGCACCCCACTGCTGATGGTGGACGAGGATGGACGAAAGCG
+>incomplete2.1   (only the second is accepted)
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
diff --git a/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_1.fastq b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_1.fastq
new file mode 100644
index 0000000..c516751
--- /dev/null
+++ b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_1.fastq
@@ -0,0 +1,12 @@
+ at pair1  (both are read)
+GAATGTCCGTCTGGGTCTCCTTGTGCTGCGGTCCTGGCAACTCGTAGAATTTCTTACCAAAGTATCGATCCGGGAGATAGTACGATGGATACTCCGCCCTCAGCCTCTCG
++pair1
+BBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFF<FFFFFFFFFFFFFFFFBFFFFF<FFFFFFFFFFFFFFFFFFFFFFFF
+ at incomplete1.1  (only the first is accepted)
+ATGTTTTCCGATCCCGCCCAGGAGTCGGTTGCCACGCAGACGGAGGCACAACCGGTTCCGTCGCCCATCTGCACCCCACTGCTGATGGTGGACGAGGATGGACGAAAGCG
++incomplete1.1
+BBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFF<FFFFFFFFFFFFFFFFBFFFFF<FFFFFFFFFFFFFFFFFFFFFFFF
+ at incomplete2.1   (only the second is accepted)
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
++incomplete2.1
+BBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFF<FFFFFFFFFFFFFFFFBFFFFFF
diff --git a/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_2.asn b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_2.asn
new file mode 100644
index 0000000..068d6d3
--- /dev/null
+++ b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_2.asn
@@ -0,0 +1,42 @@
+Seq-entry ::= seq {
+  id {
+    local str "pair2"
+  },
+  descr {
+    title "HWI-ST330:273:C19UAACXX:1:1307:6147:73672"
+  },
+  inst {
+    repr raw,
+    mol na,
+    length 67,
+    seq-data iupacna "GAATGTCCGTCTGGGTCTCCTTGTGCTGCGGTCCTGGCAACTCGTAGAATTTCTTACCAAAGTATCG"
+  }
+}
+Seq-entry ::= seq {
+  id {
+    local str "incomplete1.2"
+  },
+  descr {
+    title "HWI-ST330:273:C19UAACXX:1:1307:6147:73672"
+  },
+  inst {
+    repr raw,
+    mol na,
+    length 66,
+    seq-data iupacna "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
+  }
+}
+Seq-entry ::= seq {
+  id {
+    local str "incomplete2.2"
+  },
+  descr {
+    title "HWI-ST330:273:C19UAACXX:1:1307:6147:73672"
+  },
+  inst {
+    repr raw,
+    mol na,
+    length 67,
+    seq-data iupacna "GAATGTCCGTCTGGGTCTCCTTGTGCTGCGGTCCTGGCAACTCGTAGAATTTCTTACCAAAGTATCG"
+  }
+}
diff --git a/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_2.fa b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_2.fa
new file mode 100644
index 0000000..420b8d9
--- /dev/null
+++ b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_2.fa
@@ -0,0 +1,6 @@
+>pair2
+ATGTTTTCCGATCCCGCCCAGGAGTCGGTTGCCACGCAGACGGAGGCACAACCGGTTCCGTCGCCCATCTGCACCCCACTGCTGATGGTGGACGAGGATGGACGAAAGCG
+>incomplete1.2
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+>incomplete2.2
+ATGTTTTCCGATCCCGCCCAGGAGTCGGTTGCCACGCAGACGGAGGCACAACCGGTTCCGTCGCCCATCTGCACCCCACTGCTGATGGTGGACGAGGATGGACGAAAGCG
diff --git a/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_2.fastq b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_2.fastq
new file mode 100644
index 0000000..09c728e
--- /dev/null
+++ b/c++/src/algo/blast/blastinput/unit_test/data/paired_reads_2.fastq
@@ -0,0 +1,12 @@
+ at pair2
+ATGTTTTCCGATCCCGCCCAGGAGTCGGTTGCCACGCAGACGGAGGCACAACCGGTTCCGTCGCCCATCTGCACCCCACTGCTGATGGTGGACGAGGATGGACGAAAGCG
++pair2
+BBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFF<FFFFFFFFFFFFFFFFBFFFFF<FFFFFFFFFFFFFFFFFFFFFFFF
+ at incomplete1.2
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
++incomplete1.2
+BBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFF<FFFFFFFFFFFFFFFFBFFFFFF
+ at incomplete2.2
+ATGTTTTCCGATCCCGCCCAGGAGTCGGTTGCCACGCAGACGGAGGCACAACCGGTTCCGTCGCCCATCTGCACCCCACTGCTGATGGTGGACGAGGATGGACGAAAGCG
++incomplete2.2
+BBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFBFFFF<FFFFFFFFFFFFFFFFBFFFFF<FFFFFFFFFFFFFFFFFFFFFFFF
diff --git a/c++/src/algo/blast/composition_adjustment/compo_heap.c b/c++/src/algo/blast/composition_adjustment/compo_heap.c
index 79250b3..0c4a3fd 100644
--- a/c++/src/algo/blast/composition_adjustment/compo_heap.c
+++ b/c++/src/algo/blast/composition_adjustment/compo_heap.c
@@ -29,11 +29,6 @@
  * @author E. Michael Gertz, Alejandro Schaffer
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: compo_heap.c 124526 2008-04-15 15:27:44Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <assert.h>
 #include <algo/blast/core/ncbi_std.h>
 #include <algo/blast/composition_adjustment/compo_heap.h>
diff --git a/c++/src/algo/blast/composition_adjustment/compo_mode_condition.c b/c++/src/algo/blast/composition_adjustment/compo_mode_condition.c
index 9bc0cbb..07c2631 100644
--- a/c++/src/algo/blast/composition_adjustment/compo_mode_condition.c
+++ b/c++/src/algo/blast/composition_adjustment/compo_mode_condition.c
@@ -30,11 +30,6 @@
  * Authors: Alejandro Schaffer, Yi-Kuo Yu
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: compo_mode_condition.c 112888 2007-10-25 15:34:02Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/ncbi_std.h>
 #include <algo/blast/composition_adjustment/composition_adjustment.h>
 #include <algo/blast/composition_adjustment/compo_mode_condition.h>
diff --git a/c++/src/algo/blast/composition_adjustment/composition_adjustment.c b/c++/src/algo/blast/composition_adjustment/composition_adjustment.c
index 83ec1cd..26e9fe5 100644
--- a/c++/src/algo/blast/composition_adjustment/composition_adjustment.c
+++ b/c++/src/algo/blast/composition_adjustment/composition_adjustment.c
@@ -28,10 +28,6 @@
  *
  * @author Yi-Kuo Yu, Alejandro Schaffer, E. Michael Gertz
  */
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: composition_adjustment.c 500367 2016-05-04 12:06:01Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 #include <limits.h>
 #include <assert.h>
@@ -1177,11 +1173,23 @@ Blast_ReadAaComposition(Blast_AminoAcidComposition * composition,
         prob[i] = 0.0;
     }
     for (i = 0;  i < length;  i++) {
-        if (alphaConvert[sequence[i]] >= 0) {
+        if (alphaConvert[sequence[i]] >= 0 || sequence[i] == eSelenocysteine) {
             prob[sequence[i]]++;
             numTrueAminoAcids++;
         }
     }
+
+    /* Count Selenocysteine (U) as if it was Cysteine (C) to avoid a result
+       where C aligned to U is scored higher than C aligned to C. Otherwise,
+       because U is not counted as a true amino acid, sequences with U would
+       appear more complex than those composed only of the 20 "true" amino
+       acids. Therefore computationally adjusted alignment score would be
+       larger for sequences containing U than for sequences with C. */
+    if (prob[eSelenocysteine] > 0.0) {
+        prob[eCchar] += prob[eSelenocysteine];
+        prob[eSelenocysteine] = 0.0;
+    }
+
     composition->numTrueAminoAcids = numTrueAminoAcids;
     if (numTrueAminoAcids > 0) {
         for (i = 0;  i < alphsize;  i++) {
diff --git a/c++/src/algo/blast/composition_adjustment/matrix_frequency_data.c b/c++/src/algo/blast/composition_adjustment/matrix_frequency_data.c
index 9ed0e7d..4b17900 100644
--- a/c++/src/algo/blast/composition_adjustment/matrix_frequency_data.c
+++ b/c++/src/algo/blast/composition_adjustment/matrix_frequency_data.c
@@ -27,10 +27,6 @@
  *
  * @author Yi-Kuo Yu, Alejandro Schaffer, E. Michael Gertz
  */
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: matrix_frequency_data.c 439568 2014-07-01 16:13:36Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 #include <stdlib.h>
 #include <algo/blast/core/ncbi_std.h>
diff --git a/c++/src/algo/blast/composition_adjustment/nlm_linear_algebra.c b/c++/src/algo/blast/composition_adjustment/nlm_linear_algebra.c
index c192884..f609138 100644
--- a/c++/src/algo/blast/composition_adjustment/nlm_linear_algebra.c
+++ b/c++/src/algo/blast/composition_adjustment/nlm_linear_algebra.c
@@ -27,10 +27,6 @@
  *
  * @author E. Michael Gertz
  */
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: nlm_linear_algebra.c 138123 2008-08-21 19:28:07Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 #include <math.h>
 #include <stdlib.h>
diff --git a/c++/src/algo/blast/composition_adjustment/optimize_target_freq.c b/c++/src/algo/blast/composition_adjustment/optimize_target_freq.c
index 3b28b13..e271ecb 100644
--- a/c++/src/algo/blast/composition_adjustment/optimize_target_freq.c
+++ b/c++/src/algo/blast/composition_adjustment/optimize_target_freq.c
@@ -82,10 +82,6 @@
  *
  * @author E. Michael Gertz
  */
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: optimize_target_freq.c 74455 2005-12-19 15:38:01Z gertz $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 #include <string.h>
 #include <assert.h>
diff --git a/c++/src/algo/blast/composition_adjustment/redo_alignment.c b/c++/src/algo/blast/composition_adjustment/redo_alignment.c
index 93e914b..4d09c34 100644
--- a/c++/src/algo/blast/composition_adjustment/redo_alignment.c
+++ b/c++/src/algo/blast/composition_adjustment/redo_alignment.c
@@ -29,10 +29,6 @@
  *
  * @author Alejandro Schaffer, E. Michael Gertz
  */
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: redo_alignment.c 496008 2016-03-23 11:29:15Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 #include <stdlib.h>
 #include <assert.h>
@@ -139,7 +135,6 @@ BlastCompo_AlignmentsFree(BlastCompo_Alignment ** palign,
         /* Save the value of align->next, because align is to be deleted. */
         BlastCompo_Alignment * align_next = align->next;
 
-        align_next = align->next;
         if (free_context != NULL && align->context != NULL) {
             free_context(align->context);
         }
@@ -626,6 +621,17 @@ s_SubjectCompareWindows(const void * vp1, const void *vp2)
     return result;
 }
 
+static
+int s_GetTranslatedLength(int length,int frame, int is_pos_based) {
+	if(is_pos_based) {
+		int f = GET_SEQ_FRAME(frame);
+		int nucl_length = GET_NUCL_LENGTH(length);
+		return GET_TRANSLATED_LENGTH(nucl_length, f);
+	}
+
+	return	((length - ABS(frame) + 1)/3);
+}
+
 /**
  * Read a list of alignments from a translated search and create a
  * new array of pointers to s_WindowInfo so that each alignment is
@@ -639,7 +645,7 @@ s_WindowsFromTranslatedAligns(BlastCompo_Alignment * alignments,
                               BlastCompo_QueryInfo * query_info,
                               int hspcnt, int border, int sequence_length,
                               s_WindowInfo ***pwindows, int * nWindows,
-                              int subject_is_translated)
+                              int subject_is_translated, int is_pos_based)
 {
     int k;                            /* iteration index */
     s_WindowInfo ** windows;      /* the output list of windows */
@@ -649,10 +655,10 @@ s_WindowsFromTranslatedAligns(BlastCompo_Alignment * alignments,
                                          alignment in the main loop */
     *nWindows = 0;
     windows = *pwindows = calloc(hspcnt, sizeof(s_WindowInfo*));
-    *nWindows = hspcnt;
     if (windows == NULL)
         goto error_return;
 
+    *nWindows = hspcnt;
     for (align = alignments, k = 0;
          align != NULL;
          align = align->next, k++) {
@@ -669,7 +675,7 @@ s_WindowsFromTranslatedAligns(BlastCompo_Alignment * alignments,
         frame = align->frame;
         query_index = align->queryIndex;
         query_length = query_info[query_index].seq.length;
-        translated_length = (sequence_length - ABS(frame) + 1)/3;
+        translated_length = s_GetTranslatedLength(sequence_length, frame, is_pos_based);
 
         align_copy = s_AlignmentCopy(align);
         if (align_copy == NULL)
@@ -744,11 +750,14 @@ s_WindowsFromTranslatedAligns(BlastCompo_Alignment * alignments,
     return 0; /* normal return */
 
 error_return:
-    for (k = 0; k < *nWindows; k++) {
-        if (windows[k] != NULL)
-            s_WindowInfoFree(&windows[k]);
+    if (windows)
+    {
+    	for (k = 0; k < *nWindows; k++) {
+       	 if (windows[k] != NULL)
+       	     s_WindowInfoFree(&windows[k]);
+    	}
+    	free(windows);
     }
-    free(windows);
     *pwindows = NULL;
     return -1;
 }
@@ -812,8 +821,10 @@ s_WindowsFromProteinAligns(BlastCompo_Alignment * alignments,
     }
     /* shrink to fit */
     {
-        s_WindowInfo ** new_windows =
-            realloc(windows, window_index * sizeof(s_WindowInfo*));
+        s_WindowInfo ** new_windows = NULL;
+	if (window_index > 0)
+            new_windows = realloc(windows, window_index * sizeof(s_WindowInfo*));
+
         if (new_windows == NULL) {
             goto error_return;
         } else {
@@ -863,19 +874,19 @@ s_WindowsFromAligns(BlastCompo_Alignment * alignments,
                 BlastCompo_QueryInfo * query_info, int hspcnt,
                 int numQueries, int border, int sequence_length,
                 s_WindowInfo ***pwindows, int * nWindows,
-                int query_is_translated, int subject_is_translated)
+                int query_is_translated, int subject_is_translated, int is_pos_based)
 {
     if (subject_is_translated || query_is_translated) {
         return s_WindowsFromTranslatedAligns(alignments, query_info,
                                              hspcnt, border,
                                              sequence_length,
                                              pwindows, nWindows,
-                                             subject_is_translated);
+                                             subject_is_translated, is_pos_based);
     } else {
         return s_WindowsFromProteinAligns(alignments, query_info,
                                           numQueries, sequence_length,
                                           pwindows, nWindows);
-    }
+   }
 }
 
 
@@ -909,7 +920,6 @@ s_GetComposition(Blast_AminoAcidComposition * composition,
 
     data = seq->data;
     length = range->end - range->begin;
-
     if (query_is_translated || subject_is_translated) {
         int start;
         int end;
@@ -1125,7 +1135,7 @@ Blast_RedoOneMatch(BlastCompo_Alignment ** alignments,
     status =
             s_WindowsFromAligns(incoming_aligns, query_info, hspcnt, numQueries,
                     kWindowBorder, matchingSeq->length, &windows,
-                    &nWindows, query_is_translated, subject_is_translated);
+                    &nWindows, query_is_translated, subject_is_translated, params->positionBased);
     if (status != 0) {
         goto function_level_cleanup;
     }
@@ -1246,8 +1256,6 @@ Blast_RedoOneMatch(BlastCompo_Alignment ** alignments,
                     num_adjustments++;
                 }
 
-                // By this point there's a discrepancy in
-                //  gapping_params->context->gap_align->sbp->matrix->data
                 if ( !adjust_search_failed ) {
                     newAlign = callbacks->redo_one_alignment(
                             in_align,
@@ -1346,7 +1354,7 @@ Blast_RedoOneMatchSmithWaterman(BlastCompo_Alignment ** alignments,
     status =
         s_WindowsFromAligns(incoming_aligns, query_info, hspcnt, numQueries,
                             kWindowBorder, matchingSeq->length, &windows,
-                            &nWindows, query_is_translated, subject_is_translated);
+                            &nWindows, query_is_translated, subject_is_translated, params->positionBased);
     if (status != 0)
         goto function_level_cleanup;
     /* We are performing a Smith-Waterman alignment */
diff --git a/c++/src/algo/blast/composition_adjustment/smith_waterman.c b/c++/src/algo/blast/composition_adjustment/smith_waterman.c
index 644c43c..17af751 100644
--- a/c++/src/algo/blast/composition_adjustment/smith_waterman.c
+++ b/c++/src/algo/blast/composition_adjustment/smith_waterman.c
@@ -28,10 +28,6 @@
  *
  * @author Alejandro Schaffer, E. Michael Gertz
  */
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: smith_waterman.c 85238 2006-06-29 16:50:24Z gertz $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 #include <algo/blast/core/ncbi_std.h>
 #include <algo/blast/composition_adjustment/composition_constants.h>
diff --git a/c++/src/algo/blast/composition_adjustment/unified_pvalues.c b/c++/src/algo/blast/composition_adjustment/unified_pvalues.c
index 2b63025..0f7c530 100644
--- a/c++/src/algo/blast/composition_adjustment/unified_pvalues.c
+++ b/c++/src/algo/blast/composition_adjustment/unified_pvalues.c
@@ -29,10 +29,6 @@
  *
  * @author Yi-Kuo Yu, Alejandro Schaffer, Mike Gertz
  */
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: unified_pvalues.c 86217 2006-07-17 17:18:48Z gertz $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/c++/src/algo/blast/core/Makefile.blast.lib b/c++/src/algo/blast/core/Makefile.blast.lib
index 574ebb9..8a8a127 100644
--- a/c++/src/algo/blast/core/Makefile.blast.lib
+++ b/c++/src/algo/blast/core/Makefile.blast.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.blast.lib 498856 2016-04-20 11:37:59Z ivanov $
+# $Id: Makefile.blast.lib 504861 2016-06-20 15:45:40Z boratyng $
 
 SRC_C = aa_ungapped blast_diagnostics blast_engine blast_extend \
         blast_filter blast_gapalign blast_hits blast_hspstream blast_itree \
@@ -11,8 +11,9 @@ SRC_C = aa_ungapped blast_diagnostics blast_engine blast_extend \
         ncbi_std ncbi_math blast_encoding pattern phi_extend phi_gapalign \
         phi_lookup blast_parameters blast_posit blast_program blast_query_info \
         blast_tune blast_sw blast_dynarray split_query gencode_singleton \
-        index_ungapped blast_traceback_mt_priv blast_hspstream_mt_utils boost_erf
-    
+        index_ungapped blast_traceback_mt_priv blast_hspstream_mt_utils boost_erf \
+        jumper hspfilter_mapper
+
 SRC   = $(SRC_C)
 
 LIB = blast
@@ -20,7 +21,6 @@ LIB = blast
 #CFLAGS  = $(FAST_CFLAGS)  -pedantic -std=c99 -Wall -W -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wundef -Winline -Wno-parentheses
 CFLAGS  = $(FAST_CFLAGS)
 LDFLAGS = $(FAST_LDFLAGS)
-
 WATCHERS = madden camacho fongah2
 
 
diff --git a/c++/src/algo/blast/core/aa_ungapped.c b/c++/src/algo/blast/core/aa_ungapped.c
index a98f976..f650aee 100644
--- a/c++/src/algo/blast/core/aa_ungapped.c
+++ b/c++/src/algo/blast/core/aa_ungapped.c
@@ -1,4 +1,4 @@
-/* $Id: aa_ungapped.c 419638 2013-11-27 14:48:24Z boratyng $
+/* $Id: aa_ungapped.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -28,11 +28,6 @@
  * Functions to iterate over seed hits and perform ungapped extensions.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: aa_ungapped.c 419638 2013-11-27 14:48:24Z boratyng $";
-#endif                          /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/aa_ungapped.h>
 #include <algo/blast/core/blast_aalookup.h>
 #include <algo/blast/core/blast_aascan.h>
diff --git a/c++/src/algo/blast/core/blast_aalookup.c b/c++/src/algo/blast/core/blast_aalookup.c
index 8961a75..151c628 100644
--- a/c++/src/algo/blast/core/blast_aalookup.c
+++ b/c++/src/algo/blast/core/blast_aalookup.c
@@ -1,4 +1,4 @@
-/* $Id: blast_aalookup.c 464154 2015-04-06 16:36:18Z madden $
+/* $Id: blast_aalookup.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
 #include <algo/blast/core/lookup_util.h>
 #include <algo/blast/core/blast_encoding.h>
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_aalookup.c 464154 2015-04-06 16:36:18Z madden $";
-#endif                          /* SKIP_DOXYGEN_PROCESSING */
-
 /** Structure containing information needed for adding neighboring words. 
  */
 typedef struct NeighborInfo {
diff --git a/c++/src/algo/blast/core/blast_aascan.c b/c++/src/algo/blast/core/blast_aascan.c
index 7a6d4f8..158bd73 100644
--- a/c++/src/algo/blast/core/blast_aascan.c
+++ b/c++/src/algo/blast/core/blast_aascan.c
@@ -1,4 +1,4 @@
-/* $Id: blast_aascan.c 197897 2010-07-23 14:34:13Z maning $
+/* $Id: blast_aascan.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
 #include <algo/blast/core/blast_aalookup.h>
 #include "masksubj.inl"
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_aascan.c 197897 2010-07-23 14:34:13Z maning $";
-#endif                          /* SKIP_DOXYGEN_PROCESSING */
-
 /**
  * Scans the subject sequence from "offset" to the end of the sequence.
  * Copies at most array_size hits.
diff --git a/c++/src/algo/blast/core/blast_diagnostics.c b/c++/src/algo/blast/core/blast_diagnostics.c
index 413c2ac..c1238d5 100644
--- a/c++/src/algo/blast/core/blast_diagnostics.c
+++ b/c++/src/algo/blast/core/blast_diagnostics.c
@@ -1,4 +1,4 @@
-/* $Id: blast_diagnostics.c 303807 2011-06-13 18:22:23Z camacho $
+/* $Id: blast_diagnostics.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  */
 
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_diagnostics.c 303807 2011-06-13 18:22:23Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_diagnostics.h>
 #include <algo/blast/core/blast_def.h>
 
diff --git a/c++/src/algo/blast/core/blast_dynarray.c b/c++/src/algo/blast/core/blast_dynarray.c
index f431d4d..faf1f50 100644
--- a/c++/src/algo/blast/core/blast_dynarray.c
+++ b/c++/src/algo/blast/core/blast_dynarray.c
@@ -1,4 +1,4 @@
-/* $Id: blast_dynarray.c 113776 2007-11-08 22:38:18Z camacho $
+/* $Id: blast_dynarray.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  */
 
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_dynarray.c 113776 2007-11-08 22:38:18Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include "blast_dynarray.h"
 #include <algo/blast/core/blast_util.h>
 #include <algo/blast/core/blast_message.h>  /* for error codes */
diff --git a/c++/src/algo/blast/core/blast_encoding.c b/c++/src/algo/blast/core/blast_encoding.c
index ddd83cc..887b676 100644
--- a/c++/src/algo/blast/core/blast_encoding.c
+++ b/c++/src/algo/blast/core/blast_encoding.c
@@ -1,4 +1,4 @@
-/* $Id: blast_encoding.c 118195 2008-01-24 21:22:19Z camacho $
+/* $Id: blast_encoding.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  * @sa blast_encoding.h
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_encoding.c 118195 2008-01-24 21:22:19Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_encoding.h>
 
 const Uint1 NCBI4NA_TO_BLASTNA[BLASTNA_SIZE] = {
diff --git a/c++/src/algo/blast/core/blast_engine.c b/c++/src/algo/blast/core/blast_engine.c
index a3f0153..1b66173 100644
--- a/c++/src/algo/blast/core/blast_engine.c
+++ b/c++/src/algo/blast/core/blast_engine.c
@@ -1,4 +1,4 @@
-/* $Id: blast_engine.c 500531 2016-05-05 14:28:38Z ivanov $
+/* $Id: blast_engine.c 521263 2016-12-07 15:18:43Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,20 +32,20 @@
  * <pre>
  * Preliminary stage of the BLAST search:
  *
- *    Blast_RunPreliminarySearch 
+ *    Blast_RunPreliminarySearch
  *        BLAST_GapAlignSetUp
  *        BLAST_PreliminarySearchEngine
  *            if (RPS BLAST) {
  *                s_RPSPreliminarySearchEngine
  *                    s_BlastSearchEngineCore
  *            } else {
- *                for (all sequences in the database) 
+ *                for (all sequences in the database)
  *                    s_BlastSearchEngineCore
  *            }
- * 
+ *
  * Full BLAST search, including preliminary search and traceback:
  *
- *    Blast_RunFullSearch 
+ *    Blast_RunFullSearch
  *        BLAST_GapAlignSetUp
  *        BLAST_PreliminarySearchEngine
  *        BLAST_ComputeTraceback
@@ -53,11 +53,6 @@
  * </pre>
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_engine.c 500531 2016-05-05 14:28:38Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_engine.h>
 #include <algo/blast/core/blast_util.h>
 #include <algo/blast/core/blast_aalookup.h>
@@ -83,11 +78,11 @@ static char const rcsid[] =
 #define CONV_NUCL2PROT_COORDINATES(length) (length) / CODON_LENGTH
 
 NCBI_XBLAST_EXPORT const int   kBlastMajorVersion = 2;
-NCBI_XBLAST_EXPORT const int   kBlastMinorVersion = 4;
+NCBI_XBLAST_EXPORT const int   kBlastMinorVersion = 6;
 NCBI_XBLAST_EXPORT const int   kBlastPatchVersion = 0;
-NCBI_XBLAST_EXPORT const char* kBlastReleaseDate = "June-01-2016";
+NCBI_XBLAST_EXPORT const char* kBlastReleaseDate = "January-09-2017";
 
-/** Structure to be passed to s_BlastSearchEngineCore, containing pointers 
+/** Structure to be passed to s_BlastSearchEngineCore, containing pointers
     to various preallocated structures and arrays. */
 typedef struct BlastCoreAuxStruct {
 
@@ -96,24 +91,30 @@ typedef struct BlastCoreAuxStruct {
     BlastWordFinderType WordFinder; /**< Word finder function pointer */
     BlastGetGappedScoreType GetGappedScore; /**< Gapped extension function
                                               pointer */
-    BlastInitHitList* init_hitlist; /**< Placeholder for HSPs after 
+    JumperGappedType JumperGapped; /**< Word finder and gapped extension
+                                      for mapping short reads */
+
+    BlastInitHitList* init_hitlist; /**< Placeholder for HSPs after
                                         ungapped extension */
     BlastOffsetPair* offset_pairs; /**< Array of offset pairs for initial seeds. */
+    MapperWordHits* mapper_wordhits;
+
     Uint1* translation_buffer; /**< Placeholder for translated subject
                                    sequences */
     Uint1* translation_table; /**< Translation table for forward strand */
-    Uint1* translation_table_rc; /**< Translation table for reverse 
+    Uint1* translation_table_rc; /**< Translation table for reverse
                                      strand */
 } BlastCoreAuxStruct;
 
 /** Deallocates all memory in BlastCoreAuxStruct */
-static BlastCoreAuxStruct* 
+static BlastCoreAuxStruct*
 s_BlastCoreAuxStructFree(BlastCoreAuxStruct* aux_struct)
 {
     BlastExtendWordFree(aux_struct->ewp);
     BLAST_InitHitListFree(aux_struct->init_hitlist);
     sfree(aux_struct->offset_pairs);
-    
+    MapperWordHitsFree(aux_struct->mapper_wordhits);
+
     sfree(aux_struct);
     return NULL;
 }
@@ -172,11 +173,11 @@ static void s_BackupSubject(BLAST_SequenceBlk* subject,
         ASSERT (backup->num_seq_ranges >= 1);
         backup->hard_ranges = backup->seq_ranges;
         backup->num_hard_ranges = backup->num_seq_ranges;
-    } 
+    }
 
     backup->offset = backup->hard_ranges[0].left;
     backup->next = backup->offset;
-    subject->chunk = -1; 
+    subject->chunk = -1;
 
 }
 
@@ -219,9 +220,18 @@ const Int2 SUBJECT_SPLIT_NO_RANGE = 2;  /**< return value indicating all masked
 
 static Int2 s_GetNextSubjectChunk(BLAST_SequenceBlk* subject,
                                   SubjectSplitStruct *backup,
-                                  Boolean is_nucleotide)
+                                  Boolean is_nucleotide,
+                                  int chunk_overlap)
 {
     int start, len, i, residual;
+    int dbseq_chunk_overlap;
+
+    if (chunk_overlap > 0) {
+        dbseq_chunk_overlap = chunk_overlap;
+    }
+    else {
+        dbseq_chunk_overlap = DBSEQ_CHUNK_OVERLAP;
+    }
 
     ASSERT(subject);
     ASSERT(backup);
@@ -233,15 +243,15 @@ static Int2 s_GetNextSubjectChunk(BLAST_SequenceBlk* subject,
     subject->sequence = backup->sequence + ((is_nucleotide) ?
                         backup->offset /COMPRESSION_RATIO : backup->offset);
 
-    if (backup->offset + MAX_DBSEQ_LEN < 
+    if (backup->offset + MAX_DBSEQ_LEN <
         backup->hard_ranges[backup->hm_index].right) {
 
         subject->length = MAX_DBSEQ_LEN;
-        backup->next = backup->offset + MAX_DBSEQ_LEN - DBSEQ_CHUNK_OVERLAP;
+        backup->next = backup->offset + MAX_DBSEQ_LEN - dbseq_chunk_overlap;
 
     } else {
 
-        subject->length = backup->hard_ranges[backup->hm_index].right 
+        subject->length = backup->hard_ranges[backup->hm_index].right
                         - backup->offset;
         backup->hm_index++;
         backup->next = (backup->hm_index < backup->num_hard_ranges) ?
@@ -265,7 +275,7 @@ static Int2 s_GetNextSubjectChunk(BLAST_SequenceBlk* subject,
         subject->seq_ranges[0].right = subject->length;
         return SUBJECT_SPLIT_OK;
     }
-      
+
     /* soft masking is on, sequence is chunked, must re-allocate and adjust */
     ASSERT (residual == 0);
     start = backup->offset;
@@ -292,7 +302,7 @@ static Int2 s_GetNextSubjectChunk(BLAST_SequenceBlk* subject,
         subject->seq_ranges[i].right = backup->soft_ranges[i+start].right - backup->offset;
     }
 
-    if (subject->seq_ranges[0].left < 0) 
+    if (subject->seq_ranges[0].left < 0)
         subject->seq_ranges[0].left = 0;
     if (subject->seq_ranges[len-1].right > subject->length)
         subject->seq_ranges[len-1].right = subject->length;
@@ -310,11 +320,11 @@ static Int2 s_GetNextSubjectChunk(BLAST_SequenceBlk* subject,
  *                       tblastn only [in]
  * @param offset Shift in the subject sequence protein coordinates [in]
  */
-static void 
-s_TranslateHSPsToDNAPCoord(EBlastProgramType program, 
-                           BlastInitHitList* init_hitlist, 
+static void
+s_TranslateHSPsToDNAPCoord(EBlastProgramType program,
+                           BlastInitHitList* init_hitlist,
                            const BlastQueryInfo* query_info,
-                           Int2 subject_frame, Int4 subject_length, 
+                           Int2 subject_frame, Int4 subject_length,
                            Int4 offset)
 {
     BlastInitHSP * init_hsp = 0;
@@ -323,28 +333,28 @@ s_TranslateHSPsToDNAPCoord(EBlastProgramType program,
     for(index = 0; index < init_hitlist->total; ++index) {
         BlastContextInfo * contexts = query_info->contexts;
         init_hsp = &init_hitlist->init_hsp_array[index];
-        
+
         if (program == eBlastTypeBlastx) {
             Int4 context_idx    = 0; /* Index of this HSP's context */
             Int4 frame_idx      = 0; /* Index of this frame within set of
                                         frames with same query and sign */
             Int4 init_frame_idx = 0; /* First frame of this query */
             Int4 frame_pos      = 0; /* Start of this frame in DNA */
-           
+
             /* Find context containing this HSP */
-            context_idx = 
-               BSearchContextInfo(init_hsp->offsets.qs_offsets.q_off, 
+            context_idx =
+               BSearchContextInfo(init_hsp->offsets.qs_offsets.q_off,
                                   query_info);
-           
+
             frame_idx = context_idx % CODON_LENGTH;
             init_frame_idx = context_idx - frame_idx;
-           
+
             frame_pos = contexts[init_frame_idx].query_offset + frame_idx;
-           
+
             init_hsp->offsets.qs_offsets.q_off =
                 (init_hsp->offsets.qs_offsets.q_off -
                  contexts[context_idx].query_offset) * CODON_LENGTH + frame_pos;
-           
+
             init_hsp->ungapped_data->q_start =
                 (init_hsp->ungapped_data->q_start -
                  contexts[context_idx].query_offset) * CODON_LENGTH + frame_pos;
@@ -352,18 +362,18 @@ s_TranslateHSPsToDNAPCoord(EBlastProgramType program,
             init_hsp->offsets.qs_offsets.s_off += offset;
             init_hsp->ungapped_data->s_start += offset;
             if (subject_frame > 0) {
-                init_hsp->offsets.qs_offsets.s_off = 
-                    (init_hsp->offsets.qs_offsets.s_off * CODON_LENGTH) + 
+                init_hsp->offsets.qs_offsets.s_off =
+                    (init_hsp->offsets.qs_offsets.s_off * CODON_LENGTH) +
                     subject_frame - 1;
-                init_hsp->ungapped_data->s_start = 
-                    (init_hsp->ungapped_data->s_start * CODON_LENGTH) + 
+                init_hsp->ungapped_data->s_start =
+                    (init_hsp->ungapped_data->s_start * CODON_LENGTH) +
                     subject_frame - 1;
             } else {
-                init_hsp->offsets.qs_offsets.s_off = 
-                    (init_hsp->offsets.qs_offsets.s_off * CODON_LENGTH) + 
+                init_hsp->offsets.qs_offsets.s_off =
+                    (init_hsp->offsets.qs_offsets.s_off * CODON_LENGTH) +
                     subject_length - subject_frame;
-                init_hsp->ungapped_data->s_start = 
-                    (init_hsp->ungapped_data->s_start * CODON_LENGTH) + 
+                init_hsp->ungapped_data->s_start =
+                    (init_hsp->ungapped_data->s_start * CODON_LENGTH) +
                     subject_length - subject_frame;
             }
         }
@@ -372,7 +382,7 @@ s_TranslateHSPsToDNAPCoord(EBlastProgramType program,
 }
 
 /** Set up context offsets for the auxiliary BlastQueryInfo structure that is
- * created for the concatenated database in RPS BLAST search. Calls the public 
+ * created for the concatenated database in RPS BLAST search. Calls the public
  * function OffsetArrayToContextOffsets with a blastp program, because subjects
  * are protein sequences. This guarantees that all frames are set to 0.
  * @param info The preallocated structure [in] [out]
@@ -386,6 +396,133 @@ s_RPSOffsetArrayToContextOffsets(BlastQueryInfo    * info,
     OffsetArrayToContextOffsets(info, new_offsets, kProgram);
 }
 
+static int
+s_CompareHSPsBySubjectEnd(const void* a, const void* b)
+{
+    BlastHSP* h1, * h2;
+    BlastHSP** hp1, ** hp2;
+
+    hp1 = (BlastHSP**)a;
+    hp2 = (BlastHSP**)b;
+    h1 = *hp1;
+    h2 = *hp2;
+
+    if (!h1 && !h2) {
+        return 0;
+    }
+    else if (!h1) {
+        return -1;
+    }
+    else if (!h2) {
+        return 1;
+    }
+
+    if (h1->subject.end < h2->subject.end) {
+        return -1;
+    }
+    else if (h1->subject.end > h2->subject.end) {
+        return 1;
+    }
+
+    return 0;
+}
+
+/* Write HSPs for a single subject chunk to HSP stream, implemented for mapper.
+   A single read may align to several exons that fall in two subject chunks.
+   This is a problem because combining HSPs into exon chains is done for each
+   HSP list write independently.
+   Given the maximum intron length we can write HSPs with positions on the
+   subject too far from subject chunk end to be combined with HSPs aligned to
+   the next subject chunk. */
+static Int2
+s_WriteHSPsForChunk(BlastHSPList* hsp_list,
+                    const SubjectSplitStruct* backup,
+                    const BlastHitSavingParameters* hit_params,
+                    BlastHSPStream* hsp_stream,
+                    Int4 chunk_length,
+                    Int4 full_subject_length)
+{
+    BlastHSP** hsp_array = NULL;
+    BlastHSP** new_hsp_array = NULL;
+    BlastHSPList* hsp_list_to_write = NULL;
+    Int4 max_intron_len;
+    Int4 new_allocated;
+    Int4 last_pos_to_move;
+    Int4 status;
+    Int4 i, n = 0;
+
+    if (!hsp_list || !backup || !hit_params || !hsp_stream) {
+        return -1;
+    }
+
+    if (backup->next >= full_subject_length) {
+        /* HSPs for the last subject chunk will be written to HSP stream at
+           the end of subject processing */
+
+        return 0;
+    }
+
+    max_intron_len = hit_params->options->longest_intron;
+
+    /* HSPs up to this subject offset will be removed from hsp_list and
+       written to HSP stream */
+    /* FIXME: shoule this be until 1 * max_intron_length? */
+    last_pos_to_move = backup->offset + chunk_length - max_intron_len - 1;
+
+    hsp_array = hsp_list->hsp_array;
+
+    /* sort HSPs by subject offset */
+    qsort(hsp_array, hsp_list->hspcnt, sizeof(BlastHSP*),
+          s_CompareHSPsBySubjectEnd);
+
+    /* separate HSPs with subject offset smaller than last chunk position -
+       max intron length */
+    i = 0;
+    while (i < hsp_list->hspcnt &&
+           hsp_array[i]->subject.end < last_pos_to_move) {
+        i++;
+    }
+
+    /* copy HSPs with sbubject positions between max intron lengths and
+       chunk end */
+    new_allocated = hsp_list->hspcnt - i + 1;
+    new_hsp_array = calloc(new_allocated, sizeof(BlastHSP*));
+    if (!new_hsp_array) {
+        return -1;
+    }
+    for (;i < hsp_list->hspcnt;i++) {
+        new_hsp_array[n++] = Blast_HSPClone(hsp_array[i]);
+    }
+    ASSERT(i == hsp_list->hspcnt);
+
+    hsp_list_to_write = Blast_HSPListNew(1);
+    if (!hsp_list_to_write) {
+        return -1;
+    }
+
+    if (hsp_list_to_write->hsp_array) {
+        sfree(hsp_list_to_write->hsp_array);
+    }
+
+    hsp_list_to_write->hsp_array = hsp_array;
+    hsp_list_to_write->hspcnt = hsp_list->hspcnt /*hspcnt_to_write*/;
+    hsp_list_to_write->allocated = hsp_list->allocated;
+    hsp_list_to_write->oid = hsp_list->oid;
+
+    hsp_list->hsp_array = new_hsp_array;
+    hsp_list->hspcnt = n;
+    hsp_list->allocated = new_allocated;
+
+    /* write hsp_list_to_write */
+    status = BlastHSPStreamWrite(hsp_stream, &hsp_list_to_write);
+    if (hsp_list_to_write) {
+        hsp_list_to_write = Blast_HSPListFree(hsp_list_to_write);
+    }
+
+    return status;
+}
+
+
 /** Searches only one context of a database sequence, but does all chunks if it is split.
  * @param program_number BLAST program type [in]
  * @param query Query sequence structure [in]
@@ -395,7 +532,7 @@ s_RPSOffsetArrayToContextOffsets(BlastQueryInfo    * info,
  * @param lookup Lookup table [in]
  * @param gap_align Structure for gapped alignment information [in]
  * @param score_params Scoring parameters [in]
- * @param word_params Initial word finding and ungapped extension 
+ * @param word_params Initial word finding and ungapped extension
  *                    parameters [in]
  * @param ext_params Gapped extension parameters [in]
  * @param hit_params Hit saving parameters [in]
@@ -410,18 +547,19 @@ s_RPSOffsetArrayToContextOffsets(BlastQueryInfo    * info,
  */
 
 static Int2
-s_BlastSearchEngineOneContext(EBlastProgramType program_number, 
-        BLAST_SequenceBlk* query, BlastQueryInfo* query_info, 
-        BLAST_SequenceBlk* subject, Int4 orig_length, LookupTableWrap* lookup, 
-        BlastGapAlignStruct* gap_align, 
-        const BlastScoringParameters* score_params, 
-        const BlastInitialWordParameters* word_params, 
-        const BlastExtensionParameters* ext_params, 
-        const BlastHitSavingParameters* hit_params, 
+s_BlastSearchEngineOneContext(EBlastProgramType program_number,
+        BLAST_SequenceBlk* query, BlastQueryInfo* query_info,
+        BLAST_SequenceBlk* subject, Int4 orig_length, LookupTableWrap* lookup,
+        BlastGapAlignStruct* gap_align,
+        const BlastScoringParameters* score_params,
+        const BlastInitialWordParameters* word_params,
+        const BlastExtensionParameters* ext_params,
+        const BlastHitSavingParameters* hit_params,
         BlastDiagnostics* diagnostics,
         BlastCoreAuxStruct* aux_struct,
         BlastHSPList** hsp_list_out_ptr,
-        TInterruptFnPtr interrupt_search, 
+        BlastHSPStream* hsp_stream,
+        TInterruptFnPtr interrupt_search,
         SBlastProgress* progress_info)
 {
     Int2 status = 0; /* return value */
@@ -434,17 +572,30 @@ s_BlastSearchEngineOneContext(EBlastProgramType program_number,
     Int4 **matrix = (gap_align->positionBased) ?
                      gap_align->sbp->psi_matrix->pssm->data :
                      gap_align->sbp->matrix->data;
-    const Boolean kTranslatedSubject = 
+    const Boolean kTranslatedSubject =
        (Blast_SubjectIsTranslated(program_number) || program_number == eBlastTypeRpsTblastn);
-    const Boolean kNucleotide = (program_number == eBlastTypeBlastn ||
-       program_number == eBlastTypePhiBlastn);
+    const Boolean kNucleotide = Blast_ProgramIsNucleotide(program_number);
     const int kHspNumMax = BlastHspNumMax(score_options->gapped_calculation, hit_params->options);
     const int kScanSubjectOffsetArraySize = GetOffsetArraySize(lookup);
+    Int4 dbseq_chunk_overlap;
     Int4 overlap;
 
-    SubjectSplitStruct backup; 
+    SubjectSplitStruct backup;
     backup.sequence = NULL;
 
+    /* increase overlap on db chunks for mapping to 1.5 times the longest
+       query */
+
+    if (Blast_ProgramIsMapping(program_number) &&
+        (Int4)query_info->max_length < 110) {
+
+        dbseq_chunk_overlap = (Int4)query_info->max_length
+            + (query_info->max_length / 2);
+    }
+    else {
+        dbseq_chunk_overlap = DBSEQ_CHUNK_OVERLAP;
+    }
+
     if (diagnostics) {
         ungapped_stats = diagnostics->ungapped_stat;
         gapped_stats = diagnostics->gapped_stat;
@@ -453,7 +604,9 @@ s_BlastSearchEngineOneContext(EBlastProgramType program_number,
     s_BackupSubject(subject, &backup);
 
     while (TRUE) {
-        status = s_GetNextSubjectChunk(subject, &backup, kNucleotide);
+        status = s_GetNextSubjectChunk(subject, &backup, kNucleotide,
+                                       dbseq_chunk_overlap);
+
         if (status == SUBJECT_SPLIT_DONE) break;
         if (status == SUBJECT_SPLIT_NO_RANGE) continue;
         ASSERT(status == SUBJECT_SPLIT_OK);
@@ -466,9 +619,9 @@ s_BlastSearchEngineOneContext(EBlastProgramType program_number,
         BlastInitHitListReset(init_hitlist);
 
         if (aux_struct->WordFinder) {
-            aux_struct->WordFinder(subject, query, query_info, lookup, matrix, 
-                                   word_params, aux_struct->ewp, 
-                                   aux_struct->offset_pairs, 
+            aux_struct->WordFinder(subject, query, query_info, lookup, matrix,
+                                   word_params, aux_struct->ewp,
+                                   aux_struct->offset_pairs,
                                    kScanSubjectOffsetArraySize,
                                    init_hitlist, ungapped_stats);
 
@@ -478,9 +631,9 @@ s_BlastSearchEngineOneContext(EBlastProgramType program_number,
         if (score_options->gapped_calculation) {
             Int4 prot_length = 0;
             if (score_options->is_ooframe) {
-                /* Convert query offsets in all HSPs into the mixed-frame  
+                /* Convert query offsets in all HSPs into the mixed-frame
                    coordinates */
-                s_TranslateHSPsToDNAPCoord(program_number, init_hitlist, 
+                s_TranslateHSPsToDNAPCoord(program_number, init_hitlist,
                        query_info, subject->frame, orig_length, backup.offset);
             if (kTranslatedSubject) {
                 prot_length = subject->length;
@@ -490,28 +643,47 @@ s_BlastSearchEngineOneContext(EBlastProgramType program_number,
         /** NB: If queries are concatenated, HSP offsets must be adjusted
           * inside the following function call, so coordinates are
           * relative to the individual contexts (i.e. queries, strands or
-          * frames). Contexts should also be filled in HSPs when they 
+          * frames). Contexts should also be filled in HSPs when they
           * are saved.
           */
         /* fence_hit is null, since this is only for prelim stage. */
-        status = aux_struct->GetGappedScore(program_number, query, query_info, 
-                    subject, gap_align, score_params, ext_params, hit_params, 
+        if (aux_struct->GetGappedScore) {
+            status = aux_struct->GetGappedScore(program_number, query,
+                    query_info,
+                    subject, gap_align, score_params, ext_params, hit_params,
                     init_hitlist, &hsp_list, gapped_stats, NULL);
+        }
+        else if (aux_struct->JumperGapped) {
+            status = aux_struct->JumperGapped(subject, query, query_info,
+                                              lookup, word_params,
+                                              score_params, hit_params,
+                                              aux_struct->offset_pairs,
+                                              aux_struct->mapper_wordhits,
+                                              kScanSubjectOffsetArraySize,
+                                              gap_align, init_hitlist,
+                                              &hsp_list, ungapped_stats,
+                                              gapped_stats);
+        }
         if (status) break;
 
-        /* Removes redundant HSPs. */
-        Blast_HSPListPurgeHSPsWithCommonEndpoints(program_number, hsp_list, TRUE);
+        /* No need to do this for short reads */
+        if (aux_struct->GetGappedScore) {
+
+            /* Removes redundant HSPs. */
+            Blast_HSPListPurgeHSPsWithCommonEndpoints(program_number, hsp_list, TRUE);
 
-        /* For nucleotide search, if match score is = 2, the odd scores
-           are rounded down to the nearest even number. */
-        Blast_HSPListAdjustOddBlastnScores(hsp_list, score_options->gapped_calculation, gap_align->sbp);
+            /* For nucleotide search, if match score is = 2, the odd scores
+               are rounded down to the nearest even number. */
+            Blast_HSPListAdjustOddBlastnScores(hsp_list, score_options->gapped_calculation, gap_align->sbp);
+
+        }
 
         Blast_HSPListSortByScore(hsp_list);
 
         if (score_options->is_ooframe && kTranslatedSubject)
             subject->length = prot_length;
         } else {
-            BLAST_GetUngappedHSPList(init_hitlist, query_info, subject, 
+            BLAST_GetUngappedHSPList(init_hitlist, query_info, subject,
                     hit_params->options, &hsp_list);
         }
 
@@ -530,10 +702,19 @@ s_BlastSearchEngineOneContext(EBlastProgramType program_number,
 
         Blast_HSPListAdjustOffsets(hsp_list, backup.offset);
         overlap = (backup.offset == backup.hard_ranges[backup.hm_index].left) ?
-                  0 : DBSEQ_CHUNK_OVERLAP;
-        status = Blast_HSPListsMerge(&hsp_list, &combined_hsp_list,  
+                  0 : dbseq_chunk_overlap;
+        status = Blast_HSPListsMerge(&hsp_list, &combined_hsp_list,
                      kHspNumMax, &(backup.offset), INT4_MIN,
-                     overlap, score_options->gapped_calculation);
+                     overlap, score_options->gapped_calculation,
+                     Blast_ProgramIsMapping(program_number));
+
+        if (getenv("MAPPER_WRITE_SUBJECT_CHUNK")) {
+            s_WriteHSPsForChunk(combined_hsp_list, &backup, hit_params,
+                                hsp_stream, subject->length,
+                                backup.full_range.right -
+                                backup.full_range.left);
+        }
+
     } /* End loop on chunks of subject sequence */
 
     s_RestoreSubject(subject, &backup);
@@ -565,8 +746,8 @@ s_BlastSearchEngineCoreCleanUp(EBlastProgramType program_number,
         BlastQueryInfoFree(query_info);
 
     /* Free translation buffer and frame offsets, except for RPS tblastn,
-     * where they are taken from different structures, and hence shouldn't 
-     * be freed here. 
+     * where they are taken from different structures, and hence shouldn't
+     * be freed here.
      */
     if (program_number != eBlastTypeRpsTblastn) {
         if (translation_buffer) {
@@ -579,11 +760,11 @@ s_BlastSearchEngineCoreCleanUp(EBlastProgramType program_number,
     }
 }
 
-/** Discard the HSPs above the prelim e-value threshold from the HSP list 
+/** Discard the HSPs above the prelim e-value threshold from the HSP list
  * @param hsp_list List of HSPs for one subject sequence [in] [out]
  * @param hit_params Parameters block containing the prelim e-value [in]
 */
-static Int2 
+static Int2
 s_Blast_HSPListReapByPrelimEvalue(BlastHSPList* hsp_list, const BlastHitSavingParameters* hit_params)
 {
    BlastHSP* hsp;
@@ -619,8 +800,8 @@ s_Blast_HSPListReapByPrelimEvalue(BlastHSPList* hsp_list, const BlastHitSavingPa
 
 /** The core of the BLAST search: comparison between the (concatenated)
  * query against one subject sequence. Translation of the subject sequence
- * into 6 frames is done inside, if necessary. If subject sequence is 
- * too long, it can be split into several chunks. 
+ * into 6 frames is done inside, if necessary. If subject sequence is
+ * too long, it can be split into several chunks.
  * @param program_number BLAST program type [in]
  * @param query Query sequence structure [in]
  * @param query_info_in Query information [in]
@@ -628,7 +809,7 @@ s_Blast_HSPListReapByPrelimEvalue(BlastHSPList* hsp_list, const BlastHitSavingPa
  * @param lookup Lookup table [in]
  * @param gap_align Structure for gapped alignment information [in]
  * @param score_params Scoring parameters [in]
- * @param word_params Initial word finding and ungapped extension 
+ * @param word_params Initial word finding and ungapped extension
  *                    parameters [in]
  * @param ext_params Gapped extension parameters [in]
  * @param hit_params Hit saving parameters [in]
@@ -643,21 +824,22 @@ s_Blast_HSPListReapByPrelimEvalue(BlastHSPList* hsp_list, const BlastHitSavingPa
  *                   BLAST search [in|out]
  */
 static Int2
-s_BlastSearchEngineCore(EBlastProgramType program_number, 
-        BLAST_SequenceBlk* query, 
-        BlastQueryInfo* query_info_in, 
-        BLAST_SequenceBlk* subject, 
-        LookupTableWrap* lookup, 
-        BlastGapAlignStruct* gap_align, 
-        const BlastScoringParameters* score_params, 
-        const BlastInitialWordParameters* word_params, 
-        const BlastExtensionParameters* ext_params, 
-        const BlastHitSavingParameters* hit_params, 
+s_BlastSearchEngineCore(EBlastProgramType program_number,
+        BLAST_SequenceBlk* query,
+        BlastQueryInfo* query_info_in,
+        BLAST_SequenceBlk* subject,
+        LookupTableWrap* lookup,
+        BlastGapAlignStruct* gap_align,
+        const BlastScoringParameters* score_params,
+        const BlastInitialWordParameters* word_params,
+        const BlastExtensionParameters* ext_params,
+        const BlastHitSavingParameters* hit_params,
         const BlastDatabaseOptions* db_options,
         BlastDiagnostics* diagnostics,
         BlastCoreAuxStruct* aux_struct,
         BlastHSPList** hsp_list_out_ptr,
-        TInterruptFnPtr interrupt_search, 
+        BlastHSPStream* hsp_stream,
+        TInterruptFnPtr interrupt_search,
         SBlastProgress* progress_info)
 {
     BlastHSPList* hsp_list_out=NULL;
@@ -674,10 +856,9 @@ s_BlastSearchEngineCore(EBlastProgramType program_number,
     // To support rmblastn -RMH-
     BlastScoreBlk* sbp = gap_align->sbp;
 
-    const Boolean kTranslatedSubject = 
+    const Boolean kTranslatedSubject =
         (Blast_SubjectIsTranslated(program_number) || program_number == eBlastTypeRpsTblastn);
-    const Boolean kNucleotide = (program_number == eBlastTypeBlastn ||
-                                program_number == eBlastTypePhiBlastn);
+    const Boolean kNucleotide = Blast_ProgramIsNucleotide(program_number);
     const int kHspNumMax = BlastHspNumMax(score_options->gapped_calculation, hit_options);
     Boolean isRPS = FALSE;
     SubjectSplitStruct backup = {0,};
@@ -703,19 +884,19 @@ s_BlastSearchEngineCore(EBlastProgramType program_number,
         last_context = 5;
         if (score_options->is_ooframe) {
             BLAST_GetAllTranslations(backup.sequence, eBlastEncodingNcbi2na,
-                                     backup.full_range.right, 
+                                     backup.full_range.right,
                                      subject->gen_code_string, &translation_buffer,
                                      &frame_offsets, &subject->oof_sequence);
             subject->oof_sequence_allocated = TRUE;
             frame_offsets_a = frame_offsets;
         } else if (program_number == eBlastTypeRpsTblastn ) {
-            /* For RPS tblastn, subject is actually query, which has already 
+            /* For RPS tblastn, subject is actually query, which has already
                been translated during the setup stage. */
             translation_buffer = backup.sequence - 1;
             frame_offsets_a = frame_offsets = ContextOffsetsToOffsetArray(query_info_in);
         } else {
             BLAST_GetAllTranslations(backup.sequence, eBlastEncodingNcbi2na,
-                                     backup.full_range.right, 
+                                     backup.full_range.right,
                                      subject->gen_code_string, &translation_buffer,
                                      &frame_offsets, NULL);
             frame_offsets_a = frame_offsets;
@@ -767,9 +948,9 @@ s_BlastSearchEngineCore(EBlastProgramType program_number,
                 }
             } else if (context == 3) { /* first negative context */
                 for (i = 0; i < subject->num_seq_ranges; i++) {
-                    subject->seq_ranges[subject->num_seq_ranges-i-1].left = 
+                    subject->seq_ranges[subject->num_seq_ranges-i-1].left =
                         subject->length - CONV_NUCL2PROT_COORDINATES(backup.seq_ranges[i].right);
-                    subject->seq_ranges[subject->num_seq_ranges-i-1].right = 
+                    subject->seq_ranges[subject->num_seq_ranges-i-1].right =
                         subject->length - CONV_NUCL2PROT_COORDINATES(backup.seq_ranges[i].left);
                 }
             }
@@ -777,20 +958,21 @@ s_BlastSearchEngineCore(EBlastProgramType program_number,
             subject->frame = context;
         }
 
-        status = s_BlastSearchEngineOneContext(program_number, query, query_info, 
-                                               subject, orig_length, lookup, 
-                                               gap_align, score_params, 
-                                               word_params, ext_params, 
-                                               hit_params, diagnostics, 
+        status = s_BlastSearchEngineOneContext(program_number, query, query_info,
+                                               subject, orig_length, lookup,
+                                               gap_align, score_params,
+                                               word_params, ext_params,
+                                               hit_params, diagnostics,
                                                aux_struct, &hsp_list_for_chunks,
-                                               interrupt_search, progress_info);
+                                               hsp_stream, interrupt_search,
+                                               progress_info);
         if (status != 0)  break;
-     
+
         if (Blast_HSPListAppend(&hsp_list_for_chunks, &hsp_list_out, kHspNumMax)) {
             status = 1;
             break;
         }
-      
+
         /* if searching was interrupted, delete accumulated results
            but continue execution so temporary structures get freed */
         if (interrupt_search && (*interrupt_search)(progress_info) == TRUE) {
@@ -806,33 +988,35 @@ s_BlastSearchEngineCore(EBlastProgramType program_number,
 
     if (status) {
         hsp_list_out = Blast_HSPListFree(hsp_list_out);
-        s_BlastSearchEngineCoreCleanUp(program_number, query_info, 
-                                       query_info_in, translation_buffer, 
+        s_BlastSearchEngineCoreCleanUp(program_number, query_info,
+                                       query_info_in, translation_buffer,
                                        frame_offsets_a);
         return status;
     }
 
     if (hit_params->link_hsp_params) {
         status = BLAST_LinkHsps(program_number, hsp_list_out, query_info,
-                  subject->length, gap_align->sbp, hit_params->link_hsp_params, 
+                  subject->length, gap_align->sbp, hit_params->link_hsp_params,
                   score_options->gapped_calculation);
     } else if (!Blast_ProgramIsPhiBlast(program_number)
-           && !(isRPS && !sbp->gbp) ){
+           && !(isRPS && !sbp->gbp)
+           /* do not calculate E-values for mapping */
+           && program_number != eBlastTypeMapping ) {
         /* Calculate e-values for all HSPs. Skip this step
-           for PHI or RPS with old FSC, since calculating the E values 
+           for PHI or RPS with old FSC, since calculating the E values
            requires precomputation that has not been done yet */
         double scale_factor = 1.0;
         if (isRPS) {
             scale_factor = score_params->scale_factor;
         }
-        status = Blast_HSPListGetEvalues(program_number, query_info,
-                                         stat_length, hsp_list_out, 
-                                         score_options->gapped_calculation, 
+        Blast_HSPListGetEvalues(program_number, query_info,
+                                         stat_length, hsp_list_out,
+                                         score_options->gapped_calculation,
                                          isRPS, gap_align->sbp, 0, scale_factor);
     }
-    
-   /* Use score threshold rather than evalue if 
-    * matrix_only_scoring is used.  -RMH- 
+
+   /* Use score threshold rather than evalue if
+    * matrix_only_scoring is used.  -RMH-
     */
     if ( sbp->matrix_only_scoring )
     {
@@ -854,31 +1038,31 @@ s_BlastSearchEngineCore(EBlastProgramType program_number,
 
     s_BlastSearchEngineCoreCleanUp(program_number, query_info, query_info_in,
                                    translation_buffer, frame_offsets_a);
-    
+
     *hsp_list_out_ptr = hsp_list_out;
 
     return status;
 }
 
-/** Fills the output information about the cutoffs uses in a BLAST search. 
+/** Fills the output information about the cutoffs uses in a BLAST search.
  * @param return_cutoffs Structure for saving cutoffs information [in] [out]
  * @param score_params Scoring parameters, containing the scaling factor [in]
  * @param word_params Initial word parameters [in]
  * @param ext_params Gapped extension parameters [in]
  * @param hit_params Hit saving parameters [in]
  */
-static Int2 
-s_FillReturnCutoffsInfo(BlastRawCutoffs* return_cutoffs, 
-                        const BlastScoringParameters* score_params, 
-                        const BlastInitialWordParameters* word_params, 
+static Int2
+s_FillReturnCutoffsInfo(BlastRawCutoffs* return_cutoffs,
+                        const BlastScoringParameters* score_params,
+                        const BlastInitialWordParameters* word_params,
                         const BlastExtensionParameters* ext_params,
                         const BlastHitSavingParameters* hit_params)
 {
     /* since the cutoff score here will be used for display
-      purposes, strip out any internal scaling of the scores 
-    
+      purposes, strip out any internal scaling of the scores
+
       If this was a multi-query search, use the least stringent
-      cutoff and most generous dropoff value among all the 
+      cutoff and most generous dropoff value among all the
       possible sequences */
 
     Int4 scale_factor = (Int4)score_params->scale_factor;
@@ -888,35 +1072,36 @@ s_FillReturnCutoffsInfo(BlastRawCutoffs* return_cutoffs,
 
     return_cutoffs->x_drop_ungapped = word_params->x_dropoff_max / scale_factor;
     return_cutoffs->x_drop_gap = ext_params->gap_x_dropoff / scale_factor;
-    return_cutoffs->x_drop_gap_final = ext_params->gap_x_dropoff_final / 
+    return_cutoffs->x_drop_gap_final = ext_params->gap_x_dropoff_final /
                                                         scale_factor;
-    return_cutoffs->ungapped_cutoff = word_params->cutoff_score_min / 
+    return_cutoffs->ungapped_cutoff = word_params->cutoff_score_min /
                                                         scale_factor;
     return_cutoffs->cutoff_score = hit_params->cutoff_score_min / scale_factor;
 
     return 0;
 }
 
-/** Setup of the auxiliary BLAST structures; 
- * also calculates internally used parameters from options. 
- * @param seq_src Sequence source information, with callbacks to get 
+/** Setup of the auxiliary BLAST structures;
+ * also calculates internally used parameters from options.
+ * @param seq_src Sequence source information, with callbacks to get
  *             sequences, their lengths, etc. [in]
  * @param lookup_wrap Lookup table, already constructed. [in]
- * @param word_params Parameters for initial word finding and ungapped 
+ * @param word_params Parameters for initial word finding and ungapped
  *                    extension. [in]
  * @param ext_options options for gapped extension. [in]
  * @param hit_options options for saving hits. [in]
  * @param query The query sequence block [in]
- * @param aux_struct_ptr Placeholder joining various auxiliary memory 
+ * @param aux_struct_ptr Placeholder joining various auxiliary memory
  *                       structures [out]
  */
-static Int2 
+static Int2
 s_BlastSetUpAuxStructures(const BlastSeqSrc* seq_src,
-    LookupTableWrap* lookup_wrap,    
+    LookupTableWrap* lookup_wrap,
     const BlastInitialWordParameters* word_params,
     const BlastExtensionOptions* ext_options,
     const BlastHitSavingOptions* hit_options,
-    BLAST_SequenceBlk* query, BlastCoreAuxStruct** aux_struct_ptr)
+    BLAST_SequenceBlk* query,
+    const BlastQueryInfo* query_info, BlastCoreAuxStruct** aux_struct_ptr)
 {
     Int2 status = 0;
     BlastCoreAuxStruct* aux_struct;
@@ -927,8 +1112,10 @@ s_BlastSetUpAuxStructures(const BlastSeqSrc* seq_src,
     Boolean indexed_mb_lookup = (lookup_wrap->read_indexed_db != 0);
     Boolean phi_lookup = (lookup_wrap->lut_type == ePhiLookupTable ||
                          lookup_wrap->lut_type == ePhiNaLookupTable);
-    Boolean smith_waterman = 
+    Boolean smith_waterman =
                  (ext_options->ePrelimGapExt == eSmithWatermanScoreOnly);
+
+    Boolean jumper = (ext_options->ePrelimGapExt == eJumperWithTraceback);
     Int4 offset_array_size = GetOffsetArraySize(lookup_wrap);
 
     ASSERT(seq_src);
@@ -936,10 +1123,13 @@ s_BlastSetUpAuxStructures(const BlastSeqSrc* seq_src,
     *aux_struct_ptr = aux_struct = (BlastCoreAuxStruct*)
       calloc(1, sizeof(BlastCoreAuxStruct));
 
-    if ((status = BlastExtendWordNew(query->length, word_params, 
+    if ((status = BlastExtendWordNew(query->length, word_params,
                                     &aux_struct->ewp)) != 0)
       return status;
 
+    aux_struct->JumperGapped = NULL;
+    aux_struct->mapper_wordhits = NULL;
+
     if (smith_waterman) {
         aux_struct->WordFinder = NULL;
     /*
@@ -965,18 +1155,38 @@ s_BlastSetUpAuxStructures(const BlastSeqSrc* seq_src,
         else {
             aux_struct->WordFinder = BlastNaWordFinder;
         }
+
+        if (jumper) {
+            aux_struct->WordFinder = NULL;
+        }
     }
-    
-    aux_struct->offset_pairs = 
+
+    aux_struct->offset_pairs =
       (BlastOffsetPair*) malloc(offset_array_size * sizeof(BlastOffsetPair));
-    
+
     aux_struct->init_hitlist = BLAST_InitHitListNew();
     /* Pick which gapped alignment algorithm to use. */
     if (phi_lookup)
         aux_struct->GetGappedScore = PHIGetGappedScore;
     else if (smith_waterman)
         aux_struct->GetGappedScore = BLAST_SmithWatermanGetGappedScore;
-    else 
+    else if (jumper) {
+        aux_struct->GetGappedScore = NULL;
+
+        /* Create several lists of word hits for mapper with large number of
+           queries */
+        if (query_info->num_queries > 1000) {
+            aux_struct->mapper_wordhits = MapperWordHitsNew(query, query_info);
+        }
+
+        if (indexed_mb_lookup) {
+            aux_struct->JumperGapped = ShortRead_IndexedWordFinder;
+        }
+        else {
+            aux_struct->JumperGapped = JumperNaWordFinder;
+        }
+    }
+    else
         aux_struct->GetGappedScore = BLAST_GetGappedScore;
 
     return status;
@@ -989,7 +1199,7 @@ s_BlastSetUpAuxStructures(const BlastSeqSrc* seq_src,
  * @param query_info Additional query information [in]
  * @param seq_src Structure containing BLAST database [in]
  * @param score_params Hit scoring parameters [in]
- * @param lookup_wrap The lookup table, constructed earlier [in] 
+ * @param lookup_wrap The lookup table, constructed earlier [in]
  * @param aux_struct Wrapper for auxiliary structures used in preliminary
  *                   search [in]
  * @param word_params Parameters for processing initial word hits [in]
@@ -998,22 +1208,22 @@ s_BlastSetUpAuxStructures(const BlastSeqSrc* seq_src,
  *                  for gapped alignment. [in]
  * @param hit_params Parameters for saving the HSPs [in]
  * @param hsp_stream Placeholder for saving HSP lists [in]
- * @param diagnostics Return statistics containing numbers of hits on 
- *                    different stages of the search. Statistics saved only 
+ * @param diagnostics Return statistics containing numbers of hits on
+ *                    different stages of the search. Statistics saved only
  *                    for the allocated parts of the structure. [in] [out]
  * @param interrupt_search function callback to allow interruption of BLAST
  *                   search [in, optional]
  * @param progress_info contains information about the progress of the current
  *                   BLAST search [in|out]
  */
-static Int2 
-s_RPSPreliminarySearchEngine(EBlastProgramType program_number, 
+static Int2
+s_RPSPreliminarySearchEngine(EBlastProgramType program_number,
     BLAST_SequenceBlk* query, BlastQueryInfo* query_info,
     const BlastSeqSrc* seq_src,
-    const BlastScoringParameters* score_params, 
+    const BlastScoringParameters* score_params,
     LookupTableWrap* lookup_wrap, BlastCoreAuxStruct* aux_struct,
-    const BlastInitialWordParameters* word_params, 
-    const BlastExtensionParameters* ext_params, 
+    const BlastInitialWordParameters* word_params,
+    const BlastExtensionParameters* ext_params,
     BlastGapAlignStruct* gap_align,
     const BlastHitSavingParameters* hit_params,
     BlastHSPStream* hsp_stream, BlastDiagnostics* diagnostics,
@@ -1065,27 +1275,27 @@ s_RPSPreliminarySearchEngine(EBlastProgramType program_number,
     /* Run the search; the input query is what gets scanned
       and the concatenated DB is the sequence associated with
       the score matrix. This essentially means that 'query'
-      and 'subject' have opposite conventions for the search. 
-    
+      and 'subject' have opposite conventions for the search.
+
       Note that while scores can be calculated for any alignment
       found, we have not set up any Karlin parameters or effective
       search space sizes for the concatenated DB. This means that
       E-values cannot be calculated after hits are found. */
 
     for (index = 0; index < query_info->num_queries; ++index) {
-        /* Separate one query from the set: create an auxiliary query_info 
+        /* Separate one query from the set: create an auxiliary query_info
            structure which refers to this single query. */
-        if (Blast_GetOneQueryStructs(&one_query_info, &one_query, 
+        if (Blast_GetOneQueryStructs(&one_query_info, &one_query,
                                     query_info, query, index) != 0)
            return -1;
 
         /* It is OK to pass NULL for the BlastDatabaseOptions argument, because it
            will not be checked for RPS BLAST program types. */
         status = (Int4)
-          s_BlastSearchEngineCore(program_number, &concat_db, one_query_info, 
-             one_query, lookup_wrap, gap_align, score_params, 
-             word_params, ext_params, hit_params, NULL, 
-             diagnostics, aux_struct, &hsp_list, interrupt_search, 
+          s_BlastSearchEngineCore(program_number, &concat_db, one_query_info,
+             one_query, lookup_wrap, gap_align, score_params,
+             word_params, ext_params, hit_params, NULL,
+             diagnostics, aux_struct, &hsp_list, NULL, interrupt_search,
              progress_info);
 
         if (interrupt_search && (*interrupt_search)(progress_info) == TRUE) {
@@ -1229,26 +1439,43 @@ s_AdjustSubjectForSraSearch(BlastHSPList* hsp_list, Uint1 offset )
 }
 
 
-Int4 
-BLAST_PreliminarySearchEngine(EBlastProgramType program_number, 
+static Int4 s_GetMinimumSubjSeqLen(LookupTableWrap* lookup_wrap)
+{
+    Int4 word_length = 1;
+    if (lookup_wrap->lut_type == eAaLookupTable) {
+        BlastAaLookupTable* lut;
+        lut = (BlastAaLookupTable*)(lookup_wrap->lut);
+        word_length = lut->word_length;
+    } else if (lookup_wrap->lut_type == eCompressedAaLookupTable) {
+        BlastCompressedAaLookupTable* lut;
+        lut = (BlastCompressedAaLookupTable*)(lookup_wrap->lut);
+        word_length = lut->word_length;
+    }
+    return word_length * 3 + 2;
+}
+
+
+Int4
+BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
     BLAST_SequenceBlk* query, BlastQueryInfo* query_info,
     const BlastSeqSrc* seq_src, BlastGapAlignStruct* gap_align,
-    BlastScoringParameters* score_params, 
+    BlastScoringParameters* score_params,
     LookupTableWrap* lookup_wrap,
-    const BlastInitialWordOptions* word_options, 
-    BlastExtensionParameters* ext_params, 
+    const BlastInitialWordOptions* word_options,
+    BlastExtensionParameters* ext_params,
     BlastHitSavingParameters* hit_params,
     BlastEffectiveLengthsParameters* eff_len_params,
-    const PSIBlastOptions* psi_options, 
+    const PSIBlastOptions* psi_options,
     const BlastDatabaseOptions* db_options,
     BlastHSPStream* hsp_stream, BlastDiagnostics* diagnostics,
     TInterruptFnPtr interrupt_search, SBlastProgress* progress_info)
 {
     BlastCoreAuxStruct* aux_struct = NULL;
-    BlastHSPList* hsp_list = NULL; 
+    BlastHSPList* hsp_list = NULL;
     BlastSeqSrcGetSeqArg seq_arg;
     Int2 status = 0;
     Int8 db_length = 0;
+    Int4 min_subj_seq_length = 1;
     const BlastScoringOptions* score_options = score_params->options;
     const BlastHitSavingOptions* hit_options = hit_params->options;
     const BlastExtensionOptions* ext_options = ext_params->options;
@@ -1256,20 +1483,23 @@ BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
     Boolean gapped_calculation = score_options->gapped_calculation;
     BlastScoreBlk* sbp = gap_align->sbp;
     BlastSeqSrcIterator* itr;
-    const Boolean kNucleotide = (program_number == eBlastTypeBlastn ||
-                                program_number == eBlastTypePhiBlastn);
+    const Boolean kNucleotide = Blast_ProgramIsNucleotide(program_number);
 
-    T_MB_IdbCheckOid check_index_oid = 
+    T_MB_IdbCheckOid check_index_oid =
         (T_MB_IdbCheckOid)lookup_wrap->check_index_oid;
     Int4 last_vol_idx = LAST_VOL_IDX_INIT;
 
-    BlastInitialWordParametersNew(program_number, word_options, 
-      hit_params, lookup_wrap, sbp, query_info, 
+    if (Blast_SubjectIsTranslated(program_number)) {
+        min_subj_seq_length = s_GetMinimumSubjSeqLen(lookup_wrap);
+    }
+
+    BlastInitialWordParametersNew(program_number, word_options,
+      hit_params, lookup_wrap, sbp, query_info,
       BlastSeqSrcGetAvgSeqLen(seq_src), &word_params);
 
-    if ((status = 
-       s_BlastSetUpAuxStructures(seq_src, lookup_wrap, word_params, 
-          ext_options, hit_options, query, &aux_struct)) != 0)
+    if ((status =
+       s_BlastSetUpAuxStructures(seq_src, lookup_wrap, word_params,
+          ext_options, hit_options, query, query_info, &aux_struct)) != 0)
       return status;
 
     /* remember the current search state */
@@ -1279,9 +1509,9 @@ BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
     /* For RPS BLAST, there is no loop over subject sequences, so the preliminary
       search engine is done in a separate function. */
     if (Blast_ProgramIsRpsBlast(program_number)) {
-       status =         
-         s_RPSPreliminarySearchEngine(program_number, query, query_info, 
-            seq_src, score_params, lookup_wrap, aux_struct, word_params, 
+       status =
+         s_RPSPreliminarySearchEngine(program_number, query, query_info,
+            seq_src, score_params, lookup_wrap, aux_struct, word_params,
             ext_params, gap_align, hit_params, hsp_stream, diagnostics,
             interrupt_search, progress_info);
        word_params = BlastInitialWordParametersFree(word_params);
@@ -1291,19 +1521,19 @@ BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
 
     /* Update the parameters for linking HSPs, if necessary. */
     BlastLinkHSPParametersUpdate(word_params, hit_params, gapped_calculation);
-    
+
     memset((void*) &seq_arg, 0, sizeof(seq_arg));
 
     /* Encoding is set so there are no sentinel bytes, and protein/nucleotide
       sequences are retieved in ncbistdaa/ncbi2na encodings respectively. */
-    seq_arg.encoding = eBlastEncodingProtein; 
+    seq_arg.encoding = eBlastEncodingProtein;
 
     db_length = BlastSeqSrcGetTotLen(seq_src);
 
     itr = BlastSeqSrcIteratorNewEx(MAX(BlastSeqSrcGetNumSeqs(seq_src)/100,1));
 
     /* iterate over all subject sequences */
-    while ( (seq_arg.oid = BlastSeqSrcIteratorNext(seq_src, itr)) 
+    while ( (seq_arg.oid = BlastSeqSrcIteratorNext(seq_src, itr))
            != BLAST_SEQSRC_EOF) {
        Int4 stat_length;
        if (seq_arg.oid == BLAST_SEQSRC_ERROR) {
@@ -1311,36 +1541,42 @@ BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
            break;
        }
 
-       if( check_index_oid != 0 && 
-               check_index_oid( seq_arg.oid, &last_vol_idx ) == eNoResults ) {
+       if (check_index_oid != 0 &&
+               check_index_oid(seq_arg.oid, &last_vol_idx) == eNoResults) {
+           continue;
+       }
+
+       if (BlastSeqSrcGetSequence(seq_src, &seq_arg) < 0) {
            continue;
        }
 
-       if (BlastSeqSrcGetSequence(seq_src, &seq_arg) < 0)
+       if (seq_arg.seq->length < min_subj_seq_length) {
+           BlastSeqSrcReleaseSequence(seq_src, &seq_arg);
            continue;
+       }
 
        if (db_length == 0) {
            /* This is not a database search, hence need to recalculate and save
-            the effective search spaces and length adjustments for all 
-            queries based on the length of the current single subject 
+            the effective search spaces and length adjustments for all
+            queries based on the length of the current single subject
             sequence. */
-           if ((status = BLAST_OneSubjectUpdateParameters(program_number, 
-                          seq_arg.seq->length, score_options, query_info, 
-                          sbp, hit_params, word_params, 
+           if ((status = BLAST_OneSubjectUpdateParameters(program_number,
+                          seq_arg.seq->length, score_options, query_info,
+                          sbp, hit_params, word_params,
                           eff_len_params)) != 0)
               return status;
       }
 
-      stat_length = seq_arg.seq->length; 
+      stat_length = seq_arg.seq->length;
 
       /* Calculate cutoff scores for linking HSPs. Do this only for
          ungapped protein searches and ungapped translated
          searches. */
       if (hit_params->link_hsp_params && !kNucleotide &&
           !gapped_calculation) {
-          CalculateLinkHSPCutoffs(program_number, query_info, sbp, 
-            hit_params->link_hsp_params, word_params, db_length, 
-            seq_arg.seq->length); 
+          CalculateLinkHSPCutoffs(program_number, query_info, sbp,
+            hit_params->link_hsp_params, word_params, db_length,
+            seq_arg.seq->length);
       }
 
       if (Blast_SubjectIsTranslated(program_number)) {
@@ -1348,17 +1584,19 @@ BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
            * doesn't provide a genetic code string, use the default genetic
            * code for all subjects (as in the C toolkit) */
           if (seq_arg.seq->gen_code_string == NULL) {
-              seq_arg.seq->gen_code_string = 
+              seq_arg.seq->gen_code_string =
                   GenCodeSingletonFind(db_options->genetic_code);
           }
           ASSERT(seq_arg.seq->gen_code_string);
           stat_length /= CODON_LENGTH;
       }
-      status = 
-         s_BlastSearchEngineCore(program_number, query, query_info,
-            seq_arg.seq, lookup_wrap, gap_align, score_params, word_params, 
-            ext_params, hit_params, db_options, diagnostics, aux_struct, 
-            &hsp_list, interrupt_search, progress_info);
+      status =
+          s_BlastSearchEngineCore(program_number, query, query_info,
+                                  seq_arg.seq, lookup_wrap, gap_align,
+                                  score_params, word_params, ext_params,
+                                  hit_params, db_options, diagnostics,
+                                  aux_struct, &hsp_list, hsp_stream,
+                                  interrupt_search, progress_info);
       if (status) {
           break;
       }
@@ -1373,36 +1611,36 @@ BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
         		 else
         			 s_AdjustSubjectForSraSearch(hsp_list, seq_arg.seq->bases_offset);
         	 }
-            /* The following must be performed for any ungapped 
+            /* The following must be performed for any ungapped
                search with a nucleotide database. */
-               status = 
+               status =
                   Blast_HSPListReevaluateUngapped(
-                            program_number, hsp_list, query, 
-                            seq_arg.seq, word_params, hit_params, 
-                            query_info, sbp, score_params, seq_src, 
+                            program_number, hsp_list, query,
+                            seq_arg.seq, word_params, hit_params,
+                            query_info, sbp, score_params, seq_src,
                             seq_arg.seq->gen_code_string);
                if (status) {
                   /* Tell the indexing library that this thread is done with
                      preliminary search.
                   */
                   if( check_index_oid != 0 ) {
-                    ((T_MB_IdxEndSearchIndication)( 
+                    ((T_MB_IdxEndSearchIndication)(
                         lookup_wrap->end_search_indication))( last_vol_idx );
                   }
-         
+
                   BlastSeqSrcReleaseSequence(seq_src, &seq_arg);
                   return status;
                }
                /* Relink HSPs if sum statistics is used, because scores might
                 * have changed after reevaluation with ambiguities, and there
                 * will be no traceback stage where relinking is done normally.
-                * If sum statistics are not used, just recalculate e-values. 
+                * If sum statistics are not used, just recalculate e-values.
                 */
                if (hit_params->link_hsp_params) {
-                   status = 
+                   status =
                        BLAST_LinkHsps(program_number, hsp_list, query_info,
-                                      seq_arg.seq->length, sbp, 
-                                      hit_params->link_hsp_params, 
+                                      seq_arg.seq->length, sbp,
+                                      hit_params->link_hsp_params,
                                       gapped_calculation);
                } else {
                   Blast_HSPListGetEvalues(program_number, query_info,
@@ -1410,8 +1648,8 @@ BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
                                           gapped_calculation, FALSE,
                                           sbp, 0, 1.0);
                }
-               /* Use score threshold rather than evalue if 
-                * matrix_only_scoring is used.  -RMH- 
+               /* Use score threshold rather than evalue if
+                * matrix_only_scoring is used.  -RMH-
                 */
                if ( sbp->matrix_only_scoring )
                {
@@ -1420,13 +1658,13 @@ BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
                }else {
         	   status = s_Blast_HSPListReapByPrelimEvalue(hsp_list, hit_params);
                }
- 
+
                Blast_HSPListReapByQueryCoverage(hsp_list,hit_params->options, query_info, program_number);
             /* Calculate and fill the bit scores, since there will be no
                traceback stage where this can be done. */
             Blast_HSPListGetBitScores(hsp_list, gapped_calculation, sbp);
-         } 
-         
+         }
+
          // This should only happen for sra searches
          if((seq_arg.seq->bases_offset > 0) && (gapped_calculation))
          {
@@ -1445,12 +1683,12 @@ BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
          {
  	    for (query_index=0; query_index<hsp_stream->results->num_queries; query_index++)
               if (hsp_stream->results->hitlist_array[query_index] && hsp_stream->results->hitlist_array[query_index]->heapified)
-                   hit_params->low_score[query_index] = 
-			MAX(hit_params->low_score[query_index], 
+                   hit_params->low_score[query_index] =
+			MAX(hit_params->low_score[query_index],
                            hit_params->options->low_score_perc*(hsp_stream->results->hitlist_array[query_index]->low_score));
          }
       }
-      
+
       BlastSeqSrcReleaseSequence(seq_src, &seq_arg);
 
       /* check for interrupt */
@@ -1459,12 +1697,12 @@ BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
           break;
       }
     }
-    
+
     /* Tell the indexing library that this thread is done with
        preliminary search.
     */
     if( check_index_oid != 0 ) {
-        ((T_MB_IdxEndSearchIndication)( 
+        ((T_MB_IdxEndSearchIndication)(
             lookup_wrap->end_search_indication))( last_vol_idx );
     }
 
@@ -1474,7 +1712,7 @@ BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
 
     /* Fill the cutoff values in the diagnostics structure */
     if (diagnostics && diagnostics->cutoffs) {
-      s_FillReturnCutoffsInfo(diagnostics->cutoffs, score_params, word_params, 
+      s_FillReturnCutoffsInfo(diagnostics->cutoffs, score_params, word_params,
                               ext_params, hit_params);
     }
 
@@ -1484,21 +1722,21 @@ BLAST_PreliminarySearchEngine(EBlastProgramType program_number,
 }
 
 Int2
-Blast_RunPreliminarySearch(EBlastProgramType program, 
-    BLAST_SequenceBlk* query, 
-    BlastQueryInfo* query_info, 
-    const BlastSeqSrc* seq_src, 
+Blast_RunPreliminarySearch(EBlastProgramType program,
+    BLAST_SequenceBlk* query,
+    BlastQueryInfo* query_info,
+    const BlastSeqSrc* seq_src,
     const BlastScoringOptions* score_options,
-    BlastScoreBlk* sbp, 
+    BlastScoreBlk* sbp,
     LookupTableWrap* lookup_wrap,
-    const BlastInitialWordOptions* word_options, 
+    const BlastInitialWordOptions* word_options,
     const BlastExtensionOptions* ext_options,
     const BlastHitSavingOptions* hit_options,
     const BlastEffectiveLengthsOptions* eff_len_options,
-    const PSIBlastOptions* psi_options, 
-    const BlastDatabaseOptions* db_options, 
-    BlastHSPStream* hsp_stream, 
-    BlastDiagnostics* diagnostics) 
+    const PSIBlastOptions* psi_options,
+    const BlastDatabaseOptions* db_options,
+    BlastHSPStream* hsp_stream,
+    BlastDiagnostics* diagnostics)
 {
     return Blast_RunPreliminarySearchWithInterrupt(program,
            query, query_info, seq_src, score_options, sbp, lookup_wrap,
@@ -1506,64 +1744,64 @@ Blast_RunPreliminarySearch(EBlastProgramType program,
            psi_options, db_options, hsp_stream, diagnostics, NULL, NULL);
 }
 
-Int2 
-Blast_RunPreliminarySearchWithInterrupt(EBlastProgramType program, 
-    BLAST_SequenceBlk* query, 
-    BlastQueryInfo* query_info, 
-    const BlastSeqSrc* seq_src, 
+Int2
+Blast_RunPreliminarySearchWithInterrupt(EBlastProgramType program,
+    BLAST_SequenceBlk* query,
+    BlastQueryInfo* query_info,
+    const BlastSeqSrc* seq_src,
     const BlastScoringOptions* score_options,
-    BlastScoreBlk* sbp, 
+    BlastScoreBlk* sbp,
     LookupTableWrap* lookup_wrap,
-    const BlastInitialWordOptions* word_options, 
+    const BlastInitialWordOptions* word_options,
     const BlastExtensionOptions* ext_options,
     const BlastHitSavingOptions* hit_options,
     const BlastEffectiveLengthsOptions* eff_len_options,
-    const PSIBlastOptions* psi_options, 
-    const BlastDatabaseOptions* db_options, 
-    BlastHSPStream* hsp_stream, 
+    const PSIBlastOptions* psi_options,
+    const BlastDatabaseOptions* db_options,
+    BlastHSPStream* hsp_stream,
     BlastDiagnostics* diagnostics,
     TInterruptFnPtr interrupt_search, SBlastProgress* progress_info)
 {
     Int2 status = 0;
     BlastScoringParameters* score_params = NULL;/**< Scoring parameters */
-    BlastExtensionParameters* ext_params = NULL;/**< Gapped extension 
+    BlastExtensionParameters* ext_params = NULL;/**< Gapped extension
                                                     parameters */
     BlastHitSavingParameters* hit_params = NULL;/**< Hit saving parameters */
-    BlastEffectiveLengthsParameters* eff_len_params = NULL; /**< Parameters 
+    BlastEffectiveLengthsParameters* eff_len_params = NULL; /**< Parameters
                                           for effective lengths calculations */
     BlastGapAlignStruct* gap_align = NULL; /**< Gapped alignment structure */
-    
-    /* Use a local diagnostics structure, because the one passed in an input 
+
+    /* Use a local diagnostics structure, because the one passed in an input
       argument can be shared between multiple threads, so we don't want to pass
       it to the engine and have a lot of mutex contention. */
     BlastDiagnostics* local_diagnostics = Blast_DiagnosticsInit();
 
-    if ((status = 
-        BLAST_GapAlignSetUp(program, seq_src, score_options, 
-                            eff_len_options, ext_options, hit_options, 
-                            query_info, sbp, &score_params, &ext_params, 
+    if ((status =
+        BLAST_GapAlignSetUp(program, seq_src, score_options,
+                            eff_len_options, ext_options, hit_options,
+                            query_info, sbp, &score_params, &ext_params,
                             &hit_params, &eff_len_params, &gap_align)) != 0)
       return status;
-    
+
     if ((status=
-        BLAST_PreliminarySearchEngine(program, query, query_info, 
-                                      seq_src, gap_align, score_params, 
-                                      lookup_wrap, word_options, 
+        BLAST_PreliminarySearchEngine(program, query, query_info,
+                                      seq_src, gap_align, score_params,
+                                      lookup_wrap, word_options,
                                       ext_params, hit_params, eff_len_params,
-                                      psi_options, db_options, hsp_stream, 
-                                      local_diagnostics, interrupt_search, 
-                                      progress_info)) != 0) 
+                                      psi_options, db_options, hsp_stream,
+                                      local_diagnostics, interrupt_search,
+                                      progress_info)) != 0)
       return status;
 
     /* Do not destruct score block here */
     gap_align->sbp = NULL;
     gap_align = BLAST_GapAlignStructFree(gap_align);
-    
+
     score_params = BlastScoringParametersFree(score_params);
     hit_params = BlastHitSavingParametersFree(hit_params);
     ext_params = BlastExtensionParametersFree(ext_params);
     eff_len_params = BlastEffectiveLengthsParametersFree(eff_len_params);
-    
+
     /* Now update the input diagonistics structure. */
     Blast_DiagnosticsUpdate(diagnostics, local_diagnostics);
     Blast_DiagnosticsFree(local_diagnostics);
@@ -1589,19 +1827,19 @@ s_BlastRunFullSearchCleanUp(BlastGapAlignStruct* gap_align,
     BlastEffectiveLengthsParametersFree(eff_len_params);
 }
 
-Int4 
-Blast_RunFullSearch(EBlastProgramType program_number, 
+Int4
+Blast_RunFullSearch(EBlastProgramType program_number,
     BLAST_SequenceBlk* query, BlastQueryInfo* query_info,
     const BlastSeqSrc* seq_src,  BlastScoreBlk* sbp,
-    const BlastScoringOptions* score_options, 
+    const BlastScoringOptions* score_options,
     LookupTableWrap* lookup_wrap,
-    const BlastInitialWordOptions* word_options, 
-    const BlastExtensionOptions* ext_options, 
+    const BlastInitialWordOptions* word_options,
+    const BlastExtensionOptions* ext_options,
     const BlastHitSavingOptions* hit_options,
     const BlastEffectiveLengthsOptions* eff_len_options,
-    const PSIBlastOptions* psi_options, 
+    const PSIBlastOptions* psi_options,
     const BlastDatabaseOptions* db_options,
-    BlastHSPStream* hsp_stream, const BlastRPSInfo* rps_info, 
+    BlastHSPStream* hsp_stream, const BlastRPSInfo* rps_info,
     BlastDiagnostics* diagnostics, BlastHSPResults** results,
     TInterruptFnPtr interrupt_search,
     SBlastProgress* progress_info)
@@ -1614,44 +1852,44 @@ Blast_RunFullSearch(EBlastProgramType program_number,
     BlastGapAlignStruct* gap_align = NULL;
     SPHIPatternSearchBlk* pattern_blk = NULL;
 
-    if ((status = 
-        BLAST_GapAlignSetUp(program_number, seq_src, score_options, 
-           eff_len_options, ext_options, hit_options, query_info, sbp, 
-           &score_params, &ext_params, &hit_params, &eff_len_params, 
+    if ((status =
+        BLAST_GapAlignSetUp(program_number, seq_src, score_options,
+           eff_len_options, ext_options, hit_options, query_info, sbp,
+           &score_params, &ext_params, &hit_params, &eff_len_params,
            &gap_align)) != 0) {
-       s_BlastRunFullSearchCleanUp(gap_align, score_params, ext_params, 
+       s_BlastRunFullSearchCleanUp(gap_align, score_params, ext_params,
                                    hit_params, eff_len_params);
        return status;
     }
-      
+
     if ((status=
-        BLAST_PreliminarySearchEngine(program_number, query, query_info, 
-           seq_src, gap_align, score_params, lookup_wrap, word_options, 
-           ext_params, hit_params, eff_len_params, psi_options, 
-           db_options, hsp_stream, diagnostics, interrupt_search, 
+        BLAST_PreliminarySearchEngine(program_number, query, query_info,
+           seq_src, gap_align, score_params, lookup_wrap, word_options,
+           ext_params, hit_params, eff_len_params, psi_options,
+           db_options, hsp_stream, diagnostics, interrupt_search,
            progress_info)) != 0) {
-       s_BlastRunFullSearchCleanUp(gap_align, score_params, ext_params, 
+       s_BlastRunFullSearchCleanUp(gap_align, score_params, ext_params,
                                    hit_params, eff_len_params);
        return status;
     }
-    
+
     /* Prohibit any subsequent writing to the HSP stream. */
     BlastHSPStreamClose(hsp_stream);
 
     if (Blast_ProgramIsPhiBlast(program_number)) {
        pattern_blk = ((SPHIPatternSearchBlk*) lookup_wrap->lut);
-       pattern_blk->num_patterns_db = 
+       pattern_blk->num_patterns_db =
                         (Int4)diagnostics->ungapped_stat->lookup_hits;
-    } 
+    }
 
-    if ((status = 
+    if ((status =
         BLAST_ComputeTraceback(program_number, hsp_stream, query, query_info,
-                               seq_src, gap_align, score_params, ext_params, 
-                               hit_params, eff_len_params, db_options, 
+                               seq_src, gap_align, score_params, ext_params,
+                               hit_params, eff_len_params, db_options,
                                psi_options, rps_info, pattern_blk, results,
                                interrupt_search, progress_info))
        != 0) {
-       s_BlastRunFullSearchCleanUp(gap_align, score_params, ext_params, 
+       s_BlastRunFullSearchCleanUp(gap_align, score_params, ext_params,
                                    hit_params, eff_len_params);
        return status;
     }
diff --git a/c++/src/algo/blast/core/blast_extend.c b/c++/src/algo/blast/core/blast_extend.c
index 60db56f..36ecdd6 100644
--- a/c++/src/algo/blast/core/blast_extend.c
+++ b/c++/src/algo/blast/core/blast_extend.c
@@ -1,4 +1,4 @@
-/* $Id: blast_extend.c 167284 2009-07-30 19:29:38Z maning $
+/* $Id: blast_extend.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -28,11 +28,6 @@
  * Functions to initialize structures used for BLAST extension
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_extend.c 167284 2009-07-30 19:29:38Z maning $";
-#endif                          /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_extend.h>
 #include <algo/blast/core/blast_options.h>
 
diff --git a/c++/src/algo/blast/core/blast_filter.c b/c++/src/algo/blast/core/blast_filter.c
index 8ad388b..8b44c9c 100644
--- a/c++/src/algo/blast/core/blast_filter.c
+++ b/c++/src/algo/blast/core/blast_filter.c
@@ -1,4 +1,4 @@
-/* $Id: blast_filter.c 306966 2011-06-20 13:16:49Z maning $
+/* $Id: blast_filter.c 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -28,11 +28,6 @@
  * All code related to query sequence masking/filtering for BLAST
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_filter.c 306966 2011-06-20 13:16:49Z maning $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_util.h>
 #include <algo/blast/core/blast_filter.h>
 #include <algo/blast/core/blast_seg.h>
@@ -575,7 +570,9 @@ BlastFilteringOptionsFromString(EBlastProgramType program_number,
                 }
 		else if (*ptr == 'L' || *ptr == 'T')
 		{ /* do low-complexity filtering; dust for blastn, otherwise seg.*/
-                        if (program_number == eBlastTypeBlastn)
+                        if (program_number == eBlastTypeBlastn
+                            || program_number == eBlastTypeMapping)
+
                             SDustOptionsNew(&dustOptions);
                         else
                             SSegOptionsNew(&segOptions);
@@ -1021,7 +1018,8 @@ BLAST_ComplementMaskLocations(EBlastProgramType program_number,
    const BlastMaskLoc* mask_loc, BlastSeqLoc* *complement_mask) 
 {
    Int4 context;
-   const Boolean kIsNucl = (program_number == eBlastTypeBlastn);
+   const Boolean kIsNucl = (program_number == eBlastTypeBlastn ||
+                            program_number == eBlastTypeMapping);
    BlastSeqLoc* tail = NULL;    /* Pointer to the tail of the complement_mask
                                    linked list */
 
@@ -1196,7 +1194,8 @@ s_GetFilteringLocationsForOneContext(BLAST_SequenceBlk* query_blk,
     Int4 context_offset;
     Uint1 *buffer;              /* holds sequence for plus strand or protein. */
 
-    const Boolean kIsNucl = (program_number == eBlastTypeBlastn);
+    const Boolean kIsNucl = (program_number == eBlastTypeBlastn ||
+                             program_number == eBlastTypeMapping);
 
     context_offset = query_info->contexts[context].query_offset;
     buffer = &query_blk->sequence[context_offset];
@@ -1345,7 +1344,8 @@ BlastSetUp_MaskQuery(BLAST_SequenceBlk* query_blk,
                      const BlastMaskLoc *filter_maskloc, 
                      EBlastProgramType program_number)
 {
-    const Boolean kIsNucl = (program_number == eBlastTypeBlastn);
+    const Boolean kIsNucl = (program_number == eBlastTypeBlastn
+                             || program_number == eBlastTypeMapping);
     Int4 context; /* loop variable. */
     Int4 total_length;
     Boolean has_mask = FALSE; /* Check for whether filter_maskloc is empty. */
diff --git a/c++/src/algo/blast/core/blast_gapalign.c b/c++/src/algo/blast/core/blast_gapalign.c
index ebce005..ea07745 100644
--- a/c++/src/algo/blast/core/blast_gapalign.c
+++ b/c++/src/algo/blast/core/blast_gapalign.c
@@ -1,4 +1,4 @@
-/* $Id: blast_gapalign.c 473564 2015-07-21 15:29:04Z madden $
+/* $Id: blast_gapalign.c 516338 2016-10-12 17:32:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
  * Functions to perform gapped alignment
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_gapalign.c 473564 2015-07-21 15:29:04Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/ncbi_math.h>
 #include <algo/blast/core/blast_gapalign.h>
 #include <algo/blast/core/blast_util.h> /* for NCBI2NA_UNPACK_BASE macros */
@@ -42,18 +37,19 @@ static char const rcsid[] =
 #include "blast_gapalign_priv.h"
 #include "blast_hits_priv.h"
 #include "blast_itree.h"
+#include "jumper.h"
 
-static Int2 s_BlastDynProgNtGappedAlignment(BLAST_SequenceBlk* query_blk, 
-   BLAST_SequenceBlk* subject_blk, BlastGapAlignStruct* gap_align, 
+static Int2 s_BlastDynProgNtGappedAlignment(BLAST_SequenceBlk* query_blk,
+   BLAST_SequenceBlk* subject_blk, BlastGapAlignStruct* gap_align,
    const BlastScoringParameters* score_params, BlastInitHSP* init_hsp);
-static Int4 s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M, 
+static Int4 s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M,
    Int4* pej, Int4* pei, BlastGapAlignStruct* gap_align,
    const BlastScoringParameters* score_params, Boolean reverse_sequence);
 
-static Int2 s_BlastProtGappedAlignment(EBlastProgramType program, 
+static Int2 s_BlastProtGappedAlignment(EBlastProgramType program,
    BLAST_SequenceBlk* query_in, BLAST_SequenceBlk* subject_in,
    BlastGapAlignStruct* gap_align,
-   const BlastScoringParameters* score_params, 
+   const BlastScoringParameters* score_params,
    BlastInitHSP* init_hsp, Boolean restricted_alignment,
    Boolean * fence_hit);
 
@@ -64,9 +60,9 @@ static Int2 s_BlastProtGappedAlignment(EBlastProgramType program,
 #define	CHUNKSIZE	2097152
 
 /** Retrieve the state structure corresponding to a given length
- * @param head Pointer to the first element of the state structures 
+ * @param head Pointer to the first element of the state structures
  *        array [in]
- * @param length The length for which the state structure has to be 
+ * @param length The length for which the state structure has to be
  *        found [in]
  * @return The found or created state structure
  */
@@ -80,7 +76,7 @@ s_GapGetState(GapStateArrayStruct** head, Int4 length)
    length += length/3;	/* Add on about 30% so the end will get reused. */
    retval = NULL;
    if (*head == NULL) {
-      retval = (GapStateArrayStruct*) 
+      retval = (GapStateArrayStruct*)
          malloc(sizeof(GapStateArrayStruct));
       retval->state_array = (Uint1*) malloc(chunksize*sizeof(Uint1));
       retval->length = chunksize;
@@ -94,7 +90,7 @@ s_GapGetState(GapStateArrayStruct** head, Int4 length)
          if (length < (var->length - var->used)) {
             retval = var;
             break;
-         } else if (var->used == 0) { 
+         } else if (var->used == 0) {
             /* If it's empty and too small, replace. */
             sfree(var->state_array);
             var->state_array = (Uint1*) malloc(chunksize*sizeof(Uint1));
@@ -105,7 +101,7 @@ s_GapGetState(GapStateArrayStruct** head, Int4 length)
          last = var;
          var = var->next;
       }
-      
+
       if (var == NULL)
       {
          retval = (GapStateArrayStruct*) malloc(sizeof(GapStateArrayStruct));
@@ -121,7 +117,7 @@ s_GapGetState(GapStateArrayStruct** head, Int4 length)
    if (retval->state_array == NULL)
       ErrPostEx(SEV_ERROR, 0, 0, "state array is NULL");
 #endif
-		
+
    return retval;
 
 }
@@ -138,12 +134,12 @@ s_GapPurgeState(GapStateArrayStruct* state_struct)
       state_struct->used = 0;
       state_struct = state_struct->next;
    }
-   
+
    return TRUE;
 }
 
 /** Deallocate the memory for greedy gapped alignment */
-static SGreedyAlignMem* 
+static SGreedyAlignMem*
 s_BlastGreedyAlignsFree(SGreedyAlignMem* gamp)
 {
    if (gamp->last_seq2_off) {
@@ -170,7 +166,7 @@ s_BlastGreedyAlignsFree(SGreedyAlignMem* gamp)
  * @param Xdrop The Xdrop value [in]
  * @return The allocated SGreedyAlignMem structure
  */
-static SGreedyAlignMem* 
+static SGreedyAlignMem*
 s_BlastGreedyAlignMemAlloc(const BlastScoringParameters* score_params,
 		       const BlastExtensionParameters* ext_params,
 		       Int4 max_d, Int4 Xdrop)
@@ -179,14 +175,14 @@ s_BlastGreedyAlignMemAlloc(const BlastScoringParameters* score_params,
    Int4 max_d_1, d_diff, max_cost, gd, i;
    Int4 reward, penalty, gap_open, gap_extend;
    Int4 Mis_cost, GE_cost;
-   
+
    if (score_params == NULL || (!ext_params && !Xdrop))
       return NULL;
-   
+
    if (score_params->reward % 2 == 1) {
       reward = 2*score_params->reward;
       penalty = -2*score_params->penalty;
-      if (!Xdrop) 
+      if (!Xdrop)
           Xdrop = 2*MAX(ext_params->gap_x_dropoff,
                     ext_params->gap_x_dropoff_final);
       gap_open = 2*score_params->gap_open;
@@ -210,18 +206,18 @@ s_BlastGreedyAlignMemAlloc(const BlastScoringParameters* score_params,
 
    if (score_params->gap_open==0 && score_params->gap_extend==0) {
       d_diff = (Xdrop+reward/2)/(penalty+reward)+1;
-   
+
       gamp->last_seq2_off = (Int4**) malloc((max_d + 2) * sizeof(Int4*));
       if (gamp->last_seq2_off == NULL) {
          sfree(gamp);
          return NULL;
       }
-      gamp->last_seq2_off[0] = 
+      gamp->last_seq2_off[0] =
          (Int4*) malloc((max_d + max_d + 6) * sizeof(Int4) * 2);
       if (gamp->last_seq2_off[0] == NULL) {
 #ifdef ERR_POST_EX_DEFINED
-	 ErrPostEx(SEV_WARNING, 0, 0, 
-              "Failed to allocate %ld bytes for greedy alignment", 
+	 ErrPostEx(SEV_WARNING, 0, 0,
+              "Failed to allocate %ld bytes for greedy alignment",
               (max_d + max_d + 6) * sizeof(Int4) * 2);
 #endif
          s_BlastGreedyAlignsFree(gamp);
@@ -241,7 +237,7 @@ s_BlastGreedyAlignMemAlloc(const BlastScoringParameters* score_params,
       gd = BLAST_Gdb3(&Mis_cost, &gap_open, &GE_cost);
       d_diff = (Xdrop+reward/2)/gd+1;
       gamp->diag_bounds = (Int4*) calloc(2*(max_d+1+max_cost), sizeof(Int4));
-      gamp->last_seq2_off_affine = (SGreedyOffset**) 
+      gamp->last_seq2_off_affine = (SGreedyOffset**)
 	 malloc((MAX(max_d, max_cost) + 2) * sizeof(SGreedyOffset*));
       if (!gamp->diag_bounds || !gamp->last_seq2_off_affine) {
          s_BlastGreedyAlignsFree(gamp);
@@ -250,7 +246,7 @@ s_BlastGreedyAlignMemAlloc(const BlastScoringParameters* score_params,
       gamp->last_seq2_off_affine[0] = (SGreedyOffset*)
 	 calloc((2*max_d_1 + 6) , sizeof(SGreedyOffset) * (max_cost+1));
       for (i = 1; i <= max_cost; i++)
-	 gamp->last_seq2_off_affine[i] = 
+	 gamp->last_seq2_off_affine[i] =
 	    gamp->last_seq2_off_affine[i-1] + 2*max_d_1 + 6;
       if (!gamp->last_seq2_off_affine || !gamp->last_seq2_off_affine[0]) {
          s_BlastGreedyAlignsFree(gamp);
@@ -268,7 +264,7 @@ s_BlastGreedyAlignMemAlloc(const BlastScoringParameters* score_params,
 }
 
 /* Documented in blast_gapalign.h */
-BlastGapAlignStruct* 
+BlastGapAlignStruct*
 BLAST_GapAlignStructFree(BlastGapAlignStruct* gap_align)
 {
    if (!gap_align)
@@ -281,6 +277,7 @@ BLAST_GapAlignStructFree(BlastGapAlignStruct* gap_align)
       s_BlastGreedyAlignsFree(gap_align->greedy_align_mem);
    GapStateFree(gap_align->state_struct);
    sfree(gap_align->dp_mem);
+   JumperGapAlignFree(gap_align->jumper);
 
    sfree(gap_align);
    return NULL;
@@ -288,8 +285,8 @@ BLAST_GapAlignStructFree(BlastGapAlignStruct* gap_align)
 
 /* Documented in blast_gapalign.h */
 Int2
-BLAST_GapAlignStructNew(const BlastScoringParameters* score_params, 
-   const BlastExtensionParameters* ext_params, 
+BLAST_GapAlignStructNew(const BlastScoringParameters* score_params,
+   const BlastExtensionParameters* ext_params,
    Uint4 max_subject_length,
    BlastScoreBlk* sbp, BlastGapAlignStruct** gap_align_ptr)
 {
@@ -306,25 +303,33 @@ BLAST_GapAlignStructNew(const BlastScoringParameters* score_params,
    gap_align->sbp = sbp;
 
    gap_align->gap_x_dropoff = ext_params->gap_x_dropoff;
-
-   if (ext_params->options->ePrelimGapExt == eDynProgScoreOnly) {
-      /* allocate structures for ordinary dynamic programming */
-      gap_align->dp_mem_alloc = 1000;
-      gap_align->dp_mem = (BlastGapDP *)malloc(gap_align->dp_mem_alloc *
-                                               sizeof(BlastGapDP));
-      if (!gap_align->dp_mem)
-         gap_align = BLAST_GapAlignStructFree(gap_align);
+   gap_align->max_mismatches = ext_params->options->max_mismatches;
+   gap_align->mismatch_window = ext_params->options->mismatch_window;
+
+   /* allocate memory either for dynamic programming or jumper */
+   if (ext_params->options->ePrelimGapExt != eJumperWithTraceback) {
+       if (ext_params->options->ePrelimGapExt == eDynProgScoreOnly) {
+	   /* allocate structures for ordinary dynamic programming */
+	   gap_align->dp_mem_alloc = 1000;
+	   gap_align->dp_mem = (BlastGapDP *)malloc(gap_align->dp_mem_alloc *
+						    sizeof(BlastGapDP));
+	   if (!gap_align->dp_mem)
+	       gap_align = BLAST_GapAlignStructFree(gap_align);
+       }
+       else {
+	   /* allocate structures for greedy dynamic programming */
+	   max_subject_length = MIN(max_subject_length, MAX_DBSEQ_LEN);
+	   max_subject_length = MIN(GREEDY_MAX_COST,
+			    max_subject_length / GREEDY_MAX_COST_FRACTION + 1);
+	   gap_align->greedy_align_mem =
+	       s_BlastGreedyAlignMemAlloc(score_params, ext_params,
+					  max_subject_length, 0);
+	   if (!gap_align->greedy_align_mem)
+	       gap_align = BLAST_GapAlignStructFree(gap_align);
+       }
    }
    else {
-      /* allocate structures for greedy dynamic programming */
-      max_subject_length = MIN(max_subject_length, MAX_DBSEQ_LEN);
-      max_subject_length = MIN(GREEDY_MAX_COST,
-                      max_subject_length / GREEDY_MAX_COST_FRACTION + 1);
-      gap_align->greedy_align_mem = 
-         s_BlastGreedyAlignMemAlloc(score_params, ext_params, 
-                                    max_subject_length, 0);
-      if (!gap_align->greedy_align_mem)
-         gap_align = BLAST_GapAlignStructFree(gap_align);
+       gap_align->jumper = JumperGapAlignNew(200);
    }
 
    if (!gap_align)
@@ -350,22 +355,22 @@ enum {
 };
 
 Int4
-ALIGN_EX(const Uint1* A, const Uint1* B, Int4 M, Int4 N, Int4* a_offset, 
-	Int4* b_offset, GapPrelimEditBlock *edit_block, 
-        BlastGapAlignStruct* gap_align, 
-        const BlastScoringParameters* score_params, Int4 query_offset, 
+ALIGN_EX(const Uint1* A, const Uint1* B, Int4 M, Int4 N, Int4* a_offset,
+	Int4* b_offset, GapPrelimEditBlock *edit_block,
+        BlastGapAlignStruct* gap_align,
+        const BlastScoringParameters* score_params, Int4 query_offset,
         Boolean reversed, Boolean reverse_sequence,
         Boolean * fence_hit)
 {
-    /* See Blast_SemiGappedAlign for more general comments on 
+    /* See Blast_SemiGappedAlign for more general comments on
        what this code is doing; comments in this function
        only apply to the traceback computations */
 
-    Int4 i; 
+    Int4 i;
     Int4 a_index;
     Int4 b_index, b_size, first_b_index, last_b_index, b_increment;
     const Uint1* b_ptr;
-  
+
     BlastGapDP* score_array;
 
     Int4 gap_open;
@@ -373,16 +378,16 @@ ALIGN_EX(const Uint1* A, const Uint1* B, Int4 M, Int4 N, Int4* a_offset,
     Int4 gap_open_extend;
     Int4 x_dropoff;
     Int4 best_score;
-  
+
     Int4** matrix = NULL;
     Int4** pssm = NULL;
     Int4* matrix_row = NULL;
-  
+
     Int4 score;
     Int4 score_gap_row;
     Int4 score_gap_col;
     Int4 next_score;
-  
+
     GapStateArrayStruct* state_struct;
     Uint1* edit_script_row;
     Uint1** edit_script;
@@ -403,15 +408,15 @@ ALIGN_EX(const Uint1* A, const Uint1* B, Int4 M, Int4 N, Int4* a_offset,
     gap_extend = score_params->gap_extend;
     gap_open_extend = gap_open + gap_extend;
     x_dropoff = gap_align->gap_x_dropoff;
-  
+
     if (x_dropoff < gap_open_extend)
         x_dropoff = gap_open_extend;
-  
-    if(N <= 0 || M <= 0) 
+
+    if(N <= 0 || M <= 0)
         return 0;
-  
+
     /* Initialize traceback information. edit_script[] is
-       a 2-D array which is filled in row by row as the 
+       a 2-D array which is filled in row by row as the
        dynamic programming takes place */
 
     s_GapPurgeState(gap_align->state_struct);
@@ -421,7 +426,7 @@ ALIGN_EX(const Uint1* A, const Uint1* B, Int4 M, Int4 N, Int4* a_offset,
        separately. edit_script[i] points to the storage reserved
        for row i, and edit_start_offset[i] gives the offset into
        the B sequence corresponding to element 0 of edit_script[i].
-       
+
        Also make the number of edit script rows grow dynamically */
 
     edit_script_num_rows = 100;
@@ -456,18 +461,18 @@ ALIGN_EX(const Uint1* A, const Uint1* B, Int4 M, Int4 N, Int4* a_offset,
     score_array = gap_align->dp_mem;
     score_array[0].best = 0;
     score_array[0].best_gap = -gap_open_extend;
-  
+
     for (i = 1; i <= N; i++) {
-        if (score < -x_dropoff) 
+        if (score < -x_dropoff)
             break;
 
         score_array[i].best = score;
-        score_array[i].best_gap = score - gap_open_extend; 
+        score_array[i].best_gap = score - gap_open_extend;
         score -= gap_extend;
         edit_script_row[i] = SCRIPT_GAP_IN_A;
     }
     state_struct->used = i + 1;
-  
+
     b_size = i;
     best_score = 0;
     first_b_index = 0;
@@ -475,39 +480,39 @@ ALIGN_EX(const Uint1* A, const Uint1* B, Int4 M, Int4 N, Int4* a_offset,
         b_increment = -1;
     else
         b_increment = 1;
-  
+
     for (a_index = 1; a_index <= M; a_index++) {
 
         /* Set up the next row of the edit script; this involves
            allocating memory for the row, then pointing to it.
            It is not necessary to allocate space for offsets less
-           than first_b_index (since the inner loop will never 
-           look at them); 
-           
-           It is unknown at this point how far to the right the 
+           than first_b_index (since the inner loop will never
+           look at them);
+
+           It is unknown at this point how far to the right the
            current traceback row will extend; all that's known for
            sure is that the previous row fails the X-dropoff test
            after b_size cells, and that the current row can go at
            most num_extra_cells beyond that before failing the test */
 
         if (gap_extend > 0)
-            state_struct = s_GapGetState(&gap_align->state_struct, 
+            state_struct = s_GapGetState(&gap_align->state_struct,
                            b_size - first_b_index + num_extra_cells);
         else
-            state_struct = s_GapGetState(&gap_align->state_struct, 
+            state_struct = s_GapGetState(&gap_align->state_struct,
                                         N + 3 - first_b_index);
 
         if (a_index == edit_script_num_rows) {
             edit_script_num_rows = edit_script_num_rows * 2;
-            edit_script = (Uint1 **)realloc(edit_script, 
+            edit_script = (Uint1 **)realloc(edit_script,
                                             edit_script_num_rows *
                                             sizeof(Uint1 *));
-            edit_start_offset = (Int4 *)realloc(edit_start_offset, 
+            edit_start_offset = (Int4 *)realloc(edit_start_offset,
                                                 edit_script_num_rows *
                                                 sizeof(Int4));
         }
 
-        edit_script[a_index] = state_struct->state_array + 
+        edit_script[a_index] = state_struct->state_array +
                                 state_struct->used + 1;
         edit_start_offset[a_index] = first_b_index;
 
@@ -544,17 +549,18 @@ ALIGN_EX(const Uint1* A, const Uint1* B, Int4 M, Int4 N, Int4* a_offset,
 
             b_ptr += b_increment;
             score_gap_col = score_array[b_index].best_gap;
-            
+
             matrix_index = *b_ptr;
-            
+
             if (matrix_index == FENCE_SENTRY) {
-                ASSERT(fence_hit);
-                *fence_hit = 1;
+                if (fence_hit) {
+                    *fence_hit = 1;
+                }
                 break;
             }
-            
+
             next_score = score_array[b_index].best + matrix_row[ *b_ptr ];
-            
+
             /* script, script_row and script_col contain the
                actions specified by the dynamic programming.
                when the inner loop has finished, 'script' con-
@@ -601,7 +607,7 @@ ALIGN_EX(const Uint1* A, const Uint1* B, Int4 M, Int4 N, Int4* a_offset,
                     script += script_col;
                 }
 
-                if (score_gap_row < (score - gap_open_extend)) 
+                if (score_gap_row < (score - gap_open_extend))
                     score_gap_row = score - gap_open_extend;
                 else
                     script += script_row;
@@ -612,7 +618,7 @@ ALIGN_EX(const Uint1* A, const Uint1* B, Int4 M, Int4 N, Int4* a_offset,
             score = next_score;
             edit_script_row[b_index] = script;
         }
-        
+
         if (first_b_index == b_size || (fence_hit && *fence_hit))
             break;
 
@@ -652,45 +658,45 @@ ALIGN_EX(const Uint1* A, const Uint1* B, Int4 M, Int4 N, Int4* a_offset,
             b_size++;
         }
     }
-    
+
     /* Pick the optimal path through the now complete
-       edit_script[][]. This is equivalent to flattening 
+       edit_script[][]. This is equivalent to flattening
        the 2-D array into a 1-D list of actions. */
 
     a_index = *a_offset;
     b_index = *b_offset;
     script = SCRIPT_SUB;
-    
+
     if (fence_hit && *fence_hit)
         goto done;
-    
+
     while (a_index > 0 || b_index > 0) {
         /* Retrieve the next action to perform. Rows of
            the traceback array do not necessarily start
            at offset zero of B, so a correction is needed
            to point to the correct position */
-            
-        next_script = 
+
+        next_script =
             edit_script[a_index][b_index - edit_start_offset[a_index]];
-            
+
         switch(script) {
         case SCRIPT_GAP_IN_A:
             script = next_script & SCRIPT_OP_MASK;
             if (next_script & SCRIPT_EXTEND_GAP_A)
                 script = SCRIPT_GAP_IN_A;
             break;
-                
+
         case SCRIPT_GAP_IN_B:
             script = next_script & SCRIPT_OP_MASK;
             if (next_script & SCRIPT_EXTEND_GAP_B)
                 script = SCRIPT_GAP_IN_B;
             break;
-                
+
         default:
             script = next_script & SCRIPT_OP_MASK;
             break;
         }
-            
+
         if (script == SCRIPT_GAP_IN_A) {
             b_index--;
         }
@@ -703,18 +709,18 @@ ALIGN_EX(const Uint1* A, const Uint1* B, Int4 M, Int4 N, Int4* a_offset,
         }
         GapPrelimEditBlockAdd(edit_block, (EGapAlignOpType)script, 1);
     }
-    
+
  done:
     sfree(edit_start_offset);
     sfree(edit_script);
     return best_score;
 }
 
-Int4 
+Int4
 Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
-   Int4* a_offset, Int4* b_offset, Boolean score_only, 
-   GapPrelimEditBlock *edit_block, BlastGapAlignStruct* gap_align, 
-   const BlastScoringParameters* score_params, 
+   Int4* a_offset, Int4* b_offset, Boolean score_only,
+   GapPrelimEditBlock *edit_block, BlastGapAlignStruct* gap_align,
+   const BlastScoringParameters* score_params,
    Int4 query_offset, Boolean reversed, Boolean reverse_sequence,
    Boolean * fence_hit)
 {
@@ -722,31 +728,31 @@ Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     Int4 a_index;
     Int4 b_index, b_size, first_b_index, last_b_index, b_increment;
     const Uint1* b_ptr;
-  
+
     BlastGapDP* score_array;
 
     Int4 gap_open;              /* alignment penalty variables */
     Int4 gap_extend;
     Int4 gap_open_extend;
     Int4 x_dropoff;
-  
+
     Int4** matrix = NULL;       /* pointers to the score matrix */
     Int4** pssm = NULL;
     Int4* matrix_row = NULL;
-  
+
     Int4 score;                 /* score tracking variables */
     Int4 score_gap_row;
     Int4 score_gap_col;
     Int4 next_score;
     Int4 best_score;
     Int4 num_extra_cells;
-  
+
     if (!score_only) {
-        return ALIGN_EX(A, B, M, N, a_offset, b_offset, edit_block, gap_align, 
+        return ALIGN_EX(A, B, M, N, a_offset, b_offset, edit_block, gap_align,
                         score_params, query_offset, reversed, reverse_sequence,
                         fence_hit);
     }
-    
+
     /* do initialization and sanity-checking */
 
     matrix = gap_align->sbp->matrix->data;
@@ -759,13 +765,13 @@ Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     gap_extend = score_params->gap_extend;
     gap_open_extend = gap_open + gap_extend;
     x_dropoff = gap_align->gap_x_dropoff;
-  
+
     if (x_dropoff < gap_open_extend)
         x_dropoff = gap_open_extend;
-  
-    if(N <= 0 || M <= 0) 
+
+    if(N <= 0 || M <= 0)
         return 0;
-  
+
     /* Allocate and fill in the auxiliary bookeeping structures.
        Since A and B could be very large, maintain a window
        of auxiliary structures only large enough to contain to current
@@ -789,17 +795,17 @@ Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     score = -gap_open_extend;
     score_array[0].best = 0;
     score_array[0].best_gap = -gap_open_extend;
-  
+
     for (i = 1; i <= N; i++) {
-        if (score < -x_dropoff) 
+        if (score < -x_dropoff)
             break;
 
         score_array[i].best = score;
-        score_array[i].best_gap = score - gap_open_extend; 
+        score_array[i].best_gap = score - gap_open_extend;
         score -= gap_extend;
     }
-  
-    /* The inner loop below examines letters of B from 
+
+    /* The inner loop below examines letters of B from
        index 'first_b_index' to 'b_size' */
 
     b_size = i;
@@ -809,9 +815,9 @@ Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         b_increment = -1;
     else
         b_increment = 1;
-  
+
     for (a_index = 1; a_index <= M; a_index++) {
-        /* pick out the row of the score matrix 
+        /* pick out the row of the score matrix
            appropriate for A[a_index] */
 
         if (!(gap_align->positionBased)) {
@@ -823,7 +829,7 @@ Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         else {
             if(reversed || reverse_sequence)
                 matrix_row = pssm[M - a_index];
-            else 
+            else
                 matrix_row = pssm[a_index + query_offset];
         }
 
@@ -854,11 +860,11 @@ Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                 /* the current best score failed the X-dropoff
                    criterion. Note that this does not stop the
                    inner loop, only forces future iterations to
-                   skip this column of B. 
+                   skip this column of B.
 
                    Also, if the very first letter of B that was
                    tested failed the X dropoff criterion, make
-                   sure future inner loops start one letter to 
+                   sure future inner loops start one letter to
                    the right */
 
                 if (b_index == first_b_index)
@@ -875,7 +881,7 @@ Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                 }
 
                 /* If starting a gap at this position will improve
-                   the best row, or column, score, update them to 
+                   the best row, or column, score, update them to
                    reflect that. */
 
                 score_gap_row -= gap_extend;
@@ -890,7 +896,7 @@ Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         }
 
         /* Finish aligning if the best scores for all positions
-           of B will fail the X-dropoff test, i.e. the inner loop 
+           of B will fail the X-dropoff test, i.e. the inner loop
            bounds have converged to each other */
 
         if (first_b_index == b_size)
@@ -918,7 +924,7 @@ Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         else {
             /* The inner loop finished without failing the X-dropoff
                test; initialize extra bookkeeping structures until
-               the X dropoff test fails or we run out of letters in B. 
+               the X dropoff test fails or we run out of letters in B.
                The next inner loop will have larger bounds */
 
             while (score_gap_row >= (best_score - x_dropoff) && b_size <= N) {
@@ -935,7 +941,7 @@ Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             b_size++;
         }
     }
-    
+
     return best_score;
 }
 
@@ -943,12 +949,12 @@ Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     this many sequence offsets */
 #define RESTRICT_SIZE 10
 
-/** Low level function to perform score-only gapped extension 
+/** Low level function to perform score-only gapped extension
  *  in one direction. Gaps in one sequence or the other are only
  *  allowed to start at sequence offsets that are a multiple of
  *  RESTRICT_SIZE from the alignment start point. For more details see
  * <PRE>
- * Michael Cameron, Hugh E. Williams, Adam Cannane, "Improved 
+ * Michael Cameron, Hugh E. Williams, Adam Cannane, "Improved
  * Gapped Alignment in BLAST". IEEE/ACM Transactions on Computational
  * Biology and Bioinformatics, vol 1 #3 (2004) pp 116-129
  * </PRE>
@@ -958,18 +964,18 @@ Blast_SemiGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
  * @param N Maximal extension length in subject [in]
  * @param a_offset Resulting starting offset in query [out]
  * @param b_offset Resulting starting offset in subject [out]
- * @param gap_align Structure holding various information and allocated 
+ * @param gap_align Structure holding various information and allocated
  *        memory for the gapped alignment [in]
  * @param score_params Parameters related to scoring [in]
  * @param query_offset The starting offset in query [in]
  * @param reverse_sequence Do reverse the sequence [in]
  * @return The best alignment score found.
  */
-static Int4 
+static Int4
 s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
    Int4* a_offset, Int4* b_offset,
-   BlastGapAlignStruct* gap_align, 
-   const BlastScoringParameters* score_params, 
+   BlastGapAlignStruct* gap_align,
+   const BlastScoringParameters* score_params,
    Int4 query_offset, Boolean reverse_sequence)
 {
     /* see Blast_SemiGappedAlign for general details */
@@ -979,25 +985,25 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     Int4 b_index, b_size, first_b_index, last_b_index, b_increment;
     const Uint1* b_ptr;
     Int4 b_gap;
-  
+
     BlastGapDP* score_array;
 
     Int4 gap_open;
     Int4 gap_extend;
     Int4 gap_open_extend;
     Int4 x_dropoff;
-  
+
     Int4** matrix = NULL;
     Int4** pssm = NULL;
     Int4* matrix_row = NULL;
-  
+
     Int4 score;
     Int4 score_gap_row;
     Int4 score_gap_col;
     Int4 next_score;
     Int4 best_score;
     Int4 num_extra_cells;
-  
+
     matrix = gap_align->sbp->matrix->data;
     if (gap_align->positionBased) {
         pssm = gap_align->sbp->psi_matrix->pssm->data;
@@ -1008,13 +1014,13 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     gap_extend = score_params->gap_extend;
     gap_open_extend = gap_open + gap_extend;
     x_dropoff = gap_align->gap_x_dropoff;
-  
+
     if (x_dropoff < gap_open_extend)
         x_dropoff = gap_open_extend;
-  
-    if(N <= 0 || M <= 0) 
+
+    if(N <= 0 || M <= 0)
         return 0;
-  
+
     if (gap_extend > 0)
         num_extra_cells = x_dropoff / gap_extend + 3;
     else
@@ -1032,16 +1038,16 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     score = -gap_open_extend;
     score_array[0].best = 0;
     score_array[0].best_gap = -gap_open_extend;
-  
+
     for (i = 1; i <= N; i++) {
-        if (score < -x_dropoff) 
+        if (score < -x_dropoff)
             break;
 
         score_array[i].best = score;
-        score_array[i].best_gap = score - gap_open_extend; 
+        score_array[i].best_gap = score - gap_open_extend;
         score -= gap_extend;
     }
-  
+
     b_size = i;
     best_score = 0;
     first_b_index = 0;
@@ -1050,7 +1056,7 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         b_increment = -1;
     else
         b_increment = 1;
-  
+
     for (a_index = 1; a_index <= M; a_index++) {
 
         if (!(gap_align->positionBased)) {
@@ -1062,7 +1068,7 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         else {
             if(reverse_sequence)
                 matrix_row = pssm[M - a_index];
-            else 
+            else
                 matrix_row = pssm[a_index + query_offset];
         }
 
@@ -1077,8 +1083,8 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
 
         /* The double loop that computes the alignment is essentially
            unchanged from that of Blast_SemiGappedAlign. The only
-           real difference is that a gap in A or B is not allowed to 
-           start unless the offset of the gap is divisible by 
+           real difference is that a gap in A or B is not allowed to
+           start unless the offset of the gap is divisible by
            RESTRICT_SIZE. This allows the ordinary dynamic programming
            recurrence relations to be simplified */
 
@@ -1088,7 +1094,7 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                or updating score_gap_row */
 
             for (b_index = first_b_index; b_index < b_size; b_index++) {
-    
+
                 b_ptr += b_increment;
                 next_score = score_array[b_index].best + matrix_row[ *b_ptr ];
 
@@ -1120,10 +1126,10 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
 
                     b_gap += RESTRICT_SIZE;
                     score_gap_col = score_array[b_index].best_gap;
-    
+
                     if (score < score_gap_col)
                         score = score_gap_col;
-        
+
                     if (best_score - score > x_dropoff) {
                         score_array[b_index].best = MININT;
                         if (b_index == first_b_index)
@@ -1136,9 +1142,9 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                             *a_offset = a_index;
                             *b_offset = b_index;
                         }
-        
+
                         score_gap_col -= gap_extend;
-                        score_array[b_index].best_gap = 
+                        score_array[b_index].best_gap =
                                    MAX(score - gap_open_extend, score_gap_col);
                         score_array[b_index].best = score;
                     }
@@ -1153,7 +1159,7 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             /* gap may start in A */
 
             for (b_index = first_b_index; b_index < b_size; b_index++) {
-    
+
                 b_ptr += b_increment;
                 next_score = score_array[b_index].best + matrix_row[ *b_ptr ];
 
@@ -1164,7 +1170,7 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
 
                     if (score < score_gap_row)
                         score = score_gap_row;
-        
+
                     if (best_score - score > x_dropoff) {
                         score_array[b_index].best = MININT;
                         if (b_index == first_b_index)
@@ -1177,15 +1183,15 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                             *a_offset = a_index;
                             *b_offset = b_index;
                         }
-        
+
                         score_gap_row -= gap_extend;
-                        score_gap_row = MAX(score - gap_open_extend, 
+                        score_gap_row = MAX(score - gap_open_extend,
                                             score_gap_row);
                         score_array[b_index].best = score;
                     }
                 }
                 else {
-    
+
                     /* the ordinary case: a gap may start in A
                        or B and the full three-term recurrence
                        must be computed. This happens once every
@@ -1193,12 +1199,12 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
 
                     b_gap += RESTRICT_SIZE;
                     score_gap_col = score_array[b_index].best_gap;
-    
+
                     if (score < score_gap_col)
                         score = score_gap_col;
                     if (score < score_gap_row)
                         score = score_gap_row;
-        
+
                     if (best_score - score > x_dropoff) {
                         score_array[b_index].best = MININT;
                         if (b_index == first_b_index)
@@ -1211,12 +1217,12 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                             *a_offset = a_index;
                             *b_offset = b_index;
                         }
-        
+
                         score_gap_row -= gap_extend;
                         score_gap_col -= gap_extend;
-                        score_array[b_index].best_gap = 
+                        score_array[b_index].best_gap =
                                  MAX(score - gap_open_extend, score_gap_col);
-                        score_gap_row = MAX(score - gap_open_extend, 
+                        score_gap_row = MAX(score - gap_open_extend,
                                             score_gap_row);
                         score_array[b_index].best = score;
                     }
@@ -1252,11 +1258,11 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         else {
             /* The inner loop finished without failing the X-dropoff
                test; initialize extra bookkeeping structures until
-               the X dropoff test fails or we run out of letters in B. 
+               the X dropoff test fails or we run out of letters in B.
                The next inner loop will have larger bounds.
 
                Note that if gaps in A are not allowed for this row, then
-               score_gap_row is -infinity and the loop below will not 
+               score_gap_row is -infinity and the loop below will not
                extend the region to explore */
 
             while (score_gap_row >= (best_score - x_dropoff) && b_size <= N) {
@@ -1273,14 +1279,14 @@ s_RestrictedGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             b_size++;
         }
     }
-    
+
     return best_score;
 }
 
 /** Editing script operations for out-of-frame traceback */
 enum {
     SCRIPT_AHEAD_ONE_FRAME       = 1, /**< Shift 1 frame in sequence A
-                                         (gap 2 nucleotides) */ 
+                                         (gap 2 nucleotides) */
     SCRIPT_AHEAD_TWO_FRAMES      = 2, /**< Shift 2 frames in sequence A
                                          (gap 1 nucleotide) */
     SCRIPT_NEXT_IN_FRAME         = 3, /**< Shift to next base (substitution) */
@@ -1292,7 +1298,7 @@ enum {
 };
 
 /** Low level function to perform gapped extension with out-of-frame
- * gapping with traceback.  
+ * gapping with traceback.
  * @param A The query sequence [in]
  * @param B The subject sequence [in]
  * @param M Maximal extension length in query [in]
@@ -1300,14 +1306,14 @@ enum {
  * @param a_offset Resulting starting offset in query [out]
  * @param b_offset Resulting starting offset in subject [out]
  * @param edit_block Structure to hold generated traceback [out]
- * @param gap_align Structure holding various information and allocated 
+ * @param gap_align Structure holding various information and allocated
  *        memory for the gapped alignment [in]
  * @param score_params Parameters related to scoring [in]
  * @param query_offset The starting offset in query [in]
  * @param reversed Has the sequence been reversed? Used for psi-blast [in]
  * @return The best alignment score found.
  */
-static Int4 
+static Int4
 s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
    Int4* a_offset, Int4* b_offset, GapPrelimEditBlock *edit_block,
    BlastGapAlignStruct* gap_align, const BlastScoringParameters* score_params,
@@ -1316,7 +1322,7 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     Int4 i, increment;          /* sequence pointers and indices */
     Int4 a_index;
     Int4 b_index, b_size, first_b_index, last_b_index;
-  
+
     BlastGapDP* score_array;
 
     Int4 gap_open;              /* alignment penalty variables */
@@ -1324,23 +1330,23 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     Int4 gap_open_extend;
     Int4 shift_penalty;
     Int4 x_dropoff;
-  
+
     Int4** matrix = NULL;       /* pointers to the score matrix */
     Int4** pssm = NULL;
     Int4* matrix_row = NULL;
-  
+
     Int4 score;                 /* score tracking variables */
-    Int4 score_row1; 
-    Int4 score_row2; 
+    Int4 score_row1;
+    Int4 score_row2;
     Int4 score_row3;
-    Int4 score_gap_col; 
-    Int4 score_col1; 
-    Int4 score_col2; 
+    Int4 score_gap_col;
+    Int4 score_col1;
+    Int4 score_col2;
     Int4 score_col3;
-    Int4 score_other_frame1; 
-    Int4 score_other_frame2; 
+    Int4 score_other_frame1;
+    Int4 score_other_frame2;
     Int4 best_score;
-  
+
     GapStateArrayStruct* state_struct;
     Uint1** edit_script;
     Uint1* edit_script_row;
@@ -1363,15 +1369,15 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     gap_open_extend = gap_open + gap_extend;
     shift_penalty = score_params->shift_pen;
     x_dropoff = gap_align->gap_x_dropoff;
-  
+
     if (x_dropoff < gap_open_extend)
         x_dropoff = gap_open_extend;
-  
-    if(N <= 0 || M <= 0) 
+
+    if(N <= 0 || M <= 0)
         return 0;
-  
+
     /* Initialize traceback information. edit_script[] is
-       a 2-D array which is filled in row by row as the 
+       a 2-D array which is filled in row by row as the
        dynamic programming takes place */
 
     s_GapPurgeState(gap_align->state_struct);
@@ -1380,8 +1386,8 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
        MxN. To save on memory, each row of the array is allocated
        separately. edit_script[i] points to the storage reserved
        for row i, and edit_start_offset[i] gives the offset into
-       the B sequence corresponding to element 0 of edit_script[i] 
-       
+       the B sequence corresponding to element 0 of edit_script[i]
+
        Also make the number of edit script rows grow dynamically */
 
     edit_script_num_rows = 100;
@@ -1390,8 +1396,8 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
 
     /* allocate storage for the first row of the traceback
        array. Because row elements correspond to gaps in A,
-       the alignment can only go at most x_dropoff/gap_extend 
-       positions, in all three frames, before failing the 
+       the alignment can only go at most x_dropoff/gap_extend
+       positions, in all three frames, before failing the
        X dropoff criterion */
 
     if (gap_extend > 0)
@@ -1417,10 +1423,10 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     score = -gap_open_extend;
     score_array[0].best = 0;
     score_array[0].best_gap = -gap_open_extend;
-  
+
     for (i = 3; i <= N + 2; i += 3) {
         score_array[i].best = score;
-        score_array[i].best_gap = score - gap_open_extend; 
+        score_array[i].best_gap = score - gap_open_extend;
         edit_script_row[i] = SCRIPT_GAP_IN_B;
 
         score_array[i-1].best = MININT;
@@ -1431,12 +1437,12 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         score_array[i-2].best_gap = MININT;
         edit_script_row[i-2] = SCRIPT_GAP_IN_B;
 
-        if (score < -x_dropoff) 
+        if (score < -x_dropoff)
             break;
         score -= gap_extend;
     }
-  
-    /* The inner loop below examines letters of B from 
+
+    /* The inner loop below examines letters of B from
        index 'first_b_index' to 'b_size' */
 
     score_array[i].best = MININT;
@@ -1454,39 +1460,39 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         B -= 2;
         increment = 1;
     }
-  
+
     for (a_index = 1; a_index <= M; a_index++) {
 
         /* Set up the next row of the edit script; this involves
            allocating memory for the row, then pointing to it.
            It is not necessary to allocate space for offsets less
-           than first_b_index (since the inner loop will never 
-           look at them). 
+           than first_b_index (since the inner loop will never
+           look at them).
 
-           It is unknown at this point how far to the right the 
+           It is unknown at this point how far to the right the
            current traceback row will extend; all that's known for
            sure is that the previous row fails the X-dropoff test
            after b_size cells, and that the current row can go at
            most num_extra_cells beyond that before failing the test */
 
         if (gap_extend > 0)
-            state_struct = s_GapGetState(&gap_align->state_struct, 
+            state_struct = s_GapGetState(&gap_align->state_struct,
                            b_size - first_b_index + num_extra_cells);
         else
-            state_struct = s_GapGetState(&gap_align->state_struct, 
+            state_struct = s_GapGetState(&gap_align->state_struct,
                                         N + 5 - first_b_index);
 
         if (a_index == edit_script_num_rows) {
             edit_script_num_rows = edit_script_num_rows * 2;
-            edit_script = (Uint1 **)realloc(edit_script, 
+            edit_script = (Uint1 **)realloc(edit_script,
                                             edit_script_num_rows *
                                             sizeof(Uint1 *));
-            edit_start_offset = (Int4 *)realloc(edit_start_offset, 
+            edit_start_offset = (Int4 *)realloc(edit_start_offset,
                                                 edit_script_num_rows *
                                                 sizeof(Int4));
         }
 
-        edit_script[a_index] = state_struct->state_array + 
+        edit_script[a_index] = state_struct->state_array +
                                 state_struct->used + 1;
         edit_start_offset[a_index] = first_b_index;
 
@@ -1502,20 +1508,20 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         else {
             if(reversed)
                 matrix_row = pssm[M - a_index];
-            else 
+            else
                 matrix_row = pssm[a_index + query_offset];
         }
 
         score = MININT;
-        score_row1 = MININT; 
-        score_row2 = MININT; 
+        score_row1 = MININT;
+        score_row2 = MININT;
         score_row3 = MININT;
-        score_gap_col = MININT; 
-        score_col1 = MININT; 
-        score_col2 = MININT; 
+        score_gap_col = MININT;
+        score_col1 = MININT;
+        score_col2 = MININT;
         score_col3 = MININT;
-        score_other_frame1 = MININT; 
-        score_other_frame2 = MININT; 
+        score_other_frame1 = MININT;
+        score_other_frame2 = MININT;
         last_b_index = first_b_index;
         b_index = first_b_index;
 
@@ -1560,7 +1566,7 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                 }
 
                 if (best_score - score > x_dropoff) {
-                    if (first_b_index == b_index) 
+                    if (first_b_index == b_index)
                         first_b_index = b_index + 1;
                     else
                         score_array[b_index].best = MININT;
@@ -1574,7 +1580,7 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             }
             else {
                 if (best_score - score > x_dropoff) {
-                    if (first_b_index == b_index) 
+                    if (first_b_index == b_index)
                         first_b_index = b_index + 1;
                     else
                         score_array[b_index].best = MININT;
@@ -1642,7 +1648,7 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             if (score < MAX(score_gap_col, score_row2)) {
                 score = MAX(score_gap_col, score_row2);
                 if (best_score - score > x_dropoff) {
-                    if (first_b_index == b_index) 
+                    if (first_b_index == b_index)
                         first_b_index = b_index + 1;
                     else
                         score_array[b_index].best = MININT;
@@ -1650,7 +1656,7 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                 else {
                     if (score == score_gap_col)
                         script = SCRIPT_OOF_OPEN_GAP | SCRIPT_GAP_IN_A;
-                    else 
+                    else
                         script = SCRIPT_OOF_OPEN_GAP | SCRIPT_GAP_IN_B;
 
                     last_b_index = b_index;
@@ -1661,7 +1667,7 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             }
             else {
                 if (best_score - score > x_dropoff) {
-                    if (first_b_index == b_index) 
+                    if (first_b_index == b_index)
                         first_b_index = b_index + 1;
                     else
                         score_array[b_index].best = MININT;
@@ -1729,7 +1735,7 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             if (score < MAX(score_gap_col, score_row3)) {
                 score = MAX(score_gap_col, score_row3);
                 if (best_score - score > x_dropoff) {
-                    if (first_b_index == b_index) 
+                    if (first_b_index == b_index)
                         first_b_index = b_index + 1;
                     else
                         score_array[b_index].best = MININT;
@@ -1737,7 +1743,7 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                 else {
                     if (score == score_gap_col)
                         script = SCRIPT_OOF_OPEN_GAP | SCRIPT_GAP_IN_A;
-                    else 
+                    else
                         script = SCRIPT_OOF_OPEN_GAP | SCRIPT_GAP_IN_B;
 
                     last_b_index = b_index;
@@ -1748,7 +1754,7 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             }
             else {
                 if (best_score - score > x_dropoff) {
-                    if (first_b_index == b_index) 
+                    if (first_b_index == b_index)
                         first_b_index = b_index + 1;
                     else
                         score_array[b_index].best = MININT;
@@ -1780,9 +1786,9 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             }
             edit_script_row[b_index++] = script;
         }
-  
+
         /* Finish aligning if the best scores for all positions
-           of B will fail the X-dropoff test, i.e. the inner loop 
+           of B will fail the X-dropoff test, i.e. the inner loop
            bounds have converged to each other */
 
         if (first_b_index == b_size)
@@ -1810,9 +1816,9 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         else {
             /* The inner loop finished without failing the X-dropoff
                test; initialize extra bookkeeping structures until
-               the X dropoff test fails or we run out of letters in B. 
-               The next inner loop will have larger bounds. 
-             
+               the X dropoff test fails or we run out of letters in B.
+               The next inner loop will have larger bounds.
+
                Keep initializing extra structures until the X dropoff
                test fails in all frames for this row */
 
@@ -1823,19 +1829,19 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                 score_array[b_size].best = score_row1;
                 score_array[b_size].best_gap = score_row1 - gap_open_extend;
                 score_row1 -= gap_extend;
-                edit_script_row[b_size] = SCRIPT_OOF_OPEN_GAP | 
+                edit_script_row[b_size] = SCRIPT_OOF_OPEN_GAP |
                                           SCRIPT_GAP_IN_B;
 
                 score_array[b_size+1].best = score_row2;
                 score_array[b_size+1].best_gap = score_row2 - gap_open_extend;
                 score_row2 -= gap_extend;
-                edit_script_row[b_size+1] = SCRIPT_OOF_OPEN_GAP | 
+                edit_script_row[b_size+1] = SCRIPT_OOF_OPEN_GAP |
                                             SCRIPT_GAP_IN_B;
 
                 score_array[b_size+2].best = score_row3;
                 score_array[b_size+2].best_gap = score_row3 - gap_open_extend;
                 score_row3 -= gap_extend;
-                edit_script_row[b_size+2] = SCRIPT_OOF_OPEN_GAP | 
+                edit_script_row[b_size+2] = SCRIPT_OOF_OPEN_GAP |
                                             SCRIPT_GAP_IN_B;
                 b_size += 3;
                 score -= gap_extend;
@@ -1868,7 +1874,7 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
            at offset zero of B, so a correction is needed
            to point to the correct position */
 
-        next_script = 
+        next_script =
             edit_script[a_index][b_index - edit_start_offset[a_index]];
 
         switch (script) {
@@ -1916,56 +1922,56 @@ s_OutOfFrameAlignWithTraceback(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
  * @param b_offset Resulting starting offset in subject [out]
  * @param score_only Only find the score, without saving traceback [in]
  * @param edit_block Structure to hold generated traceback [out]
- * @param gap_align Structure holding various information and allocated 
+ * @param gap_align Structure holding various information and allocated
  *        memory for the gapped alignment [in]
  * @param score_params Parameters related to scoring [in]
  * @param query_offset The starting offset in query [in]
  * @param reversed Has the sequence been reversed? Used for psi-blast [in]
  * @return The best alignment score found.
  */
-static Int4 
+static Int4
 s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
    Int4* a_offset, Int4* b_offset, Boolean score_only,
-   GapPrelimEditBlock *edit_block, BlastGapAlignStruct* gap_align, 
+   GapPrelimEditBlock *edit_block, BlastGapAlignStruct* gap_align,
    const BlastScoringParameters* score_params,
    Int4 query_offset, Boolean reversed)
 {
     Int4 i, increment;          /* sequence pointers and indices */
     Int4 a_index;
     Int4 b_index, b_size, first_b_index, last_b_index;
-  
+
     Int4 gap_open;              /* alignment penalty variables */
     Int4 gap_extend;
     Int4 gap_open_extend;
     Int4 shift_penalty;
     Int4 x_dropoff;
-  
+
     BlastGapDP* score_array;
     Int4 num_extra_cells;
 
     Int4** matrix = NULL;       /* pointers to the score matrix */
     Int4** pssm = NULL;
     Int4* matrix_row = NULL;
-  
+
     Int4 score;                 /* score tracking variables */
-    Int4 score_row1; 
-    Int4 score_row2; 
+    Int4 score_row1;
+    Int4 score_row2;
     Int4 score_row3;
-    Int4 score_gap_col; 
-    Int4 score_col1; 
-    Int4 score_col2; 
+    Int4 score_gap_col;
+    Int4 score_col1;
+    Int4 score_col2;
     Int4 score_col3;
-    Int4 score_other_frame1; 
-    Int4 score_other_frame2; 
+    Int4 score_other_frame1;
+    Int4 score_other_frame2;
     Int4 best_score;
-  
+
     if (!score_only) {
-        return s_OutOfFrameAlignWithTraceback(A, B, M, N, a_offset, b_offset, 
-                                              edit_block, gap_align, 
-                                              score_params, query_offset, 
+        return s_OutOfFrameAlignWithTraceback(A, B, M, N, a_offset, b_offset,
+                                              edit_block, gap_align,
+                                              score_params, query_offset,
                                               reversed);
     }
-    
+
     /* do initialization and sanity-checking */
 
     matrix = gap_align->sbp->matrix->data;
@@ -1979,13 +1985,13 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     gap_open_extend = gap_open + gap_extend;
     shift_penalty = score_params->shift_pen;
     x_dropoff = gap_align->gap_x_dropoff;
-  
+
     if (x_dropoff < gap_open_extend)
         x_dropoff = gap_open_extend;
-  
-    if(N <= 0 || M <= 0) 
+
+    if(N <= 0 || M <= 0)
         return 0;
-  
+
     /* Allocate and fill in the auxiliary bookeeping structures.
        Since A and B could be very large, maintain a window
        of auxiliary structures only large enough to contain to current
@@ -2009,20 +2015,20 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
     score = -gap_open_extend;
     score_array[0].best = 0;
     score_array[0].best_gap = -gap_open_extend;
-  
+
     for (i = 3; i <= N + 2; i += 3) {
         score_array[i].best = score;
-        score_array[i].best_gap = score - gap_open_extend; 
+        score_array[i].best_gap = score - gap_open_extend;
         score_array[i-1].best = MININT;
         score_array[i-1].best_gap = MININT;
         score_array[i-2].best = MININT;
         score_array[i-2].best_gap = MININT;
-        if (score < -x_dropoff) 
+        if (score < -x_dropoff)
             break;
         score -= gap_extend;
     }
-  
-    /* The inner loop below examines letters of B from 
+
+    /* The inner loop below examines letters of B from
        index 'first_b_index' to 'b_size' */
 
     b_size = i - 2;
@@ -2039,10 +2045,10 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         B -= 2;
         increment = 1;
     }
-  
+
     for (a_index = 1; a_index <= M; a_index++) {
 
-        /* pick out the row of the score matrix 
+        /* pick out the row of the score matrix
            appropriate for A[a_index] */
 
         if (!(gap_align->positionBased)) {
@@ -2051,21 +2057,21 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         else {
             if(reversed)
                 matrix_row = pssm[M - a_index];
-            else 
+            else
                 matrix_row = pssm[a_index + query_offset];
         }
 
         /* initialize running-score variables */
         score = MININT;
-        score_row1 = MININT; 
-        score_row2 = MININT; 
+        score_row1 = MININT;
+        score_row2 = MININT;
         score_row3 = MININT;
-        score_gap_col = MININT; 
-        score_col1 = MININT; 
-        score_col2 = MININT; 
+        score_gap_col = MININT;
+        score_col1 = MININT;
+        score_col2 = MININT;
         score_col3 = MININT;
-        score_other_frame1 = MININT; 
-        score_other_frame2 = MININT; 
+        score_other_frame1 = MININT;
+        score_other_frame2 = MININT;
         last_b_index = first_b_index;
         b_index = first_b_index;
 
@@ -2075,7 +2081,7 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
 
             /* Pick the best score among all frames */
             score = MAX(score_other_frame1, score_other_frame2) - shift_penalty;
-            score = MAX(score, score_col1) + 
+            score = MAX(score, score_col1) +
                                 matrix_row[ B[ b_index * increment ] ];
             score_other_frame1 = MAX(score_col1, score_array[b_index].best);
             score_col1 = score_array[b_index].best;
@@ -2091,14 +2097,14 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                    /* the current best score failed the X-dropoff
                       criterion. Note that this does not stop the
                       inner loop, only forces future iterations to
-                      skip this column of B. 
-   
+                      skip this column of B.
+
                       Also, if the very first letter of B that was
                       tested failed the X dropoff criterion, make
-                      sure future inner loops start one letter to 
+                      sure future inner loops start one letter to
                       the right */
 
-                    if (first_b_index == b_index) 
+                    if (first_b_index == b_index)
                         first_b_index = b_index + 1;
                     else
                         score_array[b_index].best = MININT;
@@ -2117,7 +2123,7 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                    /* the current best score failed the X-dropoff
                       criterion. */
 
-                    if (first_b_index == b_index) 
+                    if (first_b_index == b_index)
                         first_b_index = b_index + 1;
                     else
                         score_array[b_index].best = MININT;
@@ -2141,7 +2147,7 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                     score -= gap_open_extend;
                     score_row1 -= gap_extend;
                     score_row1 = MAX(score, score_row1);
-                    score_array[b_index].best_gap = MAX(score, 
+                    score_array[b_index].best_gap = MAX(score,
                                                   score_gap_col - gap_extend);
                 }
             }
@@ -2165,7 +2171,7 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                is the updating of the other_frame best scores */
 
             score = MAX(score_other_frame1, score_other_frame2) - shift_penalty;
-            score = MAX(score, score_col2) + 
+            score = MAX(score, score_col2) +
                                 matrix_row[ B[ b_index * increment ] ];
             score_other_frame2 = MAX(score_col2, score_array[b_index].best);
             score_col2 = score_array[b_index].best;
@@ -2174,7 +2180,7 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             if (score < MAX(score_gap_col, score_row2)) {
                 score = MAX(score_gap_col, score_row2);
                 if (best_score - score > x_dropoff) {
-                    if (first_b_index == b_index) 
+                    if (first_b_index == b_index)
                         first_b_index = b_index + 1;
                     else
                         score_array[b_index].best = MININT;
@@ -2188,7 +2194,7 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             }
             else {
                 if (best_score - score > x_dropoff) {
-                    if (first_b_index == b_index) 
+                    if (first_b_index == b_index)
                         first_b_index = b_index + 1;
                     else
                         score_array[b_index].best = MININT;
@@ -2204,7 +2210,7 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                     score -= gap_open_extend;
                     score_row2 -= gap_extend;
                     score_row2 = MAX(score, score_row2);
-                    score_array[b_index].best_gap = MAX(score, 
+                    score_array[b_index].best_gap = MAX(score,
                                                   score_gap_col - gap_extend);
                 }
             }
@@ -2220,7 +2226,7 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             /* FRAME 2 */
 
             score = MAX(score_other_frame1, score_other_frame2) - shift_penalty;
-            score = MAX(score, score_col3) + 
+            score = MAX(score, score_col3) +
                                 matrix_row[ B[ b_index * increment ] ];
             score_other_frame1 = score_other_frame2;
             score_other_frame2 = MAX(score_col3, score_array[b_index].best);
@@ -2230,7 +2236,7 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             if (score < MAX(score_gap_col, score_row3)) {
                 score = MAX(score_gap_col, score_row3);
                 if (best_score - score > x_dropoff) {
-                    if (first_b_index == b_index) 
+                    if (first_b_index == b_index)
                         first_b_index = b_index + 1;
                     else
                         score_array[b_index].best = MININT;
@@ -2244,7 +2250,7 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
             }
             else {
                 if (best_score - score > x_dropoff) {
-                    if (first_b_index == b_index) 
+                    if (first_b_index == b_index)
                         first_b_index = b_index + 1;
                     else
                         score_array[b_index].best = MININT;
@@ -2260,15 +2266,15 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
                     score -= gap_open_extend;
                     score_row3 -= gap_extend;
                     score_row3 = MAX(score, score_row3);
-                    score_array[b_index].best_gap = MAX(score, 
+                    score_array[b_index].best_gap = MAX(score,
                                                   score_gap_col - gap_extend);
                 }
             }
             b_index++;
         }
-  
+
         /* Finish aligning if the best scores for all positions
-           of B will fail the X-dropoff test, i.e. the inner loop 
+           of B will fail the X-dropoff test, i.e. the inner loop
            bounds have converged to each other */
 
         if (first_b_index == b_size)
@@ -2296,9 +2302,9 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
         else {
             /* The inner loop finished without failing the X-dropoff
                test; initialize extra bookkeeping structures until
-               the X dropoff test fails or we run out of letters in B. 
-               The next inner loop will have larger bounds. 
-             
+               the X dropoff test fails or we run out of letters in B.
+               The next inner loop will have larger bounds.
+
                Keep initializing extra structures until the X dropoff
                test fails in all frames for this row */
 
@@ -2346,14 +2352,14 @@ s_OutOfFrameGappedAlign(const Uint1* A, const Uint1* B, Int4 M, Int4 N,
  * @param init_hsp Initial HSP [in]
  */
 static NCBI_INLINE Int4
-s_GetUngappedHSPContext(const BlastQueryInfo* query_info, 
+s_GetUngappedHSPContext(const BlastQueryInfo* query_info,
                         const BlastInitHSP* init_hsp)
 {
     return BSearchContextInfo(init_hsp->offsets.qs_offsets.q_off, query_info);
 }
 
 /** Adjust the HSP offsets in the initial ungapped HSP structure given the
- * query start 
+ * query start
  * @param init_hsp Initial HSP [in|out]
  * @param query_start Starting offset of the query sequence in the query info
  * structure [in]
@@ -2390,7 +2396,7 @@ s_SetUpLocalBlastSequenceBlk(const BLAST_SequenceBlk* concatenated_query,
            together in a special sequence. */
         Int4 query_end_pt = 0;
         Int4 mixed_frame_context = context - context % CODON_LENGTH;
-        
+
         *query_start = query_info->contexts[mixed_frame_context].query_offset;
         query_end_pt =
             query_info->contexts[mixed_frame_context+CODON_LENGTH-1].query_offset +
@@ -2412,19 +2418,19 @@ s_SetUpLocalBlastSequenceBlk(const BLAST_SequenceBlk* concatenated_query,
  * the concatenated sequence and retrieve relevant portions of the query
  * sequence data.
  * @param query Query sequence block [in]
- * @param query_info Query information structure, including context offsets 
+ * @param query_info Query information structure, including context offsets
  *                   array [in]
  * @param init_hsp Initial HSP, this will be modified to hold the adjusted
  *                 offsets [in] [out]
- * @param query_out query sequence block with modified sequence 
+ * @param query_out query sequence block with modified sequence
  *                  pointer and sequence length [out]
  * @param context Which context this HSP belongs to? [out]
  */
-static void 
-s_AdjustHspOffsetsAndGetQueryData(const BLAST_SequenceBlk* query, 
-                                  const BlastQueryInfo* query_info, 
-                                  BlastInitHSP* init_hsp, 
-                                  BLAST_SequenceBlk* query_out, 
+static void
+s_AdjustHspOffsetsAndGetQueryData(const BLAST_SequenceBlk* query,
+                                  const BlastQueryInfo* query_info,
+                                  BlastInitHSP* init_hsp,
+                                  BLAST_SequenceBlk* query_out,
                                   Int4* context)
 {
     Int4 query_start = 0;
@@ -2435,7 +2441,7 @@ s_AdjustHspOffsetsAndGetQueryData(const BLAST_SequenceBlk* query,
     ASSERT(init_hsp);
     ASSERT(context);
 
-    ASSERT(init_hsp->ungapped_data == NULL || 
+    ASSERT(init_hsp->ungapped_data == NULL ||
            init_hsp->ungapped_data->q_start >= 0);
     *context = s_GetUngappedHSPContext(query_info, init_hsp);
     s_SetUpLocalBlastSequenceBlk(query, query_info, *context,
@@ -2470,14 +2476,14 @@ Blast_PrelimEditBlockToGapEditScript (GapPrelimEditBlock* rev_prelim_tback,
       return NULL;
 
    /* The fwd_prelim_tback script will get reversed here as the traceback started from the highest scoring point
-     and worked backwards. The rev_prelim_tback script does NOT get reversed.  Since it was reversed when the 
+     and worked backwards. The rev_prelim_tback script does NOT get reversed.  Since it was reversed when the
      traceback was produced it's already "forward" */
 
    if (fwd_prelim_tback->num_ops > 0 && rev_prelim_tback->num_ops > 0 &&
-       fwd_prelim_tback->edit_ops[(fwd_prelim_tback->num_ops)-1].op_type == 
+       fwd_prelim_tback->edit_ops[(fwd_prelim_tback->num_ops)-1].op_type ==
          rev_prelim_tback->edit_ops[(rev_prelim_tback->num_ops)-1].op_type)
      merge_ops = TRUE;
- 
+
    size = fwd_prelim_tback->num_ops+rev_prelim_tback->num_ops;
    if (merge_ops)
      size--;
@@ -2514,7 +2520,7 @@ Blast_PrelimEditBlockToGapEditScript (GapPrelimEditBlock* rev_prelim_tback,
    return esp;
 }
 
-/** Fills the BlastGapAlignStruct structure with the results 
+/** Fills the BlastGapAlignStruct structure with the results
  *  of a greedy gapped extension.
  * @param gap_align the initialized gapped alignment structure [in] [out]
  * @param q_start The starting offset in query [in]
@@ -2527,9 +2533,9 @@ Blast_PrelimEditBlockToGapEditScript (GapPrelimEditBlock* rev_prelim_tback,
  * @param esp The edit script containing the traceback information [in]
  */
 static Int2
-s_BlastGreedyGapAlignStructFill(BlastGapAlignStruct* gap_align, 
-                                Int4 q_start, Int4 s_start, 
-                                Int4 q_end, Int4 s_end, 
+s_BlastGreedyGapAlignStructFill(BlastGapAlignStruct* gap_align,
+                                Int4 q_start, Int4 s_start,
+                                Int4 q_end, Int4 s_end,
                                 Int4 q_seed_start, Int4 s_seed_start,
                                 Int4 score, GapEditScript* esp)
 {
@@ -2675,8 +2681,8 @@ static void s_ReduceGaps(GapEditScript* esp, const Uint1 *q, const Uint1 *s,
            q += esp->num[i];
            s += esp->num[i];
            continue;
-       } 
-       if (i>1 && esp->op_type[i] != esp->op_type[i-2] 
+       }
+       if (i>1 && esp->op_type[i] != esp->op_type[i-2]
                && esp->num[i-2] > 0) {
            d = esp->num[i] + esp->num[i-1] + esp->num[i-2];
            if (d == 3) {
@@ -2729,10 +2735,10 @@ static void s_ReduceGaps(GapEditScript* esp, const Uint1 *q, const Uint1 *s,
    s_RebuildEditScript(esp);
 }
 
-Int2 
-BLAST_GreedyGappedAlignment(const Uint1* query, const Uint1* subject, 
+Int2
+BLAST_GreedyGappedAlignment(const Uint1* query, const Uint1* subject,
    Int4 query_length, Int4 subject_length, BlastGapAlignStruct* gap_align,
-   const BlastScoringParameters* score_params, 
+   const BlastScoringParameters* score_params,
    Int4 q_off, Int4 s_off, Boolean compressed_subject, Boolean do_traceback,
    Boolean * fence_hit)
 {
@@ -2750,10 +2756,10 @@ BLAST_GreedyGappedAlignment(const Uint1* query, const Uint1* subject,
    GapEditScript* esp = NULL;
    Int4 q_seed_start = q_off;
    Int4 s_seed_start = s_off;
-   
+
    q_avail = query_length - q_off;
    s_avail = subject_length - s_off;
-   
+
    q = query + q_off;
    if (!compressed_subject) {
       s = subject + s_off;
@@ -2765,21 +2771,21 @@ BLAST_GreedyGappedAlignment(const Uint1* query, const Uint1* subject,
    }
 
    X = gap_align->gap_x_dropoff;
-   
+
    if (do_traceback) {
       fwd_prelim_tback = gap_align->fwd_prelim_tback;
       rev_prelim_tback = gap_align->rev_prelim_tback;
       GapPrelimEditBlockReset(fwd_prelim_tback);
       GapPrelimEditBlockReset(rev_prelim_tback);
    }
-   
+
    /* extend to the right */
    while (TRUE) {
        Int4 new_dist, xdrop;
        score = BLAST_AffineGreedyAlign(q, q_avail, s, s_avail, FALSE, X,
-              score_params->reward, -score_params->penalty, 
+              score_params->reward, -score_params->penalty,
               score_params->gap_open, score_params->gap_extend,
-              &q_ext_r, &s_ext_r, gap_align->greedy_align_mem, 
+              &q_ext_r, &s_ext_r, gap_align->greedy_align_mem,
               fwd_prelim_tback, rem, fence_hit, &fwd_start_point);
        if (score >=0) break;
 
@@ -2787,7 +2793,7 @@ BLAST_GreedyGappedAlignment(const Uint1* query, const Uint1* subject,
        new_dist = gap_align->greedy_align_mem->max_dist * 2;
        xdrop    = gap_align->greedy_align_mem->xdrop;
        s_BlastGreedyAlignsFree(gap_align->greedy_align_mem);
-       gap_align->greedy_align_mem = 
+       gap_align->greedy_align_mem =
           s_BlastGreedyAlignMemAlloc(score_params, NULL, new_dist, xdrop);
 
        if (!gap_align->greedy_align_mem) {
@@ -2802,11 +2808,11 @@ BLAST_GreedyGappedAlignment(const Uint1* query, const Uint1* subject,
    /* extend to the left */
    while (TRUE) {
        Int4 new_dist, xdrop, score1;
-       score1 = BLAST_AffineGreedyAlign(query, q_off, 
-               subject, s_off, TRUE, X, 
-               score_params->reward, -score_params->penalty, 
-               score_params->gap_open, score_params->gap_extend, 
-               &q_ext_l, &s_ext_l, gap_align->greedy_align_mem, 
+       score1 = BLAST_AffineGreedyAlign(query, q_off,
+               subject, s_off, TRUE, X,
+               score_params->reward, -score_params->penalty,
+               score_params->gap_open, score_params->gap_extend,
+               &q_ext_l, &s_ext_l, gap_align->greedy_align_mem,
                rev_prelim_tback, rem, fence_hit, &rev_start_point);
        if (score1 >=0) {
            score += score1;
@@ -2817,7 +2823,7 @@ BLAST_GreedyGappedAlignment(const Uint1* query, const Uint1* subject,
        new_dist = gap_align->greedy_align_mem->max_dist * 2;
        xdrop    = gap_align->greedy_align_mem->xdrop;
        s_BlastGreedyAlignsFree(gap_align->greedy_align_mem);
-       gap_align->greedy_align_mem = 
+       gap_align->greedy_align_mem =
           s_BlastGreedyAlignMemAlloc(score_params, NULL, new_dist, xdrop);
 
        if (!gap_align->greedy_align_mem) {
@@ -2826,18 +2832,18 @@ BLAST_GreedyGappedAlignment(const Uint1* query, const Uint1* subject,
        }
    }
 
-   /* In basic case the greedy algorithm returns number of 
+   /* In basic case the greedy algorithm returns number of
       differences, hence we need to convert it to score */
    if (score_params->gap_open==0 && score_params->gap_extend==0) {
-      score = 
-         (q_ext_r + s_ext_r + q_ext_l + s_ext_l)*score_params->reward/2 - 
+      score =
+         (q_ext_r + s_ext_r + q_ext_l + s_ext_l)*score_params->reward/2 -
          score*(score_params->reward - score_params->penalty);
    } else if (score_params->reward % 2 == 1) {
       score /= 2;
    }
 
    if (do_traceback) {
-      esp = Blast_PrelimEditBlockToGapEditScript(rev_prelim_tback, 
+      esp = Blast_PrelimEditBlockToGapEditScript(rev_prelim_tback,
                                              fwd_prelim_tback);
       /* check for possible gap elimination */
       ASSERT(!compressed_subject);
@@ -2864,7 +2870,7 @@ BLAST_GreedyGappedAlignment(const Uint1* query, const Uint1* subject,
        if (q_seed_start_r < q_box_r && s_seed_start_r < s_box_r) {
            valid_seed_len_r = MIN(q_box_r - q_seed_start_r,
                                   s_box_r - s_seed_start_r);
-           valid_seed_len_r = MIN(valid_seed_len_r, 
+           valid_seed_len_r = MIN(valid_seed_len_r,
                                   fwd_start_point.match_length) / 2;
        } else {
            q_seed_start_r = q_off;
@@ -2874,7 +2880,7 @@ BLAST_GreedyGappedAlignment(const Uint1* query, const Uint1* subject,
        if (q_seed_start_l > q_box_l && s_seed_start_l > s_box_l) {
            valid_seed_len_l = MIN(q_seed_start_l - q_box_l,
                                   s_seed_start_l - s_box_l);
-           valid_seed_len_l = MIN(valid_seed_len_l, 
+           valid_seed_len_l = MIN(valid_seed_len_l,
                                   rev_start_point.match_length) / 2;
        } else {
            q_seed_start_l = q_off;
@@ -2890,16 +2896,16 @@ BLAST_GreedyGappedAlignment(const Uint1* query, const Uint1* subject,
            s_seed_start = s_seed_start_l - valid_seed_len_l;
        }
    }
-   
-   s_BlastGreedyGapAlignStructFill(gap_align, 
-                                   q_off-q_ext_l, s_off-s_ext_l, 
-                                   q_off+q_ext_r, s_off+s_ext_r, 
+
+   s_BlastGreedyGapAlignStructFill(gap_align,
+                                   q_off-q_ext_l, s_off-s_ext_l,
+                                   q_off+q_ext_r, s_off+s_ext_r,
                                    q_seed_start, s_seed_start,
                                    score, esp);
    return 0;
 }
 
-/** Performs dynamic programming style gapped extension, given an initial 
+/** Performs dynamic programming style gapped extension, given an initial
  * HSP (offset pair), two sequence blocks and scoring and extension options.
  * Note: traceback is not done in this function.
  * @param query_blk The query sequence [in]
@@ -2908,27 +2914,27 @@ BLAST_GreedyGappedAlignment(const Uint1* query, const Uint1* subject,
  * @param score_params Parameters related to scoring [in]
  * @param init_hsp The initial HSP that needs to be extended [in]
 */
-static Int2 
-s_BlastDynProgNtGappedAlignment(BLAST_SequenceBlk* query_blk, 
-   BLAST_SequenceBlk* subject_blk, BlastGapAlignStruct* gap_align, 
+static Int2
+s_BlastDynProgNtGappedAlignment(BLAST_SequenceBlk* query_blk,
+   BLAST_SequenceBlk* subject_blk, BlastGapAlignStruct* gap_align,
    const BlastScoringParameters* score_params, BlastInitHSP* init_hsp)
 {
-   Int4 q_length, s_length; 
+   Int4 q_length, s_length;
    Int4 private_q_start, private_s_start;
    Int4 score_right = 0, score_left = 0;
    Uint1 offset_adjustment;
    Uint1* query = query_blk->sequence;
    Uint1* subject = subject_blk->sequence;
 
-   /* If subject offset is not at the start of a full byte, 
+   /* If subject offset is not at the start of a full byte,
       s_BlastAlignPackedNucl won't work, so shift the alignment start
-      to the next multiple of 4 subject letters. Note that the 
-      shift amount is always nonzero, so a left extension always happens 
-      (and has a few presumed exact matches to start with). In the case 
-      of the smallest ungapped alignment (4 nucleotides), this can 
+      to the next multiple of 4 subject letters. Note that the
+      shift amount is always nonzero, so a left extension always happens
+      (and has a few presumed exact matches to start with). In the case
+      of the smallest ungapped alignment (4 nucleotides), this can
       conceivably put the start point at the end of one sequence */
 
-   offset_adjustment = COMPRESSION_RATIO - 
+   offset_adjustment = COMPRESSION_RATIO -
             (init_hsp->offsets.qs_offsets.s_off % COMPRESSION_RATIO);
    q_length = init_hsp->offsets.qs_offsets.q_off + offset_adjustment;
    s_length = init_hsp->offsets.qs_offsets.s_off + offset_adjustment;
@@ -2942,24 +2948,24 @@ s_BlastDynProgNtGappedAlignment(BLAST_SequenceBlk* query_blk,
    }
 
    /* perform extension to left */
-   score_left = s_BlastAlignPackedNucl(query, subject, q_length, s_length, 
-                      &private_q_start, &private_s_start, gap_align, 
+   score_left = s_BlastAlignPackedNucl(query, subject, q_length, s_length,
+                      &private_q_start, &private_s_start, gap_align,
                       score_params, TRUE);
-   if (score_left < 0) 
+   if (score_left < 0)
       return -1;
    gap_align->query_start = q_length - private_q_start;
    gap_align->subject_start = s_length - private_s_start;
 
    /* perform extension to right */
-   if (q_length < query_blk->length && 
+   if (q_length < query_blk->length &&
        s_length < subject_blk->length)
    {
-      score_right = s_BlastAlignPackedNucl(query+q_length-1, 
-         subject+(s_length+3)/COMPRESSION_RATIO - 1, 
-         query_blk->length-q_length, 
+      score_right = s_BlastAlignPackedNucl(query+q_length-1,
+         subject+(s_length+3)/COMPRESSION_RATIO - 1,
+         query_blk->length-q_length,
          subject_blk->length-s_length, &(gap_align->query_stop),
          &(gap_align->subject_stop), gap_align, score_params, FALSE);
-      if (score_right < 0) 
+      if (score_right < 0)
          return -1;
       gap_align->query_stop += q_length;
       gap_align->subject_stop += s_length;
@@ -2988,18 +2994,18 @@ s_BlastDynProgNtGappedAlignment(BLAST_SequenceBlk* query_blk,
  * @param reverse_sequence Reverse the sequence.
  * @return The best alignment score found.
 */
-static Int4 
-s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M, 
-	Int4* b_offset, Int4* a_offset, 
+static Int4
+s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M,
+	Int4* b_offset, Int4* a_offset,
         BlastGapAlignStruct* gap_align,
-        const BlastScoringParameters* score_params, 
+        const BlastScoringParameters* score_params,
         Boolean reverse_sequence)
-{ 
+{
     Int4 i;                     /* sequence pointers and indices */
     Int4 a_index, a_base_pair;
     Int4 b_index, b_size, first_b_index, last_b_index, b_increment;
     Uint1* b_ptr;
-  
+
     BlastGapDP* score_array;
     Int4 num_extra_cells;
 
@@ -3007,16 +3013,16 @@ s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M,
     Int4 gap_extend;
     Int4 gap_open_extend;
     Int4 x_dropoff;
-  
+
     Int4* *matrix;              /* pointers to the score matrix */
     Int4* matrix_row;
-  
+
     Int4 score;                 /* score tracking variables */
     Int4 score_gap_row;
     Int4 score_gap_col;
     Int4 next_score;
     Int4 best_score;
-  
+
     /* do initialization and sanity-checking */
 
     matrix = gap_align->sbp->matrix->data;
@@ -3026,13 +3032,13 @@ s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M,
     gap_extend = score_params->gap_extend;
     gap_open_extend = gap_open + gap_extend;
     x_dropoff = gap_align->gap_x_dropoff;
-  
+
     if (x_dropoff < gap_open_extend)
         x_dropoff = gap_open_extend;
-  
-    if(N <= 0 || M <= 0) 
+
+    if(N <= 0 || M <= 0)
         return 0;
-  
+
     /* Allocate and fill in the auxiliary bookeeping structures.
        Since A and B could be very large, maintain a window
        of auxiliary structures only large enough to contain the current
@@ -3056,17 +3062,17 @@ s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M,
     score = -gap_open_extend;
     score_array[0].best = 0;
     score_array[0].best_gap = -gap_open_extend;
-  
+
     for (i = 1; i <= N; i++) {
-        if (score < -x_dropoff) 
+        if (score < -x_dropoff)
             break;
 
         score_array[i].best = score;
-        score_array[i].best_gap = score - gap_open_extend; 
+        score_array[i].best_gap = score - gap_open_extend;
         score -= gap_extend;
     }
-  
-    /* The inner loop below examines letters of B from 
+
+    /* The inner loop below examines letters of B from
        index 'first_b_index' to 'b_size' */
 
     b_size = i;
@@ -3076,19 +3082,19 @@ s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M,
         b_increment = -1;
     else
         b_increment = 1;
-  
+
     for (a_index = 1; a_index <= M; a_index++) {
 
-        /* pick out the row of the score matrix 
+        /* pick out the row of the score matrix
            appropriate for A[a_index] */
 
         if(reverse_sequence) {
-            a_base_pair = NCBI2NA_UNPACK_BASE(A[(M-a_index)/4], 
+            a_base_pair = NCBI2NA_UNPACK_BASE(A[(M-a_index)/4],
                                                ((a_index-1)%4));
             matrix_row = matrix[a_base_pair];
-        } 
+        }
         else {
-            a_base_pair = NCBI2NA_UNPACK_BASE(A[1+((a_index-1)/4)], 
+            a_base_pair = NCBI2NA_UNPACK_BASE(A[1+((a_index-1)/4)],
                                                (3-((a_index-1)%4)));
             matrix_row = matrix[a_base_pair];
         }
@@ -3108,7 +3114,7 @@ s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M,
             b_ptr += b_increment;
             score_gap_col = score_array[b_index].best_gap;
             next_score = score_array[b_index].best + matrix_row[ *b_ptr ];
-            
+
             if (score < score_gap_col)
                 score = score_gap_col;
 
@@ -3120,11 +3126,11 @@ s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M,
                 /* the current best score failed the X-dropoff
                    criterion. Note that this does not stop the
                    inner loop, only forces future iterations to
-                   skip this column of B. 
+                   skip this column of B.
 
                    Also, if the very first letter of B that was
                    tested failed the X dropoff criterion, make
-                   sure future inner loops start one letter to 
+                   sure future inner loops start one letter to
                    the right */
 
                 if (b_index == first_b_index)
@@ -3141,7 +3147,7 @@ s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M,
                 }
 
                 /* If starting a gap at this position will improve
-                   the best row or column score, update them to 
+                   the best row or column score, update them to
                    reflect that. */
 
                 score_gap_row -= gap_extend;
@@ -3155,9 +3161,9 @@ s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M,
 
             score = next_score;
         }
-  
+
         /* Finish aligning if the best scores for all positions
-           of B will fail the X-dropoff test, i.e. the inner loop 
+           of B will fail the X-dropoff test, i.e. the inner loop
            bounds have converged to each other */
 
         if (first_b_index == b_size)
@@ -3183,7 +3189,7 @@ s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M,
         else {
             /* The inner loop finished without failing the X-dropoff
                test; initialize extra bookkeeping structures until
-               the X dropoff test fails or we run out of letters in B. 
+               the X dropoff test fails or we run out of letters in B.
                The next inner loop will have larger bounds */
 
             while (score_gap_row >= (best_score - x_dropoff) && b_size <= N) {
@@ -3200,7 +3206,7 @@ s_BlastAlignPackedNucl(Uint1* B, Uint1* A, Int4 N, Int4 M,
             b_size++;
         }
     }
-    
+
     return best_score;
 }
 
@@ -3215,7 +3221,7 @@ BlastGetOffsetsForGappedAlignment (const Uint1* query, const Uint1* subject,
     Int4 s_length = hsp->subject.end - hsp->subject.offset;
     int q_start = hsp->query.offset;
     int s_start = hsp->subject.offset;
-    
+
     if (q_length <= HSP_MAX_WINDOW) {
         *q_retval = q_start + q_length/2;
         *s_retval = s_start + q_length/2;
@@ -3279,12 +3285,12 @@ BlastGetOffsetsForGappedAlignment (const Uint1* query, const Uint1* subject,
     return FALSE;
 }
 
-void 
+void
 BlastGetStartForGappedAlignmentNucl (const Uint1* query, const Uint1* subject,
    BlastHSP* hsp)
 {
     /* We will stop when the identity count reaches to this number */
-    const Int4 HSP_MAX_IDENT_RUN = 20; 
+    int hspMaxIdentRun = 10;
     const Uint1 *q, *s;
     Int4 index, max_offset, score, max_score, q_start, s_start, q_len;
     Boolean match, prev_match;
@@ -3299,14 +3305,15 @@ BlastGetStartForGappedAlignmentNucl (const Uint1* query, const Uint1* subject,
     q_len = hsp->query.end;
     while ((q-query < q_len) && (*q++ == *s++)) {
         score++;
-        if (score > HSP_MAX_IDENT_RUN) return;
+        if (score > hspMaxIdentRun) return;
     }
     q = query + q_start;
     s = subject + s_start;
     while ((q-query >= 0) && (*q-- == *s--)) {
         score++;
-        if (score > HSP_MAX_IDENT_RUN) return;
+        if (score > hspMaxIdentRun) return;
     }
+    hspMaxIdentRun *= 1.5;  /* Demand larger value if we move */
     /* if the old value is not ok, try to find a better point */
     q_start = hsp->query.gapped_start - offset;
     s_start = hsp->subject.gapped_start - offset;
@@ -3317,7 +3324,7 @@ BlastGetStartForGappedAlignmentNucl (const Uint1* query, const Uint1* subject,
     max_offset = q_start;
     score = 0;
     match = FALSE;
-    prev_match = FALSE; 
+    prev_match = FALSE;
     for (index = q_start; index < q_start + q_len; index++) {
         match = (*q++ == *s++);
         if (match != prev_match) {
@@ -3330,12 +3337,12 @@ BlastGetStartForGappedAlignmentNucl (const Uint1* query, const Uint1* subject,
             }
         } else if (match) {
             ++score;
-            if (score > HSP_MAX_IDENT_RUN) {
-                max_offset = index - HSP_MAX_IDENT_RUN/2;
+            if (score > hspMaxIdentRun) {
+                max_offset = index - hspMaxIdentRun/2;
                 hsp->query.gapped_start = max_offset;
                 hsp->subject.gapped_start = max_offset + s_start - q_start;
                 return;
-            } 
+            }
         }
     }
     if (match && score > max_score) {
@@ -3348,15 +3355,15 @@ BlastGetStartForGappedAlignmentNucl (const Uint1* query, const Uint1* subject,
     }
 }
 
-Int4 
+Int4
 BlastGetStartForGappedAlignment (const Uint1* query, const Uint1* subject,
-   const BlastScoreBlk* sbp, Uint4 q_start, Uint4 q_length, 
+   const BlastScoreBlk* sbp, Uint4 q_start, Uint4 q_length,
    Uint4 s_start, Uint4 s_length)
 {
     Int4 index1, max_offset, score, max_score, hsp_end;
     const Uint1* query_var,* subject_var;
     Boolean positionBased = (sbp->psi_matrix != NULL);
-    
+
     if (q_length <= HSP_MAX_WINDOW) {
         max_offset = q_start + q_length/2;
         return max_offset;
@@ -3392,15 +3399,15 @@ BlastGetStartForGappedAlignment (const Uint1* query, const Uint1* subject,
     }
     if (max_score > 0)
        max_offset -= HSP_MAX_WINDOW/2;
-    else 
+    else
        max_offset = q_start;
 
     return max_offset;
 }
 
-Int2 BLAST_GetGappedScore (EBlastProgramType program_number, 
-        BLAST_SequenceBlk* query, BlastQueryInfo* query_info, 
-        BLAST_SequenceBlk* subject, 
+Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
+        BLAST_SequenceBlk* query, BlastQueryInfo* query_info,
+        BLAST_SequenceBlk* subject,
         BlastGapAlignStruct* gap_align,
         const BlastScoringParameters* score_params,
         const BlastExtensionParameters* ext_params,
@@ -3444,11 +3451,12 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
       return 0;
 
    is_prot = (program_number != eBlastTypeBlastn &&
-              program_number != eBlastTypePhiBlastn);
+              program_number != eBlastTypePhiBlastn &&
+              program_number != eBlastTypeMapping);
    is_greedy = (ext_params->options->ePrelimGapExt == eGreedyScoreOnly);
 
-   /* turn on approximate gapped alignment if 1) the search 
-      specifies it, and 2) the first, highest-scoring ungapped 
+   /* turn on approximate gapped alignment if 1) the search
+      specifies it, and 2) the first, highest-scoring ungapped
       alignment in init_hitlist scores below a reduced cutoff.
       The second condition is used to avoid computing approximate
       alignments that experiment shows are likely to be thrown
@@ -3458,7 +3466,7 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
        int i;
        Boolean* found = calloc(query_info->last_context + 1, sizeof(Boolean));
 
-       restricted_align_array = 
+       restricted_align_array =
            (Boolean*)calloc(Blast_GetQueryIndexFromContext(
                                                query_info->last_context,
                                                program_number) + 1,
@@ -3518,7 +3526,7 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
          rps_cutoff_index = subject->oid;
       else
          rps_cutoff_index = subject->oid * NUM_FRAMES +
-                            BLAST_FrameToContext(subject->frame, 
+                            BLAST_FrameToContext(subject->frame,
                                                  program_number);
    }
 
@@ -3526,7 +3534,7 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
 
    if (*hsp_list_ptr == NULL)
       *hsp_list_ptr = hsp_list = Blast_HSPListNew(kHspNumMax);
-   else 
+   else
       hsp_list = *hsp_list_ptr;
 
    /* Initialize the interval tree with the maximum possible
@@ -3535,11 +3543,11 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
       except for out-of-frame tblastn. In that case, subject->length
       is the length of one strand of the subject sequence, but the
       subject offsets of each ungapped alignment are wrt all six subject
-      frames concatenated together. Finally, add 1 to the maximum, 
+      frames concatenated together. Finally, add 1 to the maximum,
       to account for HSPs that include the end of a sequence */
 
    if (Blast_SubjectIsTranslated(program_number) &&
-       score_params->options->is_ooframe) { 
+       score_params->options->is_ooframe) {
       /* OOF search only supported for tblastn and blastx. (blastx
 	 does not have a translated subject, so can't get here.) */
       ASSERT(program_number == eBlastTypeTblastn);
@@ -3554,14 +3562,14 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
    if (!tree)
      return BLASTERR_MEMORY;
 
-   
+
    init_hsp_array = init_hitlist->init_hsp_array;
    found_high_score = (Int4*) calloc(query_info->num_queries, sizeof(Int4));
    if (hit_params->low_score)
    {
    	for (index=0; index<init_hitlist->total; index++)
    	{
-      	    int query_index = 
+      	    int query_index =
        		  Blast_GetQueryIndexFromQueryOffset(init_hsp_array[index].offsets.qs_offsets.q_off, program_number, query_info);
       	    if (init_hsp_array[index].ungapped_data->score > hit_params->low_score[query_index])
         	found_high_score[query_index] = 1;
@@ -3585,7 +3593,7 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
       }
       init_hsp = &tmp_init_hsp;
 
-      s_AdjustHspOffsetsAndGetQueryData(query, query_info, init_hsp, 
+      s_AdjustHspOffsetsAndGetQueryData(query, query_info, init_hsp,
                                         &query_tmp, &context);
 
       query_index = Blast_GetQueryIndexFromContext(context, program_number);
@@ -3611,7 +3619,7 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
       }
 
       if (rpsblast_pssms)
-         gap_align->sbp->psi_matrix->pssm->data = rpsblast_pssms + 
+         gap_align->sbp->psi_matrix->pssm->data = rpsblast_pssms +
              query_info->contexts[context].query_offset;
 
       if (!init_hsp->ungapped_data) {
@@ -3652,27 +3660,27 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
 
          if (gapped_stats)
             ++gapped_stats->extensions;
- 
+
          if(is_prot && !score_params->options->is_ooframe) {
-            max_offset = 
-               BlastGetStartForGappedAlignment(query_tmp.sequence, 
+            max_offset =
+               BlastGetStartForGappedAlignment(query_tmp.sequence,
                   subject->sequence, gap_align->sbp,
                   init_hsp->ungapped_data->q_start,
                   init_hsp->ungapped_data->length,
                   init_hsp->ungapped_data->s_start,
                   init_hsp->ungapped_data->length);
-            init_hsp->offsets.qs_offsets.s_off += 
+            init_hsp->offsets.qs_offsets.s_off +=
                 max_offset - init_hsp->offsets.qs_offsets.q_off;
             init_hsp->offsets.qs_offsets.q_off = max_offset;
          }
 
          if (is_prot) {
-            status = s_BlastProtGappedAlignment(program_number, &query_tmp, 
-                                                subject, gap_align, 
-                                                score_params, init_hsp, 
+            status = s_BlastProtGappedAlignment(program_number, &query_tmp,
+                                                subject, gap_align,
+                                                score_params, init_hsp,
                                                 restricted_alignment,
                                                 fence_hit);
-            
+
             if (restricted_alignment &&
                 gap_align->score < cutoff &&
                 gap_align->score >= restricted_cutoff) {
@@ -3682,7 +3690,7 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
                    could be highly suboptimal. Recomputing the alignment
                    would resolve the ambiguity, but when the final list of
                    HSPs contains a mix of approximate and exact gapped
-                   alignments it's possible for a highly suboptimal 
+                   alignments it's possible for a highly suboptimal
                    alignment to make it to the traceback phase, where
                    its start point is reused. We sidestep this problem
                    by throwing away all the previously computed gapped
@@ -3709,7 +3717,7 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
                         status = BlastIntervalTreeAddHSP(
                                                 hsp_list->hsp_array[index2],
                                                 tree,
-                                                query_info, 
+                                                query_info,
                                                 eQueryAndSubject);
 
                         hsp_list->hsp_array[index2] = NULL;
@@ -3727,43 +3735,43 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
                    alignments for the current query */
                 redo_index = index;
                 redo_query = query_index;
-                index = -1;   
+                index = -1;
                 continue;
             }
          } else if (is_greedy) {
             if (init_hsp->ungapped_data) {
-                init_hsp->offsets.qs_offsets.q_off = 
+                init_hsp->offsets.qs_offsets.q_off =
                     init_hsp->ungapped_data->q_start + init_hsp->ungapped_data->length/2;
-                init_hsp->offsets.qs_offsets.s_off = 
+                init_hsp->offsets.qs_offsets.s_off =
                     init_hsp->ungapped_data->s_start + init_hsp->ungapped_data->length/2;
             }
             status = BLAST_GreedyGappedAlignment(
-                         query_tmp.sequence, subject->sequence, 
-                         query_tmp.length, subject->length, 
-                         gap_align, score_params, 
-                         init_hsp->offsets.qs_offsets.q_off, 
-                         init_hsp->offsets.qs_offsets.s_off, 
+                         query_tmp.sequence, subject->sequence,
+                         query_tmp.length, subject->length,
+                         gap_align, score_params,
+                         init_hsp->offsets.qs_offsets.q_off,
+                         init_hsp->offsets.qs_offsets.s_off,
                          (Boolean) TRUE, FALSE, fence_hit);
             /* override the alignment start point with the estimate
                by the aligner of the best start point */
-            init_hsp->offsets.qs_offsets.q_off = 
+            init_hsp->offsets.qs_offsets.q_off =
                                 gap_align->greedy_query_seed_start;
             init_hsp->offsets.qs_offsets.s_off =
                                 gap_align->greedy_subject_seed_start;
          } else {
             /*  Assuming the ungapped alignment is long enough to
-                contain an 8-letter seed of exact matches, start 
-                the gapped alignment inside the first byte of the 
-                seed that contains all matches. Note that even if 
-                the ungapped alignment is not long enough, 
-                s_BlastDynProgNtGappedAlignment will still round 
-                the start point up to the first 4-base boundary 
+                contain an 8-letter seed of exact matches, start
+                the gapped alignment inside the first byte of the
+                seed that contains all matches. Note that even if
+                the ungapped alignment is not long enough,
+                s_BlastDynProgNtGappedAlignment will still round
+                the start point up to the first 4-base boundary
                 on the subject sequence */
             if (s_end >= (Int4)init_hsp->offsets.qs_offsets.s_off + 8) {
                init_hsp->offsets.qs_offsets.s_off += 3;
                init_hsp->offsets.qs_offsets.q_off += 3;
             }
-            status = s_BlastDynProgNtGappedAlignment(&query_tmp, subject, 
+            status = s_BlastDynProgNtGappedAlignment(&query_tmp, subject,
                          gap_align, score_params, init_hsp);
          }
 
@@ -3775,12 +3783,12 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
    	    tree = Blast_IntervalTreeFree(tree);
             return status;
          }
-        
+
          if (gap_align->score >= cutoff) {
              Int2 query_frame = 0;
-             /* For mixed-frame search, the query frame is determined 
+             /* For mixed-frame search, the query frame is determined
                 from the offset, not only from context. */
-             if (score_params->options->is_ooframe && 
+             if (score_params->options->is_ooframe &&
                  program_number == eBlastTypeBlastx) {
                  query_frame = gap_align->query_start % CODON_LENGTH + 1;
                  if ((context % NUM_FRAMES) >= CODON_LENGTH)
@@ -3789,12 +3797,12 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
                  query_frame = query_info->contexts[context].frame;
              }
 
-             status = Blast_HSPInit(gap_align->query_start, 
-                           gap_align->query_stop, gap_align->subject_start, 
-                           gap_align->subject_stop, 
-                           init_hsp->offsets.qs_offsets.q_off, 
-                           init_hsp->offsets.qs_offsets.s_off, context, 
-                           query_frame, subject->frame, gap_align->score, 
+             status = Blast_HSPInit(gap_align->query_start,
+                           gap_align->query_stop, gap_align->subject_start,
+                           gap_align->subject_stop,
+                           init_hsp->offsets.qs_offsets.q_off,
+                           init_hsp->offsets.qs_offsets.s_off, context,
+                           query_frame, subject->frame, gap_align->score,
                            &(gap_align->edit_script), &new_hsp);
              if (status)
 	     {
@@ -3805,7 +3813,7 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
              status = Blast_HSPListSaveHSP(hsp_list, new_hsp);
              if (status)
                  break;
-             status = BlastIntervalTreeAddHSP(new_hsp, tree, query_info, 
+             status = BlastIntervalTreeAddHSP(new_hsp, tree, query_info,
                                      eQueryAndSubject);
              if (status)
                  break;
@@ -3819,7 +3827,7 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
             }
          }
       }
-   }   
+   }
 
    sfree(found_high_score);
    if (restricted_align_array) {
@@ -3843,20 +3851,20 @@ Int2 BLAST_GetGappedScore (EBlastProgramType program_number,
  * @param private_s_start Extent of alignment in subject [out]
  * @param score_only Return score only, without traceback [in]
  * @param edit_block Structure to hold generated traceback [out]
- * @param gap_align Gapped alignment information and preallocated 
+ * @param gap_align Gapped alignment information and preallocated
  *                  memory [in] [out]
  * @param score_params Scoring parameters [in]
  * @param psi_offset Starting position in PSI-BLAST matrix [in]
  * @param reversed Direction of the extension [in]
- * @param switch_seq Sequences need to be switched for blastx, 
+ * @param switch_seq Sequences need to be switched for blastx,
  *                   but not for tblastn [in]
  */
-static Int4 
-s_OutOfFrameSemiGappedAlignWrap(const Uint1* query, const Uint1* subject, Int4 q_off, 
-   Int4 s_off, Int4* private_q_start, Int4* private_s_start, 
-   Boolean score_only, GapPrelimEditBlock *edit_block, 
-   BlastGapAlignStruct* gap_align, 
-   const BlastScoringParameters* score_params, Int4 psi_offset, 
+static Int4
+s_OutOfFrameSemiGappedAlignWrap(const Uint1* query, const Uint1* subject, Int4 q_off,
+   Int4 s_off, Int4* private_q_start, Int4* private_s_start,
+   Boolean score_only, GapPrelimEditBlock *edit_block,
+   BlastGapAlignStruct* gap_align,
+   const BlastScoringParameters* score_params, Int4 psi_offset,
    Boolean reversed, Boolean switch_seq)
 {
    if (switch_seq) {
@@ -3870,24 +3878,24 @@ s_OutOfFrameSemiGappedAlignWrap(const Uint1* query, const Uint1* subject, Int4 q
    }
 }
 
-/** Maximal subject length after which the offsets are adjusted to a 
+/** Maximal subject length after which the offsets are adjusted to a
  * subsequence.
  */
 #define MAX_SUBJECT_OFFSET 90000
 /** Approximate upper bound on a number of gaps in an HSP, needed to determine
  * the length of the subject subsequence to be retrieved for alignment with
- * traceback. 
+ * traceback.
  */
 #define MAX_TOTAL_GAPS 3000
 
-void 
-AdjustSubjectRange(Int4* subject_offset_ptr, Int4* subject_length_ptr, 
+void
+AdjustSubjectRange(Int4* subject_offset_ptr, Int4* subject_length_ptr,
 		   Int4 query_offset, Int4 query_length, Int4* start_shift)
 {
    Int4 s_offset;
    Int4 subject_length = *subject_length_ptr;
    Int4 max_extension_left, max_extension_right;
-   
+
    /* If subject sequence is not too long, leave everything as is */
    if (subject_length < MAX_SUBJECT_OFFSET) {
       *start_shift = 0;
@@ -3895,7 +3903,7 @@ AdjustSubjectRange(Int4* subject_offset_ptr, Int4* subject_length_ptr,
    }
 
    s_offset = *subject_offset_ptr;
-   /* Maximal extension length is the remaining length in the query, plus 
+   /* Maximal extension length is the remaining length in the query, plus
       an estimate of a maximal total number of gaps. */
    max_extension_left = query_offset + MAX_TOTAL_GAPS;
    max_extension_right = query_length - query_offset + MAX_TOTAL_GAPS;
@@ -3907,12 +3915,12 @@ AdjustSubjectRange(Int4* subject_offset_ptr, Int4* subject_length_ptr,
       *subject_offset_ptr = max_extension_left;
    }
 
-   *subject_length_ptr = 
+   *subject_length_ptr =
       MIN(subject_length, s_offset + max_extension_right) - *start_shift;
 }
 
 /** Performs gapped extension for protein sequences, given two
- * sequence blocks, scoring and extension options, and an initial HSP 
+ * sequence blocks, scoring and extension options, and an initial HSP
  * with information from the previously performed ungapped extension
  * @param program BLAST program [in]
  * @param query_blk The query sequence block [in]
@@ -3920,15 +3928,15 @@ AdjustSubjectRange(Int4* subject_offset_ptr, Int4* subject_length_ptr,
  * @param gap_align The auxiliary structure for gapped alignment [in]
  * @param score_params Parameters related to scoring [in]
  * @param init_hsp The initial HSP information [in]
- * @param restricted_alignment If true and search is not out-of-frame, 
+ * @param restricted_alignment If true and search is not out-of-frame,
  *              use a faster approximate gapped alignment algorithm [in]
  * @param fence_hit If not NULL, pointer to a boolean that is set to
  *                  TRUE if gapped extension reaches a neighborhood
  *                  of the subject sequence that is not initialized [in][out]
  */
-static Int2 
-s_BlastProtGappedAlignment(EBlastProgramType program, 
-   BLAST_SequenceBlk* query_blk, BLAST_SequenceBlk* subject_blk, 
+static Int2
+s_BlastProtGappedAlignment(EBlastProgramType program,
+   BLAST_SequenceBlk* query_blk, BLAST_SequenceBlk* subject_blk,
    BlastGapAlignStruct* gap_align,
    const BlastScoringParameters* score_params, BlastInitHSP* init_hsp,
    Boolean restricted_alignment,
@@ -3943,10 +3951,10 @@ s_BlastProtGappedAlignment(EBlastProgramType program,
    Int4 subject_length = subject_blk->length;
    Int4 subject_shift = 0;
    BlastScoringOptions *score_options = score_params->options;
-    
+
    if (gap_align == NULL)
       return -1;
-   
+
    if (score_options->is_ooframe) {
       ASSERT(program == eBlastTypeTblastn || program == eBlastTypeBlastx);
 
@@ -3955,7 +3963,7 @@ s_BlastProtGappedAlignment(EBlastProgramType program,
          of the mixed-frame sequence corresponding to the reverse strand. */
       if (program == eBlastTypeTblastn && subject_blk->frame < 0)
           init_hsp->offsets.qs_offsets.s_off -= subject_length + 1;
-      
+
       s_length = init_hsp->offsets.qs_offsets.s_off;
 
       if (program == eBlastTypeBlastx) {
@@ -3975,35 +3983,35 @@ s_BlastProtGappedAlignment(EBlastProgramType program,
       subject = subject_blk->sequence;
    }
 
-   AdjustSubjectRange(&s_length, &subject_length, q_length, query_length, 
+   AdjustSubjectRange(&s_length, &subject_length, q_length, query_length,
                       &subject_shift);
 
    found_start = FALSE;
    found_end = FALSE;
-    
+
    /* Looking for "left" score */
    score_left = 0;
    if (q_length != 0 && s_length != 0) {
       found_start = TRUE;
       if(score_options->is_ooframe) {
-         score_left = 
+         score_left =
              s_OutOfFrameSemiGappedAlignWrap(query, subject, q_length, s_length,
-                 &private_q_start, &private_s_start, TRUE, NULL, 
+                 &private_q_start, &private_s_start, TRUE, NULL,
                  gap_align, score_params, q_length, TRUE, switch_seq);
       } else {
          if (restricted_alignment) {
-            score_left = s_RestrictedGappedAlign(query, subject+subject_shift, 
+            score_left = s_RestrictedGappedAlign(query, subject+subject_shift,
                                    q_length, s_length,
                                    &private_q_start, &private_s_start,
-                                   gap_align, score_params, 
+                                   gap_align, score_params,
                                    init_hsp->offsets.qs_offsets.q_off, TRUE);
          }
          else {
-            score_left = Blast_SemiGappedAlign(query, subject+subject_shift, 
+            score_left = Blast_SemiGappedAlign(query, subject+subject_shift,
                                    q_length, s_length,
-                                   &private_q_start, &private_s_start, TRUE, 
-                                   NULL, gap_align, score_params, 
-                                   init_hsp->offsets.qs_offsets.q_off, 
+                                   &private_q_start, &private_s_start, TRUE,
+                                   NULL, gap_align, score_params,
+                                   init_hsp->offsets.qs_offsets.q_off,
                                    FALSE, TRUE,
                                    fence_hit);
          }
@@ -4016,46 +4024,46 @@ s_BlastProtGappedAlignment(EBlastProgramType program,
    if (q_length < query_length && s_length < subject_length) {
       found_end = TRUE;
       if(score_options->is_ooframe) {
-         score_right = 
-             s_OutOfFrameSemiGappedAlignWrap(query-1, subject-1, 
+         score_right =
+             s_OutOfFrameSemiGappedAlignWrap(query-1, subject-1,
                  query_length-q_length+1, subject_length-s_length+1,
-                 &(gap_align->query_stop), &(gap_align->subject_stop), 
-                 TRUE, NULL, gap_align, score_params, q_length, FALSE, 
+                 &(gap_align->query_stop), &(gap_align->subject_stop),
+                 TRUE, NULL, gap_align, score_params, q_length, FALSE,
                  switch_seq);
          gap_align->query_stop += q_length;
          gap_align->subject_stop += s_length + subject_shift;
       } else {
          if (restricted_alignment) {
             score_right = s_RestrictedGappedAlign(
-                                   query+init_hsp->offsets.qs_offsets.q_off, 
-                                   subject+init_hsp->offsets.qs_offsets.s_off, 
-                                   query_length-q_length, 
-                                   subject_length-s_length, 
-                                   &(gap_align->query_stop), 
-                                   &(gap_align->subject_stop), 
-                                   gap_align, score_params, 
+                                   query+init_hsp->offsets.qs_offsets.q_off,
+                                   subject+init_hsp->offsets.qs_offsets.s_off,
+                                   query_length-q_length,
+                                   subject_length-s_length,
+                                   &(gap_align->query_stop),
+                                   &(gap_align->subject_stop),
+                                   gap_align, score_params,
                                    init_hsp->offsets.qs_offsets.q_off, FALSE);
          }
          else {
             score_right = Blast_SemiGappedAlign(
-                                   query+init_hsp->offsets.qs_offsets.q_off, 
-                                   subject+init_hsp->offsets.qs_offsets.s_off, 
-                                   query_length-q_length, 
-                                   subject_length-s_length, 
-                                   &(gap_align->query_stop), 
-                                   &(gap_align->subject_stop), 
-                                   TRUE, NULL, gap_align, score_params, 
-                                   init_hsp->offsets.qs_offsets.q_off, FALSE, 
+                                   query+init_hsp->offsets.qs_offsets.q_off,
+                                   subject+init_hsp->offsets.qs_offsets.s_off,
+                                   query_length-q_length,
+                                   subject_length-s_length,
+                                   &(gap_align->query_stop),
+                                   &(gap_align->subject_stop),
+                                   TRUE, NULL, gap_align, score_params,
+                                   init_hsp->offsets.qs_offsets.q_off, FALSE,
                                    FALSE,
                                    fence_hit);
          }
-         /* Make end offsets point to the byte after the end of the 
+         /* Make end offsets point to the byte after the end of the
             alignment */
          gap_align->query_stop += init_hsp->offsets.qs_offsets.q_off + 1;
          gap_align->subject_stop += init_hsp->offsets.qs_offsets.s_off + 1;
       }
    }
-   
+
    if (found_start == FALSE) {  /* impossible for in-frame */
       gap_align->query_start = init_hsp->offsets.qs_offsets.q_off;
       gap_align->subject_start = init_hsp->offsets.qs_offsets.s_off;
@@ -4064,7 +4072,7 @@ s_BlastProtGappedAlignment(EBlastProgramType program,
       gap_align->query_stop = init_hsp->offsets.qs_offsets.q_off;
       gap_align->subject_stop = init_hsp->offsets.qs_offsets.s_off;
    }
-   
+
    gap_align->score = score_right+score_left;
 
    return 0;
@@ -4091,7 +4099,7 @@ s_BlastOOFTracebackToGapEditScript(GapPrelimEditBlock *rev_prelim_tback,
     GapPrelimEditBlock *tmp_prelim_tback;
     Int4 i, num_nuc;
     int extra_needed=0;
-    
+
     /* prepend a substitution, since the input sequences were
        shifted prior to the OOF alignment */
 
@@ -4117,7 +4125,7 @@ s_BlastOOFTracebackToGapEditScript(GapPrelimEditBlock *rev_prelim_tback,
             /* Propagating the initial extra substitution requires
                that edit operations which are not in-frame gaps must
                'flow through' an in-frame gap; the last non-gap
-               operation before the gap will appear after the gap. 
+               operation before the gap will appear after the gap.
                This could mean either one or two edit blocks
                getting created */
 
@@ -4139,8 +4147,8 @@ s_BlastOOFTracebackToGapEditScript(GapPrelimEditBlock *rev_prelim_tback,
     }
 
     /* Handle the crossing over from the left extension to
-       the right extension. Begin by writing out the final 
-       group of ops from the left extension, except for the 
+       the right extension. Begin by writing out the final
+       group of ops from the left extension, except for the
        one op that must be merged */
 
     last_num--;
@@ -4193,7 +4201,7 @@ s_BlastOOFTracebackToGapEditScript(GapPrelimEditBlock *rev_prelim_tback,
     for (i=0; i<e_script->size; i++)
     {
         int total_actions=0;
-        /* Count the number of nucleotides in the next 
+        /* Count the number of nucleotides in the next
            traceback operation and delete any traceback operations
            that would make the alignment too long. This check is
            not needed for in-frame alignment because the
@@ -4207,7 +4215,7 @@ s_BlastOOFTracebackToGapEditScript(GapPrelimEditBlock *rev_prelim_tback,
         total_actions = last_op * e_script->num[i];
 
         if (num_nuc + total_actions >= nucl_align_length) {
-            e_script->num[i] = (nucl_align_length - num_nuc + 
+            e_script->num[i] = (nucl_align_length - num_nuc +
                              last_op - 1) / last_op;
             break; /* We delete the rest of the script. */
         }
@@ -4267,13 +4275,13 @@ s_BlastOOFTracebackToGapEditScript(GapPrelimEditBlock *rev_prelim_tback,
     return 0;
 }
 
-Int2 BLAST_GappedAlignmentWithTraceback(EBlastProgramType program, 
-        const Uint1* query, const Uint1* subject, BlastGapAlignStruct* gap_align, 
+Int2 BLAST_GappedAlignmentWithTraceback(EBlastProgramType program,
+        const Uint1* query, const Uint1* subject, BlastGapAlignStruct* gap_align,
         const BlastScoringParameters* score_params,
         Int4 q_start, Int4 s_start, Int4 query_length, Int4 subject_length,
         Boolean * fence_hit)
 {
-    Boolean found_start, found_end;
+    Boolean found_end;
     Int4 score_right, score_left, private_q_length, private_s_length;
     Int4 q_length, s_length;
     Boolean is_ooframe = score_params->options->is_ooframe;
@@ -4281,23 +4289,22 @@ Int2 BLAST_GappedAlignmentWithTraceback(EBlastProgramType program,
     Boolean switch_seq = FALSE;
     GapPrelimEditBlock *fwd_prelim_tback;
     GapPrelimEditBlock *rev_prelim_tback;
-    
+
     if (gap_align == NULL)
         return -1;
-    
+
     fwd_prelim_tback = gap_align->fwd_prelim_tback;
     rev_prelim_tback = gap_align->rev_prelim_tback;
     GapPrelimEditBlockReset(fwd_prelim_tback);
     GapPrelimEditBlockReset(rev_prelim_tback);
 
-    found_start = FALSE;
     found_end = FALSE;
-    
+
     q_length = query_length;
     s_length = subject_length;
     if (is_ooframe) {
-       /* The mixed frame sequence is shifted to the 3rd position, so its 
-          maximal available length for extension is less by 2 than its 
+       /* The mixed frame sequence is shifted to the 3rd position, so its
+          maximal available length for extension is less by 2 than its
           total length. */
        switch_seq = (program == eBlastTypeBlastx);
        if (switch_seq) {
@@ -4308,60 +4315,59 @@ Int2 BLAST_GappedAlignmentWithTraceback(EBlastProgramType program,
     }
 
     score_left = 0;
-    found_start = TRUE;
-        
+
     if(is_ooframe) {
        /* NB: Left extension does not include starting point corresponding
           to the offset pair; the right extension does. */
        score_left =
-          s_OutOfFrameSemiGappedAlignWrap(query+q_start, subject+s_start, 
-             q_start, s_start, &private_q_length, &private_s_length, 
-             FALSE, rev_prelim_tback, gap_align, score_params, q_start, 
+          s_OutOfFrameSemiGappedAlignWrap(query+q_start, subject+s_start,
+             q_start, s_start, &private_q_length, &private_s_length,
+             FALSE, rev_prelim_tback, gap_align, score_params, q_start,
              TRUE, switch_seq);
        gap_align->query_start = q_start - private_q_length;
        gap_align->subject_start = s_start - private_s_length;
-    } else {        
-       /* NB: The left extension includes the starting point 
+    } else {
+       /* NB: The left extension includes the starting point
           [q_start,s_start]; the right extension does not. */
-       // <AG> score_left = 
+       // <AG> score_left =
        //    Blast_SemiGappedAlign(query, subject, q_start+1, s_start+1,
        //       &private_q_length, &private_s_length, FALSE, rev_prelim_tback,
        //       gap_align, score_params, q_start, FALSE, TRUE,
        //       fence_hit);
 
         score_left = ALIGN_EX(query, subject, q_start+1, s_start+1,  &private_q_length, &private_s_length, rev_prelim_tback,
-                              gap_align, 
+                              gap_align,
                               score_params, q_start, FALSE /*reversed*/, TRUE /*reverse_sequence*/,
              fence_hit);
 
        gap_align->query_start = q_start - private_q_length + 1;
        gap_align->subject_start = s_start - private_s_length + 1;
     }
-    
+
     score_right = 0;
-    
+
     if ((! (fence_hit && *fence_hit)) &&
         (q_start < q_length) &&
         (s_start < s_length)) {
-        
+
        found_end = TRUE;
        if(is_ooframe) {
-          score_right = 
+          score_right =
              s_OutOfFrameSemiGappedAlignWrap(query+q_start-1, subject+s_start-1,
-                q_length-q_start, s_length-s_start, 
+                q_length-q_start, s_length-s_start,
                 &private_q_length, &private_s_length, FALSE, fwd_prelim_tback,
                 gap_align, score_params, q_start, FALSE, switch_seq);
         } else {
-            // <AG> score_right = 
-            //    Blast_SemiGappedAlign(query+q_start, subject+s_start, 
-            //       q_length-q_start-1, s_length-s_start-1, &private_q_length, 
-            //       &private_s_length, FALSE, fwd_prelim_tback, gap_align, 
+            // <AG> score_right =
+            //    Blast_SemiGappedAlign(query+q_start, subject+s_start,
+            //       q_length-q_start-1, s_length-s_start-1, &private_q_length,
+            //       &private_s_length, FALSE, fwd_prelim_tback, gap_align,
             //       score_params, q_start, FALSE, FALSE,
             //       fence_hit);
-            score_right = 
-               ALIGN_EX(query+q_start, subject+s_start, 
-                  q_length-q_start-1, s_length-s_start-1, &private_q_length, 
-                  &private_s_length, fwd_prelim_tback, gap_align, 
+            score_right =
+               ALIGN_EX(query+q_start, subject+s_start,
+                  q_length-q_start-1, s_length-s_start-1, &private_q_length,
+                  &private_s_length, fwd_prelim_tback, gap_align,
                   score_params, q_start, FALSE, FALSE,
                   fence_hit);
         }
@@ -4369,12 +4375,7 @@ Int2 BLAST_GappedAlignmentWithTraceback(EBlastProgramType program,
         gap_align->query_stop = q_start + private_q_length + 1;
         gap_align->subject_stop = s_start + private_s_length + 1;
     }
-    
-    if (found_start == FALSE) {	/* Start never found */
-        gap_align->query_start = q_start;
-        gap_align->subject_start = s_start;
-    }
-    
+
     if (found_end == FALSE) {
         gap_align->query_stop = q_start - 1;
         gap_align->subject_stop = s_start - 1;
@@ -4383,15 +4384,15 @@ Int2 BLAST_GappedAlignmentWithTraceback(EBlastProgramType program,
     if(is_ooframe) {
         Int4 nucl_align_length;
         if (program == eBlastTypeBlastx) {
-            nucl_align_length = gap_align->query_stop - 
+            nucl_align_length = gap_align->query_stop -
                                 gap_align->query_start;
         }
         else {
-            nucl_align_length = gap_align->subject_stop - 
+            nucl_align_length = gap_align->subject_stop -
                                 gap_align->subject_start;
         }
-        status = s_BlastOOFTracebackToGapEditScript(rev_prelim_tback, 
-                       fwd_prelim_tback, nucl_align_length, 
+        status = s_BlastOOFTracebackToGapEditScript(rev_prelim_tback,
+                       fwd_prelim_tback, nucl_align_length,
                        &gap_align->edit_script);
     } else {
         Int4 i;
@@ -4400,10 +4401,10 @@ Int2 BLAST_GappedAlignmentWithTraceback(EBlastProgramType program,
                                                         fwd_prelim_tback);
 
         /* rarely (typically when the scoring system changes between
-           the score-only and traceback stages, as happens with 
-           composition-based statistics) it is possible to compute an 
+           the score-only and traceback stages, as happens with
+           composition-based statistics) it is possible to compute an
            optimal alignment with a leading or trailing gap. Prune
-           these unneeded gaps here and update the score and 
+           these unneeded gaps here and update the score and
            alignment boundaries */
 
         gap_align->edit_script = esp;
@@ -4411,12 +4412,12 @@ Int2 BLAST_GappedAlignmentWithTraceback(EBlastProgramType program,
             while (esp->size && esp->op_type[0] != eGapAlignSub) {
                 score_left += score_params->gap_open +
                              esp->num[0] * score_params->gap_extend;
-    
+
                 if (esp->op_type[0] == eGapAlignDel)
                     gap_align->subject_start += esp->num[0];
                 else
                     gap_align->query_start += esp->num[0];
-    
+
                 for (i = 1; i < esp->size; i++) {
                     esp->op_type[i-1] = esp->op_type[i];
                     esp->num[i-1] = esp->num[i];
@@ -4427,12 +4428,12 @@ Int2 BLAST_GappedAlignmentWithTraceback(EBlastProgramType program,
             while (esp->size && esp->op_type[i-1] != eGapAlignSub) {
                 score_right += score_params->gap_open +
                              esp->num[i-1] * score_params->gap_extend;
-    
+
                 if (esp->op_type[i-1] == eGapAlignDel)
                     gap_align->subject_stop -= esp->num[i-1];
                 else
                     gap_align->query_stop -= esp->num[i-1];
-    
+
                 esp->size--;
                 i--;
                 ASSERT(esp->size == i);
@@ -4445,9 +4446,9 @@ Int2 BLAST_GappedAlignmentWithTraceback(EBlastProgramType program,
 }
 
 Int2 BLAST_GetUngappedHSPList(BlastInitHitList* init_hitlist,
-                              BlastQueryInfo* query_info, 
-                              BLAST_SequenceBlk* subject, 
-                              const BlastHitSavingOptions* hit_options, 
+                              BlastQueryInfo* query_info,
+                              BLAST_SequenceBlk* subject,
+                              const BlastHitSavingOptions* hit_options,
                               BlastHSPList** hsp_list_ptr)
 {
    BlastHSPList* hsp_list = NULL;
@@ -4472,26 +4473,26 @@ Int2 BLAST_GetUngappedHSPList(BlastInitHitList* init_hitlist,
       BlastUngappedData* ungapped_data=NULL;
       Int4 context = 0;
       init_hsp = &init_hitlist->init_hsp_array[index];
-      if (!init_hsp->ungapped_data) 
+      if (!init_hsp->ungapped_data)
          continue;
 
       if (!hsp_list) {
          hsp_list = Blast_HSPListNew(kHspNumMax);
          *hsp_list_ptr = hsp_list;
       }
-      /* Adjust the initial HSP's coordinates in case of concatenated 
+      /* Adjust the initial HSP's coordinates in case of concatenated
          multiple queries/strands/frames */
       context = s_GetUngappedHSPContext(query_info, init_hsp);
       s_AdjustInitialHSPOffsets(init_hsp,
                                 query_info->contexts[context].query_offset);
       ungapped_data = init_hsp->ungapped_data;
-      Blast_HSPInit(ungapped_data->q_start, 
+      Blast_HSPInit(ungapped_data->q_start,
                     ungapped_data->length+ungapped_data->q_start,
-                    ungapped_data->s_start, 
+                    ungapped_data->s_start,
                     ungapped_data->length+ungapped_data->s_start,
-                    init_hsp->offsets.qs_offsets.q_off, 
-                    init_hsp->offsets.qs_offsets.s_off, 
-                    context, query_info->contexts[context].frame, 
+                    init_hsp->offsets.qs_offsets.q_off,
+                    init_hsp->offsets.qs_offsets.s_off,
+                    context, query_info->contexts[context].frame,
                     subject->frame, ungapped_data->score, NULL, &new_hsp);
       Blast_HSPListSaveHSP(hsp_list, new_hsp);
    }
diff --git a/c++/src/algo/blast/core/blast_hits.c b/c++/src/algo/blast/core/blast_hits.c
index 2cf91cc..b9b1abd 100644
--- a/c++/src/algo/blast/core/blast_hits.c
+++ b/c++/src/algo/blast/core/blast_hits.c
@@ -1,4 +1,4 @@
-/* $Id: blast_hits.c 500444 2016-05-04 17:46:06Z ivanov $
+/* $Id: blast_hits.c 516334 2016-10-12 17:30:52Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
  * BLAST functions for saving hits after the (preliminary) gapped alignment
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_hits.c 500444 2016-05-04 17:46:06Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/ncbi_math.h>
 #include <algo/blast/core/blast_hits.h>
 #include <algo/blast/core/blast_util.h>
@@ -42,6 +37,7 @@ static char const rcsid[] =
 #include <algo/blast/core/blast_hspstream.h>
 #include "blast_hits_priv.h"
 #include "blast_itree.h"
+#include "jumper.h"
 
 NCBI_XBLAST_EXPORT
 Int2 SBlastHitsParametersNew(const BlastHitSavingOptions* hit_options,
@@ -111,6 +107,7 @@ BlastHSP* Blast_HSPFree(BlastHSP* hsp)
    if (!hsp)
       return NULL;
    hsp->gap_info = GapEditScriptDelete(hsp->gap_info);
+   hsp->map_info = BlastHSPMappingInfoFree(hsp->map_info);
    sfree(hsp->pat_info);
    sfree(hsp);
    return NULL;
@@ -166,6 +163,28 @@ Blast_HSPInit(Int4 query_start, Int4 query_end, Int4 subject_start,
    return 0;
 }
 
+
+BlastHSPMappingInfo* BlastHSPMappingInfoFree(BlastHSPMappingInfo* info)
+{
+   if (!info) {
+       return NULL;
+   }
+
+   info->edits = JumperEditsBlockFree(info->edits);
+   if (info->subject_overhangs) {
+       SequenceOverhangsFree(info->subject_overhangs);
+   }
+   sfree(info);
+
+   return NULL;
+}
+
+BlastHSPMappingInfo* BlastHSPMappingInfoNew(void)
+{
+    BlastHSPMappingInfo* retval = calloc(1, sizeof(BlastHSPMappingInfo));
+    return retval;
+}
+
 Int4 BlastHspNumMax(Boolean gapped_calculation, const BlastHitSavingOptions* options)
 {
    Int4 retval=0;
@@ -216,6 +235,98 @@ s_BlastHSPCopy(const BlastHSP* hsp)
     return new_hsp;
 }
 
+/* Make a deep copy of an HSP */
+BlastHSP* Blast_HSPClone(const BlastHSP* hsp)
+{
+    BlastHSP* retval = NULL;
+
+    if (!hsp) {
+        return NULL;
+    }
+
+    retval = Blast_HSPNew();
+    if (retval) {
+        retval->score = hsp->score;
+        retval->num_ident = hsp->num_ident;
+        memcpy(&retval->query, &hsp->query, sizeof(BlastSeg));
+        memcpy(&retval->subject, &hsp->subject, sizeof(BlastSeg));
+        retval->context = hsp->context;
+        retval->evalue = hsp->evalue;
+        retval->bit_score = hsp->bit_score;
+        retval->num = hsp->num;
+        retval->comp_adjustment_method = hsp->comp_adjustment_method;
+        retval->num_positives = hsp->num_positives;
+
+        /* copy gapped traceback */
+        if (hsp->gap_info) {
+            retval->gap_info = GapEditScriptDup(hsp->gap_info);
+            if (!retval->gap_info) {
+                Blast_HSPFree(retval);
+                return NULL;
+            }
+        }
+
+        /* copy short read mapping data */
+        if (hsp->map_info) {
+            retval->map_info = BlastHSPMappingInfoNew();
+            if (!retval->map_info) {
+                Blast_HSPFree(retval);
+                return NULL;
+            }
+            retval->map_info->edits =
+                JumperEditsBlockDup(hsp->map_info->edits);
+            if (!retval->map_info->edits) {
+                Blast_HSPFree(retval);
+                return NULL;
+            }
+            retval->map_info->left_edge = hsp->map_info->left_edge;
+            retval->map_info->right_edge = hsp->map_info->right_edge;
+
+            if (hsp->map_info->subject_overhangs) {
+                SequenceOverhangs* old = hsp->map_info->subject_overhangs;
+                SequenceOverhangs* copy = calloc(1, sizeof(SequenceOverhangs));
+                if (!copy) {
+                    Blast_HSPFree(retval);
+                    return NULL;
+                }
+
+                if (old->left && old->left_len > 0) {
+                    copy->left_len = old->left_len;
+                    copy->left = malloc(copy->left_len * sizeof(Uint1));
+                    if (!copy->left) {
+                        SequenceOverhangsFree(copy);
+                        Blast_HSPFree(retval);
+                        return NULL;
+                    }
+                    memcpy(copy->left, old->left,
+                           copy->left_len * sizeof(Uint1));
+                }
+
+                if (old->right && old->right_len > 0) {
+                    copy->right_len = old->right_len;
+                    copy->right = malloc(copy->right_len * sizeof(Uint1));
+                    if (!copy->right) {
+                        SequenceOverhangsFree(copy);
+                        Blast_HSPFree(retval);
+                    }
+                    memcpy(copy->right, old->right,
+                           copy->right_len * sizeof(Uint1));
+                }
+
+                retval->map_info->subject_overhangs = copy;
+            }
+        }
+
+        /* copy phi-blast pattern data */
+        if (hsp->pat_info) {
+            retval->pat_info =
+                (SPHIHspInfo*) BlastMemDup(hsp->pat_info, sizeof(SPHIHspInfo));
+        }
+    }
+
+    return retval;
+}
+
 /** Count the number of occurrences of pattern in sequence, which
  * do not overlap by more than half the pattern match length.
  * @param query_info Query information structure, containing pattern info. [in]
@@ -559,7 +670,6 @@ Blast_HSPReevaluateWithAmbiguitiesUngapped(BlastHSP* hsp, const Uint1* query_sta
    sum = 0;
    best_q_start = best_q_end = current_q_start = query;
    best_s_start = best_s_end = current_s_start = subject;
-   index = 0;
 
    for (index = 0; index < hsp_length; ++index) {
       sum += matrix[*query & kResidueMask][*subject];
@@ -1028,7 +1138,7 @@ Blast_HSPGetTargetTranslation(SBlastTargetTranslation* target_t,
     if (target_t->partial && (start ||
         (stop < target_t->subject_blk->length / CODON_LENGTH -3)))
     {
-    	 const int kMaxTranslation = 2100; /* Needs to be divisible by three (?) */
+    	 const int kMaxTranslation = 99; /* Needs to be divisible by three (?) */
          Int4 nucl_length = 0;
          Int4 translation_length = 0;
          Int4 nucl_start = 0;
@@ -2035,7 +2145,7 @@ Int2 Blast_HitListMerge(BlastHitList** old_hit_list_ptr,
                                     hsplist2->hsp_max, split_offsets,
                                     contexts_per_query,
                                     chunk_overlap_size,
-                                    allow_gap);
+                                    allow_gap, FALSE);
             }
             else {
                 Blast_HSPListAppend(hitlist1->hsplist_array + i,
@@ -2632,7 +2742,7 @@ Int2 Blast_HSPListsMerge(BlastHSPList** hsp_list_ptr,
                    BlastHSPList** combined_hsp_list_ptr,
                    Int4 hsp_num_max, Int4 *split_offsets,
                    Int4 contexts_per_query, Int4 chunk_overlap_size,
-                   Boolean allow_gap)
+                   Boolean allow_gap, Boolean short_reads)
 {
    BlastHSPList* combined_hsp_list = *combined_hsp_list_ptr;
    BlastHSPList* hsp_list = *hsp_list_ptr;
@@ -2743,6 +2853,13 @@ Int2 Blast_HSPListsMerge(BlastHSPList** hsp_list_ptr,
             if (!hsp2 || hsp1->context != hsp2->context)
                continue;
 
+            /* Short read qureies are shorter than the overlap region and may
+               already have a traceback */
+            if (short_reads) {
+                hspp2[index2] = Blast_HSPFree(hsp2);
+                continue;
+            }
+
             /* we have to determine the starting diagonal of one HSP
                and the ending diagonal of the other */
 
@@ -3138,9 +3255,12 @@ BlastHSPResults* Blast_HSPResultsFree(BlastHSPResults* results)
    if (!results)
        return NULL;
 
-   for (index = 0; index < results->num_queries; ++index)
-      Blast_HitListFree(results->hitlist_array[index]);
-   sfree(results->hitlist_array);
+   if (results->hitlist_array)
+   {
+   	for (index = 0; index < results->num_queries; ++index)
+      		Blast_HitListFree(results->hitlist_array[index]);
+   	sfree(results->hitlist_array);
+   }
    sfree(results);
    return NULL;
 }
@@ -3589,7 +3709,6 @@ s_TrimResultsByTotalHSPLimitEx(BlastHSPResults* results,
         	 }
 
         	 qsort((void*)everything_list, total_hsp_limit, sizeof(BlastHSPwOid), s_CompareOidHSPwOid);
-        	 subj_index = 0;
        		 subj_list = NULL;
         	 for(hsp_counter = 0; hsp_counter < total_hsp_limit; ++ hsp_counter)
         	 {
@@ -3655,3 +3774,51 @@ Blast_HSPResultsFromHSPStreamWithLimitEx(BlastHSPStream* hsp_stream,
     }
     return retval;
 }
+
+
+BlastHSPChain* Blast_HSPChainNew(void)
+{
+    BlastHSPChain* chain = calloc(1, sizeof(BlastHSPChain));
+    return chain;
+}
+
+BlastHSPChain* Blast_HSPChainFree(BlastHSPChain* ch)
+{
+    Int4 i;
+
+    if (!ch) {
+        return NULL;
+    }
+
+    for (i = 0;i < ch->num_hsps;i++) {
+        Blast_HSPFree(ch->hsp_array[i]);
+    }
+    sfree(ch->hsp_array);
+    sfree(ch);
+
+    return NULL;
+}
+
+BlastMappingResults* Blast_MappingResultsNew(void)
+{
+    BlastMappingResults* retval = calloc(1, sizeof(BlastMappingResults));
+    return retval;
+}
+
+BlastMappingResults* Blast_MappingResultsFree(BlastMappingResults* results)
+{
+    if (!results) {
+        return NULL;
+    }
+
+    if (results->chain_array) {
+        Int4 i;
+        for (i = 0;i < results->num_results;i++) {
+            Blast_HSPChainFree(results->chain_array[i]);
+        }
+        sfree(results->chain_array);
+    }
+    sfree(results);
+
+    return NULL;
+}
diff --git a/c++/src/algo/blast/core/blast_hspstream.c b/c++/src/algo/blast/core/blast_hspstream.c
index 897519b..018f78c 100644
--- a/c++/src/algo/blast/core/blast_hspstream.c
+++ b/c++/src/algo/blast/core/blast_hspstream.c
@@ -1,4 +1,4 @@
-/*  $Id: blast_hspstream.c 419225 2013-11-22 17:08:29Z camacho $
+/*  $Id: blast_hspstream.c 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  * pass on to the traceback stage.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_hspstream.c 419225 2013-11-22 17:08:29Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 
 #include <algo/blast/core/blast_hspstream.h>
 #include <algo/blast/core/blast_util.h>
@@ -211,6 +206,29 @@ void BlastHSPStreamClose(BlastHSPStream* hsp_stream)
    hsp_stream->x_lock = MT_LOCK_Delete(hsp_stream->x_lock);
 }
 
+void BlastHSPStreamMappingClose(BlastHSPStream* hsp_stream,
+                                BlastMappingResults* results)
+{
+   if (!hsp_stream || !hsp_stream->writer)
+      return;
+
+   (hsp_stream->writer->FinalFnPtr)
+       (hsp_stream->writer->data, results);
+
+   hsp_stream->writer_finalized = TRUE;
+   hsp_stream->x_lock = MT_LOCK_Delete(hsp_stream->x_lock);
+}
+
+void BlastHSPStreamSimpleClose(BlastHSPStream* hsp_stream)
+{
+   if (!hsp_stream)
+      return;
+
+   s_FinalizeWriter(hsp_stream);
+
+   hsp_stream->x_lock = MT_LOCK_Delete(hsp_stream->x_lock);
+}
+
 /** Closing the HSP after traceback is done.
  * This is mainly to provide a chance to apply post-traceback pipes.
  * @param hsp_stream The HSP stream to close [in] [out]
@@ -644,6 +662,9 @@ BlastHSPStreamNew(EBlastProgramType program,
     hsp_stream->sorted_hsplists = (BlastHSPList **)malloc(
                                            hsp_stream->num_hsplists_alloc *
                                            sizeof(BlastHSPList *));
+
+    /* FIXME: This will not be needed for mapper when the new mapping
+       results structure is implemented */
     hsp_stream->results = Blast_HSPResultsNew(num_queries);
 
     hsp_stream->results_sorted = FALSE;
@@ -721,11 +742,13 @@ int BlastHSPStreamRegisterPipe(BlastHSPStream* hsp_stream,
 
 BlastHSPWriter*
 BlastHSPWriterNew (BlastHSPWriterInfo** writer_info,
-                   BlastQueryInfo* query_info)
+                   BlastQueryInfo* query_info,
+                   BLAST_SequenceBlk* query)
 {
     BlastHSPWriter * writer = NULL;
     if(writer_info && *writer_info) {
-        writer = ((*writer_info)->NewFnPtr) ((*writer_info)->params, query_info);
+        writer = ((*writer_info)->NewFnPtr) ((*writer_info)->params, query_info,
+                                             query);
         sfree(*writer_info);
     }
     ASSERT(writer_info && *writer_info == NULL);
diff --git a/c++/src/algo/blast/core/blast_hspstream_mt_utils.c b/c++/src/algo/blast/core/blast_hspstream_mt_utils.c
index e46e3e5..b5eb867 100644
--- a/c++/src/algo/blast/core/blast_hspstream_mt_utils.c
+++ b/c++/src/algo/blast/core/blast_hspstream_mt_utils.c
@@ -1,4 +1,4 @@
-/*  $Id: blast_hspstream_mt_utils.c 496008 2016-03-23 11:29:15Z ivanov $
+/*  $Id: blast_hspstream_mt_utils.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  *  with the BlastHSPStream
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_hspstream_mt_utils.c 496008 2016-03-23 11:29:15Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include "blast_hspstream_mt_utils.h"
 
 /** Reset and free the BlastHSPStreamResultBatch structures contained in the
diff --git a/c++/src/algo/blast/core/blast_hspstream_mt_utils.h b/c++/src/algo/blast/core/blast_hspstream_mt_utils.h
index cc752e4..13e5474 100644
--- a/c++/src/algo/blast/core/blast_hspstream_mt_utils.h
+++ b/c++/src/algo/blast/core/blast_hspstream_mt_utils.h
@@ -1,4 +1,4 @@
-/*  $Id: blast_hspstream_mt_utils.h 496008 2016-03-23 11:29:15Z ivanov $
+/*  $Id: blast_hspstream_mt_utils.h 495576 2016-03-18 14:26:46Z rackerst $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/core/blast_itree.c b/c++/src/algo/blast/core/blast_itree.c
index f0c5a32..b268196 100644
--- a/c++/src/algo/blast/core/blast_itree.c
+++ b/c++/src/algo/blast/core/blast_itree.c
@@ -1,4 +1,4 @@
-/* $Id: blast_itree.c 358499 2012-04-03 14:48:04Z coulouri $
+/* $Id: blast_itree.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Functions that implement an interval tree for fast HSP containment tests
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_itree.c 358499 2012-04-03 14:48:04Z coulouri $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include "blast_itree.h"
 #include "blast_gapalign_priv.h"
 #include "blast_hits_priv.h"
diff --git a/c++/src/algo/blast/core/blast_kappa.c b/c++/src/algo/blast/core/blast_kappa.c
index 8a37d1a..0368bf3 100644
--- a/c++/src/algo/blast/core/blast_kappa.c
+++ b/c++/src/algo/blast/core/blast_kappa.c
@@ -1,4 +1,4 @@
-/* $Id: blast_kappa.c 500367 2016-05-04 12:06:01Z ivanov $
+/* $Id: blast_kappa.c 516336 2016-10-12 17:31:41Z ivanov $
  * ==========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  * system for each match in blastpgp
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-"$Id: blast_kappa.c 500367 2016-05-04 12:06:01Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <float.h>
 #include <algo/blast/core/ncbi_math.h>
 #include <algo/blast/core/blast_hits.h>
@@ -358,6 +353,12 @@ s_HSPListFromDistinctAlignments(BlastHSPList *hsp_list,
     return 0;
 }
 
+Int4 s_GetSubjectLength(Int4 total_subj_length, EBlastProgramType program_number)
+{
+	return ((program_number == eBlastTypeRpsTblastn) ?
+				(GET_NUCL_LENGTH(total_subj_length) - 1 ) /3 : total_subj_length);
+}
+
 
 /**
  * Adding evalues to a list of HSPs and remove those that do not have
@@ -404,8 +405,11 @@ s_HitlistEvaluateAndPurge(int * pbestScore, double *pbestEvalue,
                                 subject_length, sbp,
                                 hitParams->link_hsp_params, TRUE);
     } else {
+
+
         status =
-            Blast_HSPListGetEvalues(program_number, queryInfo, subject_length,
+            Blast_HSPListGetEvalues(program_number, queryInfo,
+            		                s_GetSubjectLength(subject_length, program_number),
                                     hsp_list, TRUE, FALSE, sbp,
                                     0.0, /* use a non-zero gap decay
                                             only when linking HSPs */
@@ -478,10 +482,14 @@ s_ComputeNumIdentities(const BLAST_SequenceBlk* query_blk,
 
         if (program_number == eBlastTypeTblastn) {
             subject_blk = seq_arg.seq;
-    	BlastTargetTranslationNew(subject_blk, gen_code_string, eBlastTypeTblastn,
-                kIsOutOfFrame, &target_t);
-        }
-        else {
+            BlastTargetTranslationNew(
+                    subject_blk,
+                    gen_code_string,
+                    eBlastTypeTblastn,
+                    kIsOutOfFrame,
+                    &target_t
+            );
+        } else {
             subject = seq_arg.seq->sequence;
         }
     } else {
@@ -1568,6 +1576,9 @@ s_SequenceGetProteinRange(const BlastCompo_MatchingSequence * self,
     BlastKappa_SequenceInfo * local_data = self->local_data;
     BLAST_SequenceBlk * seq = self->local_data;
 
+    if (self->local_data == NULL)
+	return -1;
+
     seqData->data = NULL;
     seqData->length = 0;
     /* Copy the entire sequence (necessary for SEG filtering.) */
@@ -1582,14 +1593,19 @@ s_SequenceGetProteinRange(const BlastCompo_MatchingSequence * self,
 
     origData = (self->index >= 0) ? local_data->seq_arg.seq->sequence
                             : seq->sequence;
+    if((self->index < 0) && (align->frame != 0)) {
+    	int i=0, offsets =0;
+    	int f = GET_SEQ_FRAME(align->frame);
+    	int nucl_length = GET_NUCL_LENGTH(self->length);
+    	seqData->length = GET_TRANSLATED_LENGTH(nucl_length, f);
+    	for(; i < f; i++) {
+    		offsets = GET_TRANSLATED_LENGTH(nucl_length, i) +1;
+    		origData += offsets;
+    	}
+    }
+    /* Copy the sequence data */
     for (idx = 0;  idx < seqData->length;  idx++) {
-        /* Copy the sequence data, replacing occurrences of amino acid
-         * number 24 (Selenocysteine) with number 3 (Cysteine). */
-        if (origData[idx] != 24) {
-            seqData->data[idx] = origData[idx];
-        } else {
-            seqData->data[idx] = 3;
-        }
+        seqData->data[idx] = origData[idx];
     }
 
     if ( !(KAPPA_BLASTP_NO_SEG_SEQUENCE) ) {
@@ -1884,6 +1900,7 @@ s_RedoOneAlignment(BlastCompo_Alignment * in_align,
     BlastGapAlignStruct* gapAlign = context->gap_align;
     /* The preliminary gapped HSP that were are recomputing */
     BlastHSP * hsp = in_align->context;
+    Boolean fence_hit = FALSE;
 
     /* suppress unused parameter warnings; this is a callback
        function, so these parameter cannot be deleted */
@@ -1896,6 +1913,10 @@ s_RedoOneAlignment(BlastCompo_Alignment * in_align,
 
     gapAlign->gap_x_dropoff = gapping_params->x_dropoff;
 
+    /*
+     * Previously, last argument was NULL which could cause problems for
+     * tblastn.
+     */
     status =
         BLAST_GappedAlignmentWithTraceback(context->prog_number,
                                            query_data->data,
@@ -1904,7 +1925,7 @@ s_RedoOneAlignment(BlastCompo_Alignment * in_align,
                                            q_start, s_start,
                                            query_data->length,
                                            subject_data->length,
-                                           NULL);
+                                           &fence_hit);
     if (status == 0) {
         return s_NewAlignmentFromGapAlign(gapAlign, &gapAlign->edit_script,
                                           query_range, subject_range,
@@ -2329,11 +2350,12 @@ s_GappingParamsNew(BlastKappa_GappingParamsContext * context,
     BlastCompo_GappingParams * gapping_params = NULL;
 
     gapping_params = malloc(sizeof(BlastCompo_GappingParams));
-    if (gapping_params != NULL) {
-        gapping_params->gap_open = scoring->gap_open;
-        gapping_params->gap_extend = scoring->gap_extend;
-        gapping_params->context = context;
-    }
+    if (gapping_params == NULL)
+	return NULL;
+
+    gapping_params->gap_open = scoring->gap_open;
+    gapping_params->gap_extend = scoring->gap_extend;
+    gapping_params->context = context;
 
     for (i = 0;  i < num_queries;  i++) {
         if (context->sbp->kbp_gap[i] != NULL &&
@@ -2360,7 +2382,7 @@ redo_align_callbacks = {
 
 /* Bit score per alignment position threshold for preliminaru near identical
    test */
-#define NEAR_IDENTICAL_BITS_PER_POSITION (1.75)
+#define NEAR_IDENTICAL_BITS_PER_POSITION (1.74)
 
 /**
  * Read the parameters required for the Blast_RedoOneMatch* functions from
@@ -2384,7 +2406,7 @@ s_GetAlignParams(BlastKappa_GappingParamsContext * context,
     Blast_MatrixInfo *
         scaledMatrixInfo;         /* information about the scoring matrix */
     /* does this kind of search translate the database sequence */
-    int subject_is_translated = context->prog_number == eBlastTypeTblastn;
+    int subject_is_translated = (context->prog_number == eBlastTypeTblastn) || (context->prog_number == eBlastTypeRpsTblastn);
     int query_is_translated   = context->prog_number == eBlastTypeBlastx;
     /* is this a positiion-based search */
     Boolean positionBased = (Boolean) (context->sbp->psi_matrix != NULL);
@@ -2997,7 +3019,10 @@ Blast_RedoAlignmentCore_MT(EBlastProgramType program_number,
     BlastHSPResults* local_results = NULL;
 
     BlastCompo_QueryInfo** query_info_tld = NULL;
+    int* numContexts_tld = NULL;
+    int* compositionTestIndex_tld = NULL;
     Blast_RedoAlignParams** redo_align_params_tld = NULL;
+    BLAST_SequenceBlk** subjectBlk_tld = NULL;
     Boolean positionBased = (Boolean) (sbp->psi_matrix != NULL);
     ECompoAdjustModes compo_adjust_mode =
         (ECompoAdjustModes) extendParams->options->compositionBasedStats;
@@ -3013,7 +3038,8 @@ Blast_RedoAlignmentCore_MT(EBlastProgramType program_number,
            program_number == eBlastTypeTblastn  ||
            program_number == eBlastTypeBlastx   ||
            program_number == eBlastTypePsiBlast ||
-           program_number == eBlastTypeRpsBlast);
+           program_number == eBlastTypeRpsBlast ||
+           program_number == eBlastTypeRpsTblastn);
 
     if (0 == strcmp(scoringParams->options->matrix, "BLOSUM62_20") &&
         compo_adjust_mode == eNoCompositionBasedStats) {
@@ -3145,6 +3171,11 @@ Blast_RedoAlignmentCore_MT(EBlastProgramType program_number,
                     sizeof(Blast_CompositionWorkspace*)
             );
 
+    subjectBlk_tld =
+            (BLAST_SequenceBlk**) calloc(
+                    actual_num_threads,
+                    sizeof(BLAST_SequenceBlk*)
+            );
     redo_align_params_tld =
             (Blast_RedoAlignParams**) calloc(
                     actual_num_threads,
@@ -3185,6 +3216,16 @@ Blast_RedoAlignmentCore_MT(EBlastProgramType program_number,
                     actual_num_threads,
                     sizeof(BlastCompo_QueryInfo*)
             );
+    numContexts_tld =
+            (int*) calloc(
+                    actual_num_threads,
+                    sizeof(int)
+            );
+    compositionTestIndex_tld =
+            (int*) calloc(
+                    actual_num_threads,
+                    sizeof(int)
+            );
 
     int i;
     for (i = 0; i < actual_num_threads; ++i) {
@@ -3205,12 +3246,16 @@ Blast_RedoAlignmentCore_MT(EBlastProgramType program_number,
                 sbp->number_of_contexts
         );
 
-        seqsrc_tld[i]         = (BlastSeqSrc*) seqSrc;
-        gap_align_tld[i]      =
+        numContexts_tld[i]          = numContexts;
+        compositionTestIndex_tld[i] = compositionTestIndex;
+        seqsrc_tld[i]               = BlastSeqSrcCopy(seqSrc);
+        gap_align_tld[i]            =
                 s_BlastGapAlignStruct_Copy(gapAlign, sbp_tld[i]);
-        score_params_tld[i]   = scoringParams;
-        hit_params_tld[i]     = (BlastHitSavingParameters*) hitParams;
-        results_tld[i]        = Blast_HSPResultsNew(queryInfo->num_queries);
+        score_params_tld[i]         = scoringParams;
+        hit_params_tld[i]           = (BlastHitSavingParameters*) hitParams;
+        results_tld[i]              =
+                Blast_HSPResultsNew(queryInfo->num_queries);
+        subjectBlk_tld[i]           = subjectBlk;
 
         redoneMatches_tld[i] =
                 (BlastCompo_Heap*) calloc(numQueries, sizeof(BlastCompo_Heap));
@@ -3359,323 +3404,335 @@ Blast_RedoAlignmentCore_MT(EBlastProgramType program_number,
     }
 
     Boolean interrupt = FALSE;
-    int b;
-#pragma omp parallel for default(none) num_threads(actual_num_threads) \
-        schedule(static) \
-        if(actual_num_threads>1) \
-        shared(interrupt, seqsrc_tld, score_params_tld, hit_params_tld, \
-        gap_align_tld, results_tld, \
-        redoneMatches_tld, \
-        numQueries, numMatches, theseMatches, \
-        numFrames, program_number, subjectBlk, positionBased, \
-        default_db_genetic_code, localScalingFactor, queryInfo, \
-        sbp, smithWaterman, compositionTestIndex, forbidden, \
-        NRrecord_tld, actual_num_threads, sbp_tld, \
-        matrix_tld, query_info_tld, numContexts, \
-        genetic_code_string, queryBlk, compo_adjust_mode, \
-        alignments_tld, incoming_align_set_tld, savedParams_tld, \
-        scoringParams, redo_align_params_tld, \
-        status_code_tld)
-    for (b = 0; b < numMatches; ++b) {
+#pragma omp parallel \
+    default(none) num_threads(actual_num_threads) \
+    if(actual_num_threads>1) \
+    shared(interrupt, seqsrc_tld, score_params_tld, hit_params_tld, \
+    gap_align_tld, results_tld, \
+    redoneMatches_tld, \
+    stderr, \
+    numQueries, numMatches, theseMatches, \
+    numFrames, program_number, subjectBlk_tld, positionBased, \
+    default_db_genetic_code, localScalingFactor, queryInfo, \
+    sbp, smithWaterman, compositionTestIndex_tld, forbidden, \
+    NRrecord_tld, actual_num_threads, sbp_tld, \
+    matrix_tld, query_info_tld, numContexts_tld, \
+    genetic_code_string, queryBlk, compo_adjust_mode, \
+    alignments_tld, incoming_align_set_tld, savedParams_tld, \
+    scoringParams, redo_align_params_tld, \
+    status_code_tld)
+    {
+        int b;
+#pragma omp for schedule(static)
+        for (b = 0; b < numMatches; ++b) {
 #pragma omp flush(interrupt)
-        if (!interrupt) {
-            BlastCompo_Alignment** alignments = NULL;
-            BlastCompo_Alignment** incoming_align_set = NULL;
-            Blast_CompositionWorkspace* NRrecord = NULL;
-            BlastCompo_QueryInfo* query_info = NULL;
-
-            int numAligns[6];
-            Blast_KarlinBlk* kbp = NULL;
-            BlastCompo_MatchingSequence matchingSeq = {0,};
-            BlastHSPList* hsp_list = NULL;
-            BlastCompo_Alignment* incoming_aligns = NULL;
-            Blast_RedoAlignParams* redo_align_params;
-            double best_evalue;
-            Int4 best_score;
-            int query_index;
-            int context_index;
-            int frame_index;
-            void* discarded_aligns = NULL;
-            int tid = 0;
-            BlastSeqSrc* seqSrc;
-            BlastScoringParameters* scoringParams;
-            BlastHitSavingParameters* hitParams;
-            BlastCompo_Heap* redoneMatches;
-            BlastScoreBlk* sbp;
-            /* existing alignments for a match */
-            Int4** matrix;                   /* score matrix */
-            int* pStatusCode;
-
-            double pvalueForThisPair = (-1); /* p-value for this match
-                                                for composition; -1 == no adjustment*/
-            double LambdaRatio; /*lambda ratio*/
-
+            if (!interrupt) {
+                BlastCompo_Alignment** alignments = NULL;
+                BlastCompo_Alignment** incoming_align_set = NULL;
+                Blast_CompositionWorkspace* NRrecord = NULL;
+                BlastCompo_QueryInfo* query_info = NULL;
+
+                int numAligns[6];
+                Blast_KarlinBlk* kbp = NULL;
+                BlastCompo_MatchingSequence matchingSeq = {0,};
+                BlastHSPList* hsp_list = NULL;
+                BlastCompo_Alignment* incoming_aligns = NULL;
+                Blast_RedoAlignParams* redo_align_params;
+                double best_evalue;
+                Int4 best_score;
+                int query_index;
+                int context_index;
+                int frame_index;
+                void* discarded_aligns = NULL;
+                BlastSeqSrc* seqSrc;
+                BlastScoringParameters* scoringParams;
+                BlastHitSavingParameters* hitParams;
+                BlastCompo_Heap* redoneMatches;
+                BlastScoreBlk* sbp;
+                BLAST_SequenceBlk* subjectBlk;
+                int numContexts;
+                int compositionTestIndex;
+                /* existing alignments for a match */
+                Int4** matrix;                   /* score matrix */
+                int* pStatusCode;
+
+                double pvalueForThisPair = (-1); /* p-value for this match
+                                                    for composition; -1 == no adjustment*/
+                double LambdaRatio; /*lambda ratio*/
+
+                int tid = 0;
 #ifdef _OPENMP
-            tid = omp_get_thread_num();
+                tid = omp_get_thread_num();
 #endif
-            seqSrc             = seqsrc_tld[tid];
-            scoringParams      = score_params_tld[tid];
-            hitParams          = hit_params_tld[tid];
-            redoneMatches      = redoneMatches_tld[tid];
-            alignments         = alignments_tld[tid];
-            incoming_align_set = incoming_align_set_tld[tid];
-            NRrecord           = NRrecord_tld[tid];
-            sbp                = sbp_tld[tid];
-            redo_align_params  = redo_align_params_tld[tid];
-            matrix             = matrix_tld[tid];
-            pStatusCode        = &status_code_tld[tid];
-            query_info         = query_info_tld[tid];
-
-            BlastHSPList* localMatch = theseMatches[b];
-
-            if (localMatch->hsp_array == NULL) {
-                if (seqSrc) {
-                    continue;
-                }
+                seqSrc               = seqsrc_tld[tid];
+                scoringParams        = score_params_tld[tid];
+                hitParams            = hit_params_tld[tid];
+                redoneMatches        = redoneMatches_tld[tid];
+                alignments           = alignments_tld[tid];
+                incoming_align_set   = incoming_align_set_tld[tid];
+                NRrecord             = NRrecord_tld[tid];
+                sbp                  = sbp_tld[tid];
+                redo_align_params    = redo_align_params_tld[tid];
+                matrix               = matrix_tld[tid];
+                pStatusCode          = &status_code_tld[tid];
+                query_info           = query_info_tld[tid];
+                numContexts          = numContexts_tld[tid];
+                compositionTestIndex = compositionTestIndex_tld[tid];
+                subjectBlk           = subjectBlk_tld[tid];
+
+                BlastHSPList* localMatch = theseMatches[b];
+
+                if (localMatch->hsp_array == NULL) {
+                    if (seqSrc) {
+                        continue;
+                    }
 #pragma omp critical(intrpt)
-                interrupt = TRUE;
+                    interrupt = TRUE;
 #pragma omp flush(interrupt)
-                continue;
-            }
-
-            if (BlastCompo_EarlyTermination(
-                    localMatch->best_evalue,
-                    redoneMatches,
-                    numQueries
-            )) {
-                Blast_HSPListFree(localMatch);
-                if (seqSrc) {
                     continue;
                 }
+
+                if (BlastCompo_EarlyTermination(
+                        localMatch->best_evalue,
+                        redoneMatches,
+                        numQueries
+                )) {
+                    Blast_HSPListFree(localMatch);
+                    if (seqSrc) {
+                        continue;
+                    }
 #pragma omp critical(intrpt)
-                interrupt = TRUE;
+                    interrupt = TRUE;
 #pragma omp flush(interrupt)
-                continue;
-            }
-
-            query_index = localMatch->query_index;
-            context_index = query_index * numFrames;
-            /* Get the sequence for this match */
-            if (seqSrc && BlastSeqSrcGetSupportsPartialFetching(seqSrc)) {
-                BLAST_SetupPartialFetching(
-                        program_number,
-                        (BlastSeqSrc*) seqSrc,
-                        (const BlastHSPList**)&localMatch,
-                        1
-                );
-            }
-
-            if (subjectBlk) {
-                matchingSeq.length = subjectBlk->length;
-                matchingSeq.index = -1;
-                matchingSeq.local_data = subjectBlk;
-            } else {
-                *pStatusCode = s_MatchingSequenceInitialize(
-                        &matchingSeq,
-                        program_number,
-                        seqSrc,
-                        default_db_genetic_code,
-                        localMatch->oid
-                );
-                if (*pStatusCode != 0) {
-                    /*
-                     * some sequences may have been excluded by membit filtering
-                     * so this is not really an exception
-                     */
-                    *pStatusCode = 0;
-                    goto match_loop_cleanup;
+                    continue;
                 }
-            }
-            *pStatusCode = s_ResultHspToDistinctAlign(
-                    incoming_align_set,     /* o */
-                    numAligns,              /* o */
-                    localMatch->hsp_array,  /* i */
-                    localMatch->hspcnt,     /* i */
-                    context_index,          /* i */
-                    queryInfo,              /* i */
-                    localScalingFactor      /* i */
-            );
-            if (*pStatusCode != 0) {
-                goto match_loop_cleanup;
-            }
 
-            hsp_list = Blast_HSPListNew(0);
-            for (frame_index = 0;
-                    frame_index < numFrames;
-                    frame_index++, context_index++) {
-                incoming_aligns = incoming_align_set[frame_index];
-                if (!incoming_aligns) {
-                    continue;
+                query_index = localMatch->query_index;
+                context_index = query_index * numFrames;
+                /* Get the sequence for this match */
+                if (seqSrc && BlastSeqSrcGetSupportsPartialFetching(seqSrc)) {
+                    BLAST_SetupPartialFetching(
+                            program_number,
+                            (BlastSeqSrc*) seqSrc,
+                            (const BlastHSPList**)&localMatch,
+                            1
+                    );
                 }
-                /*
-                 * All alignments in thisMatch should be to the same query
-                 */
-                kbp = sbp->kbp_gap[context_index];
-                if (smithWaterman) {
-                    *pStatusCode =
-                            Blast_RedoOneMatchSmithWaterman(
-                                    alignments,
-                                    redo_align_params,
-                                    incoming_aligns,
-                                    numAligns[frame_index],
-                                    kbp->Lambda,
-                                    kbp->logK,
-                                    &matchingSeq,
-                                    query_info,
-                                    numQueries,
-                                    matrix,
-                                    BLASTAA_SIZE,
-                                    NRrecord,
-                                    &forbidden,
-                                    redoneMatches,
-                                    &pvalueForThisPair,
-                                    compositionTestIndex,
-                                    &LambdaRatio
-                            );
+
+                if (subjectBlk) {
+                    matchingSeq.length = subjectBlk->length;
+                    matchingSeq.index = -1;
+                    matchingSeq.local_data = subjectBlk;
                 } else {
-                    *pStatusCode =
-                            Blast_RedoOneMatch(
-                                    alignments,             // thread-local
-                                    redo_align_params,      // thread-local
-                                    incoming_aligns,        // thread-local
-                                    numAligns[frame_index], // local
-                                    kbp->Lambda,            // thread-local
-                                    &matchingSeq,           // local
-                                    -1,                     // const
-                                    query_info,             // thread-local
-                                    numContexts,            // shared
-                                    matrix,                 // thread-local
-                                    BLASTAA_SIZE,           // const
-                                    NRrecord,               // thread-local
-                                    &pvalueForThisPair,     // local
-                                    compositionTestIndex,   // shared
-                                    &LambdaRatio            // local
-                            );
+                    *pStatusCode = s_MatchingSequenceInitialize(
+                            &matchingSeq,
+                            program_number,
+                            seqSrc,
+                            default_db_genetic_code,
+                            localMatch->oid
+                    );
+                    if (*pStatusCode != 0) {
+                        /*
+                         * some sequences may have been excluded by membit filtering
+                         * so this is not really an exception
+                         */
+                        *pStatusCode = 0;
+                        goto match_loop_cleanup;
+                    }
                 }
-
+                *pStatusCode = s_ResultHspToDistinctAlign(
+                        incoming_align_set,     /* o */
+                        numAligns,              /* o */
+                        localMatch->hsp_array,  /* i */
+                        localMatch->hspcnt,     /* i */
+                        context_index,          /* i */
+                        queryInfo,              /* i */
+                        localScalingFactor      /* i */
+                );
                 if (*pStatusCode != 0) {
                     goto match_loop_cleanup;
                 }
 
-                if (alignments[context_index] != NULL) {
-                    Int2 qframe = frame_index;
-                    if (program_number == eBlastTypeBlastx) {
-                        if (qframe < 3) {
-                            qframe++;
-                        } else {
-                            qframe = 2 - qframe;
-                        }
+                hsp_list = Blast_HSPListNew(0);
+                for (frame_index = 0;
+                        frame_index < numFrames;
+                        frame_index++, context_index++) {
+                    incoming_aligns = incoming_align_set[frame_index];
+                    if (!incoming_aligns) {
+                        continue;
                     }
-                    *pStatusCode =
-                            s_HSPListFromDistinctAlignments(hsp_list,
-                                    &alignments[context_index],
-                                    matchingSeq.index,
-                                    queryInfo, qframe);
-                    if (*pStatusCode) {
+                    /*
+                     * All alignments in thisMatch should be to the same query
+                     */
+                    kbp = sbp->kbp_gap[context_index];
+                    if (smithWaterman) {
+                        *pStatusCode =
+                                Blast_RedoOneMatchSmithWaterman(
+                                        alignments,
+                                        redo_align_params,
+                                        incoming_aligns,
+                                        numAligns[frame_index],
+                                        kbp->Lambda,
+                                        kbp->logK,
+                                        &matchingSeq,
+                                        query_info,
+                                        numQueries,
+                                        matrix,
+                                        BLASTAA_SIZE,
+                                        NRrecord,
+                                        &forbidden,
+                                        redoneMatches,
+                                        &pvalueForThisPair,
+                                        compositionTestIndex,
+                                        &LambdaRatio
+                                );
+                    } else {
+                        *pStatusCode =
+                                Blast_RedoOneMatch(
+                                        alignments,             // thread-local
+                                        redo_align_params,      // thread-local
+                                        incoming_aligns,        // thread-local
+                                        numAligns[frame_index], // local
+                                        kbp->Lambda,            // thread-local
+                                        &matchingSeq,           // thread-local
+                                        -1,                     // const
+                                        query_info,             // thread-local
+                                        numContexts,            // thread-local
+                                        matrix,                 // thread-local
+                                        BLASTAA_SIZE,           // const
+                                        NRrecord,               // thread-local
+                                        &pvalueForThisPair,     // local
+                                        compositionTestIndex,   // thread-local
+                                        &LambdaRatio            // local
+                                );
+                    }
+
+                    if (*pStatusCode != 0) {
                         goto match_loop_cleanup;
                     }
-                }
-                BlastCompo_AlignmentsFree(&incoming_aligns, NULL);
-                incoming_align_set[frame_index] = NULL;
-            }
 
-            if (hsp_list->hspcnt > 1) {
-                s_HitlistReapContained(hsp_list->hsp_array,
-                        &hsp_list->hspcnt);
-            }
-            *pStatusCode =
-                    s_HitlistEvaluateAndPurge(&best_score, &best_evalue,
-                            hsp_list,
-                            seqSrc,
-                            matchingSeq.length,
-                            program_number,
-                            queryInfo, context_index,
-                            sbp, hitParams,
-                            pvalueForThisPair, LambdaRatio,
-                            matchingSeq.index);
-            if (*pStatusCode != 0) {
-                goto query_loop_cleanup;
-            }
-            if (best_evalue <= hitParams->options->expect_value) {
-                /* The best alignment is significant */
-                s_HSPListNormalizeScores(hsp_list, kbp->Lambda, kbp->logK,
-                        localScalingFactor);
-                s_ComputeNumIdentities(
-                        queryBlk,
-                        queryInfo,
-                        subjectBlk,
-                        seqSrc,
-                        hsp_list,
-                        scoringParams->options,
-                        genetic_code_string,
-                        sbp
-                );
-                if (!seqSrc) {
-                    goto query_loop_cleanup;
-                }
-                if (BlastCompo_HeapWouldInsert(
-                        &redoneMatches[query_index],
-                        best_evalue,
-                        best_score,
-                        localMatch->oid
-                )) {
-                    *pStatusCode =
-                            BlastCompo_HeapInsert(
-                                    &redoneMatches[query_index],
-                                    hsp_list,
-                                    best_evalue,
-                                    best_score,
-                                    localMatch->oid,
-                                    &discarded_aligns
-                            );
-                    if (*pStatusCode == 0) {
-                        hsp_list = NULL;
+                    if (alignments[context_index] != NULL) {
+                        Int2 qframe = frame_index;
+                        if (program_number == eBlastTypeBlastx) {
+                            if (qframe < 3) {
+                                qframe++;
+                            } else {
+                                qframe = 2 - qframe;
+                            }
+                        }
+                        *pStatusCode =
+                                s_HSPListFromDistinctAlignments(hsp_list,
+                                        &alignments[context_index],
+                                        matchingSeq.index,
+                                        queryInfo, qframe);
+                        if (*pStatusCode) {
+                            goto match_loop_cleanup;
+                        }
                     }
-                } else {
-                    hsp_list = Blast_HSPListFree(hsp_list);
+                    BlastCompo_AlignmentsFree(&incoming_aligns, NULL);
+                    incoming_align_set[frame_index] = NULL;
                 }
 
-                if (*pStatusCode) {
+                if (hsp_list->hspcnt > 1) {
+                    s_HitlistReapContained(hsp_list->hsp_array,
+                            &hsp_list->hspcnt);
+                }
+                *pStatusCode =
+                        s_HitlistEvaluateAndPurge(&best_score, &best_evalue,
+                                hsp_list,
+                                seqSrc,
+                                matchingSeq.length,
+                                program_number,
+                                queryInfo, context_index,
+                                sbp, hitParams,
+                                pvalueForThisPair, LambdaRatio,
+                                matchingSeq.index);
+                if (*pStatusCode != 0) {
                     goto query_loop_cleanup;
                 }
-                if (discarded_aligns != NULL) {
-                    Blast_HSPListFree(discarded_aligns);
+                if (best_evalue <= hitParams->options->expect_value) {
+                    /* The best alignment is significant */
+                    s_HSPListNormalizeScores(hsp_list, kbp->Lambda, kbp->logK,
+                            localScalingFactor);
+                    s_ComputeNumIdentities(
+                            queryBlk,
+                            queryInfo,
+                            subjectBlk,
+                            seqSrc,
+                            hsp_list,
+                            scoringParams->options,
+                            genetic_code_string,
+                            sbp
+                    );
+                    if (!seqSrc) {
+                        goto query_loop_cleanup;
+                    }
+                    if (BlastCompo_HeapWouldInsert(
+                            &redoneMatches[query_index],
+                            best_evalue,
+                            best_score,
+                            localMatch->oid
+                    )) {
+                        *pStatusCode =
+                                BlastCompo_HeapInsert(
+                                        &redoneMatches[query_index],
+                                        hsp_list,
+                                        best_evalue,
+                                        best_score,
+                                        localMatch->oid,
+                                        &discarded_aligns
+                                );
+                        if (*pStatusCode == 0) {
+                            hsp_list = NULL;
+                        }
+                    } else {
+                        hsp_list = Blast_HSPListFree(hsp_list);
+                    }
+
+                    if (*pStatusCode) {
+                        goto query_loop_cleanup;
+                    }
+                    if (discarded_aligns != NULL) {
+                        Blast_HSPListFree(discarded_aligns);
+                    }
                 }
-            }
 query_loop_cleanup:
 match_loop_cleanup:
-            if (seqSrc) {
-                localMatch = Blast_HSPListFree(localMatch);
-            } else {
-                Blast_HSPListSwap(localMatch, hsp_list);
-                localMatch->oid = hsp_list->oid;
-            }
-            hsp_list = Blast_HSPListFree(hsp_list);
-
-            if (*pStatusCode != 0) {
-                for (context_index = 0;
-                        context_index < numContexts;
-                        context_index++) {
-                    BlastCompo_AlignmentsFree(
-                            &alignments[context_index],
-                            s_FreeEditScript
-                    );
+                if (seqSrc) {
+                    localMatch = Blast_HSPListFree(localMatch);
+                } else {
+                    Blast_HSPListSwap(localMatch, hsp_list);
+                    localMatch->oid = hsp_list->oid;
                 }
-            }
-            s_MatchingSequenceRelease(&matchingSeq);
-            BlastCompo_AlignmentsFree(&incoming_aligns, NULL);
-            if (*pStatusCode != 0 || !seqSrc) {
+                hsp_list = Blast_HSPListFree(hsp_list);
+
+                if (*pStatusCode != 0) {
+                    for (context_index = 0;
+                            context_index < numContexts;
+                            context_index++) {
+                        BlastCompo_AlignmentsFree(
+                                &alignments[context_index],
+                                s_FreeEditScript
+                        );
+                    }
+                }
+                s_MatchingSequenceRelease(&matchingSeq);
+                BlastCompo_AlignmentsFree(&incoming_aligns, NULL);
+                if (*pStatusCode != 0 || !seqSrc) {
 #pragma omp critical(intrpt)
-                interrupt = TRUE;
+                    interrupt = TRUE;
 #pragma omp flush(interrupt)
-                continue;
-            }
+                    continue;
+                }
+
+            } /* end of if(!interrupt) */
+        }
+#pragma omp barrier
 
-        } /* end of if(!interrupt) */
+        /*
+         * end of omp parallel section
+         */
     }
-    /*
-     * end of omp parallel section
-     */
 
 function_cleanup:
 
@@ -3800,24 +3857,31 @@ function_cleanup:
         sfree(incoming_align_set_tld[i]);
         Blast_CompositionWorkspaceFree(&NRrecord_tld[i]);
         s_SavedParametersFree(&savedParams_tld[i]);
+        BlastSeqSrcFree(seqsrc_tld[i]);
     }
-    sfree(theseMatches);
-    sfree(NRrecord_tld);
     sfree(alignments_tld);
-    sfree(incoming_align_set_tld);
-    sfree(savedParams_tld);
-    sfree(sbp_tld);
-    sfree(matrix_tld);
-    sfree(seqsrc_tld);
+    sfree(compositionTestIndex_tld);
     sfree(gap_align_tld);
-    sfree(score_params_tld);
-    sfree(hit_params_tld);
-    sfree(results_tld);
     sfree(gapping_params_context_tld);
+    sfree(hit_params_tld);
+    sfree(incoming_align_set_tld);
+    sfree(matrix_tld);
+    sfree(NRrecord_tld);
+    sfree(numContexts_tld);
+    sfree(query_info_tld);
     sfree(redo_align_params_tld);
     sfree(redoneMatches_tld);
+    sfree(results_tld);
+    sfree(savedParams_tld);
+    sfree(sbp_tld);
+    sfree(score_params_tld);
+    sfree(seqsrc_tld);
     sfree(status_code_tld);
-    sfree(query_info_tld);
+    sfree(subjectBlk_tld);
+    sfree(theseMatches);
 
     return (Int2) status_code;
 }
+
+
+
diff --git a/c++/src/algo/blast/core/blast_lookup.c b/c++/src/algo/blast/core/blast_lookup.c
index fb36d3a..5b7c43e 100644
--- a/c++/src/algo/blast/core/blast_lookup.c
+++ b/c++/src/algo/blast/core/blast_lookup.c
@@ -1,4 +1,4 @@
-/* $Id: blast_lookup.c 94150 2006-11-22 19:39:04Z papadopo $
+/* $Id: blast_lookup.c 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 
 #include <algo/blast/core/blast_lookup.h>
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_lookup.c 94150 2006-11-22 19:39:04Z papadopo $";
-#endif                          /* SKIP_DOXYGEN_PROCESSING */
-
 void BlastLookupAddWordHit(Int4 **backbone, Int4 wordsize,
                            Int4 charsize, Uint1* seq,
                            Int4 query_offset)
@@ -136,3 +131,194 @@ void BlastLookupIndexQueryExactMatches(Int4 **backbone,
     }
 }
 
+
+BackboneCell* BackboneCellFree(BackboneCell* cell)
+{
+    BackboneCell* b = cell;
+    while (b) {
+        BackboneCell* next = b->next;
+        if (b->offsets) {
+            free(b->offsets);
+        }
+        sfree(b);
+        b = next;
+    }
+
+    return NULL;
+}
+
+BackboneCell* BackboneCellNew(Uint4 word, Int4 offset, Int4 size)
+{
+    BackboneCell* cell = calloc(1, sizeof(BackboneCell));
+    if (!cell) {
+        BackboneCellFree(cell);
+        return NULL;
+    }
+
+    cell->offsets = malloc(size * sizeof(Int4));
+    if (!cell->offsets) {
+        BackboneCellFree(cell);
+        return NULL;
+    }
+
+    cell->word = word;
+    cell->offsets[0] = offset;
+    cell->num_offsets = 1;
+    cell->allocated = size;
+
+    return cell;
+}
+
+#define MAX_WORD_COUNT (10)
+
+/* Test whether a word count is at least one and at most MAX_WORD_COUNT.
+   Counts are stored in 4 bits. */
+static Boolean s_TestCounts(Uint4 word, Uint1* counts)
+{
+    if (!(word & 1)) {
+        if ((counts[word / 2] >> 4) == 0 ||
+            (counts[word / 2] >> 4) >= MAX_WORD_COUNT) {
+            return FALSE;
+        }
+    }
+    else {
+        if ((counts[word / 2] & 0xf) == 0 ||
+            (counts[word / 2] & 0xf) >= MAX_WORD_COUNT) {
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+static Int2 s_AddWordHit(BackboneCell** backbone, Int4 wordsize,
+                         Int4 charsize, Uint1* seq, Int4 offset,
+                         TNaLookupHashFunction hash_func, Uint4 mask,
+                         Uint1* counts)
+{
+    Uint4 large_index;
+    Int8 index;
+    Int4 i;
+    Int4 num_collisions = 0;
+
+    /* convert a sequence from 4NA to 2NA */
+    large_index = 0;
+    for (i = 0;i < wordsize;i++) {
+        large_index = (large_index << charsize) | seq[i];
+    }
+
+    /* if filtering by database word count, then do not add words
+       that do not appear in the database or appear to many times */
+    if (counts && !s_TestCounts(large_index, counts)) {
+        return 0;
+    }
+
+    index = (Int8)hash_func((Uint1*)&large_index, mask);
+
+    /* if the hash table entry is emtpy, create a new cell */
+    if (!backbone[index]) {
+        Int4 size = 8;
+        backbone[index] = BackboneCellNew(large_index, offset, size);
+        if (!backbone[index]) {
+            return -1;
+        }
+    }
+    else {
+        /* otherwiose check if the word was already added */
+
+        BackboneCell* b = backbone[index];
+        while (b->next && b->word != large_index) {
+            b = b->next;
+        }
+
+        /* if word was already added, add the new offset to an existing cell */
+        if (b->word == large_index) {
+            if (b->num_offsets >= b->allocated) {
+                Int4 new_size = b->allocated * 2;
+                b->offsets = realloc(b->offsets, new_size * sizeof(Int4));
+                if (!b->offsets) {
+                    return -1;
+                }
+                b->allocated = new_size;
+            }
+            b->offsets[b->num_offsets++] = offset;
+        }
+        else {
+            /* otherwise creare a new cell */
+
+            Int4 size = 8;
+            ASSERT(!b->next);
+            b->next = BackboneCellNew(large_index, offset, size);
+            if (!b->next) {
+                return -1;
+            }
+
+            num_collisions++;
+        }
+    }
+
+    return 0;
+}
+
+void BlastHashLookupIndexQueryExactMatches(BackboneCell **backbone,
+                                           Int4 word_length,
+                                           Int4 charsize,
+                                           Int4 lut_word_length,
+                                           BLAST_SequenceBlk* query,
+                                           BlastSeqLoc* locations,
+                                           TNaLookupHashFunction hash_func,
+                                           Uint4 mask,
+                                           Uint1* counts)
+{
+    BlastSeqLoc *loc;
+    Int4 offset;
+    Uint1 *seq;
+    Uint1 *word_target;
+    Uint1 invalid_mask = 0xff << charsize;
+
+    for (loc = locations; loc; loc = loc->next) {
+        Int4 from = loc->ssr->left;
+        Int4 to = loc->ssr->right;
+
+        /* if this location is too small to fit a complete word, skip the
+           location */
+
+        if (word_length > to - from + 1)
+            continue;
+
+        /* Indexing proceeds from the start point to the last offset
+           such that a full lookup table word can be created. word_target
+           points to the letter beyond which indexing is allowed */
+        seq = query->sequence + from;
+        word_target = seq + lut_word_length;
+
+        for (offset = from; offset <= to; offset++, seq++) {
+
+            if (seq >= word_target) {
+                s_AddWordHit(backbone,
+                             lut_word_length, charsize,
+                             seq - lut_word_length,
+                             offset - lut_word_length,
+                             hash_func, mask,
+                             counts);
+            }
+
+            /* if the current word contains an ambiguity, skip all the
+               words that would contain that ambiguity */
+            if (*seq & invalid_mask)
+                word_target = seq + lut_word_length + 1;
+        }
+
+        /* handle the last word, without loading *seq */
+        if (seq >= word_target) {
+            s_AddWordHit(backbone, 
+                         lut_word_length, charsize,
+                         seq - lut_word_length, 
+                         offset - lut_word_length,
+                         hash_func, mask,
+                         counts);
+        }
+        
+    }
+}
+
diff --git a/c++/src/algo/blast/core/blast_message.c b/c++/src/algo/blast/core/blast_message.c
index e0d4b18..6271a29 100644
--- a/c++/src/algo/blast/core/blast_message.c
+++ b/c++/src/algo/blast/core/blast_message.c
@@ -1,4 +1,4 @@
-/* $Id: blast_message.c 442874 2014-08-07 19:26:31Z camacho $
+/* $Id: blast_message.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  * the BLAST code as a wrapper for error and warning messages.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_message.c 442874 2014-08-07 19:26:31Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_def.h>
 #include <algo/blast/core/blast_message.h>
 
diff --git a/c++/src/algo/blast/core/blast_nalookup.c b/c++/src/algo/blast/core/blast_nalookup.c
index e81c82b..2e19c29 100644
--- a/c++/src/algo/blast/core/blast_nalookup.c
+++ b/c++/src/algo/blast/core/blast_nalookup.c
@@ -1,4 +1,4 @@
-/* $Id: blast_nalookup.c 435845 2014-05-21 14:12:49Z fongah2 $
+/* $Id: blast_nalookup.c 506275 2016-07-06 14:42:04Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -34,11 +34,6 @@
 #include <algo/blast/core/blast_util.h>
 #include <algo/blast/core/blast_filter.h>
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_nalookup.c 435845 2014-05-21 14:12:49Z fongah2 $";
-#endif                          /* SKIP_DOXYGEN_PROCESSING */
-
 /** bitfield used to detect ambiguities in uncompressed
  *  nucleotide letters
  */
@@ -71,6 +66,14 @@ BlastChooseNaLookupTable(const LookupTableOptions* lookup_options,
       return eMBLookupTable;
    }
 
+   /* always use megablast lookup table and word size 16 for mapping */
+   if (Blast_ProgramIsMapping(lookup_options->program_number) &&
+       lookup_options->word_size >= 16) {
+
+       *lut_width = 16;
+       return eMBLookupTable;
+   }
+
    switch(lookup_options->word_size) {
    case 4:
    case 5:
@@ -810,6 +813,115 @@ s_FillDiscMBTable(BLAST_SequenceBlk* query, BlastSeqLoc* location,
    return 0;
 }
 
+static Int2 
+s_FillPV(BLAST_SequenceBlk* query, 
+        BlastSeqLoc* location,
+        BlastMBLookupTable* mb_lt,
+        const LookupTableOptions* lookup_options) 
+
+{
+   BlastSeqLoc* loc;
+   /* 12-mers (or perhaps 8-mers) are used to build the lookup table 
+      and this is what kLutWordLength specifies. */
+   const Int4 kLutWordLength = mb_lt->lut_word_length;
+   const Int8 kLutMask = mb_lt->hashsize - 1;
+   /* The user probably specified a much larger word size (like 28) 
+      and this is what full_word_size is. */
+   Int4 full_word_size = mb_lt->word_length;
+   Int4 index;
+   PV_ARRAY_TYPE *pv_array;
+   Int4 pv_array_bts;
+
+   ASSERT(mb_lt);
+
+   pv_array = mb_lt->pv_array;
+   pv_array_bts = mb_lt->pv_array_bts;
+
+   for (loc = location; loc; loc = loc->next) {
+      /* We want index to be always pointing to the start of the word.
+         Since sequence pointer points to the end of the word, subtract
+         word length from the loop boundaries.  */
+      Int4 from = loc->ssr->left;
+      Int4 to = loc->ssr->right - kLutWordLength;
+      Int8 ecode = 0;
+      Int4 last_offset;
+      Uint1* pos;
+      Uint1* seq;
+      Uint1 val;
+//      int counter = 1; /* collect this many adjacent words */
+
+     /* case of unmasked region >=  kLutWordLength but < full_word_size,
+        so no hits should be generated. */
+      if (full_word_size > (loc->ssr->right - loc->ssr->left + 1))
+         continue; 
+
+      seq = query->sequence_start + from;
+      pos = seq + kLutWordLength;
+      
+      /* Also add 1 to all indices, because lookup table indices count 
+         from 1. */
+      from -= kLutWordLength - 2;
+      last_offset = to + 2;
+
+      for (index = from; index <= last_offset; index++) {
+         val = *++seq;
+         /* if an ambiguity is encountered, do not add
+            any words that would contain it */
+         if ((val & BLAST2NA_MASK) != 0) {
+            ecode = 0;
+            pos = seq + kLutWordLength;
+            continue;
+         }
+
+         /* get next base */
+         ecode = ((ecode << BITS_PER_NUC) & kLutMask) + val;
+         if (seq < pos) 
+            continue;
+
+         PV_SET(pv_array, ecode, pv_array_bts);
+      }
+   }
+
+   return 0;
+}
+
+
+/* Remove words that appear in polyA tails from the lookup table: string of As,
+   string of Ts, and As and Ts with one error. */
+static Int2 s_RemovePolyAWords(BlastMBLookupTable* mb_lt)
+{
+    Int4 word_size = mb_lt->lut_word_length;
+    Int8 word;
+    Int4 i, k;
+
+    ASSERT(word_size == 16);
+
+    /* remove As and Ts */
+    mb_lt->hashtable[0] = 0;
+    mb_lt->hashtable[(Int8)0xffffffff] = 0;
+
+    /* remove As with a single error */
+    for (i = 1;i < 4;i++) {
+        word = i;
+        for (k = 0;k < word_size;k++) {
+            mb_lt->hashtable[word << (k * 2)] = 0;
+        }
+    }
+
+    /* remove Ts with a single error */
+    for (i = 0;i < 3;i++) {
+        for (k = 0;k < word_size;k++) {
+            word = ((0xffffffff ^ (3 << k*2)) | (i << k*2)) & 0xffffffff;
+            mb_lt->hashtable[word] = 0;
+        }
+    }
+
+    return 0;
+}
+
+
+#define MAX_WORD_COUNT (10)
+
 /** Fills in the hashtable and next_pos fields of BlastMBLookupTable*
  * for the contiguous case.
  *
@@ -822,14 +934,15 @@ s_FillDiscMBTable(BLAST_SequenceBlk* query, BlastSeqLoc* location,
 static Int2 
 s_FillContigMBTable(BLAST_SequenceBlk* query, 
         BlastSeqLoc* location,
-        BlastMBLookupTable* mb_lt) 
-
+        BlastMBLookupTable* mb_lt,
+        const LookupTableOptions* lookup_options,
+        Uint1* counts)
 {
    BlastSeqLoc* loc;
    /* 12-mers (or perhaps 8-mers) are used to build the lookup table 
       and this is what kLutWordLength specifies. */
    const Int4 kLutWordLength = mb_lt->lut_word_length;
-   const Int4 kLutMask = mb_lt->hashsize - 1;
+   const Int8 kLutMask = mb_lt->hashsize - 1;
    /* The user probably specified a much larger word size (like 28) 
       and this is what full_word_size is. */
    Int4 full_word_size = mb_lt->word_length;
@@ -845,7 +958,7 @@ s_FillContigMBTable(BLAST_SequenceBlk* query,
    const Int4 kCompressionFactor=2048; /* compress helper_array by this much */
    Uint4 longest_chain;
    Uint4* helper_array;
-
+   const Boolean kDbFilter = lookup_options->db_filter;
 
    ASSERT(mb_lt);
 
@@ -861,17 +974,32 @@ s_FillContigMBTable(BLAST_SequenceBlk* query,
    if (helper_array == NULL)
 	return -1;
 
+   /* if filtering by database word counts, then reset the pv array to avoid
+      too many bits set for database scanning */
+   if (kDbFilter) {
+       memset(pv_array, 0,
+              (mb_lt->hashsize >> mb_lt->pv_array_bts) * PV_ARRAY_BYTES);
+   }
+
    for (loc = location; loc; loc = loc->next) {
       /* We want index to be always pointing to the start of the word.
          Since sequence pointer points to the end of the word, subtract
          word length from the loop boundaries.  */
       Int4 from = loc->ssr->left;
       Int4 to = loc->ssr->right - kLutWordLength;
-      Int4 ecode = 0;
+      Int8 ecode = 0;
       Int4 last_offset;
       Uint1* pos;
       Uint1* seq;
       Uint1 val;
+//      int counter = 1; /* collect this many adjacent words */
+      int shift = 0;
+      int pos_shift = 0;
+      if (lookup_options->stride > 0) {
+          shift = lookup_options->stride - 1;
+          pos_shift = kLutWordLength + 1;
+      }
+
 
      /* case of unmasked region >=  kLutWordLength but < full_word_size,
         so no hits should be generated. */
@@ -901,9 +1029,40 @@ s_FillContigMBTable(BLAST_SequenceBlk* query,
          if (seq < pos) 
             continue;
 
+         /* if filtering by database word count, then do not add words
+            with too many counts */
+         if (kDbFilter) {
+             if (!(ecode & 1)) {
+                 if ((counts[ecode / 2] >> 4) >= MAX_WORD_COUNT) {
+                     continue;
+                 }
+             }
+             else {
+                 if ((counts[ecode / 2] & 0xf) >= MAX_WORD_COUNT) {
+                     continue;
+                 }
+             }
+         }
+
+
+	 /* collect 1 word and skip lookup_options->stride */
+	 
+ /*
+	 if (!counter) {
+	     pos = seq + lookup_options->stride;
+	     counter = 1;
+		 	     
+	     continue;
+	 }
+	 if (lookup_options->stride) {
+	     counter--;
+	 }
+ */
+
 #ifdef LOOKUP_VERBOSE
          mb_lt->num_words_added++;
 #endif
+
          if (mb_lt->hashtable[ecode] == 0) {
 #ifdef LOOKUP_VERBOSE
             mb_lt->num_unique_pos_added++;
@@ -915,9 +1074,20 @@ s_FillContigMBTable(BLAST_SequenceBlk* query,
          }
          mb_lt->next_pos[index] = mb_lt->hashtable[ecode];
          mb_lt->hashtable[ecode] = index;
+
+         /* skip shift words */
+         index += shift;
+         seq += shift;
+         pos = seq + pos_shift;
       }
    }
 
+   /* FIXME: should this be done only for spliced reads? */
+   if (Blast_ProgramIsMapping(lookup_options->program_number) &&
+       mb_lt->lut_word_length == 16) {
+       s_RemovePolyAWords(mb_lt);
+   }
+
    longest_chain = 2;
    for (index = 0; index < mb_lt->hashsize / kCompressionFactor; index++)
        longest_chain = MAX(longest_chain, helper_array[index]);
@@ -928,13 +1098,123 @@ s_FillContigMBTable(BLAST_SequenceBlk* query,
 }
 
 
+/** Scan a subject sequecne and update words counters, for 16-base words with
+ *  scan step of 1. The counters are 4-bit and counting is done up to 10.
+ *
+ * @param sequence Subject sequence [in]
+ * @param mb_lt Megablast lookup table [in|out]
+ * @param counts Word counters [in|out]
+ */
+static Int2
+s_MBCountWordsInSubject_16_1(const BLAST_SequenceBlk* sequence,
+                             BlastMBLookupTable* mb_lt,
+                             Uint1* counts)
+{
+    Uint1 *s;
+    Int4 i;
+    Int8 mask = mb_lt->hashsize - 1;
+    Int8 word, index, w;
+    const Int4 kNumWords
+        = sequence->length - mb_lt->lut_word_length;
+
+    PV_ARRAY_TYPE* pv = mb_lt->pv_array;
+    Int4 pv_array_bts = mb_lt->pv_array_bts;
+    Int4 shift;
+        
+    if (!sequence || !counts || !mb_lt || !pv) {
+        return -1;
+    }
+
+    ASSERT(mb_lt->lut_word_length == 16);
+
+    /* scan the words in the sequence */
+    shift = 8;
+    s = sequence->sequence;
+    w = (Int8)s[0] << 24 | (Int8)s[1] << 16 | (Int8)s[2] << 8 | s[3];
+    for (i = 0;i < kNumWords;i++) {
+
+        if (i % COMPRESSION_RATIO == 0) {
+            shift = 8;
+            w = (w << 8) | (Int8)s[i / COMPRESSION_RATIO + 4];
+        }
+        else {
+            shift -= 2;
+            ASSERT(shift > 0);
+        }
+
+        word = (w >> shift) & mask;
+
+        /* skip words that do not appear in the query */
+        if (!PV_TEST(pv, word, pv_array_bts)) {
+            continue;
+        }
+
+        /* update the counter */
+        index = word / 2;
+        if (word & 1) {
+            if ((counts[index] & 0xf) < MAX_WORD_COUNT) {
+                counts[index]++;
+            }
+        }
+        else {
+            if ((counts[index] >> 4) < MAX_WORD_COUNT) {
+                counts[index] += 1 << 4;
+            }
+        }
+    }
+
+    return 0;
+}
+
+/** Scan database sequences and count query words that appear in the database.
+ *  Then reset pv_array bits that correspond to words that do not appear in
+ *  in the database, or appear 10 or more times
+ *
+ * @param seq_src Source for subject sequences [in]
+ * @param mb_lt Megablast lookuptable [in|out]
+ */
+static Int2
+s_ScanSubjectForWordCounts(BlastSeqSrc* seq_src,
+                           BlastMBLookupTable* mb_lt,
+                           Uint1* counts)
+{
+    BlastSeqSrcIterator* itr;
+    BlastSeqSrcGetSeqArg seq_arg;
+    PV_ARRAY_TYPE* pv = mb_lt->pv_array;
+
+    if (!seq_src || !pv || !counts) {
+        return -1;
+    }
+
+    memset(&seq_arg, 0, sizeof(seq_arg));
+    seq_arg.encoding = eBlastEncodingProtein;
+
+    /* scan subject sequences and update the counters for each */
+    BlastSeqSrcResetChunkIterator(seq_src);
+    itr = BlastSeqSrcIteratorNewEx(MAX(BlastSeqSrcGetNumSeqs(seq_src)/100,1));
+    while ((seq_arg.oid = BlastSeqSrcIteratorNext(seq_src, itr))
+           != BLAST_SEQSRC_EOF) {
+
+        BlastSeqSrcGetSequence(seq_src, &seq_arg);
+        s_MBCountWordsInSubject_16_1(seq_arg.seq, mb_lt, counts);
+        BlastSeqSrcReleaseSequence(seq_src, &seq_arg);
+    }
+
+    BlastSequenceBlkFree(seq_arg.seq);
+    BlastSeqSrcIteratorFree(itr);
+
+    return 0;
+}
+
+
 /* Documentation in mb_lookup.h */
 Int2 BlastMBLookupTableNew(BLAST_SequenceBlk* query, BlastSeqLoc* location,
         BlastMBLookupTable** mb_lt_ptr,
         const LookupTableOptions* lookup_options,
         const QuerySetUpOptions* query_options,
         Int4 approx_table_entries,
-        Int4 lut_width)
+        Int4 lut_width,
+        BlastSeqSrc* seqsrc)
 {
    Int4 pv_size;
    Int2 status = 0;
@@ -942,6 +1222,7 @@ Int2 BlastMBLookupTableNew(BLAST_SequenceBlk* query, BlastSeqLoc* location,
    const Int4 kTargetPVSize = 131072;
    const Int4 kSmallQueryCutoff = 15000;
    const Int4 kLargeQueryCutoff = 800000;
+   Uint1* counts = NULL; /* array of word counts */
    
    *mb_lt_ptr = NULL;
 
@@ -954,15 +1235,18 @@ Int2 BlastMBLookupTableNew(BLAST_SequenceBlk* query, BlastSeqLoc* location,
    if (mb_lt == NULL) {
 	return -1;
    }
-    
+
    ASSERT(lut_width >= 9);
    mb_lt->word_length = lookup_options->word_size;
+/*   mb_lt->skip = lookup_options->skip; */
+   mb_lt->stride = lookup_options->stride > 0;
    mb_lt->lut_word_length = lut_width;
-   mb_lt->hashsize = 1 << (BITS_PER_NUC * mb_lt->lut_word_length);
-   mb_lt->hashtable = (Int4*)calloc(mb_lt->hashsize, sizeof(Int4));
+   mb_lt->hashsize = 1ULL << (BITS_PER_NUC * mb_lt->lut_word_length);
+
+   mb_lt->hashtable = (Int4*)calloc(mb_lt->hashsize, sizeof(Int4)); 
    if (mb_lt->hashtable == NULL) {
-      BlastMBLookupTableDestruct(mb_lt);
-      return -1;
+       BlastMBLookupTableDestruct(mb_lt);
+       return -1;
    }
 
    if (location && 
@@ -983,20 +1267,44 @@ Int2 BlastMBLookupTableNew(BLAST_SequenceBlk* query, BlastSeqLoc* location,
       and large queries saturate it. In either case, cache
       is better used on something else */
 
-   if (mb_lt->hashsize <= 8 * kTargetPVSize)
-      pv_size = mb_lt->hashsize >> PV_ARRAY_BTS;
-   else
-      pv_size = kTargetPVSize / PV_ARRAY_BYTES;
+   if (mb_lt->lut_word_length <= 12) {
+       if (mb_lt->hashsize <= 8 * kTargetPVSize)
+           pv_size = mb_lt->hashsize >> PV_ARRAY_BTS;
+       else
+           pv_size = kTargetPVSize / PV_ARRAY_BYTES;
+   }
+   else {
+       /* use 8M-byte pv array for large lut word (only size 16 implemented
+          currently) */
+           pv_size = kTargetPVSize * 64 / PV_ARRAY_BYTES;
+   }
 
-   if(approx_table_entries <= kSmallQueryCutoff ||
-      approx_table_entries >= kLargeQueryCutoff) {
-         pv_size = pv_size / 2;
+   if(!lookup_options->db_filter &&
+      (approx_table_entries <= kSmallQueryCutoff ||
+       approx_table_entries >= kLargeQueryCutoff)) {
+       pv_size = pv_size / 2;
    }
+
    mb_lt->pv_array_bts = ilog2(mb_lt->hashsize / pv_size);
    mb_lt->pv_array = calloc(PV_ARRAY_BYTES, pv_size);
    if (mb_lt->pv_array == NULL) {
-      BlastMBLookupTableDestruct(mb_lt);
-      return -1;
+       BlastMBLookupTableDestruct(mb_lt);
+       return -1;
+   }
+
+
+   /* allocate word counters, to save memory we are using 4 bits per word */
+   if (lookup_options->db_filter) {
+       counts = (Uint1*)calloc(mb_lt->hashsize / 2, sizeof(Uint1));
+       if (counts == NULL) {
+           BlastMBLookupTableDestruct(mb_lt);
+           return -1;
+       }
+   }  
+
+   if (lookup_options->db_filter) {
+       s_FillPV(query, location, mb_lt, lookup_options);
+       s_ScanSubjectForWordCounts(seqsrc, mb_lt, counts);
    }
 
    if (lookup_options->mb_template_length > 0) {
@@ -1007,9 +1315,20 @@ Int2 BlastMBLookupTableNew(BLAST_SequenceBlk* query, BlastSeqLoc* location,
    else {
         /* contiguous megablast */
         mb_lt->scan_step = mb_lt->word_length - mb_lt->lut_word_length + 1;
-        status = s_FillContigMBTable(query, location, mb_lt);
+        status = s_FillContigMBTable(query, location, mb_lt, lookup_options,
+                                     counts);
+
+        if (status) {
+            BlastMBLookupTableDestruct(mb_lt);
+            return -1;
+        }
+   }
+
+   if (lookup_options->db_filter && counts) {
+       free(counts);
    }
 
+
    if (status > 0) {
       BlastMBLookupTableDestruct(mb_lt);
       return status;
@@ -1018,12 +1337,12 @@ Int2 BlastMBLookupTableNew(BLAST_SequenceBlk* query, BlastSeqLoc* location,
    *mb_lt_ptr = mb_lt;
 
 #ifdef LOOKUP_VERBOSE
-   printf("lookup table size: %d (%d letters)\n", mb_lt->hashsize,
+   printf("lookup table size: %ld (%d letters)\n", mb_lt->hashsize,
                                         mb_lt->lut_word_length);
    printf("words in table: %d\n", mb_lt->num_words_added);
    printf("filled entries: %d (%f%%)\n", mb_lt->num_unique_pos_added,
                         100.0 * mb_lt->num_unique_pos_added / mb_lt->hashsize);
-   printf("PV array size: %d bytes (%d table entries/bit)\n",
+   printf("PV array size: %d bytes (%ld table entries/bit)\n",
                                  pv_size * PV_ARRAY_BYTES, 
                                  mb_lt->hashsize / (pv_size << PV_ARRAY_BTS));
    printf("longest chain: %d\n", mb_lt->longest_chain);
@@ -1031,6 +1350,7 @@ Int2 BlastMBLookupTableNew(BLAST_SequenceBlk* query, BlastSeqLoc* location,
    return 0;
 }
 
+
 BlastMBLookupTable* BlastMBLookupTableDestruct(BlastMBLookupTable* mb_lt)
 {
    if (!mb_lt)
@@ -1046,3 +1366,562 @@ BlastMBLookupTable* BlastMBLookupTableDestruct(BlastMBLookupTable* mb_lt)
    sfree(mb_lt);
    return mb_lt;
 }
+
+
+/* Hash function: Fowler-Noll-Vo (FNV) hash 
+   http://www.isthe.com/chongo/tech/comp/fnv/index.html */
+static Uint4 FNV_hash(Uint1* seq, Uint4 mask)
+{
+    const Uint4 fnv_prime = 16777619u;
+    const Uint4 fnv_offset_basis = 2166136261u;
+    Int4 i;
+    Uint4 hash;
+    
+    hash = fnv_offset_basis;
+    for (i = 0;i < 4;i++) {
+        hash *= fnv_prime;
+        hash ^= seq[i];
+    }
+
+    return hash & mask;
+}
+
+
+static Int2
+s_NaHashLookupFillPV(BLAST_SequenceBlk* query, 
+                     BlastSeqLoc* locations,
+                     BlastNaHashLookupTable* lookup)
+{
+    BlastSeqLoc *loc;
+    Int4 word_length;
+    Int4 lut_word_length;
+    PV_ARRAY_TYPE* pv = NULL;
+    const Int4 pv_array_bts = lookup->pv_array_bts;
+
+    ASSERT(lookup);
+
+    word_length = lookup->word_length;
+    lut_word_length = lookup->lut_word_length;
+    pv = lookup->pv;
+    ASSERT(pv);
+    
+    for (loc = locations; loc; loc = loc->next) {
+        /* We want index to be always pointing to the start of the word.
+           Since sequence pointer points to the end of the word, subtract
+           word length from the loop boundaries.  */
+        Int4 from = loc->ssr->left;
+        Int4 to = loc->ssr->right;
+        Uint4 ecode = 0;
+        Uint1* pos;
+        Uint1* seq;
+        Uint1* end;
+        Uint1 base;
+
+        /* case of unmasked region >=  kLutWordLength but < full_word_size,
+           so no hits should be generated. */
+        if (word_length > (loc->ssr->right - loc->ssr->left + 1)) {
+            continue; 
+        }
+
+        seq = query->sequence + from;
+        pos = seq + lut_word_length - 1;
+        end = query->sequence + to + 1;
+
+        for (; seq < end; seq++) {
+
+            base = *seq;
+            /* if an ambiguity is encountered, do not add
+               any words that would contain it */
+            if ((base & BLAST2NA_MASK) != 0) {
+                ecode = 0;
+                pos = seq + lut_word_length;
+                continue;
+            }
+
+            /* get next base */
+            ecode = (ecode << BITS_PER_NUC) | base;
+            if (seq < pos) {
+                continue;
+            }
+
+            PV_SET(pv, (Int8)ecode, pv_array_bts);
+        }
+    }
+        
+    return 0;
+}
+
+
+/** Scan a subject sequecne and update words counters, for 16-base words with
+ *  scan step of 1. The counters are 4-bit and counting is done up to 10.
+ *
+ * @param sequence Subject sequence [in]
+ * @param lookup Hashed lookup table [in|out]
+ * @param counts Word counters [in|out]
+ */
+static Int2
+s_NaHashLookupCountWordsInSubject_16_1(const BLAST_SequenceBlk* sequence,
+                                       BlastNaHashLookupTable* lookup,
+                                       Uint1* counts)
+{
+    Uint1 *s;
+    Int4 i;
+    Int8 mask = (1ULL << (16 * BITS_PER_NUC)) - 1;
+    Int8 word, index, w;
+    const Int4 kNumWords
+        = sequence->length - lookup->lut_word_length;
+
+    PV_ARRAY_TYPE* pv = lookup->pv;
+    Int4 pv_array_bts = lookup->pv_array_bts;
+    Int4 shift;
+
+    if (!sequence || !counts || !lookup || !pv) {
+        return -1;
+    }
+
+    ASSERT(lookup->lut_word_length == 16);
+
+    /* scan the words in the sequence */
+    shift = 8;
+    s = sequence->sequence;
+    w = (Int8)s[0] << 24 | (Int8)s[1] << 16 | (Int8)s[2] << 8 | s[3];
+    for (i = 0;i < kNumWords;i++) {
+
+        if (i % COMPRESSION_RATIO == 0) {
+            shift = 8;
+            w = (w << 8) | (Int8)s[i / COMPRESSION_RATIO + 4];
+        }
+        else {
+            shift -= 2;
+            ASSERT(shift > 0);
+        }
+
+        word = (w >> shift) & mask;
+
+        /* skip words that do not appear in the query */
+        if (!PV_TEST(pv, word, pv_array_bts)) {
+            continue;
+        }
+
+        /* update the counter */
+        index = word / 2;
+        if (word & 1) {
+            if ((counts[index] & 0xf) < MAX_WORD_COUNT) {
+                counts[index]++;
+            }
+        }
+        else {
+            if ((counts[index] >> 4) < MAX_WORD_COUNT) {
+                counts[index] += 1 << 4;
+            }
+        }
+    }
+
+    return 0;
+}
+
+/** Scan database sequences and count query words that appear in the database.
+ *  Then reset pv_array bits that correspond to words that do not appear in
+ *  in the database, or appear 10 or more times
+ *
+ * @param seq_src Source for subject sequences [in]
+ * @param lookup Hashed lookuptable [in|out]
+ */
+static Int2
+s_NaHashLookupScanSubjectForWordCounts(BlastSeqSrc* seq_src,
+                                       BlastNaHashLookupTable* lookup,
+                                       Uint1* counts)
+{
+    BlastSeqSrcIterator* itr;
+    BlastSeqSrcGetSeqArg seq_arg;
+
+    if (!seq_src || !lookup || !lookup->pv || !counts) {
+        return -1;
+    }
+
+    memset(&seq_arg, 0, sizeof(seq_arg));
+    seq_arg.encoding = eBlastEncodingProtein;
+
+    /* scan subject sequences and update the counters for each */
+    BlastSeqSrcResetChunkIterator(seq_src);
+    itr = BlastSeqSrcIteratorNewEx(MAX(BlastSeqSrcGetNumSeqs(seq_src)/100,1));
+    while ((seq_arg.oid = BlastSeqSrcIteratorNext(seq_src, itr))
+           != BLAST_SEQSRC_EOF) {
+
+        BlastSeqSrcGetSequence(seq_src, &seq_arg);
+        s_NaHashLookupCountWordsInSubject_16_1(seq_arg.seq, lookup, counts);
+        BlastSeqSrcReleaseSequence(seq_src, &seq_arg);
+    }
+
+    BlastSequenceBlkFree(seq_arg.seq);
+    BlastSeqSrcIteratorFree(itr);
+
+    return 0;
+}
+
+
+static void s_NaHashLookupRemoveWordFromThinBackbone(
+                                         BackboneCell** thin_backbone,
+                                         Uint4 word,
+                                         TNaLookupHashFunction hash_func,
+                                         Uint4 mask)
+{
+    BackboneCell* prev = NULL;
+    BackboneCell* next = NULL;
+    BackboneCell* b = NULL;
+    Int8 index = hash_func((Uint1*)&word, mask);
+
+    if (!thin_backbone[index]) {
+        return;
+    }
+
+    /* if word present in the first enrty for the hashed value */
+    if (thin_backbone[index]->word == word) {
+        next = thin_backbone[index]->next;
+        thin_backbone[index]->next = NULL;
+        BackboneCellFree(thin_backbone[index]);
+        thin_backbone[index] = next;
+
+        return;
+    }
+
+    /* in case of a collision check the remaining words with the same hash
+       value */
+    prev = thin_backbone[index];
+    b = thin_backbone[index]->next;
+    for (; b; prev = prev->next, b = b->next) {
+        if (b->word == word) {
+            next = b->next;
+            b->next = NULL;
+            BackboneCellFree(b);
+            prev->next = next;
+
+            break;
+        }
+    }
+}
+
+
+static Int2 s_NaHashLookupRemovePolyAWords(BackboneCell** thin_backbone,
+                                           Int4 size,
+                                           TNaLookupHashFunction hash_func,
+                                           Uint4 mask)
+{
+    Int4 word_size = 16;
+    Int8 word;
+    Int4 i, k;
+
+    ASSERT(word_size == 16);
+
+    /* remove As and Ts */
+    s_NaHashLookupRemoveWordFromThinBackbone(thin_backbone, 0, hash_func, mask);
+    s_NaHashLookupRemoveWordFromThinBackbone(thin_backbone, 0xffffffff,
+                                             hash_func, mask);
+
+    /* remove As with a single error */
+    for (i = 1;i < 4;i++) {
+        word = i;
+        for (k = 0;k < word_size;k++) {
+            s_NaHashLookupRemoveWordFromThinBackbone(thin_backbone,
+                                                     word << (k * 2),
+                                                     hash_func,
+                                                     mask);
+        }
+    }
+
+    /* remove Ts with a single error */
+    for (i = 0;i < 3;i++) {
+        for (k = 0;k < word_size;k++) {
+            word = ((0xffffffff ^ (3 << k*2)) | (i << k*2)) & 0xffffffff;
+            s_NaHashLookupRemoveWordFromThinBackbone(thin_backbone, word,
+                                                     hash_func, mask);
+        }
+    }
+
+    return 0;
+}
+
+
+/** Pack the data structures comprising a nucleotide lookup table
+ * into their final form
+ * @param thin_backbone structure containing indexed query offsets [in][out]
+ * @param lookup the lookup table [in]
+ */
+static void s_BlastNaHashLookupFinalize(BackboneCell** thin_backbone,
+                                        BlastNaHashLookupTable* lookup)
+{
+    Int4 i;
+    Int4 overflow_cells_needed = 0;
+    Int4 overflow_cursor = 0;
+    Int4 longest_chain = 0;
+    PV_ARRAY_TYPE *pv;
+    const Int4 pv_array_bts = lookup->pv_array_bts;
+#ifdef LOOKUP_VERBOSE
+    Int4 backbone_occupancy = 0;
+    Int4 thick_backbone_occupancy = 0;
+    Int4 num_overflows = 0;
+    Int4 words_per_hash[5] = {0,};
+#endif
+
+    ASSERT(lookup->lut_word_length == 16);
+
+    /* allocate the new lookup table */
+    lookup->thick_backbone = (NaHashLookupBackboneCell *)calloc(
+                                           lookup->backbone_size, 
+                                           sizeof(NaHashLookupBackboneCell));
+    ASSERT(lookup->thick_backbone != NULL);
+
+    pv = lookup->pv;
+    ASSERT(pv != NULL);
+    /* reset PV array, it might have been set earlier to count database words,
+       and a few bits may need to be reset */
+    memset(pv, 0, (lookup->backbone_size >> pv_array_bts) * PV_ARRAY_BYTES);
+
+    /* remove polyA words from the lookup table */
+    s_NaHashLookupRemovePolyAWords(thin_backbone, lookup->backbone_size,
+                                   lookup->hash_callback, lookup->mask);
+
+    /* find out how many cells are needed for the overflow array */
+    for (i = 0; i < lookup->backbone_size; i++) {
+        BackboneCell* b = thin_backbone[i];
+        Int4 num_hits = 0;
+        Int4 num_words = 0;
+        for (; b; b = b->next) {
+            num_hits += b->num_offsets;
+            num_words++;
+        }
+
+        if (num_words > NA_WORDS_PER_HASH || num_hits > NA_OFFSETS_PER_HASH) {
+            /* +1 because we store unhashed word to resolve hash collisions
+               +1 for number of offsets */
+            overflow_cells_needed += num_hits + (num_words * 2);
+        }
+        longest_chain = MAX(longest_chain, num_hits);
+    }
+
+    lookup->longest_chain = longest_chain;
+
+    /* allocate the overflow array */
+    if (overflow_cells_needed > 0) {
+        lookup->overflow = (Int4*)calloc(overflow_cells_needed, sizeof(Int4));
+        ASSERT(lookup->overflow != NULL);
+    }
+
+    /* for each position in the lookup table backbone, */
+    for (i = 0; i < lookup->backbone_size; i++) {
+
+        Int4 num_words = 0;
+        Int4 num_offsets = 0;
+        NaHashLookupBackboneCell* cell = lookup->thick_backbone + i;
+        BackboneCell* head = thin_backbone[i];
+        BackboneCell* b = NULL;
+        Boolean is_overflow = FALSE;
+        
+        if (!head) {
+            continue;
+        }
+
+#ifdef LOOKUP_VERBOSE
+        thick_backbone_occupancy++;
+#endif
+
+        /* for each cell with the same hash value in the thin backbone
+           count number of words and offsets stored */
+        for (b = head; b; b = b->next) {
+            num_words++;
+            num_offsets += b->num_offsets;
+
+#ifdef LOOKUP_VERBOSE
+            backbone_occupancy++;
+#endif
+        }
+        cell->num_words = num_words;
+
+#ifdef LOOKUP_VERBOSE
+        words_per_hash[((num_words < 6) ? num_words : 5) - 1]++;
+#endif
+
+        /* if the thin cell stores at most 3 words and 9 offsets, store them
+           all in the thick backbone */
+        if (num_words <= NA_WORDS_PER_HASH &&
+            num_offsets <= NA_OFFSETS_PER_HASH) {
+            Int4 k = 0;
+            Int4 n = 0;
+            
+            for (b = head; b; b = b->next, k++) {
+                Int4 j;
+                cell->words[k] = b->word;
+                cell->num_offsets[k] = b->num_offsets;
+
+                PV_SET(pv, (Int8)b->word, pv_array_bts);
+
+                for (j = 0;j < b->num_offsets;j++) {
+                    ASSERT(n <= NA_OFFSETS_PER_HASH);
+                    cell->offsets[n++] = b->offsets[j];
+                }
+            }
+        }
+        /* otherwise, store them in the overflow array */
+        else if (num_words <= NA_WORDS_PER_HASH) {
+            Int4 k = 0;
+            for (b = head; b; b = b->next, k++) {
+                cell->words[k] = b->word;
+            }
+            is_overflow = TRUE;
+        }
+        else {
+            is_overflow = TRUE;
+        }
+
+        /* add words and offsets to overflow array: word, number of offsets,
+           offsets */
+        if (is_overflow) {
+#ifdef LOOKUP_VERBOSE
+            num_overflows++;
+#endif
+            cell->offsets[0] = overflow_cursor;
+            for (b = head; b; b = b->next) {
+                Int4 j;
+                lookup->overflow[overflow_cursor++] = *(Int4*)(&b->word);
+                lookup->overflow[overflow_cursor++] = b->num_offsets;
+                for (j = 0;j < b->num_offsets;j++) {
+                    lookup->overflow[overflow_cursor++] = b->offsets[j];
+                }
+                ASSERT(overflow_cursor <= overflow_cells_needed);
+                PV_SET(pv, (Int8)b->word, pv_array_bts);
+            }
+        }
+
+        /* done with this chain */
+        thin_backbone[i] = BackboneCellFree(thin_backbone[i]);
+    }
+
+    lookup->offsets_size = overflow_cursor;
+
+#ifdef LOOKUP_VERBOSE
+    printf("backbone size: %d\n", lookup->backbone_size);
+    printf("backbone occupancy: %d (%f%%)\n", backbone_occupancy,
+           100.0 * backbone_occupancy / lookup->backbone_size);
+    printf("thick_backbone occupancy: %d (%f%%)\n",
+           thick_backbone_occupancy,
+           100.0 * thick_backbone_occupancy / lookup->backbone_size);
+    printf("num_overflows: %d\n", num_overflows);
+    printf("\tnumber of words per hash\tcount\n");
+    {
+        Int4 ii;
+        for (ii = 0;ii < 5;ii++) {
+            printf("\t%d\t%d\n", ii + 1, words_per_hash[ii]);
+        }
+    }
+    printf("overflow size: %d\n", overflow_cells_needed);
+    printf("longest chain: %d\n", longest_chain);
+#endif
+}
+
+
+BlastNaHashLookupTable*
+BlastNaHashLookupTableDestruct(BlastNaHashLookupTable* lookup)
+{
+    sfree(lookup->thick_backbone);
+    sfree(lookup->overflow);
+    if (lookup->masked_locations)
+       lookup->masked_locations = BlastSeqLocFree(lookup->masked_locations);
+    sfree(lookup->pv);
+    sfree(lookup);
+
+    return NULL;
+}
+
+
+Int4 BlastNaHashLookupTableNew(BLAST_SequenceBlk* query,
+                               BlastSeqLoc* locations,
+                               BlastNaHashLookupTable** lut,
+                               const LookupTableOptions* opt, 
+                               const QuerySetUpOptions* query_options,
+                               BlastSeqSrc* seqsrc)
+{
+    BackboneCell **thin_backbone = NULL;
+    BlastNaHashLookupTable *lookup = *lut =
+        (BlastNaHashLookupTable*) calloc(1, sizeof(BlastNaHashLookupTable));
+    /* Number of possible 16-base words */
+    const Int8 kNumWords = (1ULL << 32);
+    Uint1* counts = NULL;
+    Int4 num_hash_bits = 24;
+    Int8 database_length = 0LL;
+
+    ASSERT(lookup != NULL);
+
+    if (opt->db_filter && !seqsrc) {
+        return -1;
+    }
+
+    /* use more bits for hash function for larger databases to decrease number
+       of collisions */
+    /* FIXME: number of bits may also depend on concatenated query length */
+    if (seqsrc) {
+        database_length = BlastSeqSrcGetTotLen(seqsrc);
+    }
+    if (database_length > 500000000L) {
+        num_hash_bits = 25;
+    }
+
+    lookup->word_length = opt->word_size;
+    lookup->lut_word_length = 16;
+    /* 16-base words are hashed to 24-bit or 25-bit values */
+    lookup->backbone_size = 1 << num_hash_bits;
+    lookup->mask = lookup->backbone_size - 1;
+    lookup->overflow = NULL;
+    lookup->scan_step = lookup->word_length - lookup->lut_word_length + 1;
+    lookup->hash_callback = FNV_hash;
+
+    thin_backbone = (BackboneCell**)calloc(lookup->backbone_size,
+                                          sizeof(BackboneCell*));
+    ASSERT(thin_backbone != NULL);
+
+    /* PV array does not use hashing, and uses 64 words per bit */
+    lookup->pv_array_bts = 11;
+    lookup->pv = (PV_ARRAY_TYPE*)calloc(kNumWords / 64 / PV_ARRAY_BYTES,
+                                        sizeof(PV_ARRAY_TYPE));
+    ASSERT(lookup->pv);
+
+    
+    /* allocate word counters, to save memory we are using 4 bits per word */
+    if (opt->db_filter) {
+        ASSERT(lookup->word_length == 16);
+        counts = (Uint1*)calloc(kNumWords / 2, sizeof(Uint1));
+        if (counts == NULL) {
+    	    sfree(thin_backbone);
+            BlastNaHashLookupTableDestruct(lookup);
+            return -1;
+        }
+    }  
+
+    /* count words in the database */
+    if (opt->db_filter) {
+        s_NaHashLookupFillPV(query, locations, lookup);
+        s_NaHashLookupScanSubjectForWordCounts(seqsrc, lookup, counts);
+    }
+
+    
+    BlastHashLookupIndexQueryExactMatches(thin_backbone,
+                                          lookup->word_length,
+                                          BITS_PER_NUC,
+                                          lookup->lut_word_length,
+                                          query, locations,
+                                          lookup->hash_callback,
+                                          lookup->mask,
+                                          counts);
+    if (locations && 
+        lookup->word_length > lookup->lut_word_length && 
+        s_HasMaskAtHashEnabled(query_options)) {
+        lookup->masked_locations = s_SeqLocListInvert(locations, query->length);
+    }
+    s_BlastNaHashLookupFinalize(thin_backbone, lookup);
+    sfree(thin_backbone);
+    if (counts) {
+        sfree(counts);
+    }
+
+    return 0;
+}
+
diff --git a/c++/src/algo/blast/core/blast_nascan.c b/c++/src/algo/blast/core/blast_nascan.c
index 626040a..1af5e3e 100644
--- a/c++/src/algo/blast/core/blast_nascan.c
+++ b/c++/src/algo/blast/core/blast_nascan.c
@@ -1,4 +1,4 @@
-/* $Id: blast_nascan.c 431697 2014-04-07 15:06:02Z madden $
+/* $Id: blast_nascan.c 505619 2016-06-27 18:51:47Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
 #include <algo/blast/core/blast_nascan.h>
 #include <algo/blast/core/blast_util.h> /* for NCBI2NA_UNPACK_BASE */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_nascan.c 431697 2014-04-07 15:06:02Z madden $";
-#endif                          /* SKIP_DOXYGEN_PROCESSING */
-
 /**
 * Retrieve the number of query offsets associated with this subject word.
 * @param lookup The lookup table to read from. [in]
@@ -1389,7 +1384,7 @@ static void s_SmallNaChooseScanSubject(LookupTableWrap *lookup_wrap)
 * @return 1 if there are hits, 0 otherwise.
 */
 static NCBI_INLINE Int4 s_BlastMBLookupHasHits(BlastMBLookupTable * lookup,
-                                               Int4 index)
+                                               Int8 index)
 {
     PV_ARRAY_TYPE *pv = lookup->pv_array;
     Int4 pv_array_bts = lookup->pv_array_bts;
@@ -1409,7 +1404,7 @@ static NCBI_INLINE Int4 s_BlastMBLookupHasHits(BlastMBLookupTable * lookup,
 * @return The number of hits copied.
 */
 static NCBI_INLINE Int4 s_BlastMBLookupRetrieve(BlastMBLookupTable * lookup,
-                                                Int4 index,
+                                                Int8 index,
                                                 BlastOffsetPair * offset_pairs,
                                                 Int4 s_off)
 {
@@ -1433,7 +1428,7 @@ static NCBI_INLINE Int4 s_BlastMBLookupRetrieve(BlastMBLookupTable * lookup,
 * @return The number of hits copied.
 */
 static NCBI_INLINE Int4 s_BlastMBLookupRetrieve2(BlastMBLookupTable * lookup,
-                                                 Int4 index,
+                                                 Int8 index,
                                                  BlastOffsetPair * offset_pairs,
                                                  Int4 s_off)
 {
@@ -1493,8 +1488,8 @@ static Int4 s_MBScanSubject_Any(const LookupTableWrap* lookup_wrap,
    Uint1* s;
    Uint1* abs_start = subject->sequence;
    Int4 s_off;
-   Int4 index;
-   Int4 mask = mb_lt->hashsize - 1;
+   Int8 index;
+   Int8 mask = mb_lt->hashsize - 1;
    Int4 total_hits = 0;
    Int4 lut_word_length = mb_lt->lut_word_length;
    Int4 scan_step = mb_lt->scan_step;
@@ -1503,7 +1498,8 @@ static Int4 s_MBScanSubject_Any(const LookupTableWrap* lookup_wrap,
    ASSERT(lut_word_length == 9 || 
           lut_word_length == 10 ||
           lut_word_length == 11 ||
-          lut_word_length == 12);
+          lut_word_length == 12 ||
+          lut_word_length == 16);
 
    /* Since the test for number of hits here is done after adding them, 
       subtract the longest chain length from the allowed offset array size. */
@@ -1541,7 +1537,48 @@ static Int4 s_MBScanSubject_Any(const LookupTableWrap* lookup_wrap,
       }
       scan_range[0] = (s - abs_start)*COMPRESSION_RATIO;
 
+   } else if (lut_word_length == 16 && scan_step == 1) {
+       /* scan for lookup table width 16 and stride 1 */
+       Int8 w;
+       Int4 shift; 
+
+       s = abs_start + (scan_range[0] / COMPRESSION_RATIO);
+       w = (Int8)s[0] << 24 | (Int8)s[1] << 16 | (Int8)s[2] << 8 | s[3];
+       if (scan_range[0] % COMPRESSION_RATIO != 0) {
+           w = (w << 8) | (Int8)s[4];
+       }
+       shift = 2 * (COMPRESSION_RATIO - (scan_range[0] % COMPRESSION_RATIO));
+       for (; scan_range[0] <= scan_range[1]; scan_range[0] += scan_step) {
+
+           if (scan_range[0] % COMPRESSION_RATIO == 0) {
+               s = abs_start + (scan_range[0] / COMPRESSION_RATIO);
+               w = (w << 8) | (Int8)s[4];
+               shift = 8;
+           }
+
+           index = (w >> shift) & mask;
+
+           shift -= 2;
+           ASSERT(shift >= 0);
+           MB_ACCESS_HITS();
+       }
+
+   } else if (lut_word_length == 16) {
+       /* scan for lookup table width 16 and any stride */
+       for (; scan_range[0] <= scan_range[1]; scan_range[0] += scan_step) {
+
+           Int4 shift = 2 * (COMPRESSION_RATIO - (scan_range[0] % COMPRESSION_RATIO));
+           s = abs_start + (scan_range[0] / COMPRESSION_RATIO);
+           Int8 w = (Int8)s[0] << 32 | (Int8)s[1] << 24 | (Int8)s[2] << 16 |
+               (Int8)s[3] << 8 | s[4];
+
+           index = (w >> shift) & mask;
+
+           MB_ACCESS_HITS();
+       }
+
    } else if (lut_word_length > 9) {
+       ASSERT (lut_word_length <= 12);
 
       /* when the stride is not a multiple of 4, extra bases
          may occur both before and after every word read from
@@ -2630,6 +2667,7 @@ static void s_MBChooseScanSubject(LookupTableWrap *lookup_wrap)
             break;
 
         case 12:
+        case 16:
             /* lookup tables of width 12 are only used
                for very large queries, and the latency of
                cache misses dominates the runtime in that
@@ -2641,12 +2679,314 @@ static void s_MBChooseScanSubject(LookupTableWrap *lookup_wrap)
     }
 }
 
+/** Diagnostics for scanning with NaHashLookupTable */
+typedef struct SNaHashLookupScanDiags
+{
+   Int4 not_pv;
+   Int4 not_backbone;
+   Int4 hits;
+   Int4 h_num_words[5];
+   Int4 missed;
+   Int4 present;
+} SNaHashLookupScanDiags;
+
+
+static Int4 s_BlastNaHashLookupRetieveHits(BlastNaHashLookupTable* lookup,
+                                  Uint4 index,
+                                  Int4 s_off,
+                                  BlastOffsetPair* NCBI_RESTRICT offset_pairs,
+                                  SNaHashLookupScanDiags* diags)
+{
+    Int8 hashed_index;
+    const Int4 pv_array_bts = lookup->pv_array_bts;
+    const Uint4 kMask = lookup->mask;
+    Int4 num_hits = 0;
+    TNaLookupHashFunction hash_func =
+        (TNaLookupHashFunction)lookup->hash_callback;
+
+    /* test word in pv array */
+    if (!PV_TEST(lookup->pv, (Int8)index, pv_array_bts)) {
+#ifdef SCAN_VERBOSE
+        diags->not_pv++;
+#endif
+        return 0;
+    }
+
+    /* access words in lookup table */
+    hashed_index = hash_func((Uint1*)&index, kMask);
+    if (lookup->thick_backbone[hashed_index].num_words > 0) {
+        NaHashLookupBackboneCell* cell =
+            lookup->thick_backbone + hashed_index;
+        Int4 cursor = -1;
+
+#ifdef SCAN_VERBOSE
+        diags->hits++;
+        diags->h_num_words[
+                    ((lookup->thick_backbone[hashed_index].num_words < 5) ?
+                     lookup->thick_backbone[hashed_index].num_words - 1 :
+                     4)]++;
+#endif
+
+        /* if words are in thick backbone */
+        if (cell->num_words <= NA_WORDS_PER_HASH) {
+            Int4 i;
+            for (i = 0; i < cell->num_words; i++) {
+
+                if (cell->words[i] == (Uint4)index) {
+
+                    /* if offsets are in thick backbone, access them */
+                    if (cell->num_offsets[i] > 0) {
+                        /* get offsets */
+                        Int4 j;
+                        Int4 start = 0;
+
+#ifdef SCAN_VERBOSE
+                        diags->present++;
+#endif
+                               
+                        for (j = 0;j < i;j++) {
+                            start += cell->num_offsets[j];
+                        }
+
+                        for (j = 0;j < cell->num_offsets[i];j++) {
+                            ASSERT(start + j <= NA_OFFSETS_PER_HASH);
+                            offset_pairs[num_hits].qs_offsets.q_off
+                                = cell->offsets[start + j];
+
+                            offset_pairs[num_hits].qs_offsets.s_off
+                                = s_off;
+
+                            ASSERT(offset_pairs[num_hits].qs_offsets.q_off
+                                   >= 0);
+
+                            num_hits++;
+                        }
+                                   
+                    }
+                    else {
+                        /* otherwise get pointer to the overflow array */
+                        cursor = cell->offsets[0];
+                    }
+                           
+#ifdef SCAN_VERBOSE
+                    diags->missed--;
+#endif
+                    break;
+                }
+            }
+#ifdef SCAN_VERBOSE
+            diags->missed++;
+#endif
+
+        }
+        else {
+            /* otherwise get pointer to the overflow array */
+            cursor = cell->offsets[0];
+        }
+
+        /* aceess overflow array */
+        if (cursor >= 0) {
+            Int4 k = 0;
+            Int4* overflow = lookup->overflow + cell->offsets[0];
+
+            /* cursor points to beginning of data for a given hashed
+               word; the data are: word, number of offsets, offsets,
+               next word, ... */
+            for (k = 0; k < cell->num_words; k++) {
+                Uint4 word = *(Uint4*)(overflow);
+                Int4 num_offsets = overflow[1];
+                Int4 i;
+
+                if (word != index) {
+                    overflow += num_offsets + 2;
+                    continue;
+                }
+
+#ifdef SCAN_VERBOSE
+                diags->present++;
+#endif
+
+                overflow += 2;
+                for (i = 0;i < num_offsets;i++) {
+                    offset_pairs[num_hits + i].qs_offsets.q_off =
+                        overflow[i];
+
+                    offset_pairs[num_hits + i].qs_offsets.s_off =
+                        s_off;
+
+                    ASSERT(offset_pairs[num_hits + i].
+                           qs_offsets.q_off <= INT4_MAX);
+                }
+                num_hits += i;
+
+#ifdef SCAN_VERBOSE
+                diags->missed--;
+#endif
+                break;
+            }
+#ifdef SCAN_VERBOSE
+            diags->missed++;
+#endif
+        }
+    }
+#ifdef SCAN_VERBOSE
+    else {
+        diags->not_backbone++;
+    }
+#endif
+
+    return num_hits;
+}
+
+
+/** Scan the compressed subject sequence, returning 9-to-12 letter word hits
+ * with arbitrary stride. Assumes a megablast lookup table
+ * @param lookup_wrap Pointer to the (wrapper to) lookup table [in]
+ * @param subject The (compressed) sequence to be scanned for words [in]
+ * @param offset_pairs Array of query and subject positions where words are 
+ *                found [out]
+ * @param max_hits The allocated size of the above array - how many offsets 
+ *        can be returned [in]
+ * @param scan_range The starting and ending pos to be scanned [in] 
+ *        on exit, scan_range[0] is updated to be the stopping pos [out]
+*/
+static Int4 s_BlastNaHashScanSubject_Any(const LookupTableWrap* lookup_wrap,
+       const BLAST_SequenceBlk* subject, 
+       BlastOffsetPair* NCBI_RESTRICT offset_pairs, Int4 max_hits,  
+       Int4* scan_range)
+{
+   BlastNaHashLookupTable* lookup = (BlastNaHashLookupTable*) lookup_wrap->lut;
+   Uint1* s;
+   Uint1* abs_start = subject->sequence;
+   Int8 mask = (1ULL << 32) - 1;
+   Int4 total_hits = 0;
+   Int4 lut_word_length = lookup->lut_word_length;
+   Int4 scan_step = lookup->scan_step;
+   SNaHashLookupScanDiags diags;
+
+#ifdef SCAN_VERBOSE
+   memset(&diags, 0, sizeof(SNaHashLookupScanDiags));
+#endif
+   
+   ASSERT(lookup_wrap->lut_type == eNaHashLookupTable);
+   ASSERT(lut_word_length == 16);
+
+   /* Since the test for number of hits here is done after adding them, 
+      subtract the longest chain length from the allowed offset array size. */
+   max_hits -= lookup->longest_chain;
+
+   if (lut_word_length == 16 && scan_step == 1) {
+       /* scan for lookup table width 16 and stride 1 */
+
+       Int8 w;
+       Int4 shift; 
+       Uint4 index;
+
+       s = abs_start + (scan_range[0] / COMPRESSION_RATIO);
+       w = (Int8)s[0] << 24 | (Int8)s[1] << 16 | (Int8)s[2] << 8 | s[3];
+       if (scan_range[0] % COMPRESSION_RATIO != 0) {
+           w = (w << 8) | (Int8)s[4];
+       }
+       shift = 2 * (COMPRESSION_RATIO - (scan_range[0] % COMPRESSION_RATIO));
+       for (; scan_range[0] <= scan_range[1]; scan_range[0] += scan_step) {
+
+           if (scan_range[0] % COMPRESSION_RATIO == 0) {
+               s = abs_start + (scan_range[0] / COMPRESSION_RATIO);
+               w = (w << 8) | (Int8)s[4];
+               shift = 8;
+           }
+
+           index = (Uint4)((w >> shift) & mask);
+
+           shift -= 2;
+           ASSERT(shift >= 0);
+
+           if (total_hits >= max_hits)
+               break;
+
+
+           total_hits += s_BlastNaHashLookupRetieveHits(lookup, index,
+                                  scan_range[0], offset_pairs + total_hits,
+                                  &diags);
+       }
+   } 
+   else if (lut_word_length == 16) {
+
+       Int8 w;
+       Int4 shift; 
+       Uint4 index;
+
+       for (; scan_range[0] <= scan_range[1]; scan_range[0] += scan_step) {
+
+           s = abs_start + (scan_range[0] / COMPRESSION_RATIO);
+           w = (Int8)s[0] << 24 | (Int8)s[1] << 16 | (Int8)s[2] << 8 | s[3];
+           if (scan_range[0] % COMPRESSION_RATIO != 0) {
+               w = (w << 8) | (Int8)s[4];
+               shift = 2 * (COMPRESSION_RATIO - (scan_range[0] % COMPRESSION_RATIO));
+               index = (Uint4)((w >> shift) & mask);
+           }
+           else {
+               index = (Uint4)w;
+           }
+
+           if (total_hits >= max_hits)
+               break;
+
+           total_hits += s_BlastNaHashLookupRetieveHits(lookup, index,
+                                  scan_range[0], offset_pairs + total_hits,
+                                  &diags);
+       }
+   }
+   else {
+       /* scanning modes with different strides are not implemented */
+       ASSERT(0);
+
+       return -1;
+   }
+
+#ifdef SCAN_VERBOSE
+   printf("Num words not in PV:\t%d\n", diags.not_pv);
+   printf("Num words not in backbone\t%d\n", diags.not_backbone);
+   printf("Num hash value hits in backbone:\t%d\n", diags.hits);
+   printf("\tNum query words with the same hash value\tCount\n");
+   {
+       Int4 ii;
+       for (ii = 0;ii < 5;ii++) {
+           printf("\t%d\t%d\n", ii + 1, diags.h_num_words[ii]);
+       }
+   }
+   printf("Num backbone misses:\t%d\n", diags.missed);
+   printf("Num word hits:\t%d\n", diags.present);
+   printf("Total hits:\t%d\n", total_hits);
+   printf("\n");
+#endif
+
+   return total_hits;
+}
+
+
+/** Choose the most appropriate function to scan through
+ * subject sequences, assuming a standard blastn lookup table
+ * @param lookup_wrap Structure containing lookup table [in][out]
+ */
+static void s_NaHashChooseScanSubject(LookupTableWrap *lookup_wrap)
+{
+    BlastNaHashLookupTable *lookup = (BlastNaHashLookupTable *)lookup_wrap->lut;
+
+    ASSERT(lookup_wrap->lut_type == eNaHashLookupTable);
+
+    lookup->scansub_callback = (void*)s_BlastNaHashScanSubject_Any;
+}
+
+
 void BlastChooseNucleotideScanSubject(LookupTableWrap *lookup_wrap)
 {
     if (lookup_wrap->lut_type == eNaLookupTable)
         s_NaChooseScanSubject(lookup_wrap);
     else if (lookup_wrap->lut_type == eSmallNaLookupTable)
         s_SmallNaChooseScanSubject(lookup_wrap);
+    else if (lookup_wrap->lut_type == eNaHashLookupTable)
+        s_NaHashChooseScanSubject(lookup_wrap);
     else
         s_MBChooseScanSubject(lookup_wrap);
 }
@@ -2658,6 +2998,10 @@ void * BlastChooseNucleotideScanSubjectAny(LookupTableWrap *lookup_wrap)
 
     if (lookup_wrap->lut_type == eSmallNaLookupTable)
         return (void *)s_BlastSmallNaScanSubject_Any;
+
+    if (lookup_wrap->lut_type == eNaHashLookupTable) {
+        return (void*)s_BlastNaHashScanSubject_Any;
+    }
  
     return (void *)s_MBScanSubject_Any;
 }
diff --git a/c++/src/algo/blast/core/blast_options.c b/c++/src/algo/blast/core/blast_options.c
index b930f0e..f50d59e 100644
--- a/c++/src/algo/blast/core/blast_options.c
+++ b/c++/src/algo/blast/core/blast_options.c
@@ -1,4 +1,4 @@
-/* $Id: blast_options.c 493454 2016-02-26 19:57:55Z ivanov $
+/* $Id: blast_options.c 506100 2016-07-01 15:46:25Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  *
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_options.c 493454 2016-02-26 19:57:55Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_options.h>
 #include <algo/blast/core/blast_filter.h>
 #include <algo/blast/core/blast_stat.h>
@@ -427,7 +422,8 @@ Int2 SBlastFilterOptionsValidate(EBlastProgramType program_number, const SBlastF
 
        if (filter_options->repeatFilterOptions)
        {
-           if (program_number != eBlastTypeBlastn)
+           if (program_number != eBlastTypeBlastn &&
+               program_number != eBlastTypeMapping)
            {
                if (blast_message)
                   Blast_MessageWrite(blast_message, eBlastSevError, kBlastMessageNoContext,
@@ -446,7 +442,8 @@ Int2 SBlastFilterOptionsValidate(EBlastProgramType program_number, const SBlastF
 
        if (filter_options->dustOptions)
        {
-           if (program_number != eBlastTypeBlastn)
+           if (program_number != eBlastTypeBlastn &&
+               program_number != eBlastTypeMapping)
            {
                if (blast_message)
                   Blast_MessageWrite(blast_message, eBlastSevError, kBlastMessageNoContext,
@@ -457,7 +454,8 @@ Int2 SBlastFilterOptionsValidate(EBlastProgramType program_number, const SBlastF
   
        if (filter_options->segOptions)
        {
-           if (program_number == eBlastTypeBlastn)
+           if (program_number == eBlastTypeBlastn &&
+               program_number != eBlastTypeMapping)
            {
                if (blast_message)
                   Blast_MessageWrite(blast_message, eBlastSevError, kBlastMessageNoContext,
@@ -514,7 +512,8 @@ Int2 BLAST_FillQuerySetUpOptions(QuerySetUpOptions* options,
    
    if (strand_option && 
        (program == eBlastTypeBlastn || program == eBlastTypePhiBlastn || 
-        program == eBlastTypeBlastx || program == eBlastTypeTblastx)) {
+        program == eBlastTypeBlastx || program == eBlastTypeTblastx ||
+        program == eBlastTypeMapping)) {
       options->strand_option = strand_option;
    }
 
@@ -550,8 +549,9 @@ BlastInitialWordOptionsNew(EBlastProgramType program,
    if (*options == NULL)
       return BLASTERR_MEMORY;
 
-   if (program != eBlastTypeBlastn &&
-       program != eBlastTypePhiBlastn) {	/* protein-protein options. */
+   if (/*program != eBlastTypeBlastn &&
+         program != eBlastTypePhiBlastn */
+       !Blast_ProgramIsNucleotide(program)) {	/* protein-protein options. */
       (*options)->window_size = BLAST_WINDOW_SIZE_PROT;
       (*options)->x_dropoff = BLAST_UNGAPPED_X_DROPOFF_PROT;
       (*options)->gap_trigger = BLAST_GAP_TRIGGER_PROT;
@@ -579,6 +579,7 @@ BlastInitialWordOptionsValidate(EBlastProgramType program_number,
    /* PHI-BLAST has no ungapped extension phase.  Megablast may not have it,
     but generally does now. */
    if (program_number != eBlastTypeBlastn  &&
+       program_number != eBlastTypeMapping &&
        (!Blast_ProgramIsPhiBlast(program_number)) &&
        options->x_dropoff <= 0.0)
    {
@@ -636,8 +637,9 @@ BlastExtensionOptionsNew(EBlastProgramType program, BlastExtensionOptions* *opti
 	if (*options == NULL)
 		return BLASTERR_MEMORY;
 
-	if (program != eBlastTypeBlastn &&
-        program != eBlastTypePhiBlastn) /* protein-protein options. */
+	if (/* program != eBlastTypeBlastn &&
+           program != eBlastTypePhiBlastn*/
+        !Blast_ProgramIsNucleotide(program)) /* protein-protein options. */
 	{
 		(*options)->gap_x_dropoff = BLAST_GAP_X_DROPOFF_PROT;
 		(*options)->gap_x_dropoff_final = 
@@ -657,6 +659,8 @@ BlastExtensionOptionsNew(EBlastProgramType program, BlastExtensionOptions* *opti
         (*options)->compositionBasedStats = eCompositionBasedStats;
     }
 
+    (*options)->max_mismatches = 5;
+    (*options)->mismatch_window = 10;
     (*options)->program_number = program;
 
 	return 0;
@@ -670,7 +674,8 @@ BLAST_FillExtensionOptions(BlastExtensionOptions* options,
    if (!options)
       return BLASTERR_INVALIDPARAM;
 
-   if (program == eBlastTypeBlastn || program == eBlastTypePhiBlastn) {
+   if (/*program == eBlastTypeBlastn || program == eBlastTypePhiBlastn*/
+       Blast_ProgramIsNucleotide(program)) {
       if (greedy) {
          options->gap_x_dropoff = BLAST_GAP_X_DROPOFF_GREEDY;
          options->gap_x_dropoff_final = BLAST_GAP_X_DROPOFF_FINAL_NUCL;
@@ -711,6 +716,7 @@ BlastExtensionOptionsValidate(EBlastProgramType program_number,
 		return  BLASTERR_INVALIDPARAM;
 
 	if (program_number != eBlastTypeBlastn &&
+        program_number != eBlastTypeMapping &&
             (options->ePrelimGapExt == eGreedyScoreOnly ||
              options->eTbackExt == eGreedyTbck))
 	{
@@ -757,8 +763,9 @@ BlastScoringOptionsNew(EBlastProgramType program_number, BlastScoringOptions* *o
    if (*options == NULL)
       return BLASTERR_INVALIDPARAM;
    
-   if (program_number != eBlastTypeBlastn &&
-       program_number != eBlastTypePhiBlastn) {	/* protein-protein options. */
+   if (/*program_number != eBlastTypeBlastn &&
+         program_number != eBlastTypePhiBlastn*/
+       !Blast_ProgramIsNucleotide(program_number)) {/*protein-protein options.*/
       (*options)->shift_pen = INT2_MAX;
       (*options)->is_ooframe = FALSE;
       (*options)->gap_open = BLAST_GAP_OPEN_PROT;
@@ -791,8 +798,9 @@ BLAST_FillScoringOptions(BlastScoringOptions* options,
    if (!options)
       return BLASTERR_INVALIDPARAM;
 
-   if (program_number != eBlastTypeBlastn &&
-       program_number != eBlastTypePhiBlastn) {	/* protein-protein options. */
+   if (/*program_number != eBlastTypeBlastn &&
+         program_number != eBlastTypePhiBlastn*/
+       !Blast_ProgramIsNucleotide(program_number)) {/* protein-protein options. */
       /* If matrix name is not provided, keep the default "BLOSUM62" value filled in 
          BlastScoringOptionsNew, otherwise reset it. */
       if (matrix)
@@ -836,7 +844,8 @@ BlastScoringOptionsValidate(EBlastProgramType program_number,
 		return BLASTERR_OPTION_PROGRAM_INVALID;
         }
 
-	if (program_number == eBlastTypeBlastn || program_number == eBlastTypePhiBlastn)
+        if (/*program_number == eBlastTypeBlastn || program_number == eBlastTypePhiBlastn*/
+            Blast_ProgramIsNucleotide(program_number))
 	{
            // A penalty/reward of 0/0 is a signal that this is rmblastn
            // which allows specification of penalties as positive integers.
@@ -849,7 +858,10 @@ BlastScoringOptionsValidate(EBlastProgramType program_number,
 			return BLASTERR_OPTION_VALUE_INVALID;
 		}
 
-                if (options->gapped_calculation && !BLAST_CheckRewardPenaltyScores(options->reward, options->penalty))
+        /* !!! this is temporary until there is jumper or mapping options handle */
+        if (0 && options->gapped_calculation &&
+            !Blast_ProgramIsMapping(program_number) &&
+            !BLAST_CheckRewardPenaltyScores(options->reward, options->penalty))
                 {
 			Blast_MessageWrite(blast_msg, eBlastSevWarning, kBlastMessageNoContext,
                             "BLASTN reward/penalty combination not supported for gapped search");
@@ -1041,6 +1053,7 @@ LookupTableOptionsNew(EBlastProgramType program_number, LookupTableOptions* *opt
       return BLASTERR_INVALIDPARAM;
    
    switch (program_number) {
+   case eBlastTypeMapping:
    case eBlastTypeBlastn:
        /* Blastn default is megablast. */
        (*options)->word_size = BLAST_WORDSIZE_MEGABLAST;
@@ -1077,6 +1090,7 @@ LookupTableOptionsNew(EBlastProgramType program_number, LookupTableOptions* *opt
    }
 
    (*options)->program_number = program_number;
+   (*options)->stride = 0;
 
    return 0;
 }
@@ -1090,6 +1104,7 @@ BLAST_FillLookupTableOptions(LookupTableOptions* options,
       return BLASTERR_INVALIDPARAM;
 
    if (program_number == eBlastTypeBlastn) {
+
       if (is_megablast)	{
          options->lut_type = eMBLookupTable;
          options->word_size = BLAST_WORDSIZE_MEGABLAST;
@@ -1097,6 +1112,9 @@ BLAST_FillLookupTableOptions(LookupTableOptions* options,
          options->lut_type = eNaLookupTable;
          options->word_size = BLAST_WORDSIZE_NUCL;
       }
+   } else if (program_number == eBlastTypeMapping) {
+       options->lut_type = eNaHashLookupTable;
+       options->word_size = BLAST_WORDSIZE_MAPPER;
    } else {
       options->lut_type = eAaLookupTable;
    }
@@ -1127,7 +1145,8 @@ Int2 BLAST_GetSuggestedThreshold(EBlastProgramType program_number, const char* m
 
     const double kB62_threshold = 11;
 
-    if (program_number == eBlastTypeBlastn)
+    if (program_number == eBlastTypeBlastn ||
+        program_number == eBlastTypeMapping)
       return 0;
 
     if (matrixName == NULL)
@@ -1162,7 +1181,8 @@ Int2 BLAST_GetSuggestedWindowSize(EBlastProgramType program_number, const char*
 {
     const Int4 kB62_windowsize = 40;
 
-    if (program_number == eBlastTypeBlastn)
+    if (program_number == eBlastTypeBlastn ||
+        program_number == eBlastTypeMapping)
       return 0;
 
     if (matrixName == NULL)
@@ -1250,6 +1270,7 @@ LookupTableOptionsValidate(EBlastProgramType program_number,
         return 0;
 
     if (program_number != eBlastTypeBlastn && 
+        program_number != eBlastTypeMapping &&
         (!Blast_ProgramIsRpsBlast(program_number)) &&
         options->threshold <= 0)
     {
@@ -1265,12 +1286,15 @@ LookupTableOptionsValidate(EBlastProgramType program_number,
                                      "Word-size must be greater than zero");
             return BLASTERR_OPTION_VALUE_INVALID;
         }
-    } else if (program_number == eBlastTypeBlastn && options->word_size < 4)
+    } else if (/*program_number == eBlastTypeBlastn*/
+               Blast_ProgramIsNucleotide(program_number) &&
+               !Blast_QueryIsPattern(program_number) && options->word_size < 4)
     {
         Blast_MessageWrite(blast_msg, eBlastSevError, kBlastMessageNoContext, 
                   "Word-size must be 4 or greater for nucleotide comparison");
         return BLASTERR_OPTION_VALUE_INVALID;
-    } else if (program_number != eBlastTypeBlastn && options->word_size > 5)
+    } else if (program_number != eBlastTypeBlastn &&
+               program_number != eBlastTypeMapping && options->word_size > 5)
     {
         if (program_number == eBlastTypeBlastp ||
             program_number == eBlastTypeTblastn ||
@@ -1293,7 +1317,8 @@ LookupTableOptionsValidate(EBlastProgramType program_number,
         }
     }
 
-    if (program_number != eBlastTypeBlastn && 
+    if (program_number != eBlastTypeBlastn &&
+        program_number != eBlastTypeMapping &&
        options->lut_type == eMBLookupTable)
     {
         Blast_MessageWrite(blast_msg, eBlastSevError, kBlastMessageNoContext,
@@ -1323,7 +1348,10 @@ LookupTableOptionsValidate(EBlastProgramType program_number,
         }
     }
 
-   if (program_number == eBlastTypeBlastn && options->mb_template_length > 0) {
+    if (/*program_number == eBlastTypeBlastn &&*/
+        Blast_ProgramIsNucleotide(program_number) &&
+        !Blast_QueryIsPattern(program_number) &&
+        options->mb_template_length > 0) {
       if (!s_DiscWordOptionsValidate(options->word_size,
               options->mb_template_length, 
               options->mb_template_type,
@@ -1335,6 +1363,21 @@ LookupTableOptionsValidate(EBlastProgramType program_number,
          return BLASTERR_OPTION_VALUE_INVALID;
       } 
    }
+
+   if (!Blast_ProgramIsNucleotide(program_number) && options->db_filter) {
+       Blast_MessageWrite(blast_msg, eBlastSevError, kBlastMessageNoContext,
+                          "The limit_lookup option can only be used for "
+                          "nucleotide searches");
+       return BLASTERR_OPTION_VALUE_INVALID;
+   }
+
+   if (options->db_filter && options->word_size < BLAST_WORDSIZE_MAPPER) {
+       Blast_MessageWrite(blast_msg, eBlastSevError, kBlastMessageNoContext,
+                          "The limit_lookup option can only be used with "
+                          "word size >= 16");
+       return BLASTERR_OPTION_VALUE_INVALID;
+   }
+
     return 0;
 }
 
@@ -1431,7 +1474,8 @@ BlastHitSavingOptionsValidate(EBlastProgramType program_number,
    if (options->longest_intron != 0 &&
        program_number != eBlastTypeTblastn &&
        program_number != eBlastTypePsiTblastn &&
-       program_number != eBlastTypeBlastx) {
+       program_number != eBlastTypeBlastx &&
+       program_number != eBlastTypeMapping) {
                 Blast_MessageWrite(blast_msg, eBlastSevError, kBlastMessageNoContext,
          "Uneven gap linking of HSPs is allowed for blastx, "
          "tblastn, and psitblastn only");
@@ -1605,32 +1649,45 @@ static Int2 s_BlastExtensionScoringOptionsValidate(EBlastProgramType program_num
     {
         if (score_options->gap_open == 0 && score_options->gap_extend == 0)
         {
-	    if (ext_options->ePrelimGapExt != eGreedyScoreOnly && 
+            if (ext_options->ePrelimGapExt != eGreedyScoreOnly && 
                 ext_options->eTbackExt != eGreedyTbck)
-	    {
-			Blast_MessageWrite(blast_msg, eBlastSevWarning, kBlastMessageNoContext,
-                            "Greedy extension must be used if gap existence and extension options are zero");
-			return BLASTERR_OPTION_VALUE_INVALID;
-	    }
-	}
+                {
+                    Blast_MessageWrite(blast_msg, eBlastSevWarning,
+                                       kBlastMessageNoContext,
+                                       "Greedy extension must be used if gap existence and extension options are zero");
+                    return BLASTERR_OPTION_VALUE_INVALID;
+                }
+        }
+    }
+
+    if (program_number == eBlastTypeMapping) {
+        if (ext_options->ePrelimGapExt != eJumperWithTraceback) {
+
+            Blast_MessageWrite(blast_msg, eBlastSevWarning,
+                               kBlastMessageNoContext,
+                               "Jumper extension must be used for mapping");
+
+            return BLASTERR_OPTION_VALUE_INVALID;
+        }
     }
 
     if (ext_options->compositionBasedStats != eNoCompositionBasedStats)
     {
-            if (!Blast_QueryIsPssm(program_number) && program_number != eBlastTypeTblastn && 
-                 program_number != eBlastTypeBlastp &&
-                 program_number != eBlastTypeBlastx &&
-                 program_number != eBlastTypeRpsBlast &&
-                 program_number != eBlastTypePsiBlast) {
+        if (!Blast_QueryIsPssm(program_number) && program_number != eBlastTypeTblastn && 
+            program_number != eBlastTypeBlastp &&
+            program_number != eBlastTypeBlastx &&
+            program_number != eBlastTypeRpsBlast &&
+            program_number != eBlastTypeRpsTblastn &&
+            program_number != eBlastTypePsiBlast) {
 			Blast_MessageWrite(blast_msg, eBlastSevWarning, kBlastMessageNoContext,
                             "Compositional adjustments are only supported with blastp, blastx, or tblastn");
 			return BLASTERR_OPTION_VALUE_INVALID;
-            }
-            if (!score_options->gapped_calculation) {
+        }
+        if (!score_options->gapped_calculation) {
 			Blast_MessageWrite(blast_msg, eBlastSevWarning, kBlastMessageNoContext,
                             "Compositional adjustments are only supported for gapped searches");
 			return BLASTERR_OPTION_VALUE_INVALID;
-            }
+        }
             
     }
 
@@ -1824,7 +1881,6 @@ BlastHSPFilteringOptionsValidate(const BlastHSPFilteringOptions* opts)
     if ((opts->culling_stage & ePrelimSearch) && writer_found) {
         return 1;
     }
-    writer_found = (opts->culling_stage & ePrelimSearch ? TRUE : FALSE);
 
     return retval;
 }
diff --git a/c++/src/algo/blast/core/blast_parameters.c b/c++/src/algo/blast/core/blast_parameters.c
index cf87835..360c31d 100644
--- a/c++/src/algo/blast/core/blast_parameters.c
+++ b/c++/src/algo/blast/core/blast_parameters.c
@@ -1,4 +1,4 @@
-/* $Id: blast_parameters.c 416177 2013-10-24 14:58:42Z camacho $
+/* $Id: blast_parameters.c 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -28,11 +28,6 @@
  * Definitions for functions dealing with BLAST CORE parameter structures.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_parameters.c 416177 2013-10-24 14:58:42Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_parameters.h>
 #include <algo/blast/core/ncbi_math.h>
 #include <algo/blast/core/blast_nalookup.h>
@@ -137,6 +132,7 @@ static double
 s_GetCutoffEvalue(EBlastProgramType program)
 {
    switch(program) {
+   case eBlastTypeMapping:
    case eBlastTypeBlastn:
       return CUTOFF_E_BLASTN;
    case eBlastTypeBlastp: 
@@ -224,9 +220,10 @@ BlastInitialWordParametersNew(EBlastProgramType program_number,
       }
    }
 
-   if (program_number == eBlastTypeBlastn &&
-      (query_info->contexts[query_info->last_context].query_offset +
-            query_info->contexts[query_info->last_context].query_length) > kQueryLenForHashTable)
+   if (Blast_ProgramIsNucleotide(program_number) &&
+       !Blast_QueryIsPattern(program_number) &&
+       (query_info->contexts[query_info->last_context].query_offset +
+        query_info->contexts[query_info->last_context].query_length) > kQueryLenForHashTable)
        p->container_type = eDiagHash;
    else
        p->container_type = eDiagArray;
@@ -234,7 +231,7 @@ BlastInitialWordParametersNew(EBlastProgramType program_number,
    status = BlastInitialWordParametersUpdate(program_number,
                hit_params, sbp, query_info, subject_length, p);
 
-   if (program_number == eBlastTypeBlastn) {
+   if (program_number == eBlastTypeBlastn || program_number == eBlastTypeMapping) {
       Int4 i;
       Int4 reward = sbp->reward;
       Int4 penalty = sbp->penalty;
@@ -352,7 +349,8 @@ BlastInitialWordParametersUpdate(EBlastProgramType program_number,
 
          /* include the length of reverse complement for blastn searchs. */
          ASSERT(query_length > 0);
-         if (program_number == eBlastTypeBlastn)
+         if (program_number == eBlastTypeBlastn ||
+             program_number == eBlastTypeMapping)
             query_length *= 2;
       
          kbp = kbp_array[context];
@@ -407,7 +405,8 @@ BlastInitialWordParametersUpdate(EBlastProgramType program_number,
 
       /* Nucleotide searches first compute an approximate ungapped
          alignment and compare it to a reduced ungapped cutoff score */
-      if (program_number == eBlastTypeBlastn) {
+      if (program_number == eBlastTypeBlastn ||
+          program_number == eBlastTypeMapping) {
          curr_cutoffs->reduced_nucl_cutoff_score = (Int4)(0.8 * new_cutoff);
       }
    }
@@ -863,7 +862,8 @@ BlastHitSavingParametersUpdate(EBlastProgramType program_number,
     params->prelim_evalue = options->expect_value;  /* evalue and prelim_evalue same if no CBS. */
 
    // Set masklevel parameter -RMH-
-   if ( program_number == eBlastTypeBlastn && options->mask_level >= 0 )
+    if ((program_number == eBlastTypeBlastn ||
+         program_number == eBlastTypeMapping) && options->mask_level >= 0 )
      params->mask_level = options->mask_level;
 
    /* Calculate cutoffs based on effective length information */
diff --git a/c++/src/algo/blast/core/blast_posit.c b/c++/src/algo/blast/core/blast_posit.c
index 00d587e..bc46f78 100644
--- a/c++/src/algo/blast/core/blast_posit.c
+++ b/c++/src/algo/blast/core/blast_posit.c
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_posit.c 99676 2007-03-05 20:41:55Z kazimird $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/core/blast_program.c b/c++/src/algo/blast/core/blast_program.c
index 303e493..57b2465 100644
--- a/c++/src/algo/blast/core/blast_program.c
+++ b/c++/src/algo/blast/core/blast_program.c
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_program.c 97157 2007-01-19 14:27:24Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -77,6 +73,17 @@ Boolean Blast_ProgramIsPhiBlast(EBlastProgramType p)
 Boolean Blast_ProgramIsRpsBlast(EBlastProgramType p)
 { return SAFE_CAST_INT_TO_BOOLEAN(p & PSSM_SUBJECT_MASK); }
 
+Boolean Blast_ProgramIsMapping(EBlastProgramType p)
+{ return SAFE_CAST_INT_TO_BOOLEAN(p & MAPPING_MASK); }
+
+Boolean Blast_QueryIsPattern(EBlastProgramType p)
+{ return SAFE_CAST_INT_TO_BOOLEAN(p & PATTERN_QUERY_MASK); }
+
+Boolean Blast_ProgramIsNucleotide(EBlastProgramType p)
+{ return Blast_QueryIsNucleotide(p) && Blast_SubjectIsNucleotide(p) &&
+        !Blast_QueryIsTranslated(p) && !Blast_SubjectIsTranslated(p);}
+
+
 Boolean Blast_ProgramIsValid(EBlastProgramType p)
 {
     switch (p) {
@@ -91,6 +98,7 @@ Boolean Blast_ProgramIsValid(EBlastProgramType p)
     case eBlastTypeRpsTblastn:
     case eBlastTypePhiBlastp:
     case eBlastTypePhiBlastn:
+    case eBlastTypeMapping:
         return TRUE;
         break;
     default:
diff --git a/c++/src/algo/blast/core/blast_psi.c b/c++/src/algo/blast/core/blast_psi.c
index 591f175..58dd59a 100644
--- a/c++/src/algo/blast/core/blast_psi.c
+++ b/c++/src/algo/blast/core/blast_psi.c
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_psi.c 459883 2015-02-23 16:45:34Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/core/blast_psi_priv.c b/c++/src/algo/blast/core/blast_psi_priv.c
index 080bd4a..9be43c4 100644
--- a/c++/src/algo/blast/core/blast_psi_priv.c
+++ b/c++/src/algo/blast/core/blast_psi_priv.c
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_psi_priv.c 464171 2015-04-06 17:39:26Z boratyng $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/core/blast_query_info.c b/c++/src/algo/blast/core/blast_query_info.c
index 7f05de9..cfe5a13 100644
--- a/c++/src/algo/blast/core/blast_query_info.c
+++ b/c++/src/algo/blast/core/blast_query_info.c
@@ -1,4 +1,4 @@
-/* $Id: blast_query_info.c 419225 2013-11-22 17:08:29Z camacho $
+/* $Id: blast_query_info.c 517499 2016-10-25 17:20:41Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  */
 
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_query_info.c 419225 2013-11-22 17:08:29Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_util.h>
 #include <algo/blast/core/blast_query_info.h>
 #include <algo/blast/core/pattern.h>
@@ -97,6 +92,10 @@ BlastQueryInfo* BlastQueryInfoNew(EBlastProgramType program, int num_queries)
             ASSERT(retval->contexts[i].frame != INT1_MAX);
 
             retval->contexts[i].is_valid = TRUE;
+
+            if (Blast_ProgramIsMapping(program)) {
+                retval->contexts[i].segment_flags = eNoSegments;
+            }
         }
     }
 
@@ -170,7 +169,7 @@ Int4 BlastQueryInfoGetQueryLength(const BlastQueryInfo* qinfo,
 
     if (Blast_QueryIsTranslated(program)) {
         return s_GetTranslatedQueryDNALength(qinfo, query_index);
-    } else if (program == eBlastTypeBlastn) {
+    } else if (program == eBlastTypeBlastn || program == eBlastTypeMapping) {
         Int4 retval = qinfo->contexts[query_index*kNumContexts].query_length;
         if (retval <= 0) {
             retval = qinfo->contexts[query_index*kNumContexts+1].query_length;
@@ -222,9 +221,17 @@ Int4 BSearchContextInfo(Int4 n, const BlastQueryInfo * A)
     Int4 m=0, b=0, e=0, size=0;
     
     size = A->last_context+1;
-    
-    b = 0;
-    e = size;
+
+    if (A->min_length > 0 && A->max_length > 0 && A->first_context == 0) {
+        b = MIN(n / (A->max_length + 1), size - 1);
+        e = MIN(n / (A->min_length + 1) + 1, size);
+        ASSERT(e <= size);
+    }
+    else {
+        b = 0;
+        e = size;
+    }
+
     while (b < e - 1) {
 	m = (b + e) / 2;
 	if (A->contexts[m].query_offset > n)
diff --git a/c++/src/algo/blast/core/blast_seg.c b/c++/src/algo/blast/core/blast_seg.c
index f83223b..b8229fd 100644
--- a/c++/src/algo/blast/core/blast_seg.c
+++ b/c++/src/algo/blast/core/blast_seg.c
@@ -1,25 +1,25 @@
-/* $Id: blast_seg.c 473564 2015-07-21 15:29:04Z madden $
+/* $Id: blast_seg.c 510159 2016-08-11 11:28:47Z ivanov $
  * ===========================================================================
  *
- *                            PUBLIC DOMAIN NOTICE                          
+ *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
- *                                                                          
- *  This software/database is a "United States Government Work" under the   
- *  terms of the United States Copyright Act.  It was written as part of    
- *  the author's official duties as a United States Government employee and 
- *  thus cannot be copyrighted.  This software/database is freely available 
- *  to the public for use. The National Library of Medicine and the U.S.    
- *  Government have not placed any restriction on its use or reproduction.  
- *                                                                          
- *  Although all reasonable efforts have been taken to ensure the accuracy  
- *  and reliability of the software and data, the NLM and the U.S.          
- *  Government do not and cannot warrant the performance or results that    
- *  may be obtained by using this software or data. The NLM and the U.S.    
- *  Government disclaim all warranties, express or implied, including       
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
  *  warranties of performance, merchantability or fitness for any particular
- *  purpose.                                                                
- *                                                                          
- *  Please cite the author in any work or product based on this material.   
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
  *
  * ===========================================================================
  *
@@ -28,21 +28,18 @@
  */
 
 /** @file blast_seg.c
- * A utility to find low complexity AA regions. This parallels functionality 
- * of seg.c from the C toolkit, but without using the structures generated 
+ * A utility to find low complexity AA regions. This parallels functionality
+ * of seg.c from the C toolkit, but without using the structures generated
  * from ASN.1 spec.
  * @todo FIXME needs comments
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_seg.c 473564 2015-07-21 15:29:04Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_seg.h>
 #include <algo/blast/core/ncbi_math.h>
 #include <algo/blast/core/blast_filter.h>
 
+#include <algo/blast/core/blast_util.h>
+
 
 /** Declared in blast_def.h. */
 const int kSegWindow = 12;
@@ -50,1268 +47,1268 @@ const double kSegLocut = 2.2;
 const double kSegHicut = 2.5;
 
 /** Natural log of factorials: 0!, 1!, 2!, 3! */
-double lnfact[] = 
+double lnfact[] =
   {
-   0.000000, 0.000000, 0.693147, 1.791759, 3.178054, 4.787492, 6.579251, 8.525161, 
-   10.604603, 12.801827, 15.104413, 17.502308, 19.987214, 22.552164, 25.191221, 27.899271, 
-   30.671860, 33.505073, 36.395445, 39.339884, 42.335616, 45.380139, 48.471181, 51.606676, 
-   54.784729, 58.003605, 61.261702, 64.557539, 67.889743, 71.257039, 74.658236, 78.092224, 
-   81.557959, 85.054467, 88.580828, 92.136176, 95.719695, 99.330612, 102.968199, 106.631760, 
-   110.320640, 114.034212, 117.771881, 121.533082, 125.317271, 129.123934, 132.952575, 136.802723, 
-   140.673924, 144.565744, 148.477767, 152.409593, 156.360836, 160.331128, 164.320112, 168.327445, 
-   172.352797, 176.395848, 180.456291, 184.533829, 188.628173, 192.739047, 196.866182, 201.009316, 
-   205.168199, 209.342587, 213.532241, 217.736934, 221.956442, 226.190548, 230.439044, 234.701723, 
-   238.978390, 243.268849, 247.572914, 251.890402, 256.221136, 260.564941, 264.921650, 269.291098, 
-   273.673124, 278.067573, 282.474293, 286.893133, 291.323950, 295.766601, 300.220949, 304.686857, 
-   309.164194, 313.652830, 318.152640, 322.663499, 327.185288, 331.717887, 336.261182, 340.815059, 
-   345.379407, 349.954118, 354.539086, 359.134205, 363.739376, 368.354496, 372.979469, 377.614198, 
-   382.258589, 386.912549, 391.575988, 396.248817, 400.930948, 405.622296, 410.322777, 415.032307, 
-   419.750806, 424.478193, 429.214392, 433.959324, 438.712914, 443.475088, 448.245773, 453.024896, 
-   457.812388, 462.608179, 467.412200, 472.224384, 477.044665, 481.872979, 486.709261, 491.553448, 
-   496.405478, 501.265291, 506.132825, 511.008023, 515.890825, 520.781174, 525.679014, 530.584288, 
-   535.496943, 540.416924, 545.344178, 550.278652, 555.220294, 560.169054, 565.124881, 570.087726, 
-   575.057539, 580.034273, 585.017879, 590.008312, 595.005524, 600.009471, 605.020106, 610.037386, 
-   615.061266, 620.091704, 625.128657, 630.172082, 635.221938, 640.278184, 645.340779, 650.409683, 
-   655.484857, 660.566261, 665.653857, 670.747608, 675.847474, 680.953420, 686.065407, 691.183401, 
-   696.307365, 701.437264, 706.573062, 711.714726, 716.862220, 722.015512, 727.174567, 732.339353, 
-   737.509837, 742.685987, 747.867770, 753.055156, 758.248113, 763.446610, 768.650617, 773.860103, 
-   779.075039, 784.295395, 789.521141, 794.752250, 799.988692, 805.230439, 810.477463, 815.729736, 
-   820.987232, 826.249922, 831.517780, 836.790780, 842.068894, 847.352098, 852.640365, 857.933670, 
-   863.231987, 868.535292, 873.843560, 879.156766, 884.474886, 889.797896, 895.125772, 900.458491, 
-   905.796029, 911.138363, 916.485471, 921.837329, 927.193915, 932.555207, 937.921183, 943.291821, 
-   948.667100, 954.046997, 959.431492, 964.820564, 970.214191, 975.612354, 981.015031, 986.422203, 
-   991.833849, 997.249950, 1002.670485, 1008.095435, 1013.524780, 1018.958502, 1024.396582, 1029.838999, 
-   1035.285737, 1040.736775, 1046.192096, 1051.651682, 1057.115514, 1062.583574, 1068.055844, 1073.532308, 
-   1079.012947, 1084.497744, 1089.986681, 1095.479743, 1100.976911, 1106.478169, 1111.983501, 1117.492889, 
-   1123.006318, 1128.523771, 1134.045232, 1139.570685, 1145.100114, 1150.633503, 1156.170838, 1161.712101, 
-   1167.257279, 1172.806355, 1178.359314, 1183.916142, 1189.476824, 1195.041344, 1200.609689, 1206.181843, 
-   1211.757792, 1217.337522, 1222.921018, 1228.508267, 1234.099254, 1239.693965, 1245.292387, 1250.894506, 
-   1256.500308, 1262.109780, 1267.722908, 1273.339679, 1278.960080, 1284.584097, 1290.211718, 1295.842930, 
-   1301.477720, 1307.116075, 1312.757982, 1318.403428, 1324.052403, 1329.704892, 1335.360884, 1341.020366, 
-   1346.683326, 1352.349753, 1358.019634, 1363.692957, 1369.369711, 1375.049884, 1380.733463, 1386.420439, 
-   1392.110798, 1397.804530, 1403.501624, 1409.202067, 1414.905850, 1420.612960, 1426.323387, 1432.037120, 
-   1437.754148, 1443.474460, 1449.198045, 1454.924892, 1460.654992, 1466.388333, 1472.124906, 1477.864699, 
-   1483.607702, 1489.353905, 1495.103298, 1500.855871, 1506.611613, 1512.370515, 1518.132566, 1523.897757, 
-   1529.666078, 1535.437519, 1541.212071, 1546.989723, 1552.770467, 1558.554292, 1564.341189, 1570.131149, 
-   1575.924163, 1581.720221, 1587.519313, 1593.321432, 1599.126567, 1604.934709, 1610.745850, 1616.559981, 
-   1622.377092, 1628.197175, 1634.020221, 1639.846221, 1645.675166, 1651.507049, 1657.341860, 1663.179590, 
-   1669.020232, 1674.863776, 1680.710215, 1686.559540, 1692.411742, 1698.266814, 1704.124747, 1709.985533, 
-   1715.849165, 1721.715633, 1727.584930, 1733.457047, 1739.331978, 1745.209714, 1751.090247, 1756.973569, 
-   1762.859673, 1768.748551, 1774.640196, 1780.534598, 1786.431752, 1792.331650, 1798.234283, 1804.139645, 
-   1810.047728, 1815.958524, 1821.872027, 1827.788229, 1833.707123, 1839.628702, 1845.552957, 1851.479884, 
-   1857.409473, 1863.341718, 1869.276612, 1875.214148, 1881.154319, 1887.097119, 1893.042539, 1898.990574, 
-   1904.941217, 1910.894460, 1916.850298, 1922.808722, 1928.769728, 1934.733307, 1940.699454, 1946.668161, 
-   1952.639423, 1958.613233, 1964.589584, 1970.568470, 1976.549884, 1982.533820, 1988.520272, 1994.509233, 
-   2000.500698, 2006.494659, 2012.491111, 2018.490048, 2024.491463, 2030.495350, 2036.501703, 2042.510516, 
-   2048.521784, 2054.535499, 2060.551656, 2066.570249, 2072.591272, 2078.614720, 2084.640586, 2090.668864, 
-   2096.699550, 2102.732636, 2108.768117, 2114.805988, 2120.846243, 2126.888876, 2132.933881, 2138.981253, 
-   2145.030987, 2151.083076, 2157.137515, 2163.194299, 2169.253423, 2175.314879, 2181.378665, 2187.444773, 
-   2193.513198, 2199.583936, 2205.656981, 2211.732327, 2217.809969, 2223.889902, 2229.972121, 2236.056620, 
-   2242.143395, 2248.232440, 2254.323750, 2260.417320, 2266.513144, 2272.611219, 2278.711537, 2284.814096, 
-   2290.918889, 2297.025912, 2303.135160, 2309.246627, 2315.360309, 2321.476201, 2327.594299, 2333.714596, 
-   2339.837089, 2345.961772, 2352.088641, 2358.217692, 2364.348918, 2370.482316, 2376.617881, 2382.755608, 
-   2388.895493, 2395.037530, 2401.181716, 2407.328045, 2413.476513, 2419.627116, 2425.779849, 2431.934707, 
-   2438.091686, 2444.250781, 2450.411988, 2456.575303, 2462.740721, 2468.908238, 2475.077848, 2481.249549, 
-   2487.423335, 2493.599202, 2499.777146, 2505.957163, 2512.139248, 2518.323397, 2524.509606, 2530.697870, 
-   2536.888185, 2543.080548, 2549.274953, 2555.471397, 2561.669876, 2567.870385, 2574.072920, 2580.277478, 
-   2586.484054, 2592.692644, 2598.903244, 2605.115850, 2611.330458, 2617.547065, 2623.765665, 2629.986255, 
-   2636.208831, 2642.433390, 2648.659926, 2654.888437, 2661.118919, 2667.351367, 2673.585777, 2679.822147, 
-   2686.060472, 2692.300747, 2698.542971, 2704.787138, 2711.033244, 2717.281287, 2723.531263, 2729.783166, 
-   2736.036995, 2742.292745, 2748.550413, 2754.809994, 2761.071486, 2767.334884, 2773.600185, 2779.867386, 
-   2786.136482, 2792.407471, 2798.680348, 2804.955110, 2811.231753, 2817.510275, 2823.790671, 2830.072937, 
-   2836.357071, 2842.643070, 2848.930928, 2855.220644, 2861.512213, 2867.805632, 2874.100898, 2880.398007, 
-   2886.696957, 2892.997742, 2899.300361, 2905.604810, 2911.911085, 2918.219184, 2924.529102, 2930.840837, 
-   2937.154385, 2943.469743, 2949.786908, 2956.105876, 2962.426644, 2968.749209, 2975.073568, 2981.399718, 
-   2987.727655, 2994.057376, 3000.388877, 3006.722157, 3013.057211, 3019.394037, 3025.732631, 3032.072990, 
-   3038.415112, 3044.758992, 3051.104629, 3057.452018, 3063.801157, 3070.152043, 3076.504672, 3082.859042, 
-   3089.215150, 3095.572992, 3101.932566, 3108.293868, 3114.656896, 3121.021647, 3127.388118, 3133.756305, 
-   3140.126206, 3146.497818, 3152.871137, 3159.246162, 3165.622889, 3172.001315, 3178.381438, 3184.763254, 
-   3191.146760, 3197.531955, 3203.918834, 3210.307396, 3216.697636, 3223.089553, 3229.483144, 3235.878406, 
-   3242.275335, 3248.673930, 3255.074188, 3261.476105, 3267.879679, 3274.284908, 3280.691788, 3287.100316, 
-   3293.510491, 3299.922310, 3306.335768, 3312.750865, 3319.167598, 3325.585963, 3332.005958, 3338.427580, 
-   3344.850827, 3351.275696, 3357.702184, 3364.130290, 3370.560009, 3376.991340, 3383.424280, 3389.858827, 
-   3396.294977, 3402.732729, 3409.172079, 3415.613026, 3422.055566, 3428.499697, 3434.945417, 3441.392723, 
-   3447.841612, 3454.292083, 3460.744132, 3467.197757, 3473.652955, 3480.109725, 3486.568063, 3493.027968, 
-   3499.489436, 3505.952465, 3512.417053, 3518.883198, 3525.350897, 3531.820147, 3538.290947, 3544.763293, 
-   3551.237184, 3557.712616, 3564.189589, 3570.668098, 3577.148143, 3583.629720, 3590.112827, 3596.597463, 
-   3603.083624, 3609.571308, 3616.060512, 3622.551236, 3629.043476, 3635.537230, 3642.032495, 3648.529270, 
-   3655.027552, 3661.527339, 3668.028629, 3674.531419, 3681.035707, 3687.541491, 3694.048769, 3700.557538, 
-   3707.067797, 3713.579542, 3720.092772, 3726.607485, 3733.123678, 3739.641349, 3746.160496, 3752.681117, 
-   3759.203210, 3765.726773, 3772.251802, 3778.778297, 3785.306255, 3791.835674, 3798.366551, 3804.898886, 
-   3811.432675, 3817.967916, 3824.504607, 3831.042747, 3837.582333, 3844.123363, 3850.665835, 3857.209747, 
-   3863.755097, 3870.301882, 3876.850101, 3883.399752, 3889.950832, 3896.503340, 3903.057274, 3909.612630, 
-   3916.169409, 3922.727607, 3929.287222, 3935.848253, 3942.410697, 3948.974552, 3955.539817, 3962.106490, 
-   3968.674567, 3975.244049, 3981.814932, 3988.387214, 3994.960895, 4001.535970, 4008.112440, 4014.690301, 
-   4021.269553, 4027.850192, 4034.432217, 4041.015626, 4047.600417, 4054.186589, 4060.774139, 4067.363066, 
-   4073.953367, 4080.545040, 4087.138085, 4093.732498, 4100.328279, 4106.925425, 4113.523934, 4120.123804, 
-   4126.725034, 4133.327622, 4139.931566, 4146.536864, 4153.143514, 4159.751515, 4166.360864, 4172.971560, 
-   4179.583601, 4186.196985, 4192.811711, 4199.427776, 4206.045179, 4212.663918, 4219.283991, 4225.905397, 
-   4232.528133, 4239.152198, 4245.777591, 4252.404308, 4259.032350, 4265.661713, 4272.292396, 4278.924398, 
-   4285.557717, 4292.192350, 4298.828297, 4305.465555, 4312.104122, 4318.743998, 4325.385180, 4332.027667, 
-   4338.671457, 4345.316548, 4351.962938, 4358.610627, 4365.259611, 4371.909890, 4378.561462, 4385.214325, 
-   4391.868478, 4398.523918, 4405.180645, 4411.838656, 4418.497950, 4425.158525, 4431.820380, 4438.483512, 
-   4445.147921, 4451.813605, 4458.480562, 4465.148790, 4471.818288, 4478.489054, 4485.161087, 4491.834385, 
-   4498.508947, 4505.184770, 4511.861853, 4518.540196, 4525.219795, 4531.900649, 4538.582758, 4545.266119, 
-   4551.950731, 4558.636592, 4565.323700, 4572.012055, 4578.701654, 4585.392497, 4592.084580, 4598.777904, 
-   4605.472466, 4612.168265, 4618.865299, 4625.563567, 4632.263068, 4638.963799, 4645.665759, 4652.368947, 
-   4659.073361, 4665.779001, 4672.485863, 4679.193947, 4685.903251, 4692.613774, 4699.325515, 4706.038471, 
-   4712.752642, 4719.468025, 4726.184620, 4732.902424, 4739.621438, 4746.341658, 4753.063083, 4759.785713, 
-   4766.509546, 4773.234579, 4779.960813, 4786.688244, 4793.416873, 4800.146697, 4806.877715, 4813.609926, 
-   4820.343328, 4827.077919, 4833.813700, 4840.550666, 4847.288819, 4854.028156, 4860.768675, 4867.510376, 
-   4874.253256, 4880.997315, 4887.742552, 4894.488964, 4901.236550, 4907.985310, 4914.735241, 4921.486343, 
-   4928.238613, 4934.992051, 4941.746655, 4948.502424, 4955.259356, 4962.017451, 4968.776706, 4975.537121, 
-   4982.298694, 4989.061423, 4995.825308, 5002.590347, 5009.356539, 5016.123882, 5022.892375, 5029.662017, 
-   5036.432806, 5043.204742, 5049.977822, 5056.752046, 5063.527412, 5070.303919, 5077.081566, 5083.860351, 
-   5090.640273, 5097.421330, 5104.203522, 5110.986848, 5117.771305, 5124.556892, 5131.343609, 5138.131454, 
-   5144.920426, 5151.710523, 5158.501745, 5165.294089, 5172.087555, 5178.882142, 5185.677848, 5192.474671, 
-   5199.272612, 5206.071668, 5212.871838, 5219.673121, 5226.475515, 5233.279021, 5240.083635, 5246.889358, 
-   5253.696187, 5260.504122, 5267.313161, 5274.123304, 5280.934548, 5287.746893, 5294.560338, 5301.374881, 
-   5308.190521, 5315.007257, 5321.825087, 5328.644011, 5335.464028, 5342.285135, 5349.107333, 5355.930619, 
-   5362.754992, 5369.580452, 5376.406998, 5383.234627, 5390.063339, 5396.893133, 5403.724007, 5410.555960, 
-   5417.388992, 5424.223101, 5431.058286, 5437.894545, 5444.731878, 5451.570283, 5458.409759, 5465.250306, 
-   5472.091921, 5478.934605, 5485.778355, 5492.623170, 5499.469050, 5506.315993, 5513.163998, 5520.013065, 
-   5526.863191, 5533.714376, 5540.566618, 5547.419917, 5554.274272, 5561.129681, 5567.986143, 5574.843657, 
-   5581.702222, 5588.561837, 5595.422500, 5602.284212, 5609.146970, 5616.010773, 5622.875621, 5629.741512, 
-   5636.608445, 5643.476419, 5650.345434, 5657.215487, 5664.086579, 5670.958707, 5677.831871, 5684.706069, 
-   5691.581301, 5698.457566, 5705.334862, 5712.213188, 5719.092544, 5725.972928, 5732.854339, 5739.736777, 
-   5746.620240, 5753.504726, 5760.390236, 5767.276768, 5774.164320, 5781.052893, 5787.942484, 5794.833093, 
-   5801.724719, 5808.617361, 5815.511017, 5822.405687, 5829.301370, 5836.198064, 5843.095769, 5849.994483, 
-   5856.894207, 5863.794937, 5870.696674, 5877.599417, 5884.503164, 5891.407915, 5898.313668, 5905.220423, 
-   5912.128178, 5919.036933, 5925.946687, 5932.857437, 5939.769185, 5946.681927, 5953.595665, 5960.510396, 
-   5967.426119, 5974.342834, 5981.260540, 5988.179235, 5995.098919, 6002.019590, 6008.941249, 6015.863892, 
-   6022.787521, 6029.712133, 6036.637729, 6043.564306, 6050.491864, 6057.420401, 6064.349918, 6071.280413, 
-   6078.211885, 6085.144333, 6092.077756, 6099.012153, 6105.947523, 6112.883866, 6119.821180, 6126.759465, 
-   6133.698719, 6140.638941, 6147.580131, 6154.522288, 6161.465410, 6168.409497, 6175.354548, 6182.300562, 
-   6189.247538, 6196.195476, 6203.144373, 6210.094229, 6217.045044, 6223.996816, 6230.949545, 6237.903229, 
-   6244.857868, 6251.813460, 6258.770006, 6265.727503, 6272.685952, 6279.645350, 6286.605698, 6293.566994, 
-   6300.529237, 6307.492427, 6314.456563, 6321.421643, 6328.387668, 6335.354635, 6342.322544, 6349.291394, 
-   6356.261185, 6363.231915, 6370.203584, 6377.176190, 6384.149733, 6391.124212, 6398.099626, 6405.075974, 
-   6412.053255, 6419.031469, 6426.010614, 6432.990690, 6439.971696, 6446.953631, 6453.936493, 6460.920283, 
-   6467.905000, 6474.890641, 6481.877208, 6488.864698, 6495.853111, 6502.842447, 6509.832703, 6516.823880, 
-   6523.815976, 6530.808991, 6537.802924, 6544.797774, 6551.793541, 6558.790222, 6565.787818, 6572.786328, 
-   6579.785750, 6586.786085, 6593.787330, 6600.789486, 6607.792552, 6614.796526, 6621.801408, 6628.807197, 
-   6635.813892, 6642.821493, 6649.829998, 6656.839407, 6663.849719, 6670.860933, 6677.873048, 6684.886064, 
-   6691.899979, 6698.914794, 6705.930506, 6712.947116, 6719.964622, 6726.983024, 6734.002320, 6741.022511, 
-   6748.043595, 6755.065571, 6762.088439, 6769.112198, 6776.136847, 6783.162386, 6790.188813, 6797.216127, 
-   6804.244328, 6811.273416, 6818.303389, 6825.334246, 6832.365988, 6839.398612, 6846.432118, 6853.466506, 
-   6860.501775, 6867.537923, 6874.574951, 6881.612857, 6888.651641, 6895.691301, 6902.731837, 6909.773249, 
-   6916.815535, 6923.858695, 6930.902728, 6937.947633, 6944.993410, 6952.040057, 6959.087574, 6966.135961, 
-   6973.185215, 6980.235338, 6987.286327, 6994.338183, 7001.390904, 7008.444490, 7015.498939, 7022.554252, 
-   7029.610428, 7036.667465, 7043.725362, 7050.784121, 7057.843738, 7064.904215, 7071.965549, 7079.027741, 
-   7086.090789, 7093.154693, 7100.219452, 7107.285065, 7114.351532, 7121.418852, 7128.487024, 7135.556047, 
-   7142.625922, 7149.696646, 7156.768219, 7163.840641, 7170.913911, 7177.988027, 7185.062991, 7192.138799, 
-   7199.215453, 7206.292951, 7213.371293, 7220.450477, 7227.530504, 7234.611372, 7241.693080, 7248.775629, 
-   7255.859017, 7262.943243, 7270.028307, 7277.114209, 7284.200947, 7291.288521, 7298.376929, 7305.466172, 
-   7312.556249, 7319.647159, 7326.738901, 7333.831475, 7340.924880, 7348.019114, 7355.114179, 7362.210072, 
-   7369.306793, 7376.404342, 7383.502718, 7390.601920, 7397.701947, 7404.802799, 7411.904475, 7419.006974, 
-   7426.110296, 7433.214440, 7440.319406, 7447.425192, 7454.531798, 7461.639223, 7468.747468, 7475.856530, 
-   7482.966409, 7490.077105, 7497.188617, 7504.300945, 7511.414087, 7518.528043, 7525.642812, 7532.758395, 
-   7539.874789, 7546.991994, 7554.110010, 7561.228837, 7568.348472, 7575.468917, 7582.590169, 7589.712229, 
-   7596.835096, 7603.958769, 7611.083247, 7618.208530, 7625.334617, 7632.461508, 7639.589202, 7646.717698, 
-   7653.846995, 7660.977094, 7668.107992, 7675.239691, 7682.372189, 7689.505485, 7696.639578, 7703.774469, 
-   7710.910156, 7718.046640, 7725.183918, 7732.321991, 7739.460858, 7746.600518, 7753.740971, 7760.882217, 
-   7768.024253, 7775.167081, 7782.310698, 7789.455105, 7796.600301, 7803.746286, 7810.893058, 7818.040617, 
-   7825.188963, 7832.338095, 7839.488012, 7846.638713, 7853.790199, 7860.942467, 7868.095519, 7875.249353, 
-   7882.403968, 7889.559364, 7896.715541, 7903.872497, 7911.030233, 7918.188747, 7925.348039, 7932.508108, 
-   7939.668954, 7946.830576, 7953.992973, 7961.156146, 7968.320093, 7975.484813, 7982.650306, 7989.816572, 
-   7996.983610, 8004.151419, 8011.319999, 8018.489349, 8025.659469, 8032.830357, 8040.002014, 8047.174439, 
-   8054.347631, 8061.521589, 8068.696313, 8075.871803, 8083.048057, 8090.225076, 8097.402859, 8104.581404, 
-   8111.760712, 8118.940782, 8126.121613, 8133.303205, 8140.485557, 8147.668669, 8154.852540, 8162.037169, 
-   8169.222556, 8176.408700, 8183.595601, 8190.783258, 8197.971671, 8205.160839, 8212.350761, 8219.541437, 
-   8226.732866, 8233.925048, 8241.117983, 8248.311668, 8255.506105, 8262.701293, 8269.897230, 8277.093916, 
-   8284.291352, 8291.489535, 8298.688466, 8305.888145, 8313.088570, 8320.289741, 8327.491657, 8334.694318, 
-   8341.897724, 8349.101873, 8356.306765, 8363.512401, 8370.718778, 8377.925897, 8385.133757, 8392.342357, 
-   8399.551697, 8406.761777, 8413.972595, 8421.184152, 8428.396447, 8435.609478, 8442.823246, 8450.037751, 
-   8457.252991, 8464.468966, 8471.685675, 8478.903119, 8486.121296, 8493.340205, 8500.559847, 8507.780221, 
-   8515.001326, 8522.223162, 8529.445728, 8536.669024, 8543.893049, 8551.117802, 8558.343284, 8565.569493, 
-   8572.796429, 8580.024091, 8587.252480, 8594.481593, 8601.711432, 8608.941995, 8616.173282, 8623.405293, 
-   8630.638026, 8637.871481, 8645.105658, 8652.340557, 8659.576176, 8666.812515, 8674.049574, 8681.287353, 
-   8688.525849, 8695.765064, 8703.004997, 8710.245647, 8717.487013, 8724.729095, 8731.971893, 8739.215406, 
-   8746.459634, 8753.704575, 8760.950230, 8768.196598, 8775.443679, 8782.691472, 8789.939976, 8797.189191, 
-   8804.439116, 8811.689752, 8818.941097, 8826.193151, 8833.445913, 8840.699383, 8847.953561, 8855.208446, 
-   8862.464037, 8869.720335, 8876.977337, 8884.235045, 8891.493457, 8898.752573, 8906.012393, 8913.272915, 
-   8920.534141, 8927.796068, 8935.058696, 8942.322026, 8949.586056, 8956.850786, 8964.116216, 8971.382345, 
-   8978.649172, 8985.916697, 8993.184920, 9000.453841, 9007.723457, 9014.993770, 9022.264779, 9029.536483, 
-   9036.808881, 9044.081973, 9051.355760, 9058.630239, 9065.905412, 9073.181276, 9080.457833, 9087.735080, 
-   9095.013019, 9102.291648, 9109.570967, 9116.850975, 9124.131672, 9131.413058, 9138.695132, 9145.977893, 
-   9153.261341, 9160.545476, 9167.830297, 9175.115803, 9182.401995, 9189.688871, 9196.976432, 9204.264676, 
-   9211.553604, 9218.843215, 9226.133507, 9233.424482, 9240.716138, 9248.008476, 9255.301493, 9262.595191, 
-   9269.889568, 9277.184625, 9284.480360, 9291.776773, 9299.073864, 9306.371632, 9313.670077, 9320.969199, 
-   9328.268996, 9335.569469, 9342.870617, 9350.172439, 9357.474936, 9364.778106, 9372.081949, 9379.386465, 
-   9386.691653, 9393.997513, 9401.304045, 9408.611247, 9415.919120, 9423.227662, 9430.536875, 9437.846756, 
-   9445.157306, 9452.468525, 9459.780411, 9467.092965, 9474.406185, 9481.720072, 9489.034625, 9496.349843, 
-   9503.665726, 9510.982275, 9518.299487, 9525.617363, 9532.935903, 9540.255105, 9547.574970, 9554.895497, 
-   9562.216686, 9569.538535, 9576.861046, 9584.184217, 9591.508047, 9598.832537, 9606.157686, 9613.483494, 
-   9620.809959, 9628.137082, 9635.464863, 9642.793300, 9650.122394, 9657.452144, 9664.782549, 9672.113609, 
-   9679.445324, 9686.777694, 9694.110717, 9701.444393, 9708.778722, 9716.113704, 9723.449338, 9730.785624, 
-   9738.122561, 9745.460148, 9752.798387, 9760.137275, 9767.476812, 9774.816999, 9782.157835, 9789.499319, 
-   9796.841450, 9804.184230, 9811.527656, 9818.871729, 9826.216448, 9833.561813, 9840.907823, 9848.254478, 
-   9855.601778, 9862.949721, 9870.298309, 9877.647540, 9884.997414, 9892.347930, 9899.699088, 9907.050888, 
-   9914.403329, 9921.756411, 9929.110133, 9936.464495, 9943.819497, 9951.175138, 9958.531418, 9965.888337, 
-   9973.245893, 9980.604087, 9987.962917, 9995.322385, 10002.682489, 10010.043229, 10017.404604, 10024.766615, 
-   10032.129260, 10039.492540, 10046.856453, 10054.221000, 10061.586180, 10068.951993, 10076.318438, 10083.685515, 
-   10091.053224, 10098.421564, 10105.790534, 10113.160135, 10120.530366, 10127.901226, 10135.272715, 10142.644833, 
-   10150.017579, 10157.390954, 10164.764956, 10172.139585, 10179.514840, 10186.890722, 10194.267231, 10201.644364, 
-   10209.022123, 10216.400507, 10223.779515, 10231.159147, 10238.539403, 10245.920282, 10253.301784, 10260.683908, 
-   10268.066655, 10275.450023, 10282.834012, 10290.218623, 10297.603854, 10304.989705, 10312.376176, 10319.763266, 
-   10327.150975, 10334.539303, 10341.928249, 10349.317813, 10356.707994, 10364.098793, 10371.490208, 10378.882240, 
-   10386.274887, 10393.668150, 10401.062029, 10408.456522, 10415.851629, 10423.247351, 10430.643686, 10438.040635, 
-   10445.438196, 10452.836370, 10460.235157, 10467.634555, 10475.034564, 10482.435185, 10489.836416, 10497.238258, 
-   10504.640709, 10512.043770, 10519.447441, 10526.851720, 10534.256607, 10541.662103, 10549.068206, 10556.474917, 
-   10563.882235, 10571.290159, 10578.698690, 10586.107826, 10593.517568, 10600.927915, 10608.338867, 10615.750423, 
-   10623.162584, 10630.575348, 10637.988715, 10645.402685, 10652.817258, 10660.232433, 10667.648210, 10675.064589, 
-   10682.481568, 10689.899149, 10697.317330, 10704.736111, 10712.155491, 10719.575471, 10726.996050, 10734.417227, 
-   10741.839003, 10749.261377, 10756.684348, 10764.107917, 10771.532082, 10778.956844, 10786.382202, 10793.808155, 
-   10801.234704, 10808.661848, 10816.089587, 10823.517920, 10830.946848, 10838.376369, 10845.806483, 10853.237190, 
-   10860.668489, 10868.100381, 10875.532865, 10882.965940, 10890.399607, 10897.833864, 10905.268712, 10912.704150, 
-   10920.140178, 10927.576795, 10935.014002, 10942.451797, 10949.890180, 10957.329152, 10964.768711, 10972.208858, 
-   10979.649592, 10987.090912, 10994.532819, 11001.975312, 11009.418390, 11016.862054, 11024.306302, 11031.751136, 
-   11039.196553, 11046.642555, 11054.089140, 11061.536308, 11068.984059, 11076.432393, 11083.881309, 11091.330807, 
-   11098.780887, 11106.231548, 11113.682789, 11121.134612, 11128.587014, 11136.039996, 11143.493558, 11150.947699, 
-   11158.402419, 11165.857718, 11173.313594, 11180.770049, 11188.227081, 11195.684690, 11203.142876, 11210.601639, 
-   11218.060978, 11225.520893, 11232.981383, 11240.442449, 11247.904089, 11255.366304, 11262.829093, 11270.292456, 
-   11277.756393, 11285.220903, 11292.685985, 11300.151641, 11307.617868, 11315.084668, 11322.552039, 11330.019981, 
-   11337.488494, 11344.957578, 11352.427232, 11359.897457, 11367.368250, 11374.839613, 11382.311546, 11389.784046, 
-   11397.257115, 11404.730752, 11412.204957, 11419.679729, 11427.155069, 11434.630975, 11442.107447, 11449.584486, 
-   11457.062090, 11464.540259, 11472.018994, 11479.498294, 11486.978158, 11494.458586, 11501.939579, 11509.421134, 
-   11516.903253, 11524.385935, 11531.869179, 11539.352986, 11546.837355, 11554.322285, 11561.807777, 11569.293829, 
-   11576.780443, 11584.267616, 11591.755350, 11599.243644, 11606.732496, 11614.221909, 11621.711879, 11629.202409, 
-   11636.693496, 11644.185142, 11651.677345, 11659.170105, 11666.663423, 11674.157296, 11681.651727, 11689.146713, 
-   11696.642255, 11704.138352, 11711.635005, 11719.132212, 11726.629974, 11734.128289, 11741.627159, 11749.126582, 
-   11756.626559, 11764.127088, 11771.628171, 11779.129805, 11786.631991, 11794.134730, 11801.638019, 11809.141860, 
-   11816.646252, 11824.151194, 11831.656686, 11839.162728, 11846.669320, 11854.176461, 11861.684151, 11869.192390, 
-   11876.701177, 11884.210512, 11891.720395, 11899.230826, 11906.741804, 11914.253328, 11921.765400, 11929.278017, 
-   11936.791181, 11944.304890, 11951.819145, 11959.333944, 11966.849289, 11974.365178, 11981.881611, 11989.398589, 
-   11996.916109, 12004.434174, 12011.952781, 12019.471931, 12026.991623, 12034.511858, 12042.032634, 12049.553952, 
-   12057.075811, 12064.598212, 12072.121152, 12079.644634, 12087.168655, 12094.693216, 12102.218317, 12109.743957, 
-   12117.270136, 12124.796854, 12132.324110, 12139.851904, 12147.380235, 12154.909105, 12162.438511, 12169.968454, 
-   12177.498934, 12185.029951, 12192.561503, 12200.093591, 12207.626215, 12215.159374, 12222.693067, 12230.227296, 
-   12237.762058, 12245.297355, 12252.833186, 12260.369549, 12267.906447, 12275.443877, 12282.981839, 12290.520334, 
-   12298.059361, 12305.598920, 12313.139010, 12320.679632, 12328.220784, 12335.762468, 12343.304681, 12350.847425, 
-   12358.390698, 12365.934501, 12373.478833, 12381.023694, 12388.569084, 12396.115002, 12403.661448, 12411.208422, 
-   12418.755924, 12426.303953, 12433.852509, 12441.401592, 12448.951201, 12456.501336, 12464.051997, 12471.603184, 
-   12479.154896, 12486.707134, 12494.259896, 12501.813182, 12509.366993, 12516.921328, 12524.476187, 12532.031569, 
-   12539.587474, 12547.143902, 12554.700852, 12562.258325, 12569.816320, 12577.374837, 12584.933875, 12592.493435, 
-   12600.053515, 12607.614116, 12615.175238, 12622.736880, 12630.299041, 12637.861722, 12645.424923, 12652.988643, 
-   12660.552881, 12668.117638, 12675.682913, 12683.248707, 12690.815018, 12698.381846, 12705.949192, 12713.517054, 
-   12721.085434, 12728.654329, 12736.223741, 12743.793669, 12751.364112, 12758.935071, 12766.506544, 12774.078533, 
-   12781.651036, 12789.224053, 12796.797584, 12804.371629, 12811.946188, 12819.521259, 12827.096844, 12834.672941, 
-   12842.249551, 12849.826673, 12857.404307, 12864.982452, 12872.561109, 12880.140277, 12887.719956, 12895.300146, 
-   12902.880845, 12910.462055, 12918.043775, 12925.626004, 12933.208742, 12940.791990, 12948.375746, 12955.960011, 
-   12963.544784, 12971.130065, 12978.715854, 12986.302150, 12993.888954, 13001.476264, 13009.064082, 13016.652405, 
-   13024.241235, 13031.830571, 13039.420413, 13047.010759, 13054.601612, 13062.192969, 13069.784830, 13077.377196, 
-   13084.970067, 13092.563441, 13100.157319, 13107.751700, 13115.346584, 13122.941972, 13130.537862, 13138.134254, 
-   13145.731148, 13153.328545, 13160.926443, 13168.524842, 13176.123742, 13183.723144, 13191.323046, 13198.923448, 
-   13206.524351, 13214.125753, 13221.727655, 13229.330056, 13236.932957, 13244.536356, 13252.140254, 13259.744650, 
-   13267.349545, 13274.954937, 13282.560827, 13290.167214, 13297.774099, 13305.381480, 13312.989359, 13320.597733, 
-   13328.206604, 13335.815970, 13343.425832, 13351.036190, 13358.647043, 13366.258390, 13373.870233, 13381.482570, 
-   13389.095401, 13396.708726, 13404.322544, 13411.936857, 13419.551662, 13427.166960, 13434.782751, 13442.399035, 
-   13450.015811, 13457.633079, 13465.250838, 13472.869089, 13480.487832, 13488.107065, 13495.726789, 13503.347004, 
-   13510.967709, 13518.588904, 13526.210589, 13533.832764, 13541.455428, 13549.078581, 13556.702223, 13564.326353, 
-   13571.950972, 13579.576080, 13587.201675, 13594.827757, 13602.454328, 13610.081385, 13617.708929, 13625.336960, 
-   13632.965478, 13640.594482, 13648.223972, 13655.853948, 13663.484409, 13671.115355, 13678.746787, 13686.378704, 
-   13694.011105, 13701.643990, 13709.277360, 13716.911213, 13724.545551, 13732.180371, 13739.815675, 13747.451462, 
-   13755.087732, 13762.724484, 13770.361718, 13777.999435, 13785.637633, 13793.276313, 13800.915474, 13808.555116, 
-   13816.195239, 13823.835843, 13831.476927, 13839.118492, 13846.760536, 13854.403060, 13862.046064, 13869.689547, 
-   13877.333509, 13884.977950, 13892.622869, 13900.268267, 13907.914143, 13915.560496, 13923.207328, 13930.854637, 
-   13938.502423, 13946.150686, 13953.799425, 13961.448642, 13969.098334, 13976.748503, 13984.399148, 13992.050268, 
-   13999.701863, 14007.353934, 14015.006480, 14022.659500, 14030.312995, 14037.966964, 14045.621407, 14053.276325, 
-   14060.931715, 14068.587579, 14076.243916, 14083.900726, 14091.558009, 14099.215765, 14106.873992, 14114.532692, 
-   14122.191863, 14129.851506, 14137.511620, 14145.172206, 14152.833262, 14160.494789, 14168.156787, 14175.819255, 
-   14183.482192, 14191.145600, 14198.809477, 14206.473824, 14214.138640, 14221.803924, 14229.469678, 14237.135900, 
-   14244.802590, 14252.469748, 14260.137374, 14267.805468, 14275.474029, 14283.143057, 14290.812553, 14298.482515, 
-   14306.152943, 14313.823838, 14321.495199, 14329.167026, 14336.839318, 14344.512076, 14352.185299, 14359.858987, 
-   14367.533140, 14375.207758, 14382.882840, 14390.558386, 14398.234396, 14405.910869, 14413.587806, 14421.265207, 
-   14428.943070, 14436.621397, 14444.300186, 14451.979437, 14459.659151, 14467.339326, 14475.019964, 14482.701063, 
-   14490.382623, 14498.064645, 14505.747127, 14513.430070, 14521.113474, 14528.797338, 14536.481662, 14544.166446, 
-   14551.851690, 14559.537393, 14567.223555, 14574.910176, 14582.597256, 14590.284795, 14597.972792, 14605.661248, 
-   14613.350161, 14621.039532, 14628.729361, 14636.419647, 14644.110390, 14651.801590, 14659.493247, 14667.185360, 
-   14674.877930, 14682.570956, 14690.264437, 14697.958375, 14705.652767, 14713.347616, 14721.042919, 14728.738677, 
-   14736.434889, 14744.131556, 14751.828678, 14759.526253, 14767.224282, 14774.922765, 14782.621701, 14790.321091, 
-   14798.020933, 14805.721228, 14813.421976, 14821.123176, 14828.824829, 14836.526933, 14844.229489, 14851.932497, 
-   14859.635956, 14867.339866, 14875.044227, 14882.749039, 14890.454302, 14898.160014, 14905.866177, 14913.572790, 
-   14921.279853, 14928.987365, 14936.695327, 14944.403737, 14952.112597, 14959.821905, 14967.531662, 14975.241867, 
-   14982.952521, 14990.663622, 14998.375171, 15006.087167, 15013.799611, 15021.512502, 15029.225840, 15036.939625, 
-   15044.653856, 15052.368533, 15060.083657, 15067.799226, 15075.515242, 15083.231702, 15090.948609, 15098.665960, 
-   15106.383756, 15114.101997, 15121.820683, 15129.539812, 15137.259386, 15144.979404, 15152.699866, 15160.420771, 
-   15168.142120, 15175.863912, 15183.586146, 15191.308824, 15199.031944, 15206.755506, 15214.479511, 15222.203958, 
-   15229.928846, 15237.654176, 15245.379948, 15253.106160, 15260.832814, 15268.559908, 15276.287444, 15284.015419, 
-   15291.743835, 15299.472691, 15307.201986, 15314.931722, 15322.661897, 15330.392511, 15338.123564, 15345.855056, 
-   15353.586986, 15361.319356, 15369.052163, 15376.785409, 15384.519092, 15392.253214, 15399.987773, 15407.722769, 
-   15415.458202, 15423.194072, 15430.930380, 15438.667123, 15446.404303, 15454.141920, 15461.879972, 15469.618460, 
-   15477.357384, 15485.096743, 15492.836537, 15500.576767, 15508.317431, 15516.058530, 15523.800064, 15531.542032, 
-   15539.284434, 15547.027270, 15554.770540, 15562.514243, 15570.258380, 15578.002949, 15585.747952, 15593.493388, 
-   15601.239256, 15608.985557, 15616.732290, 15624.479455, 15632.227051, 15639.975080, 15647.723540, 15655.472431, 
-   15663.221754, 15670.971507, 15678.721691, 15686.472306, 15694.223351, 15701.974826, 15709.726732, 15717.479067, 
-   15725.231832, 15732.985026, 15740.738650, 15748.492702, 15756.247184, 15764.002094, 15771.757433, 15779.513200, 
-   15787.269395, 15795.026019, 15802.783070, 15810.540549, 15818.298455, 15826.056788, 15833.815549, 15841.574736, 
-   15849.334350, 15857.094391, 15864.854858, 15872.615751, 15880.377070, 15888.138815, 15895.900986, 15903.663582, 
-   15911.426603, 15919.190050, 15926.953921, 15934.718217, 15942.482938, 15950.248083, 15958.013652, 15965.779645, 
-   15973.546062, 15981.312902, 15989.080166, 15996.847853, 16004.615964, 16012.384497, 16020.153453, 16027.922832, 
-   16035.692633, 16043.462856, 16051.233501, 16059.004568, 16066.776057, 16074.547967, 16082.320299, 16090.093052, 
-   16097.866225, 16105.639820, 16113.413835, 16121.188270, 16128.963126, 16136.738402, 16144.514098, 16152.290213, 
-   16160.066748, 16167.843703, 16175.621076, 16183.398869, 16191.177080, 16198.955710, 16206.734759, 16214.514226, 
-   16222.294111, 16230.074414, 16237.855135, 16245.636274, 16253.417830, 16261.199803, 16268.982193, 16276.765000, 
-   16284.548224, 16292.331865, 16300.115922, 16307.900395, 16315.685285, 16323.470590, 16331.256311, 16339.042447, 
-   16346.828999, 16354.615966, 16362.403348, 16370.191145, 16377.979356, 16385.767982, 16393.557023, 16401.346477, 
-   16409.136346, 16416.926628, 16424.717324, 16432.508434, 16440.299957, 16448.091893, 16455.884242, 16463.677003, 
-   16471.470178, 16479.263764, 16487.057764, 16494.852175, 16502.646998, 16510.442233, 16518.237879, 16526.033937, 
-   16533.830407, 16541.627287, 16549.424578, 16557.222280, 16565.020393, 16572.818916, 16580.617849, 16588.417193, 
-   16596.216946, 16604.017109, 16611.817682, 16619.618664, 16627.420055, 16635.221855, 16643.024065, 16650.826683, 
-   16658.629710, 16666.433145, 16674.236988, 16682.041239, 16689.845899, 16697.650966, 16705.456440, 16713.262322, 
-   16721.068612, 16728.875308, 16736.682411, 16744.489921, 16752.297838, 16760.106161, 16767.914890, 16775.724026, 
-   16783.533567, 16791.343514, 16799.153867, 16806.964625, 16814.775788, 16822.587357, 16830.399330, 16838.211708, 
-   16846.024491, 16853.837678, 16861.651270, 16869.465266, 16877.279665, 16885.094469, 16892.909676, 16900.725286, 
-   16908.541300, 16916.357717, 16924.174537, 16931.991760, 16939.809385, 16947.627413, 16955.445844, 16963.264676, 
-   16971.083910, 16978.903547, 16986.723585, 16994.544024, 17002.364865, 17010.186107, 17018.007750, 17025.829794, 
-   17033.652239, 17041.475084, 17049.298330, 17057.121976, 17064.946022, 17072.770468, 17080.595314, 17088.420559, 
-   17096.246204, 17104.072248, 17111.898691, 17119.725533, 17127.552774, 17135.380413, 17143.208451, 17151.036888, 
-   17158.865722, 17166.694955, 17174.524585, 17182.354613, 17190.185039, 17198.015862, 17205.847082, 17213.678699, 
-   17221.510714, 17229.343124, 17237.175932, 17245.009136, 17252.842736, 17260.676733, 17268.511125, 17276.345913, 
-   17284.181097, 17292.016676, 17299.852651, 17307.689020, 17315.525785, 17323.362945, 17331.200499, 17339.038448, 
-   17346.876791, 17354.715529, 17362.554661, 17370.394186, 17378.234105, 17386.074418, 17393.915125, 17401.756225, 
-   17409.597718, 17417.439604, 17425.281882, 17433.124554, 17440.967618, 17448.811074, 17456.654923, 17464.499164, 
-   17472.343796, 17480.188821, 17488.034237, 17495.880044, 17503.726243, 17511.572833, 17519.419814, 17527.267186, 
-   17535.114948, 17542.963101, 17550.811645, 17558.660579, 17566.509902, 17574.359616, 17582.209720, 17590.060213, 
-   17597.911096, 17605.762368, 17613.614029, 17621.466079, 17629.318518, 17637.171346, 17645.024562, 17652.878167, 
-   17660.732160, 17668.586541, 17676.441311, 17684.296468, 17692.152012, 17700.007944, 17707.864264, 17715.720971, 
-   17723.578065, 17731.435545, 17739.293413, 17747.151667, 17755.010308, 17762.869335, 17770.728748, 17778.588547, 
-   17786.448732, 17794.309303, 17802.170259, 17810.031601, 17817.893328, 17825.755440, 17833.617938, 17841.480820, 
-   17849.344086, 17857.207738, 17865.071773, 17872.936193, 17880.800997, 17888.666185, 17896.531757, 17904.397712, 
-   17912.264051, 17920.130774, 17927.997879, 17935.865368, 17943.733239, 17951.601493, 17959.470130, 17967.339150, 
-   17975.208551, 17983.078335, 17990.948501, 17998.819049, 18006.689979, 18014.561290, 18022.432983, 18030.305056, 
-   18038.177512, 18046.050348, 18053.923565, 18061.797163, 18069.671141, 18077.545500, 18085.420239, 18093.295358, 
-   18101.170858, 18109.046737, 18116.922996, 18124.799634, 18132.676652, 18140.554049, 18148.431825, 18156.309981, 
-   18164.188515, 18172.067428, 18179.946719, 18187.826389, 18195.706438, 18203.586864, 18211.467668, 18219.348850, 
-   18227.230410, 18235.112348, 18242.994663, 18250.877355, 18258.760424, 18266.643871, 18274.527694, 18282.411894, 
-   18290.296470, 18298.181423, 18306.066752, 18313.952458, 18321.838539, 18329.724997, 18337.611830, 18345.499038, 
-   18353.386622, 18361.274582, 18369.162916, 18377.051626, 18384.940710, 18392.830169, 18400.720003, 18408.610211, 
-   18416.500794, 18424.391750, 18432.283081, 18440.174786, 18448.066864, 18455.959316, 18463.852142, 18471.745341, 
-   18479.638913, 18487.532858, 18495.427176, 18503.321867, 18511.216930, 18519.112366, 18527.008175, 18534.904355, 
-   18542.800908, 18550.697833, 18558.595129, 18566.492797, 18574.390837, 18582.289248, 18590.188030, 18598.087184, 
-   18605.986708, 18613.886604, 18621.786870, 18629.687506, 18637.588513, 18645.489891, 18653.391638, 18661.293756, 
-   18669.196243, 18677.099100, 18685.002327, 18692.905923, 18700.809889, 18708.714224, 18716.618928, 18724.524001, 
-   18732.429442, 18740.335253, 18748.241431, 18756.147979, 18764.054894, 18771.962178, 18779.869829, 18787.777849, 
-   18795.686236, 18803.594991, 18811.504113, 18819.413602, 18827.323459, 18835.233683, 18843.144273, 18851.055231, 
-   18858.966555, 18866.878245, 18874.790302, 18882.702725, 18890.615515, 18898.528670, 18906.442191, 18914.356077, 
-   18922.270330, 18930.184947, 18938.099930, 18946.015279, 18953.930992, 18961.847070, 18969.763513, 18977.680320, 
-   18985.597492, 18993.515029, 19001.432929, 19009.351194, 19017.269823, 19025.188815, 19033.108171, 19041.027891, 
-   19048.947974, 19056.868421, 19064.789230, 19072.710403, 19080.631939, 19088.553837, 19096.476098, 19104.398722, 
-   19112.321708, 19120.245056, 19128.168766, 19136.092839, 19144.017273, 19151.942069, 19159.867226, 19167.792745, 
-   19175.718626, 19183.644867, 19191.571470, 19199.498433, 19207.425758, 19215.353443, 19223.281488, 19231.209894, 
-   19239.138661, 19247.067787, 19254.997274, 19262.927120, 19270.857326, 19278.787892, 19286.718817, 19294.650102, 
-   19302.581746, 19310.513749, 19318.446112, 19326.378833, 19334.311912, 19342.245351, 19350.179148, 19358.113303, 
-   19366.047816, 19373.982688, 19381.917917, 19389.853505, 19397.789450, 19405.725753, 19413.662413, 19421.599430, 
-   19429.536805, 19437.474537, 19445.412625, 19453.351071, 19461.289873, 19469.229032, 19477.168547, 19485.108419, 
-   19493.048647, 19500.989230, 19508.930170, 19516.871466, 19524.813117, 19532.755124, 19540.697486, 19548.640204, 
-   19556.583276, 19564.526704, 19572.470487, 19580.414624, 19588.359116, 19596.303963, 19604.249164, 19612.194720, 
-   19620.140629, 19628.086893, 19636.033511, 19643.980482, 19651.927807, 19659.875485, 19667.823517, 19675.771903, 
-   19683.720641, 19691.669733, 19699.619177, 19707.568974, 19715.519124, 19723.469627, 19731.420482, 19739.371689, 
-   19747.323248, 19755.275159, 19763.227423, 19771.180038, 19779.133005, 19787.086323, 19795.039993, 19802.994014, 
-   19810.948386, 19818.903109, 19826.858184, 19834.813609, 19842.769385, 19850.725511, 19858.681988, 19866.638815, 
-   19874.595992, 19882.553520, 19890.511397, 19898.469624, 19906.428201, 19914.387128, 19922.346403, 19930.306029, 
-   19938.266003, 19946.226327, 19954.187000, 19962.148021, 19970.109391, 19978.071110, 19986.033177, 19993.995593, 
-   20001.958357, 20009.921469, 20017.884929, 20025.848737, 20033.812893, 20041.777396, 20049.742247, 20057.707445, 
-   20065.672991, 20073.638884, 20081.605123, 20089.571710, 20097.538644, 20105.505924, 20113.473550, 20121.441524, 
-   20129.409843, 20137.378509, 20145.347521, 20153.316878, 20161.286582, 20169.256631, 20177.227026, 20185.197767, 
-   20193.168852, 20201.140283, 20209.112059, 20217.084181, 20225.056647, 20233.029457, 20241.002613, 20248.976113, 
-   20256.949957, 20264.924146, 20272.898679, 20280.873556, 20288.848776, 20296.824341, 20304.800249, 20312.776501, 
-   20320.753097, 20328.730036, 20336.707318, 20344.684943, 20352.662911, 20360.641222, 20368.619875, 20376.598872, 
-   20384.578211, 20392.557892, 20400.537916, 20408.518281, 20416.498989, 20424.480039, 20432.461431, 20440.443164, 
-   20448.425239, 20456.407655, 20464.390413, 20472.373512, 20480.356952, 20488.340733, 20496.324855, 20504.309317, 
-   20512.294121, 20520.279265, 20528.264749, 20536.250574, 20544.236739, 20552.223244, 20560.210089, 20568.197273, 
-   20576.184798, 20584.172662, 20592.160865, 20600.149408, 20608.138291, 20616.127512, 20624.117073, 20632.106972, 
-   20640.097210, 20648.087787, 20656.078702, 20664.069956, 20672.061549, 20680.053479, 20688.045748, 20696.038354, 
-   20704.031299, 20712.024581, 20720.018201, 20728.012159, 20736.006454, 20744.001086, 20751.996056, 20759.991362, 
-   20767.987006, 20775.982986, 20783.979304, 20791.975958, 20799.972948, 20807.970275, 20815.967938, 20823.965937, 
-   20831.964273, 20839.962944, 20847.961951, 20855.961294, 20863.960973, 20871.960987, 20879.961336, 20887.962021, 
-   20895.963041, 20903.964396, 20911.966086, 20919.968111, 20927.970470, 20935.973165, 20943.976193, 20951.979556, 
-   20959.983254, 20967.987285, 20975.991651, 20983.996350, 20992.001384, 21000.006751, 21008.012451, 21016.018485, 
-   21024.024853, 21032.031554, 21040.038588, 21048.045955, 21056.053655, 21064.061688, 21072.070053, 21080.078752, 
-   21088.087782, 21096.097145, 21104.106841, 21112.116868, 21120.127228, 21128.137919, 21136.148943, 21144.160298, 
-   21152.171985, 21160.184003, 21168.196352, 21176.209033, 21184.222045, 21192.235389, 21200.249063, 21208.263068, 
-   21216.277404, 21224.292070, 21232.307067, 21240.322394, 21248.338052, 21256.354040, 21264.370357, 21272.387005, 
-   21280.403983, 21288.421291, 21296.438928, 21304.456894, 21312.475191, 21320.493816, 21328.512771, 21336.532055, 
-   21344.551667, 21352.571609, 21360.591879, 21368.612479, 21376.633406, 21384.654663, 21392.676247, 21400.698160, 
-   21408.720401, 21416.742970, 21424.765867, 21432.789091, 21440.812644, 21448.836524, 21456.860731, 21464.885266, 
-   21472.910128, 21480.935317, 21488.960834, 21496.986677, 21505.012847, 21513.039344, 21521.066168, 21529.093318, 
-   21537.120795, 21545.148597, 21553.176726, 21561.205182, 21569.233963, 21577.263070, 21585.292503, 21593.322261, 
-   21601.352345, 21609.382755, 21617.413490, 21625.444550, 21633.475935, 21641.507646, 21649.539681, 21657.572041, 
-   21665.604726, 21673.637736, 21681.671070, 21689.704728, 21697.738711, 21705.773018, 21713.807649, 21721.842604, 
-   21729.877883, 21737.913485, 21745.949412, 21753.985662, 21762.022235, 21770.059132, 21778.096352, 21786.133895, 
-   21794.171761, 21802.209950, 21810.248462, 21818.287297, 21826.326455, 21834.365934, 21842.405737, 21850.445862, 
-   21858.486308, 21866.527077, 21874.568168, 21882.609581, 21890.651316, 21898.693372, 21906.735750, 21914.778450, 
-   21922.821471, 21930.864813, 21938.908476, 21946.952461, 21954.996766, 21963.041392, 21971.086339, 21979.131607, 
-   21987.177195, 21995.223104, 22003.269333, 22011.315883, 22019.362752, 22027.409942, 22035.457451, 22043.505281, 
-   22051.553430, 22059.601898, 22067.650687, 22075.699794, 22083.749222, 22091.798968, 22099.849033, 22107.899418, 
-   22115.950121, 22124.001143, 22132.052484, 22140.104144, 22148.156122, 22156.208418, 22164.261033, 22172.313966, 
-   22180.367217, 22188.420787, 22196.474674, 22204.528879, 22212.583401, 22220.638241, 22228.693399, 22236.748874, 
-   22244.804667, 22252.860776, 22260.917203, 22268.973947, 22277.031008, 22285.088385, 22293.146079, 22301.204090, 
-   22309.262417, 22317.321061, 22325.380021, 22333.439297, 22341.498890, 22349.558798, 22357.619022, 22365.679562, 
-   22373.740418, 22381.801589, 22389.863076, 22397.924879, 22405.986996, 22414.049429, 22422.112177, 22430.175240, 
-   22438.238618, 22446.302310, 22454.366318, 22462.430639, 22470.495276, 22478.560227, 22486.625492, 22494.691071, 
-   22502.756965, 22510.823173, 22518.889694, 22526.956529, 22535.023678, 22543.091141, 22551.158917, 22559.227007, 
-   22567.295410, 22575.364126, 22583.433155, 22591.502498, 22599.572153, 22607.642121, 22615.712402, 22623.782996, 
-   22631.853902, 22639.925120, 22647.996651, 22656.068494, 22664.140650, 22672.213117, 22680.285896, 22688.358988, 
-   22696.432391, 22704.506105, 22712.580131, 22720.654469, 22728.729118, 22736.804078, 22744.879350, 22752.954933, 
-   22761.030826, 22769.107031, 22777.183546, 22785.260372, 22793.337509, 22801.414956, 22809.492714, 22817.570781, 
-   22825.649160, 22833.727848, 22841.806846, 22849.886154, 22857.965772, 22866.045700, 22874.125937, 22882.206484, 
-   22890.287341, 22898.368507, 22906.449982, 22914.531766, 22922.613859, 22930.696261, 22938.778972, 22946.861992, 
-   22954.945321, 22963.028958, 22971.112904, 22979.197158, 22987.281720, 22995.366591, 23003.451770, 23011.537257, 
-   23019.623051, 23027.709154, 23035.795564, 23043.882282, 23051.969308, 23060.056640, 23068.144281, 23076.232228, 
-   23084.320483, 23092.409045, 23100.497914, 23108.587089, 23116.676572, 23124.766361, 23132.856457, 23140.946859, 
-   23149.037568, 23157.128583, 23165.219904, 23173.311531, 23181.403465, 23189.495704, 23197.588250, 23205.681101, 
-   23213.774257, 23221.867720, 23229.961487, 23238.055560, 23246.149939, 23254.244623, 23262.339611, 23270.434905, 
-   23278.530504, 23286.626407, 23294.722616, 23302.819129, 23310.915946, 23319.013068, 23327.110494, 23335.208225, 
-   23343.306260, 23351.404598, 23359.503241, 23367.602188, 23375.701439, 23383.800993, 23391.900851, 23400.001012, 
-   23408.101477, 23416.202245, 23424.303317, 23432.404692, 23440.506369, 23448.608350, 23456.710634, 23464.813220, 
-   23472.916109, 23481.019301, 23489.122795, 23497.226592, 23505.330691, 23513.435092, 23521.539796, 23529.644801, 
-   23537.750109, 23545.855718, 23553.961629, 23562.067842, 23570.174357, 23578.281173, 23586.388290, 23594.495709, 
-   23602.603429, 23610.711450, 23618.819773, 23626.928396, 23635.037320, 23643.146545, 23651.256071, 23659.365897, 
-   23667.476024, 23675.586451, 23683.697179, 23691.808206, 23699.919534, 23708.031163, 23716.143091, 23724.255319, 
-   23732.367846, 23740.480674, 23748.593801, 23756.707228, 23764.820954, 23772.934979, 23781.049304, 23789.163928, 
-   23797.278851, 23805.394073, 23813.509594, 23821.625413, 23829.741532, 23837.857949, 23845.974664, 23854.091678, 
-   23862.208991, 23870.326602, 23878.444511, 23886.562718, 23894.681223, 23902.800026, 23910.919127, 23919.038525, 
-   23927.158221, 23935.278215, 23943.398507, 23951.519095, 23959.639981, 23967.761165, 23975.882645, 23984.004422, 
-   23992.126497, 24000.248868, 24008.371536, 24016.494501, 24024.617762, 24032.741320, 24040.865174, 24048.989325, 
-   24057.113772, 24065.238515, 24073.363554, 24081.488889, 24089.614520, 24097.740447, 24105.866669, 24113.993187, 
-   24122.120001, 24130.247110, 24138.374515, 24146.502215, 24154.630210, 24162.758500, 24170.887085, 24179.015965, 
-   24187.145140, 24195.274610, 24203.404374, 24211.534433, 24219.664787, 24227.795435, 24235.926377, 24244.057614, 
-   24252.189144, 24260.320969, 24268.453088, 24276.585501, 24284.718207, 24292.851207, 24300.984501, 24309.118089, 
-   24317.251970, 24325.386144, 24333.520611, 24341.655372, 24349.790426, 24357.925773, 24366.061413, 24374.197346, 
-   24382.333571, 24390.470090, 24398.606900, 24406.744004, 24414.881400, 24423.019088, 24431.157068, 24439.295341, 
-   24447.433906, 24455.572762, 24463.711911, 24471.851352, 24479.991084, 24488.131108, 24496.271423, 24504.412030, 
-   24512.552929, 24520.694119, 24528.835600, 24536.977372, 24545.119435, 24553.261789, 24561.404435, 24569.547371, 
-   24577.690597, 24585.834115, 24593.977923, 24602.122021, 24610.266410, 24618.411089, 24626.556059, 24634.701318, 
-   24642.846868, 24650.992708, 24659.138837, 24667.285256, 24675.431965, 24683.578964, 24691.726252, 24699.873830, 
-   24708.021697, 24716.169854, 24724.318299, 24732.467034, 24740.616058, 24748.765371, 24756.914973, 24765.064863, 
-   24773.215042, 24781.365510, 24789.516267, 24797.667312, 24805.818645, 24813.970267, 24822.122177, 24830.274375, 
-   24838.426861, 24846.579635, 24854.732697, 24862.886046, 24871.039684, 24879.193609, 24887.347822, 24895.502322, 
-   24903.657110, 24911.812184, 24919.967547, 24928.123196, 24936.279132, 24944.435355, 24952.591866, 24960.748663, 
-   24968.905746, 24977.063117, 24985.220774, 24993.378717, 25001.536947, 25009.695464, 25017.854266, 25026.013355, 
-   25034.172730, 25042.332390, 25050.492337, 25058.652569, 25066.813088, 25074.973892, 25083.134981, 25091.296356, 
-   25099.458017, 25107.619962, 25115.782193, 25123.944710, 25132.107511, 25140.270597, 25148.433969, 25156.597625, 
-   25164.761566, 25172.925791, 25181.090302, 25189.255097, 25197.420176, 25205.585539, 25213.751187, 25221.917120, 
-   25230.083336, 25238.249836, 25246.416620, 25254.583689, 25262.751041, 25270.918676, 25279.086596, 25287.254799, 
-   25295.423285, 25303.592055, 25311.761108, 25319.930444, 25328.100064, 25336.269967, 25344.440152, 25352.610621, 
-   25360.781372, 25368.952406, 25377.123723, 25385.295323, 25393.467205, 25401.639369, 25409.811816, 25417.984545, 
-   25426.157556, 25434.330850, 25442.504425, 25450.678283, 25458.852422, 25467.026843, 25475.201546, 25483.376531, 
-   25491.551797, 25499.727344, 25507.903173, 25516.079284, 25524.255675, 25532.432348, 25540.609302, 25548.786537, 
-   25556.964053, 25565.141849, 25573.319927, 25581.498285, 25589.676924, 25597.855843, 25606.035043, 25614.214523, 
-   25622.394284, 25630.574324, 25638.754645, 25646.935246, 25655.116127, 25663.297288, 25671.478729, 25679.660449, 
-   25687.842449, 25696.024729, 25704.207288, 25712.390127, 25720.573245, 25728.756642, 25736.940319, 25745.124275, 
-   25753.308510, 25761.493023, 25769.677816, 25777.862887, 25786.048238, 25794.233867, 25802.419774, 25810.605960, 
-   25818.792424, 25826.979167, 25835.166188, 25843.353488, 25851.541065, 25859.728920, 25867.917054, 25876.105465, 
-   25884.294154, 25892.483121, 25900.672366, 25908.861888, 25917.051687, 25925.241764, 25933.432119, 25941.622750, 
-   25949.813659, 25958.004845, 25966.196308, 25974.388048, 25982.580065, 25990.772359, 25998.964930, 26007.157777, 
-   26015.350900, 26023.544301, 26031.737977, 26039.931930, 26048.126160, 26056.320665, 26064.515447, 26072.710504, 
-   26080.905838, 26089.101448, 26097.297333, 26105.493494, 26113.689931, 26121.886643, 26130.083631, 26138.280895, 
-   26146.478434, 26154.676248, 26162.874337, 26171.072701, 26179.271341, 26187.470255, 26195.669444, 26203.868909, 
-   26212.068648, 26220.268661, 26228.468950, 26236.669512, 26244.870350, 26253.071461, 26261.272847, 26269.474507, 
-   26277.676442, 26285.878650, 26294.081133, 26302.283889, 26310.486919, 26318.690223, 26326.893801, 26335.097652, 
-   26343.301777, 26351.506176, 26359.710848, 26367.915793, 26376.121011, 26384.326503, 26392.532267, 26400.738305, 
-   26408.944616, 26417.151200, 26425.358056, 26433.565185, 26441.772587, 26449.980261, 26458.188208, 26466.396428, 
-   26474.604919, 26482.813684, 26491.022720, 26499.232028, 26507.441609, 26515.651461, 26523.861586, 26532.071982, 
-   26540.282650, 26548.493590, 26556.704801, 26564.916284, 26573.128038, 26581.340064, 26589.552361, 26597.764930, 
-   26605.977769, 26614.190880, 26622.404262, 26630.617914, 26638.831838, 26647.046032, 26655.260498, 26663.475233, 
-   26671.690240, 26679.905517, 26688.121064, 26696.336882, 26704.552970, 26712.769328, 26720.985957, 26729.202855, 
-   26737.420024, 26745.637463, 26753.855171, 26762.073149, 26770.291397, 26778.509915, 26786.728702, 26794.947759, 
-   26803.167085, 26811.386680, 26819.606545, 26827.826679, 26836.047082, 26844.267754, 26852.488695, 26860.709905, 
-   26868.931384, 26877.153132, 26885.375148, 26893.597433, 26901.819987, 26910.042809, 26918.265900, 26926.489259, 
-   26934.712886, 26942.936781, 26951.160945, 26959.385376, 26967.610076, 26975.835043, 26984.060279, 26992.285782, 
-   27000.511553, 27008.737591, 27016.963897, 27025.190470, 27033.417311, 27041.644420, 27049.871795, 27058.099438, 
-   27066.327348, 27074.555525, 27082.783968, 27091.012679, 27099.241657, 27107.470901, 27115.700412, 27123.930190, 
-   27132.160234, 27140.390545, 27148.621123, 27156.851966, 27165.083076, 27173.314452, 27181.546094, 27189.778002, 
-   27198.010177, 27206.242617, 27214.475323, 27222.708295, 27230.941532, 27239.175035, 27247.408804, 27255.642838, 
-   27263.877138, 27272.111703, 27280.346533, 27288.581629, 27296.816989, 27305.052615, 27313.288506, 27321.524661, 
-   27329.761082, 27337.997767, 27346.234717, 27354.471932, 27362.709411, 27370.947155, 27379.185163, 27387.423436, 
-   27395.661973, 27403.900774, 27412.139839, 27420.379169, 27428.618762, 27436.858620, 27445.098741, 27453.339126, 
-   27461.579775, 27469.820687, 27478.061864, 27486.303303, 27494.545006, 27502.786973, 27511.029203, 27519.271696, 
-   27527.514452, 27535.757472, 27544.000754, 27552.244300, 27560.488108, 27568.732180, 27576.976514, 27585.221110, 
-   27593.465970, 27601.711092, 27609.956476, 27618.202123, 27626.448032, 27634.694204, 27642.940638, 27651.187334, 
-   27659.434292, 27667.681512, 27675.928994, 27684.176738, 27692.424743, 27700.673011, 27708.921540, 27717.170331, 
-   27725.419383, 27733.668697, 27741.918272, 27750.168108, 27758.418206, 27766.668565, 27774.919185, 27783.170066, 
-   27791.421208, 27799.672611, 27807.924275, 27816.176200, 27824.428385, 27832.680832, 27840.933538, 27849.186505, 
-   27857.439733, 27865.693221, 27873.946969, 27882.200978, 27890.455247, 27898.709776, 27906.964565, 27915.219614, 
-   27923.474922, 27931.730491, 27939.986319, 27948.242408, 27956.498755, 27964.755363, 27973.012230, 27981.269356, 
-   27989.526741, 27997.784386, 28006.042291, 28014.300454, 28022.558876, 28030.817558, 28039.076498, 28047.335698, 
-   28055.595156, 28063.854873, 28072.114849, 28080.375083, 28088.635576, 28096.896327, 28105.157337, 28113.418605, 
-   28121.680131, 28129.941916, 28138.203959, 28146.466260, 28154.728819, 28162.991636, 28171.254711, 28179.518043, 
-   28187.781634, 28196.045482, 28204.309588, 28212.573951, 28220.838572, 28229.103450, 28237.368586, 28245.633979, 
-   28253.899629, 28262.165536, 28270.431701, 28278.698122, 28286.964801, 28295.231736, 28303.498928, 28311.766377, 
-   28320.034083, 28328.302045, 28336.570264, 28344.838739, 28353.107471, 28361.376459, 28369.645704, 28377.915205, 
-   28386.184962, 28394.454975, 28402.725244, 28410.995769, 28419.266550, 28427.537587, 28435.808879, 28444.080428, 
-   28452.352232, 28460.624291, 28468.896606, 28477.169177, 28485.442003, 28493.715084, 28501.988421, 28510.262013, 
-   28518.535860, 28526.809962, 28535.084319, 28543.358931, 28551.633798, 28559.908919, 28568.184296, 28576.459927, 
-   28584.735812, 28593.011952, 28601.288347, 28609.564996, 28617.841900, 28626.119058, 28634.396470, 28642.674136, 
-   28650.952056, 28659.230230, 28667.508659, 28675.787341, 28684.066277, 28692.345466, 28700.624910, 28708.904607, 
-   28717.184558, 28725.464762, 28733.745220, 28742.025931, 28750.306895, 28758.588113, 28766.869584, 28775.151308, 
-   28783.433285, 28791.715515, 28799.997998, 28808.280734, 28816.563722, 28824.846964, 28833.130458, 28841.414205, 
-   28849.698204, 28857.982456, 28866.266960, 28874.551717, 28882.836726, 28891.121987, 28899.407500, 28907.693265, 
-   28915.979283, 28924.265552, 28932.552074, 28940.838847, 28949.125872, 28957.413149, 28965.700677, 28973.988457, 
-   28982.276489, 28990.564772, 28998.853306, 29007.142092, 29015.431129, 29023.720417, 29032.009957, 29040.299748, 
-   29048.589789, 29056.880082, 29065.170625, 29073.461420, 29081.752465, 29090.043761, 29098.335307, 29106.627104, 
-   29114.919152, 29123.211450, 29131.503998, 29139.796797, 29148.089846, 29156.383146, 29164.676695, 29172.970495, 
-   29181.264545, 29189.558844, 29197.853394, 29206.148193, 29214.443242, 29222.738541, 29231.034090, 29239.329888, 
-   29247.625935, 29255.922232, 29264.218779, 29272.515575, 29280.812620, 29289.109914, 29297.407458, 29305.705251, 
-   29314.003292, 29322.301583, 29330.600122, 29338.898911, 29347.197948, 29355.497234, 29363.796768, 29372.096552, 
-   29380.396583, 29388.696863, 29396.997392, 29405.298169, 29413.599194, 29421.900468, 29430.201989, 29438.503759, 
-   29446.805777, 29455.108043, 29463.410557, 29471.713318, 29480.016327, 29488.319585, 29496.623089, 29504.926842, 
-   29513.230842, 29521.535089, 29529.839584, 29538.144326, 29546.449316, 29554.754553, 29563.060037, 29571.365768, 
-   29579.671746, 29587.977971, 29596.284444, 29604.591163, 29612.898129, 29621.205341, 29629.512800, 29637.820506, 
-   29646.128459, 29654.436658, 29662.745104, 29671.053795, 29679.362734, 29687.671918, 29695.981349, 29704.291026, 
-   29712.600949, 29720.911118, 29729.221533, 29737.532194, 29745.843101, 29754.154253, 29762.465651, 29770.777295, 
-   29779.089185, 29787.401320, 29795.713701, 29804.026327, 29812.339198, 29820.652315, 29828.965677, 29837.279284, 
-   29845.593136, 29853.907233, 29862.221576, 29870.536163, 29878.850995, 29887.166072, 29895.481394, 29903.796960, 
-   29912.112772, 29920.428827, 29928.745128, 29937.061672, 29945.378461, 29953.695495, 29962.012773, 29970.330295, 
-   29978.648061, 29986.966071, 29995.284325, 30003.602824, 30011.921566, 30020.240552, 30028.559782, 30036.879256, 
-   30045.198973, 30053.518934, 30061.839139, 30070.159587, 30078.480278, 30086.801213, 30095.122392, 30103.443813, 
-   30111.765478, 30120.087386, 30128.409537, 30136.731931, 30145.054568, 30153.377448, 30161.700571, 30170.023937, 
-   30178.347545, 30186.671397, 30194.995490, 30203.319827, 30211.644406, 30219.969227, 30228.294290, 30236.619597, 
-   30244.945145, 30253.270935, 30261.596968, 30269.923243, 30278.249760, 30286.576518, 30294.903519, 30303.230762, 
-   30311.558246, 30319.885972, 30328.213940, 30336.542150, 30344.870601, 30353.199293, 30361.528227, 30369.857403, 
-   30378.186820, 30386.516478, 30394.846377, 30403.176517, 30411.506899, 30419.837522, 30428.168385, 30436.499490, 
-   30444.830835, 30453.162422, 30461.494249, 30469.826316, 30478.158625, 30486.491174, 30494.823963, 30503.156993, 
-   30511.490263, 30519.823774, 30528.157525, 30536.491516, 30544.825748, 30553.160219, 30561.494931, 30569.829882, 
-   30578.165074, 30586.500506, 30594.836177, 30603.172088, 30611.508239, 30619.844629, 30628.181259, 30636.518129, 
-   30644.855238, 30653.192587, 30661.530175, 30669.868002, 30678.206068, 30686.544374, 30694.882919, 30703.221703, 
-   30711.560726, 30719.899988, 30728.239489, 30736.579229, 30744.919207, 30753.259425, 30761.599881, 30769.940575, 
-   30778.281508, 30786.622680, 30794.964090, 30803.305739, 30811.647626, 30819.989751, 30828.332115, 30836.674716, 
-   30845.017556, 30853.360634, 30861.703950, 30870.047504, 30878.391296, 30886.735325, 30895.079592, 30903.424098, 
-   30911.768840, 30920.113821, 30928.459039, 30936.804494, 30945.150187, 30953.496117, 30961.842285, 30970.188690, 
-   30978.535332, 30986.882211, 30995.229327, 31003.576681, 31011.924271, 31020.272098, 31028.620163, 31036.968464, 
-   31045.317002, 31053.665776, 31062.014787, 31070.364035, 31078.713519, 31087.063240, 31095.413198, 31103.763391, 
-   31112.113821, 31120.464487, 31128.815390, 31137.166529, 31145.517903, 31153.869514, 31162.221361, 31170.573443, 
-   31178.925762, 31187.278316, 31195.631106, 31203.984132, 31212.337394, 31220.690891, 31229.044624, 31237.398592, 
-   31245.752795, 31254.107234, 31262.461908, 31270.816818, 31279.171963, 31287.527343, 31295.882958, 31304.238808, 
-   31312.594893, 31320.951213, 31329.307767, 31337.664557, 31346.021582, 31354.378841, 31362.736335, 31371.094063, 
-   31379.452026, 31387.810223, 31396.168655, 31404.527322, 31412.886222, 31421.245357, 31429.604726, 31437.964329, 
-   31446.324167, 31454.684238, 31463.044544, 31471.405083, 31479.765856, 31488.126863, 31496.488104, 31504.849579, 
-   31513.211287, 31521.573229, 31529.935405, 31538.297814, 31546.660456, 31555.023332, 31563.386441, 31571.749784, 
-   31580.113359, 31588.477168, 31596.841210, 31605.205485, 31613.569993, 31621.934734, 31630.299708, 31638.664915, 
-   31647.030355, 31655.396027, 31663.761932, 31672.128070, 31680.494440, 31688.861043, 31697.227878, 31705.594946, 
-   31713.962246, 31722.329779, 31730.697543, 31739.065540, 31747.433769, 31755.802230, 31764.170924, 31772.539849, 
-   31780.909006, 31789.278395, 31797.648016, 31806.017868, 31814.387953, 31822.758269, 31831.128816, 31839.499595, 
-   31847.870606, 31856.241848, 31864.613322, 31872.985027, 31881.356963, 31889.729130, 31898.101529, 31906.474159, 
-   31914.847019, 31923.220111, 31931.593434, 31939.966988, 31948.340772, 31956.714788, 31965.089034, 31973.463511, 
-   31981.838218, 31990.213157, 31998.588325, 32006.963725, 32015.339354, 32023.715214, 32032.091305, 32040.467625, 
-   32048.844176, 32057.220957, 32065.597968, 32073.975209, 32082.352681, 32090.730382, 32099.108313, 32107.486474, 
-   32115.864865, 32124.243485, 32132.622336, 32141.001415, 32149.380725, 32157.760264, 32166.140032, 32174.520030, 
-   32182.900258, 32191.280714, 32199.661400, 32208.042316, 32216.423460, 32224.804833, 32233.186436, 32241.568267, 
-   32249.950328, 32258.332617, 32266.715136, 32275.097883, 32283.480859, 32291.864063, 32300.247496, 32308.631158, 
-   32317.015049, 32325.399167, 32333.783515, 32342.168090, 32350.552894, 32358.937927, 32367.323187, 32375.708676, 
-   32384.094393, 32392.480338, 32400.866510, 32409.252911, 32417.639540, 32426.026397, 32434.413481, 32442.800794, 
-   32451.188334, 32459.576101, 32467.964097, 32476.352319, 32484.740770, 32493.129447, 32501.518353, 32509.907485, 
-   32518.296845, 32526.686432, 32535.076246, 32543.466288, 32551.856556, 32560.247052, 32568.637774, 32577.028724, 
-   32585.419900, 32593.811303, 32602.202933, 32610.594790, 32618.986873, 32627.379183, 32635.771720, 32644.164483, 
-   32652.557473, 32660.950689, 32669.344131, 32677.737800, 32686.131695, 32694.525816, 32702.920163, 32711.314737, 
-   32719.709536, 32728.104562, 32736.499813, 32744.895291, 32753.290994, 32761.686923, 32770.083078, 32778.479459, 
-   32786.876065, 32795.272897, 32803.669954, 32812.067237, 32820.464745, 32828.862479, 32837.260438, 32845.658623, 
-   32854.057032, 32862.455667, 32870.854527, 32879.253612, 32887.652922, 32896.052457, 32904.452218, 32912.852203, 
-   32921.252412, 32929.652847, 32938.053506, 32946.454390, 32954.855499, 32963.256832, 32971.658390, 32980.060173, 
-   32988.462179, 32996.864411, 33005.266866, 33013.669546, 33022.072450, 33030.475578, 33038.878931, 33047.282507, 
-   33055.686308, 33064.090332, 33072.494581, 33080.899053, 33089.303749, 33097.708669, 33106.113813, 33114.519180, 
-   33122.924771, 33131.330586, 33139.736624, 33148.142885, 33156.549370, 33164.956079, 33173.363011, 33181.770166, 
-   33190.177544, 33198.585146, 33206.992970, 33215.401018, 33223.809289, 33232.217783, 33240.626499, 33249.035439, 
-   33257.444601, 33265.853987, 33274.263595, 33282.673425, 33291.083479, 33299.493754, 33307.904253, 33316.314974, 
-   33324.725917, 33333.137083, 33341.548471, 33349.960082, 33358.371914, 33366.783969, 33375.196246, 33383.608745, 
-   33392.021466, 33400.434410, 33408.847575, 33417.260962, 33425.674571, 33434.088401, 33442.502454, 33450.916728, 
-   33459.331224, 33467.745941, 33476.160880, 33484.576041, 33492.991422, 33501.407026, 33509.822850, 33518.238897, 
-   33526.655164, 33535.071652, 33543.488362, 33551.905293, 33560.322445, 33568.739817, 33577.157411, 33585.575226, 
-   33593.993262, 33602.411518, 33610.829995, 33619.248693, 33627.667612, 33636.086751, 33644.506111, 33652.925691, 
-   33661.345492, 33669.765513, 33678.185755, 33686.606217, 33695.026899, 33703.447802, 33711.868925, 33720.290267, 
-   33728.711830, 33737.133613, 33745.555616, 33753.977839, 33762.400282, 33770.822945, 33779.245827, 33787.668930, 
-   33796.092252, 33804.515793, 33812.939555, 33821.363535, 33829.787736, 33838.212156, 33846.636795, 33855.061653, 
-   33863.486731, 33871.912028, 33880.337545, 33888.763280, 33897.189235, 33905.615409, 33914.041802, 33922.468414, 
-   33930.895244, 33939.322294, 33947.749562, 33956.177050, 33964.604756, 33973.032680, 33981.460824, 33989.889186, 
-   33998.317766, 34006.746565, 34015.175583, 34023.604819, 34032.034273, 34040.463946, 34048.893836, 34057.323946, 
-   34065.754273, 34074.184818, 34082.615582, 34091.046563, 34099.477763, 34107.909180, 34116.340815, 34124.772669, 
-   34133.204739, 34141.637028, 34150.069535, 34158.502259, 34166.935200, 34175.368359, 34183.801736, 34192.235330, 
-   34200.669142, 34209.103171, 34217.537417, 34225.971881, 34234.406561, 34242.841459, 34251.276574, 34259.711907, 
-   34268.147456, 34276.583222, 34285.019205, 34293.455405, 34301.891822, 34310.328456, 34318.765306, 34327.202373, 
-   34335.639657, 34344.077158, 34352.514874, 34360.952808, 34369.390958, 34377.829324, 34386.267907, 34394.706706, 
-   34403.145722, 34411.584953, 34420.024401, 34428.464065, 34436.903945, 34445.344041, 34453.784354, 34462.224882, 
-   34470.665626, 34479.106586, 34487.547761, 34495.989153, 34504.430760, 34512.872583, 34521.314621, 34529.756875, 
-   34538.199345, 34546.642030, 34555.084931, 34563.528047, 34571.971378, 34580.414925, 34588.858687, 34597.302664, 
-   34605.746856, 34614.191264, 34622.635886, 34631.080724, 34639.525776, 34647.971044, 34656.416526, 34664.862223, 
-   34673.308135, 34681.754262, 34690.200603, 34698.647159, 34707.093930, 34715.540915, 34723.988115, 34732.435530, 
-   34740.883158, 34749.331001, 34757.779059, 34766.227331, 34774.675817, 34783.124517, 34791.573431, 34800.022560, 
-   34808.471902, 34816.921459, 34825.371229, 34833.821214, 34842.271412, 34850.721824, 34859.172450, 34867.623290, 
-   34876.074343, 34884.525610, 34892.977091, 34901.428785, 34909.880693, 34918.332814, 34926.785149, 34935.237697, 
-   34943.690458, 34952.143433, 34960.596620, 34969.050021, 34977.503636, 34985.957463, 34994.411503, 35002.865757, 
-   35011.320223, 35019.774902, 35028.229795, 35036.684900, 35045.140217, 35053.595748, 35062.051491, 35070.507447, 
-   35078.963615, 35087.419997, 35095.876590, 35104.333396, 35112.790415, 35121.247645, 35129.705089, 35138.162744, 
-   35146.620612, 35155.078692, 35163.536984, 35171.995488, 35180.454204, 35188.913133, 35197.372273, 35205.831625, 
-   35214.291189, 35222.750965, 35231.210953, 35239.671152, 35248.131563, 35256.592186, 35265.053021, 35273.514067, 
-   35281.975324, 35290.436793, 35298.898474, 35307.360366, 35315.822469, 35324.284783, 35332.747309, 35341.210046, 
-   35349.672994, 35358.136154, 35366.599524, 35375.063106, 35383.526898, 35391.990901, 35400.455116, 35408.919541, 
-   35417.384177, 35425.849023, 35434.314081, 35442.779349, 35451.244828, 35459.710517, 35468.176417, 35476.642527, 
-   35485.108848, 35493.575379, 35502.042121, 35510.509073, 35518.976235, 35527.443608, 35535.911191, 35544.378983, 
-   35552.846986, 35561.315199, 35569.783622, 35578.252255, 35586.721098, 35595.190151, 35603.659414, 35612.128886, 
-   35620.598568, 35629.068460, 35637.538562, 35646.008873, 35654.479394, 35662.950124, 35671.421064, 35679.892213, 
-   35688.363572, 35696.835140, 35705.306917, 35713.778904, 35722.251100, 35730.723505, 35739.196119, 35747.668942, 
-   35756.141974, 35764.615216, 35773.088666, 35781.562325, 35790.036193, 35798.510270, 35806.984556, 35815.459050, 
-   35823.933753, 35832.408665, 35840.883786, 35849.359115, 35857.834652, 35866.310398, 35874.786353, 35883.262515, 
-   35891.738887, 35900.215466, 35908.692254, 35917.169250, 35925.646454, 35934.123866, 35942.601487, 35951.079315, 
-   35959.557352, 35968.035596, 35976.514049, 35984.992709, 35993.471577, 36001.950653, 36010.429936, 36018.909428, 
-   36027.389127, 36035.869033, 36044.349147, 36052.829469, 36061.309998, 36069.790735, 36078.271679, 36086.752831, 
-   36095.234189, 36103.715755, 36112.197529, 36120.679509, 36129.161697, 36137.644091, 36146.126693, 36154.609502, 
-   36163.092517, 36171.575740, 36180.059170, 36188.542806, 36197.026649, 36205.510699, 36213.994956, 36222.479419, 
-   36230.964089, 36239.448966, 36247.934049, 36256.419339, 36264.904835, 36273.390537, 36281.876446, 36290.362561, 
-   36298.848883, 36307.335411, 36315.822145, 36324.309085, 36332.796231, 36341.283584, 36349.771142, 36358.258906, 
-   36366.746877, 36375.235053, 36383.723435, 36392.212023, 36400.700817, 36409.189816, 36417.679021, 36426.168432, 
-   36434.658048, 36443.147870, 36451.637898, 36460.128131, 36468.618569, 36477.109213, 36485.600063, 36494.091117, 
-   36502.582377, 36511.073842, 36519.565512, 36528.057388, 36536.549468, 36545.041754, 36553.534244, 36562.026940, 
-   36570.519840, 36579.012946, 36587.506256, 36595.999771, 36604.493491, 36612.987415, 36621.481545, 36629.975878, 
-   36638.470417, 36646.965160, 36655.460108, 36663.955260, 36672.450616, 36680.946177, 36689.441942, 36697.937912, 
-   36706.434086, 36714.930464, 36723.427046, 36731.923832, 36740.420823, 36748.918017, 36757.415416, 36765.913019, 
-   36774.410825, 36782.908835, 36791.407050, 36799.905468, 36808.404089, 36816.902915, 36825.401944, 36833.901177, 
-   36842.400614, 36850.900254, 36859.400097, 36867.900144, 36876.400395, 36884.900848, 36893.401506, 36901.902366, 
-   36910.403430, 36918.904697, 36927.406167, 36935.907841, 36944.409717, 36952.911797, 36961.414079, 36969.916565, 
-   36978.419253, 36986.922145, 36995.425239, 37003.928536, 37012.432036, 37020.935739, 37029.439644, 37037.943752, 
-   37046.448062, 37054.952576, 37063.457291, 37071.962209, 37080.467330, 37088.972653, 37097.478178, 37105.983906, 
-   37114.489836, 37122.995968, 37131.502303, 37140.008839, 37148.515578, 37157.022519, 37165.529662, 37174.037007, 
-   37182.544554, 37191.052302, 37199.560253, 37208.068405, 37216.576760, 37225.085316, 37233.594073, 37242.103033, 
-   37250.612194, 37259.121556, 37267.631120, 37276.140886, 37284.650853, 37293.161022, 37301.671392, 37310.181963, 
-   37318.692736, 37327.203710, 37335.714885, 37344.226261, 37352.737838, 37361.249617, 37369.761597, 37378.273777, 
-   37386.786159, 37395.298742, 37403.811525, 37412.324509, 37420.837695, 37429.351080, 37437.864667, 37446.378455, 
-   37454.892443, 37463.406631, 37471.921021, 37480.435610, 37488.950401, 37497.465391, 37505.980583, 37514.495974, 
-   37523.011566, 37531.527358, 37540.043351, 37548.559544, 37557.075936, 37565.592529, 37574.109323, 37582.626316, 
-   37591.143509, 37599.660902, 37608.178495, 37616.696288, 37625.214281, 37633.732474, 37642.250866, 37650.769458, 
-   37659.288250, 37667.807242, 37676.326433, 37684.845824, 37693.365414, 37701.885204, 37710.405193, 37718.925382, 
-   37727.445770, 37735.966357, 37744.487144, 37753.008130, 37761.529315, 37770.050700, 37778.572283, 37787.094066, 
-   37795.616048, 37804.138228, 37812.660608, 37821.183187, 37829.705964, 37838.228941, 37846.752116, 37855.275490, 
-   37863.799063, 37872.322834, 37880.846805, 37889.370973, 37897.895341, 37906.419907, 37914.944671, 37923.469634, 
-   37931.994796, 37940.520155, 37949.045713, 37957.571470, 37966.097424, 37974.623577, 37983.149929, 37991.676478, 
-   38000.203225, 38008.730171, 38017.257314, 38025.784656, 38034.312195, 38042.839933, 38051.367868, 38059.896001, 
-   38068.424332, 38076.952861, 38085.481587, 38094.010511, 38102.539633, 38111.068952, 38119.598469, 38128.128184, 
-   38136.658096, 38145.188205, 38153.718512, 38162.249016, 38170.779718, 38179.310617, 38187.841713, 38196.373006, 
-   38204.904497, 38213.436184, 38221.968069, 38230.500151, 38239.032430, 38247.564905, 38256.097578, 38264.630448, 
-   38273.163514, 38281.696778, 38290.230238, 38298.763895, 38307.297748, 38315.831799, 38324.366046, 38332.900489, 
-   38341.435129, 38349.969966, 38358.504999, 38367.040229, 38375.575655, 38384.111277, 38392.647096, 38401.183110, 
-   38409.719322, 38418.255729, 38426.792333, 38435.329132, 38443.866128, 38452.403320, 38460.940708, 38469.478292, 
-   38478.016072, 38486.554047, 38495.092219, 38503.630586, 38512.169150, 38520.707909, 38529.246863, 38537.786014, 
-   38546.325360, 38554.864901, 38563.404638, 38571.944571, 38580.484699, 38589.025023, 38597.565542, 38606.106256, 
-   38614.647166, 38623.188271, 38631.729571, 38640.271067, 38648.812757, 38657.354643, 38665.896724, 38674.439000, 
-   38682.981471, 38691.524137, 38700.066998, 38708.610054, 38717.153305, 38725.696750, 38734.240391, 38742.784226, 
-   38751.328256, 38759.872480, 38768.416899, 38776.961513, 38785.506321, 38794.051324, 38802.596522, 38811.141913, 
-   38819.687500, 38828.233280, 38836.779255, 38845.325425, 38853.871788, 38862.418346, 38870.965098, 38879.512044, 
-   38888.059184, 38896.606519, 38905.154047, 38913.701770, 38922.249686, 38930.797796, 38939.346100, 38947.894598, 
-   38956.443290, 38964.992176, 38973.541255, 38982.090528, 38990.639995, 38999.189656, 39007.739510, 39016.289557, 
-   39024.839798, 39033.390233, 39041.940861, 39050.491682, 39059.042697, 39067.593905, 39076.145306, 39084.696901, 
-   39093.248689, 39101.800670, 39110.352844, 39118.905211, 39127.457771, 39136.010525, 39144.563471, 39153.116610, 
-   39161.669943, 39170.223468, 39178.777186, 39187.331097, 39195.885200, 39204.439496, 39212.993985, 39221.548667, 
-   39230.103541, 39238.658608, 39247.213867, 39255.769319, 39264.324964, 39272.880801, 39281.436830, 39289.993051, 
-   39298.549465, 39307.106071, 39315.662870, 39324.219861, 39332.777043, 39341.334418, 39349.891985, 39358.449745, 
-   39367.007696, 39375.565839, 39384.124174, 39392.682701, 39401.241420, 39409.800331, 39418.359434, 39426.918728, 
-   39435.478214, 39444.037892, 39452.597761, 39461.157822, 39469.718075, 39478.278519, 39486.839155, 39495.399982, 
-   39503.961001, 39512.522211, 39521.083612, 39529.645205, 39538.206989, 39546.768965, 39555.331131, 39563.893489, 
-   39572.456038, 39581.018778, 39589.581709, 39598.144831, 39606.708144, 39615.271648, 39623.835343, 39632.399229, 
-   39640.963306, 39649.527574, 39658.092032, 39666.656681, 39675.221521, 39683.786551, 39692.351773, 39700.917184, 
-   39709.482787, 39718.048580, 39726.614563, 39735.180737, 39743.747101, 39752.313656, 39760.880401, 39769.447336, 
-   39778.014461, 39786.581777, 39795.149283, 39803.716979, 39812.284866, 39820.852942, 39829.421209, 39837.989665, 
-   39846.558311, 39855.127148, 39863.696174, 39872.265390, 39880.834797, 39889.404392, 39897.974178, 39906.544153, 
-   39915.114319, 39923.684673, 39932.255218, 39940.825952, 39949.396875, 39957.967988, 39966.539291, 39975.110783, 
-   39983.682464, 39992.254335, 40000.826395, 40009.398644, 40017.971083, 40026.543711, 40035.116528, 40043.689534, 
-   40052.262730, 40060.836114, 40069.409688, 40077.983450, 40086.557402, 40095.131542, 40103.705871, 40112.280390, 
-   40120.855097, 40129.429993, 40138.005077, 40146.580351, 40155.155813, 40163.731464, 40172.307303, 40180.883331, 
-   40189.459548, 40198.035953, 40206.612546, 40215.189328, 40223.766298, 40232.343457, 40240.920804, 40249.498340, 
-   40258.076063, 40266.653975, 40275.232076, 40283.810364, 40292.388840, 40300.967505, 40309.546357, 40318.125398, 
-   40326.704627, 40335.284043, 40343.863648, 40352.443440, 40361.023420, 40369.603588, 40378.183944, 40386.764487, 
-   40395.345218, 40403.926137, 40412.507244, 40421.088538, 40429.670020, 40438.251689, 40446.833546, 40455.415590, 
-   40463.997821, 40472.580240, 40481.162847, 40489.745640, 40498.328621, 40506.911789, 40515.495145, 40524.078687, 
-   40532.662417, 40541.246334, 40549.830438, 40558.414729, 40566.999207, 40575.583872, 40584.168723, 40592.753762, 
-   40601.338988, 40609.924400, 40618.509999, 40627.095785, 40635.681758, 40644.267918, 40652.854264, 40661.440796, 
-   40670.027515, 40678.614421, 40687.201514, 40695.788792, 40704.376258, 40712.963909, 40721.551747, 40730.139772, 
-   40738.727982, 40747.316379, 40755.904963, 40764.493732, 40773.082687, 40781.671829, 40790.261157, 40798.850671, 
-   40807.440371, 40816.030257, 40824.620328, 40833.210586, 40841.801030, 40850.391659, 40858.982475, 40867.573476, 
-   40876.164663, 40884.756035, 40893.347594, 40901.939337, 40910.531267, 40919.123382, 40927.715683, 40936.308169, 
-   40944.900841, 40953.493698, 40962.086740, 40970.679968, 40979.273381, 40987.866980, 40996.460764, 41005.054733, 
-   41013.648887, 41022.243226, 41030.837751, 41039.432460, 41048.027355, 41056.622435, 41065.217700, 41073.813149, 
-   41082.408784, 41091.004603, 41099.600608, 41108.196797, 41116.793171, 41125.389730, 41133.986473, 41142.583401, 
-   41151.180514, 41159.777812, 41168.375294, 41176.972960, 41185.570811, 41194.168847, 41202.767067, 41211.365471, 
-   41219.964060, 41228.562833, 41237.161791, 41245.760933, 41254.360259, 41262.959769, 41271.559463, 41280.159342, 
-   41288.759405, 41297.359651, 41305.960082, 41314.560697, 41323.161496, 41331.762478, 41340.363645, 41348.964995, 
-   41357.566530, 41366.168248, 41374.770150, 41383.372236, 41391.974505, 41400.576958, 41409.179595, 41417.782415, 
-   41426.385419, 41434.988606, 41443.591977, 41452.195531, 41460.799269, 41469.403190, 41478.007295, 41486.611583, 
-   41495.216054, 41503.820708, 41512.425546, 41521.030567, 41529.635771, 41538.241158, 41546.846729, 41555.452482, 
-   41564.058418, 41572.664538, 41581.270840, 41589.877325, 41598.483994, 41607.090845, 41615.697879, 41624.305095, 
-   41632.912495, 41641.520077, 41650.127842, 41658.735789, 41667.343920, 41675.952232, 41684.560728, 41693.169406, 
-   41701.778266, 41710.387309, 41718.996534, 41727.605942, 41736.215532, 41744.825304, 41753.435259, 41762.045396, 
-   41770.655715, 41779.266216, 41787.876900, 41796.487766, 41805.098813, 41813.710043, 41822.321455, 41830.933049, 
-   41839.544825, 41848.156783, 41856.768922, 41865.381244, 41873.993747, 41882.606432, 41891.219299, 41899.832348, 
-   41908.445578, 41917.058990, 41925.672584, 41934.286359, 41942.900316, 41951.514455, 41960.128774, 41968.743276, 
-   41977.357959, 41985.972823, 41994.587868, 42003.203095, 42011.818504, 42020.434093, 42029.049864, 42037.665816, 
-   42046.281949, 42054.898263, 42063.514759, 42072.131435, 42080.748293, 42089.365331, 42097.982551, 42106.599951, 
-   42115.217532, 42123.835295, 42132.453238, 42141.071362, 42149.689666, 42158.308152, 42166.926818, 42175.545665, 
-   42184.164692, 42192.783900, 42201.403289, 42210.022858, 42218.642608, 42227.262539, 42235.882649, 42244.502940, 
-   42253.123412, 42261.744064, 42270.364896, 42278.985909, 42287.607101, 42296.228474, 42304.850028, 42313.471761, 
-   42322.093674, 42330.715768, 42339.338042, 42347.960495, 42356.583129, 42365.205943, 42373.828936, 42382.452110, 
-   42391.075463, 42399.698997, 42408.322710, 42416.946602, 42425.570675, 42434.194927, 42442.819359, 42451.443971, 
-   42460.068762, 42468.693733, 42477.318883, 42485.944213, 42494.569722, 42503.195411, 42511.821279, 42520.447327, 
-   42529.073554, 42537.699960, 42546.326546, 42554.953310, 42563.580254, 42572.207378, 42580.834680, 42589.462162, 
-   42598.089822, 42606.717662, 42615.345681, 42623.973879, 42632.602255, 42641.230811, 42649.859545, 42658.488459, 
-   42667.117551, 42675.746822, 42684.376272, 42693.005901, 42701.635708, 42710.265694, 42718.895859, 42727.526202, 
-   42736.156724, 42744.787424, 42753.418303, 42762.049361, 42770.680597, 42779.312011, 42787.943604, 42796.575375, 
-   42805.207324, 42813.839452, 42822.471758, 42831.104242, 42839.736905, 42848.369745, 42857.002764, 42865.635961, 
-   42874.269336, 42882.902889, 42891.536620, 42900.170529, 42908.804616, 42917.438881, 42926.073323, 42934.707944, 
-   42943.342743, 42951.977719, 42960.612873, 42969.248204, 42977.883714, 42986.519401, 42995.155266, 43003.791308, 
-   43012.427528, 43021.063925, 43029.700500, 43038.337253, 43046.974183, 43055.611290, 43064.248575, 43072.886037, 
-   43081.523676, 43090.161493, 43098.799486, 43107.437658, 43116.076006, 43124.714531, 43133.353234, 43141.992114, 
-   43150.631170, 43159.270404, 43167.909815, 43176.549403, 43185.189168, 43193.829109, 43202.469228, 43211.109523, 
-   43219.749995, 43228.390644, 43237.031470, 43245.672473, 43254.313652, 43262.955008, 43271.596540, 43280.238249, 
-   43288.880135, 43297.522197, 43306.164436, 43314.806851, 43323.449442, 43332.092210, 43340.735155, 43349.378276, 
-   43358.021573, 43366.665046, 43375.308696, 43383.952521, 43392.596524, 43401.240702, 43409.885056, 43418.529586, 
-   43427.174293, 43435.819176, 43444.464234, 43453.109469, 43461.754879, 43470.400466, 43479.046228, 43487.692166, 
-   43496.338280, 43504.984570, 43513.631035, 43522.277677, 43530.924493, 43539.571486, 43548.218654, 43556.865998, 
-   43565.513518, 43574.161213, 43582.809083, 43591.457129, 43600.105351, 43608.753748, 43617.402320, 43626.051067, 
-   43634.699990, 43643.349089, 43651.998362, 43660.647811, 43669.297435, 43677.947234, 43686.597208, 43695.247358, 
-   43703.897682, 43712.548182, 43721.198856, 43729.849706, 43738.500731, 43747.151930, 43755.803304, 43764.454854, 
-   43773.106578, 43781.758477, 43790.410550, 43799.062799, 43807.715222, 43816.367820, 43825.020592, 43833.673539, 
-   43842.326661, 43850.979957, 43859.633428, 43868.287073, 43876.940893, 43885.594887, 43894.249056, 43902.903399, 
-   43911.557917, 43920.212608, 43928.867474, 43937.522514, 43946.177729, 43954.833118, 43963.488681, 43972.144418, 
-   43980.800329, 43989.456414, 43998.112673, 44006.769106, 44015.425714, 44024.082495, 44032.739450, 44041.396579, 
-   44050.053882, 44058.711359, 44067.369009, 44076.026833, 44084.684831, 44093.343003, 44102.001349, 44110.659868, 
-   44119.318561, 44127.977427, 44136.636467, 44145.295680, 44153.955067, 44162.614628, 44171.274362, 44179.934269, 
-   44188.594350, 44197.254604, 44205.915031, 44214.575632, 44223.236406, 44231.897353, 44240.558473, 44249.219767, 
-   44257.881233, 44266.542873, 44275.204686, 44283.866672, 44292.528831, 44301.191163, 44309.853668, 44318.516346, 
-   44327.179196, 44335.842220, 44344.505416, 44353.168786, 44361.832328, 44370.496043, 44379.159930, 44387.823991, 
-   44396.488223, 44405.152629, 44413.817207, 44422.481958, 44431.146881, 44439.811977, 44448.477245, 44457.142686, 
-   44465.808299, 44474.474085, 44483.140043, 44491.806173, 44500.472476, 44509.138951, 44517.805598, 44526.472417, 
-   44535.139409, 44543.806573, 44552.473908, 44561.141416, 44569.809096, 44578.476948, 44587.144973, 44595.813169, 
-   44604.481537, 44613.150077, 44621.818788, 44630.487672, 44639.156728, 44647.825955, 44656.495354, 44665.164925, 
-   44673.834668, 44682.504582, 44691.174668, 44699.844925, 44708.515355, 44717.185955, 44725.856728, 44734.527671, 
-   44743.198787, 44751.870073, 44760.541531, 44769.213161, 44777.884962, 44786.556934, 44795.229078, 44803.901393, 
-   44812.573879, 44821.246536, 44829.919364, 44838.592364, 44847.265535, 44855.938877, 44864.612390, 44873.286074, 
-   44881.959929, 44890.633955, 44899.308152, 44907.982519, 44916.657058, 44925.331768, 44934.006648, 44942.681700, 
-   44951.356922, 44960.032314, 44968.707878, 44977.383612, 44986.059517, 44994.735593, 45003.411839, 45012.088255, 
-   45020.764843, 45029.441600, 45038.118529, 45046.795627, 45055.472896, 45064.150336, 45072.827946, 45081.505726, 
-   45090.183677, 45098.861798, 45107.540089, 45116.218550, 45124.897182, 45133.575983, 45142.254955, 45150.934097, 
-   45159.613409, 45168.292891, 45176.972543, 45185.652366, 45194.332358, 45203.012520, 45211.692852, 45220.373353, 
-   45229.054025, 45237.734866, 45246.415878, 45255.097059, 45263.778410, 45272.459930, 45281.141620, 45289.823480, 
-   45298.505509, 45307.187709, 45315.870077, 45324.552615, 45333.235323, 45341.918200, 45350.601247, 45359.284462, 
-   45367.967848, 45376.651403, 45385.335127, 45394.019020, 45402.703083, 45411.387315, 45420.071716, 45428.756286, 
-   45437.441025, 45446.125934, 45454.811012, 45463.496258, 45472.181674, 45480.867259, 45489.553013, 45498.238936, 
-   45506.925028, 45515.611288, 45524.297718, 45532.984316, 45541.671083, 45550.358019, 45559.045124, 45567.732397, 
-   45576.419840, 45585.107450, 45593.795230, 45602.483178, 45611.171295, 45619.859580, 45628.548034, 45637.236656, 
-   45645.925447, 45654.614406, 45663.303534, 45671.992830, 45680.682294, 45689.371927, 45698.061728, 45706.751697, 
-   45715.441835, 45724.132141, 45732.822615, 45741.513257, 45750.204067, 45758.895046, 45767.586192, 45776.277507, 
-   45784.968989, 45793.660640, 45802.352458, 45811.044445, 45819.736599, 45828.428921, 45837.121412, 45845.814070, 
-   45854.506895, 45863.199889, 45871.893050, 45880.586379, 45889.279876, 45897.973540, 45906.667372, 45915.361372, 
-   45924.055539, 45932.749874, 45941.444376, 45950.139045, 45958.833883, 45967.528887, 45976.224059, 45984.919399, 
-   45993.614905, 46002.310579, 46011.006421, 46019.702429, 46028.398605, 46037.094948, 46045.791458, 46054.488136, 
-   46063.184980, 46071.881992, 46080.579171, 46089.276516, 46097.974029, 46106.671709, 46115.369556, 46124.067569, 
-   46132.765750, 46141.464097, 46150.162611, 46158.861292, 46167.560140, 46176.259155, 46184.958336, 46193.657684, 
-   46202.357199, 46211.056880, 46219.756728, 46228.456743, 46237.156924, 46245.857272, 46254.557786, 46263.258467, 
-   46271.959314, 46280.660328, 46289.361508, 46298.062854, 46306.764367, 46315.466046, 46324.167891, 46332.869903, 
-   46341.572081, 46350.274425, 46358.976935, 46367.679612, 46376.382454, 46385.085463, 46393.788638, 46402.491978, 
-   46411.195485, 46419.899158, 46428.602997, 46437.307001, 46446.011172, 46454.715508, 46463.420011, 46472.124679, 
-   46480.829513, 46489.534512, 46498.239678, 46506.945009, 46515.650506, 46524.356168, 46533.061996, 46541.767990, 
-   46550.474149, 46559.180474, 46567.886964, 46576.593620, 46585.300442, 46594.007428, 46602.714581, 46611.421898, 
-   46620.129381, 46628.837029, 46637.544843, 46646.252822, 46654.960966, 46663.669275, 46672.377749, 46681.086389, 
-   46689.795194, 46698.504164, 46707.213299, 46715.922599, 46724.632064, 46733.341694, 46742.051489, 46750.761449, 
-   46759.471574, 46768.181864, 46776.892319, 46785.602938, 46794.313722, 46803.024672, 46811.735785, 46820.447064, 
-   46829.158507, 46837.870115, 46846.581888, 46855.293825, 46864.005927, 46872.718194, 46881.430625, 46890.143220, 
-   46898.855980, 46907.568904, 46916.281993, 46924.995247, 46933.708664, 46942.422246, 46951.135993, 46959.849903, 
-   46968.563978, 46977.278217, 46985.992621, 46994.707188, 47003.421920, 47012.136816, 47020.851876, 47029.567100, 
-   47038.282488, 47046.998040, 47055.713756, 47064.429636, 47073.145680, 47081.861888, 47090.578260, 47099.294796, 
-   47108.011495, 47116.728359, 47125.445386, 47134.162577, 47142.879932, 47151.597450, 47160.315132, 47169.032978, 
-   47177.750987, 47186.469160, 47195.187496, 47203.905996, 47212.624660, 47221.343487, 47230.062478, 47238.781632, 
-   47247.500949, 47256.220430, 47264.940074, 47273.659881, 47282.379852, 47291.099986, 47299.820283, 47308.540744, 
-   47317.261368, 47325.982154, 47334.703104, 47343.424218, 47352.145494, 47360.866933, 47369.588536, 47378.310301, 
-   47387.032229, 47395.754321, 47404.476575, 47413.198992, 47421.921572, 47430.644315, 47439.367220, 47448.090289, 
-   47456.813520, 47465.536914, 47474.260471, 47482.984190, 47491.708073, 47500.432117, 47509.156325, 47517.880695, 
-   47526.605227, 47535.329922, 47544.054780, 47552.779800, 47561.504982, 47570.230327, 47578.955835, 47587.681504, 
-   47596.407336, 47605.133331, 47613.859487, 47622.585806, 47631.312288, 47640.038931, 47648.765737, 47657.492704, 
-   47666.219834, 47674.947126, 47683.674580, 47692.402197, 47701.129975, 47709.857915, 47718.586017, 47727.314281, 
-   47736.042707, 47744.771295, 47753.500045, 47762.228957, 47770.958031, 47779.687266, 47788.416663, 47797.146222, 
-   47805.875943, 47814.605825, 47823.335869, 47832.066074, 47840.796442, 47849.526970, 47858.257661, 47866.988513, 
-   47875.719526, 47884.450701, 47893.182037, 47901.913535, 47910.645194, 47919.377015, 47928.108997, 47936.841140, 
-   47945.573445, 47954.305911, 47963.038538, 47971.771326, 47980.504275, 47989.237386, 47997.970658, 48006.704091, 
-   48015.437685, 48024.171440, 48032.905356, 48041.639434, 48050.373672, 48059.108071, 48067.842631, 48076.577352, 
-   48085.312234, 48094.047277, 48102.782480, 48111.517845, 48120.253370, 48128.989056, 48137.724902, 48146.460910, 
-   48155.197078, 48163.933407, 48172.669896, 48181.406546, 48190.143356, 48198.880328, 48207.617459, 48216.354751, 
-   48225.092204, 48233.829817, 48242.567590, 48251.305524, 48260.043618, 48268.781873, 48277.520288, 48286.258863, 
-   48294.997599, 48303.736494, 48312.475550, 48321.214766, 48329.954143, 48338.693679, 48347.433376, 48356.173232, 
-   48364.913249, 48373.653426, 48382.393762, 48391.134259, 48399.874916, 48408.615732, 48417.356709, 48426.097845, 
-   48434.839142, 48443.580598, 48452.322214, 48461.063989, 48469.805925, 48478.548020, 48487.290275, 48496.032689, 
-   48504.775264, 48513.517998, 48522.260891, 48531.003944, 48539.747157, 48548.490529, 48557.234060, 48565.977752, 
-   48574.721602, 48583.465612, 48592.209782, 48600.954110, 48609.698598, 48618.443246, 48627.188053, 48635.933019, 
-   48644.678144, 48653.423428, 48662.168872, 48670.914475, 48679.660237, 48688.406158, 48697.152238, 48705.898477, 
-   48714.644876, 48723.391433, 48732.138150, 48740.885025, 48749.632059, 48758.379252, 48767.126604, 48775.874115, 
-   48784.621785, 48793.369614, 48802.117601, 48810.865747, 48819.614052, 48828.362516, 48837.111138, 48845.859919, 
-   48854.608859, 48863.357957, 48872.107214, 48880.856629, 48889.606203, 48898.355936, 48907.105827, 48915.855876, 
-   48924.606084, 48933.356450, 48942.106975, 48950.857658, 48959.608499, 48968.359499, 48977.110657, 48985.861973, 
-   48994.613448, 49003.365080, 49012.116871, 49020.868820, 49029.620928, 49038.373193, 49047.125616, 49055.878198, 
-   49064.630937, 49073.383835, 49082.136890, 49090.890104, 49099.643475, 49108.397005, 49117.150692, 49125.904537, 
-   49134.658540, 49143.412701, 49152.167019, 49160.921495, 49169.676129, 49178.430921, 49187.185871, 49195.940978, 
-   49204.696243, 49213.451665, 49222.207245, 49230.962982, 49239.718877, 49248.474930, 49257.231140, 49265.987508, 
-   49274.744033, 49283.500715, 49292.257555, 49301.014552, 49309.771707, 49318.529019, 49327.286488, 49336.044114, 
-   49344.801898, 49353.559839, 49362.317937, 49371.076192, 49379.834604, 49388.593174, 49397.351900, 49406.110784, 
-   49414.869825, 49423.629023, 49432.388377, 49441.147889, 49449.907558, 49458.667383, 49467.427366, 49476.187505, 
-   49484.947801, 49493.708254, 49502.468864, 49511.229631, 49519.990554, 49528.751634, 49537.512871, 49546.274265, 
-   49555.035815, 49563.797522, 49572.559385, 49581.321405, 49590.083581, 49598.845915, 49607.608404, 49616.371050, 
-   49625.133853, 49633.896811, 49642.659927, 49651.423199, 49660.186627, 49668.950211, 49677.713952, 49686.477849, 
-   49695.241902, 49704.006112, 49712.770477, 49721.534999, 49730.299677, 49739.064511, 49747.829502, 49756.594648, 
-   49765.359951, 49774.125409, 49782.891024, 49791.656794, 49800.422721, 49809.188803, 49817.955042, 49826.721436, 
-   49835.487986, 49844.254692, 49853.021554, 49861.788572, 49870.555745, 49879.323074, 49888.090559, 49896.858200, 
-   49905.625996, 49914.393948, 49923.162055, 49931.930318, 49940.698737, 49949.467311, 49958.236041, 49967.004927, 
-   49975.773967, 49984.543164, 49993.312515, 50002.082022, 50010.851685, 50019.621503, 50028.391476, 50037.161605, 
-   50045.931888, 50054.702327, 50063.472922, 50072.243671, 50081.014576, 50089.785636, 50098.556851, 50107.328221, 
-   50116.099747, 50124.871427, 50133.643262, 50142.415253, 50151.187398, 50159.959699, 50168.732154, 50177.504764, 
-   50186.277529, 50195.050450, 50203.823525, 50212.596754, 50221.370139, 50230.143678, 50238.917372, 50247.691221, 
-   50256.465225, 50265.239383, 50274.013696, 50282.788164, 50291.562786, 50300.337563, 50309.112494, 50317.887580, 
-   50326.662821, 50335.438216, 50344.213765, 50352.989469, 50361.765327, 50370.541340, 50379.317507, 50388.093828, 
-   50396.870304, 50405.646934, 50414.423719, 50423.200657, 50431.977750, 50440.754997, 50449.532399, 50458.309954, 
-   50467.087664, 50475.865527, 50484.643545, 50493.421717, 50502.200043, 50510.978523, 50519.757157, 50528.535945, 
-   50537.314887, 50546.093983, 50554.873232, 50563.652636, 50572.432193, 50581.211905, 50589.991770, 50598.771789, 
-   50607.551961, 50616.332288, 50625.112768, 50633.893402, 50642.674189, 50651.455130, 50660.236225, 50669.017473, 
-   50677.798875, 50686.580431, 50695.362140, 50704.144002, 50712.926018, 50721.708187, 50730.490510, 50739.272987, 
-   50748.055616, 50756.838399, 50765.621336, 50774.404425, 50783.187668, 50791.971064, 50800.754614, 50809.538317, 
-   50818.322173, 50827.106182, 50835.890344, 50844.674659, 50853.459128, 50862.243749, 50871.028524, 50879.813451, 
-   50888.598532, 50897.383766, 50906.169152, 50914.954692, 50923.740384, 50932.526230, 50941.312228, 50950.098379, 
-   50958.884683, 50967.671139, 50976.457749, 50985.244511, 50994.031426, 51002.818494, 51011.605714, 51020.393087, 
-   51029.180613, 51037.968291, 51046.756122, 51055.544105, 51064.332241, 51073.120529, 51081.908970, 51090.697564, 
-   51099.486310, 51108.275208, 51117.064259, 51125.853462, 51134.642817, 51143.432325, 51152.221985, 51161.011798, 
-   51169.801762, 51178.591879, 51187.382148, 51196.172569, 51204.963143, 51213.753869, 51222.544746, 51231.335776, 
-   51240.126958, 51248.918292, 51257.709778, 51266.501416, 51275.293206, 51284.085148, 51292.877242, 51301.669488, 
-   51310.461886, 51319.254435, 51328.047137, 51336.839990, 51345.632995, 51354.426152, 51363.219461, 51372.012921, 
-   51380.806533, 51389.600297, 51398.394212, 51407.188279, 51415.982498, 51424.776868, 51433.571390, 51442.366064, 
-   51451.160889, 51459.955865, 51468.750993, 51477.546272, 51486.341703, 51495.137285, 51503.933019, 51512.728904, 
-   51521.524940, 51530.321128, 51539.117467, 51547.913957, 51556.710598, 51565.507391, 51574.304335, 51583.101430, 
-   51591.898676, 51600.696074, 51609.493622, 51618.291322, 51627.089172, 51635.887174, 51644.685327, 51653.483631, 
-   51662.282085, 51671.080691, 51679.879447, 51688.678355, 51697.477413, 51706.276623, 51715.075983, 51723.875494, 
-   51732.675155, 51741.474968, 51750.274931, 51759.075045, 51767.875310, 51776.675725, 51785.476291, 51794.277007, 
-   51803.077875, 51811.878893, 51820.680061, 51829.481380, 51838.282849, 51847.084469, 51855.886240, 51864.688161, 
-   51873.490232, 51882.292454, 51891.094826, 51899.897348, 51908.700021, 51917.502844, 51926.305818, 51935.108942, 
-   51943.912216, 51952.715640, 51961.519214, 51970.322939, 51979.126814, 51987.930838, 51996.735013, 52005.539339, 
-   52014.343814, 52023.148439, 52031.953214, 52040.758140, 52049.563215, 52058.368440, 52067.173815, 52075.979340, 
-   52084.785015, 52093.590840, 52102.396815, 52111.202939, 52120.009213, 52128.815637, 52137.622211, 52146.428935, 
-   52155.235808, 52164.042831, 52172.850004, 52181.657326, 52190.464798, 52199.272419, 52208.080190, 52216.888111, 
-   52225.696181, 52234.504401, 52243.312770, 52252.121289, 52260.929957, 52269.738774, 52278.547741, 52287.356857, 
-   52296.166123, 52304.975538, 52313.785102, 52322.594816, 52331.404678, 52340.214690, 52349.024852, 52357.835162, 
-   52366.645622, 52375.456231, 52384.266989, 52393.077896, 52401.888952, 52410.700157, 52419.511511, 52428.323014, 
-   52437.134667, 52445.946468, 52454.758418, 52463.570517, 52472.382765, 52481.195162, 52490.007708, 52498.820402, 
-   52507.633246, 52516.446238, 52525.259379, 52534.072669, 52542.886107, 52551.699695, 52560.513430, 52569.327315, 
-   52578.141348, 52586.955530, 52595.769860, 52604.584339, 52613.398967, 52622.213743, 52631.028668, 52639.843741, 
-   52648.658962, 52657.474332, 52666.289851, 52675.105518, 52683.921333, 52692.737296, 52701.553408, 52710.369668, 
-   52719.186077, 52728.002634, 52736.819339, 52745.636192, 52754.453193, 52763.270343, 52772.087641, 52780.905087, 
-   52789.722681, 52798.540423, 52807.358313, 52816.176351, 52824.994538, 52833.812872, 52842.631354, 52851.449984, 
-   52860.268763, 52869.087689, 52877.906763, 52886.725985, 52895.545354, 52904.364872, 52913.184537, 52922.004350, 
-   52930.824311, 52939.644420, 52948.464676, 52957.285080, 52966.105632, 52974.926331, 52983.747178, 52992.568173, 
-   53001.389315, 53010.210605, 53019.032042, 53027.853627, 53036.675360, 53045.497240, 53054.319267, 53063.141442, 
-   53071.963764, 53080.786233, 53089.608850, 53098.431615, 53107.254526, 53116.077585, 53124.900791, 53133.724145, 
-   53142.547646, 53151.371294, 53160.195089, 53169.019031, 53177.843121, 53186.667357, 53195.491741, 53204.316272, 
-   53213.140950, 53221.965775, 53230.790747, 53239.615866, 53248.441131, 53257.266544, 53266.092104, 53274.917811, 
-   53283.743665, 53292.569665, 53301.395813, 53310.222107, 53319.048548, 53327.875136, 53336.701870, 53345.528752, 
-   53354.355780, 53363.182955, 53372.010276, 53380.837744, 53389.665359, 53398.493120, 53407.321028, 53416.149083, 
-   53424.977284, 53433.805631, 53442.634126, 53451.462766, 53460.291553, 53469.120487, 53477.949567, 53486.778793, 
-   53495.608166, 53504.437685, 53513.267350, 53522.097162, 53530.927120, 53539.757224, 53548.587475, 53557.417872, 
-   53566.248415, 53575.079104, 53583.909939, 53592.740921, 53601.572049, 53610.403322, 53619.234742, 53628.066308, 
-   53636.898020, 53645.729878, 53654.561882, 53663.394032, 53672.226328, 53681.058769, 53689.891357, 53698.724091, 
-   53707.556970, 53716.389995, 53725.223167, 53734.056483, 53742.889946, 53751.723555, 53760.557309, 53769.391209, 
-   53778.225254, 53787.059446, 53795.893783, 53804.728265, 53813.562894, 53822.397667, 53831.232587, 53840.067652, 
-   53848.902862, 53857.738218, 53866.573720, 53875.409367, 53884.245159, 53893.081097, 53901.917180, 53910.753408, 
-   53919.589782, 53928.426302, 53937.262966, 53946.099776, 53954.936731, 53963.773832, 53972.611077, 53981.448468, 
-   53990.286004, 53999.123685, 54007.961512, 54016.799483, 54025.637600, 54034.475862, 54043.314268, 54052.152820, 
-   54060.991517, 54069.830359, 54078.669346, 54087.508477, 54096.347754, 54105.187176, 54114.026742, 54122.866453, 
-   54131.706310, 54140.546311, 54149.386457, 54158.226747, 54167.067183, 54175.907763, 54184.748488, 54193.589357, 
-   54202.430372, 54211.271531, 54220.112834, 54228.954283, 54237.795875, 54246.637613, 54255.479495, 54264.321521, 
-   54273.163692, 54282.006008, 54290.848468, 54299.691073, 54308.533821, 54317.376715, 54326.219753, 54335.062935, 
-   54343.906261, 54352.749732, 54361.593347, 54370.437106, 54379.281010, 54388.125058, 54396.969250, 54405.813586, 
-   54414.658067, 54423.502692, 54432.347460, 54441.192373, 54450.037430, 54458.882631, 54467.727977, 54476.573466, 
-   54485.419099, 54494.264876, 54503.110798, 54511.956863, 54520.803072, 54529.649425, 54538.495922, 54547.342563, 
-   54556.189347, 54565.036276, 54573.883348, 54582.730564, 54591.577924, 54600.425428, 54609.273075, 54618.120866, 
-   54626.968801, 54635.816879, 54644.665102, 54653.513467, 54662.361977, 54671.210629, 54680.059426, 54688.908366, 
-   54697.757449, 54706.606676, 54715.456047, 54724.305561, 54733.155218, 54742.005019, 54750.854963, 54759.705051, 
-   54768.555282, 54777.405656, 54786.256174, 54795.106835, 54803.957639, 54812.808586, 54821.659677, 54830.510911, 
-   54839.362288, 54848.213808, 54857.065472, 54865.917278, 54874.769228, 54883.621321, 54892.473557, 54901.325936, 
-   54910.178457, 54919.031122, 54927.883930, 54936.736881, 54945.589975, 54954.443212, 54963.296591, 54972.150114, 
-   54981.003779, 54989.857588, 54998.711539, 55007.565633, 55016.419869, 55025.274249, 55034.128771, 55042.983436, 
-   55051.838244, 55060.693194, 55069.548287, 55078.403523, 55087.258901, 55096.114422, 55104.970085, 55113.825891, 
-   55122.681840, 55131.537931, 55140.394164, 55149.250540, 55158.107059, 55166.963720, 55175.820523, 55184.677469, 
-   55193.534557, 55202.391787, 55211.249160, 55220.106675, 55228.964333, 55237.822133, 55246.680075, 55255.538159, 
-   55264.396385, 55273.254754, 55282.113265, 55290.971918, 55299.830713, 55308.689650, 55317.548729, 55326.407951, 
-   55335.267314, 55344.126820, 55352.986467, 55361.846257, 55370.706188, 55379.566261, 55388.426477, 55397.286834, 
-   55406.147333, 55415.007974, 55423.868757, 55432.729682, 55441.590749, 55450.451957, 55459.313307, 55468.174799, 
-   55477.036432, 55485.898208, 55494.760125, 55503.622183, 55512.484384, 55521.346726, 55530.209209, 55539.071834, 
-   55547.934601, 55556.797509, 55565.660559, 55574.523751, 55583.387083, 55592.250558, 55601.114174, 55609.977931, 
-   55618.841829, 55627.705869, 55636.570051, 55645.434373, 55654.298837, 55663.163443, 55672.028190, 55680.893077, 
-   55689.758107, 55698.623277, 55707.488589, 55716.354042, 55725.219636, 55734.085371, 55742.951247, 55751.817264, 
-   55760.683423, 55769.549722, 55778.416163, 55787.282745, 55796.149467, 55805.016331, 55813.883336, 55822.750481, 
-   55831.617768, 55840.485195, 55849.352764, 55858.220473, 55867.088323, 55875.956314, 55884.824445, 55893.692718, 
-   55902.561131, 55911.429685, 55920.298380, 55929.167216, 55938.036192, 55946.905309, 55955.774566, 55964.643964, 
-   55973.513503, 55982.383182, 55991.253002, 56000.122963, 56008.993064, 56017.863305, 56026.733688, 56035.604210, 
-   56044.474873, 56053.345677, 56062.216620, 56071.087705, 56079.958929, 56088.830294, 56097.701800, 56106.573445, 
-   56115.445231, 56124.317158, 56133.189224, 56142.061431, 56150.933778, 56159.806265, 56168.678892, 56177.551660, 
-   56186.424568, 56195.297615, 56204.170803, 56213.044131, 56221.917599, 56230.791207, 56239.664956, 56248.538844, 
-   56257.412872, 56266.287040, 56275.161348, 56284.035796, 56292.910384, 56301.785112, 56310.659979, 56319.534987, 
-   56328.410134, 56337.285421, 56346.160848, 56355.036415, 56363.912121, 56372.787967, 56381.663953, 56390.540079, 
-   56399.416344, 56408.292749, 56417.169294, 56426.045978, 56434.922801, 56443.799765, 56452.676868, 56461.554110, 
-   56470.431492, 56479.309014, 56488.186674, 56497.064475, 56505.942415, 56514.820494, 56523.698713, 56532.577071, 
-   56541.455568, 56550.334205, 56559.212981, 56568.091896, 56576.970951, 56585.850145, 56594.729478, 56603.608950, 
-   56612.488562, 56621.368313, 56630.248203, 56639.128232, 56648.008400, 56656.888708, 56665.769154, 56674.649740, 
-   56683.530464, 56692.411328, 56701.292330, 56710.173472, 56719.054753, 56727.936172, 56736.817731, 56745.699428, 
-   56754.581264, 56763.463239, 56772.345354, 56781.227606, 56790.109998, 56798.992529, 56807.875198, 56816.758006, 
-   56825.640953, 56834.524038, 56843.407263, 56852.290625, 56861.174127, 56870.057767, 56878.941546, 56887.825464, 
-   56896.709520, 56905.593714, 56914.478047, 56923.362519, 56932.247129, 56941.131878, 56950.016765, 56958.901791, 
-   56967.786955, 56976.672258, 56985.557699, 56994.443278, 57003.328995, 57012.214851, 57021.100846, 57029.986978, 
-   57038.873249, 57047.759658, 57056.646206, 57065.532892, 57074.419715, 57083.306677, 57092.193778, 57101.081016, 
-   57109.968392, 57118.855907, 57127.743560, 57136.631350, 57145.519279, 57154.407346, 57163.295551, 57172.183894, 
-   57181.072375, 57189.960994, 57198.849750, 57207.738645, 57216.627678, 57225.516848, 57234.406156, 57243.295602, 
-   57252.185186, 57261.074908, 57269.964768, 57278.854765, 57287.744900, 57296.635173, 57305.525584, 57314.416132, 
-   57323.306818, 57332.197641, 57341.088603, 57349.979702, 57358.870938, 57367.762312, 57376.653824, 57385.545473, 
-   57394.437259, 57403.329183, 57412.221245, 57421.113444, 57430.005781, 57438.898255, 57447.790866, 57456.683615, 
-   57465.576501, 57474.469524, 57483.362685, 57492.255983, 57501.149419, 57510.042992, 57518.936702, 57527.830549, 
-   57536.724533, 57545.618655, 57554.512914, 57563.407310, 57572.301843, 57581.196513, 57590.091320, 57598.986265, 
-   57607.881346, 57616.776565, 57625.671921, 57634.567413, 57643.463043, 57652.358809, 57661.254713, 57670.150754, 
-   57679.046931, 57687.943245, 57696.839696, 57705.736285, 57714.633009, 57723.529871, 57732.426870, 57741.324005, 
-   57750.221277, 57759.118686, 57768.016232, 57776.913914, 57785.811733, 57794.709689, 57803.607781, 57812.506010, 
-   57821.404376, 57830.302878, 57839.201517, 57848.100292, 57856.999204, 57865.898252, 57874.797437, 57883.696759, 
-   57892.596217, 57901.495811, 57910.395542, 57919.295409, 57928.195413, 57937.095553, 57945.995829, 57954.896242, 
-   57963.796791, 57972.697476, 57981.598298, 57990.499255, 57999.400350, 58008.301580, 58017.202946, 58026.104449, 
-   58035.006088, 58043.907863, 58052.809774, 58061.711822, 58070.614005, 58079.516325, 58088.418780, 58097.321372, 
-   58106.224100, 58115.126963, 58124.029963, 58132.933099, 58141.836370, 58150.739778, 58159.643321, 58168.547001, 
-   58177.450816, 58186.354767, 58195.258854, 58204.163076, 58213.067435, 58221.971929, 58230.876559, 58239.781325, 
-   58248.686227, 58257.591264, 58266.496437, 58275.401746, 58284.307190, 58293.212770, 58302.118486, 58311.024337, 
-   58319.930324, 58328.836446, 58337.742704, 58346.649097, 58355.555626, 58364.462291, 58373.369090, 58382.276026, 
-   58391.183097, 58400.090303, 58408.997644, 58417.905121, 58426.812734, 58435.720481, 58444.628364, 58453.536383, 
-   58462.444536, 58471.352825, 58480.261249, 58489.169809, 58498.078503, 58506.987333, 58515.896298, 58524.805398, 
-   58533.714633, 58542.624004, 58551.533509, 58560.443150, 58569.352926, 58578.262836, 58587.172882, 58596.083063, 
-   58604.993379, 58613.903829, 58622.814415, 58631.725136, 58640.635991, 58649.546982, 58658.458107, 58667.369368, 
-   58676.280763, 58685.192293, 58694.103957, 58703.015757, 58711.927691, 58720.839760, 58729.751964, 58738.664303, 
-   58747.576776, 58756.489384, 58765.402127, 58774.315004, 58783.228016, 58792.141162, 58801.054444, 58809.967859, 
-   58818.881410, 58827.795094, 58836.708914, 58845.622868, 58854.536956, 58863.451179, 58872.365536, 58881.280028, 
-   58890.194654, 58899.109414, 58908.024309, 58916.939339, 58925.854502, 58934.769800, 58943.685232, 58952.600799, 
-   58961.516500, 58970.432335, 58979.348304, 58988.264408, 58997.180645, 59006.097017, 59015.013523, 59023.930164, 
-   59032.846938, 59041.763846, 59050.680889, 59059.598066, 59068.515376, 59077.432821, 59086.350400, 59095.268113, 
-   59104.185959, 59113.103940, 59122.022055, 59130.940303, 59139.858686, 59148.777202, 59157.695852, 59166.614637, 
-   59175.533555, 59184.452606, 59193.371792, 59202.291111, 59211.210565, 59220.130151, 59229.049872, 59237.969726, 
-   59246.889715, 59255.809836, 59264.730092, 59273.650481, 59282.571003, 59291.491660, 59300.412450, 59309.333373, 
-   59318.254430, 59327.175621, 59336.096945, 59345.018402, 59353.939993, 59362.861718, 59371.783576, 59380.705567, 
-   59389.627692, 59398.549950, 59407.472342, 59416.394867, 59425.317525, 59434.240317, 59443.163242, 59452.086300, 
-   59461.009491, 59469.932816, 59478.856274, 59487.779865, 59496.703590, 59505.627447, 59514.551438, 59523.475562, 
-   59532.399819, 59541.324209, 59550.248732, 59559.173389, 59568.098178, 59577.023100, 59585.948156, 59594.873344, 
-   59603.798666, 59612.724120, 59621.649707, 59630.575428, 59639.501281, 59648.427267, 59657.353386, 59666.279638, 
-   59675.206023, 59684.132540, 59693.059190, 59701.985973, 59710.912889, 59719.839938, 59728.767119, 59737.694433, 
-   59746.621880, 59755.549460, 59764.477172, 59773.405017, 59782.332994, 59791.261104, 59800.189347, 59809.117722, 
-   59818.046230, 59826.974870, 59835.903643, 59844.832549, 59853.761587, 59862.690757, 59871.620060, 59880.549495, 
-   59889.479063, 59898.408763, 59907.338596, 59916.268560, 59925.198658, 59934.128887, 59943.059249, 59951.989743, 
-   59960.920370, 59969.851128, 59978.782019, 59987.713043, 59996.644198, 60005.575486, 60014.506906, 60023.438458, 
-   60032.370142, 60041.301958, 60050.233906, 60059.165987, 60068.098199, 60077.030544, 60085.963020, 60094.895629, 
-   60103.828370, 60112.761242, 60121.694247, 60130.627383, 60139.560652, 60148.494052, 60157.427585, 60166.361249, 
-   60175.295045, 60184.228973, 60193.163032, 60202.097224, 60211.031547, 60219.966002, 60228.900589, 60237.835308, 
-   60246.770158, 60255.705140, 60264.640254, 60273.575499, 60282.510876, 60291.446385, 60300.382025, 60309.317797, 
-   60318.253701, 60327.189736, 60336.125903, 60345.062201, 60353.998631, 60362.935192, 60371.871884, 60380.808709, 
-   60389.745664, 60398.682751, 60407.619970, 60416.557320, 60425.494801, 60434.432413, 60443.370157, 60452.308033, 
-   60461.246039, 60470.184177, 60479.122446, 60488.060847, 60496.999378, 60505.938041, 60514.876835, 60523.815760, 
-   60532.754817, 60541.694005, 60550.633323, 60559.572773, 60568.512354, 60577.452066, 60586.391909, 60595.331883, 
-   60604.271989, 60613.212225, 60622.152592, 60631.093090, 60640.033720, 60648.974480, 60657.915371, 60666.856393, 
-   60675.797546, 60684.738829, 60693.680244, 60702.621789, 60711.563466, 60720.505273, 60729.447211, 60738.389279, 
-   60747.331479, 60756.273809, 60765.216270, 60774.158862, 60783.101584, 60792.044437, 60800.987421, 60809.930535, 
-   60818.873780, 60827.817155, 60836.760662, 60845.704298, 60854.648066, 60863.591963, 60872.535992, 60881.480151, 
-   60890.424440, 60899.368860, 60908.313410, 60917.258091, 60926.202902, 60935.147843, 60944.092915, 60953.038117, 
-   60961.983450, 60970.928913, 60979.874506, 60988.820230, 60997.766084, 61006.712068, 61015.658182, 61024.604427, 
-   61033.550802, 61042.497307, 61051.443942, 61060.390707, 61069.337603, 61078.284628, 61087.231784, 61096.179070, 
-   61105.126486, 61114.074032, 61123.021708, 61131.969514, 61140.917450, 61149.865516, 61158.813712, 61167.762038, 
-   61176.710494, 61185.659080, 61194.607796, 61203.556642, 61212.505618, 61221.454723, 61230.403958, 61239.353323, 
-   61248.302818, 61257.252443, 61266.202198, 61275.152082, 61284.102096, 61293.052240, 61302.002513, 61310.952916, 
-   61319.903449, 61328.854112, 61337.804904, 61346.755826, 61355.706877, 61364.658058, 61373.609369, 61382.560809, 
-   61391.512378, 61400.464077, 61409.415906, 61418.367864, 61427.319952, 61436.272169, 61445.224516, 61454.176992, 
-   61463.129597, 61472.082332, 61481.035196, 61489.988189, 61498.941312, 61507.894564, 61516.847946, 61525.801457, 
-   61534.755097, 61543.708866, 61552.662764, 61561.616792, 61570.570949, 61579.525235, 61588.479651, 61597.434195, 
-   61606.388869, 61615.343672, 61624.298603, 61633.253664, 61642.208854, 61651.164173, 61660.119622, 61669.075199, 
-   61678.030905, 61686.986740, 61695.942704, 61704.898797, 61713.855019, 61722.811370, 61731.767850, 61740.724459, 
-   61749.681196, 61758.638063, 61767.595058, 61776.552182, 61785.509435, 61794.466817, 61803.424327, 61812.381967, 
-   61821.339735, 61830.297631, 61839.255657, 61848.213811, 61857.172094, 61866.130505, 61875.089045, 61884.047714, 
-   61893.006512, 61901.965437, 61910.924492, 61919.883675, 61928.842987, 61937.802427, 61946.761995, 61955.721693, 
-   61964.681518, 61973.641472, 61982.601555, 61991.561766, 62000.522105, 62009.482573, 62018.443169, 62027.403894, 
-   62036.364746, 62045.325728, 62054.286837, 62063.248075, 62072.209441, 62081.170935, 62090.132558, 62099.094309, 
-   62108.056188, 62117.018195, 62125.980330, 62134.942594, 62143.904985, 62152.867505, 62161.830153, 62170.792929, 
-   62179.755833, 62188.718866, 62197.682026, 62206.645314, 62215.608730, 62224.572275, 62233.535947, 62242.499747, 
-   62251.463675, 62260.427732, 62269.391916, 62278.356228, 62287.320667, 62296.285235, 62305.249931, 62314.214754, 
-   62323.179705, 62332.144784, 62341.109991, 62350.075326, 62359.040788, 62368.006378, 62376.972096, 62385.937941, 
-   62394.903915, 62403.870015, 62412.836244, 62421.802600, 62430.769084, 62439.735695, 62448.702434, 62457.669301, 
-   62466.636295, 62475.603416, 62484.570666, 62493.538042, 62502.505547, 62511.473178, 62520.440937, 62529.408824, 
-   62538.376838, 62547.344979, 62556.313248, 62565.281644, 62574.250168, 62583.218819, 62592.187597, 62601.156503, 
-   62610.125535, 62619.094696, 62628.063983, 62637.033398, 62646.002940, 62654.972609, 62663.942405, 62672.912328, 
-   62681.882379, 62690.852557, 62699.822862, 62708.793294, 62717.763853, 62726.734539, 62735.705353, 62744.676293, 
-   62753.647361, 62762.618555, 62771.589876, 62780.561325, 62789.532900, 62798.504603, 62807.476432, 62816.448388, 
-   62825.420472, 62834.392682, 62843.365019, 62852.337482, 62861.310073, 62870.282791, 62879.255635, 62888.228606, 
-   62897.201704, 62906.174929, 62915.148280, 62924.121758, 62933.095363, 62942.069095, 62951.042953, 62960.016938, 
-   62968.991049, 62977.965288, 62986.939652, 62995.914144, 63004.888762, 63013.863507, 63022.838378, 63031.813375, 
-   63040.788500, 63049.763750, 63058.739128, 63067.714631, 63076.690262, 63085.666018, 63094.641901, 63103.617911, 
-   63112.594047, 63121.570309, 63130.546697, 63139.523212, 63148.499854, 63157.476621, 63166.453515, 63175.430535, 
-   63184.407682, 63193.384955, 63202.362354, 63211.339879, 63220.317530, 63229.295308, 63238.273212, 63247.251242, 
-   63256.229398, 63265.207680, 63274.186088, 63283.164623, 63292.143283, 63301.122070, 63310.100982, 63319.080021, 
-   63328.059186, 63337.038476, 63346.017893, 63354.997435, 63363.977104, 63372.956898, 63381.936819, 63390.916865, 
-   63399.897037, 63408.877335, 63417.857759, 63426.838309, 63435.818985, 63444.799786, 63453.780713, 63462.761766, 
-   63471.742945, 63480.724250, 63489.705680, 63498.687236, 63507.668917, 63516.650725, 63525.632658, 63534.614716, 
-   63543.596901, 63552.579211, 63561.561646, 63570.544207, 63579.526894, 63588.509706, 63597.492644, 63606.475707, 
-   63615.458896, 63624.442210, 63633.425650, 63642.409215, 63651.392906, 63660.376722, 63669.360664, 63678.344730, 
-   63687.328923, 63696.313240, 63705.297684, 63714.282252, 63723.266946, 63732.251765, 63741.236709, 63750.221778, 
-   63759.206973, 63768.192293, 63777.177739, 63786.163309, 63795.149005, 63804.134826, 63813.120772, 63822.106843, 
-   63831.093039, 63840.079361, 63849.065807, 63858.052379, 63867.039075, 63876.025897, 63885.012844, 63893.999916, 
-   63902.987113, 63911.974434, 63920.961881, 63929.949453, 63938.937150, 63947.924971, 63956.912918, 63965.900989, 
-   63974.889186, 63983.877507, 63992.865953, 64001.854524, 64010.843219, 64019.832040, 64028.820985, 64037.810055, 
-   64046.799250, 64055.788570, 64064.778014, 64073.767583, 64082.757277, 64091.747095, 64100.737038, 64109.727106, 
-   64118.717298, 64127.707615, 64136.698057, 64145.688623, 64154.679313, 64163.670129, 64172.661069, 64181.652133, 
-   64190.643322, 64199.634635, 64208.626073, 64217.617635, 64226.609322, 64235.601133, 64244.593069, 64253.585129, 
-   64262.577313, 64271.569622, 64280.562055, 64289.554612, 64298.547294, 64307.540100, 64316.533030, 64325.526085, 
-   64334.519264, 64343.512567, 64352.505994, 64361.499546, 64370.493222, 64379.487022, 64388.480946, 64397.474994, 
-   64406.469167, 64415.463463, 64424.457884, 64433.452429, 64442.447097, 64451.441890, 64460.436807, 64469.431848, 
-   64478.427013, 64487.422302, 64496.417715, 64505.413252, 64514.408913, 64523.404698, 64532.400607, 64541.396639, 
-   64550.392796, 64559.389076, 64568.385481, 64577.382009, 64586.378661, 64595.375437, 64604.372336, 64613.369360, 
-   64622.366507, 64631.363778, 64640.361172, 64649.358691, 64658.356333, 64667.354098, 64676.351988, 64685.350001, 
-   64694.348138, 64703.346398, 64712.344782, 64721.343290, 64730.341921, 64739.340676, 64748.339554, 64757.338556, 
-   64766.337681, 64775.336930, 64784.336303, 64793.335799, 64802.335418, 64811.335161, 64820.335027, 64829.335016, 
-   64838.335130, 64847.335366, 64856.335726, 64865.336209, 64874.336815, 64883.337545, 64892.338398, 64901.339375, 
-   64910.340475, 64919.341698, 64928.343044, 64937.344513, 64946.346106, 64955.347822, 64964.349661, 64973.351623, 
-   64982.353709, 64991.355917, 65000.358249, 65009.360704, 65018.363282, 65027.365983, 65036.368807, 65045.371754, 
-   65054.374824, 65063.378017, 65072.381334, 65081.384773, 65090.388335, 65099.392020, 65108.395828, 65117.399759, 
-   65126.403813, 65135.407990, 65144.412290, 65153.416712, 65162.421258, 65171.425926, 65180.430717, 65189.435631, 
-   65198.440668, 65207.445827, 65216.451110, 65225.456515, 65234.462042, 65243.467693, 65252.473466, 65261.479362, 
-   65270.485381, 65279.491522, 65288.497786, 65297.504172, 65306.510681, 65315.517313, 65324.524067, 65333.530944, 
-   65342.537944, 65351.545066, 65360.552310, 65369.559677, 65378.567167, 65387.574779, 65396.582513, 65405.590370, 
-   65414.598350, 65423.606451, 65432.614676, 65441.623022, 65450.631491, 65459.640082, 65468.648796, 65477.657632, 
-   65486.666590, 65495.675671, 65504.684874, 65513.694199, 65522.703647, 65531.713216, 65540.722908, 65549.732722, 
-   65558.742659, 65567.752717, 65576.762898, 65585.773200, 65594.783625, 65603.794172, 65612.804842, 65621.815633, 
-   65630.826546, 65639.837582, 65648.848739, 65657.860019, 65666.871420, 65675.882944, 65684.894589, 65693.906357, 
-   65702.918246, 65711.930257, 65720.942391, 65729.954646, 65738.967023, 65747.979522, 65756.992143, 65766.004886, 
-   65775.017750, 65784.030737, 65793.043845, 65802.057075, 65811.070427, 65820.083900, 65829.097495, 65838.111213, 
-   65847.125051, 65856.139012, 65865.153094, 65874.167298, 65883.181623, 65892.196070, 65901.210639, 65910.225329, 
-   65919.240141, 65928.255075, 65937.270130, 65946.285307, 65955.300605, 65964.316025, 65973.331566, 65982.347229, 
-   65991.363013, 66000.378919, 66009.394946, 66018.411095, 66027.427365, 66036.443756, 66045.460269, 66054.476904, 
-   66063.493659, 66072.510536, 66081.527534, 66090.544654, 66099.561895, 66108.579257, 66117.596741, 66126.614346, 
-   66135.632072, 66144.649919, 66153.667887, 66162.685977, 66171.704188, 66180.722520, 66189.740973, 66198.759548, 
-   66207.778243, 66216.797060, 66225.815997, 66234.835056, 66243.854236, 66252.873537, 66261.892959, 66270.912502, 
-   66279.932166, 66288.951951, 66297.971857, 66306.991884, 66316.012032, 66325.032301, 66334.052690, 66343.073201, 
-   66352.093833, 66361.114585, 66370.135459, 66379.156453, 66388.177568, 66397.198804, 66406.220160, 66415.241638, 
-   66424.263236, 66433.284955, 66442.306795, 66451.328755, 66460.350837, 66469.373038, 66478.395361, 66487.417804, 
-   66496.440368, 66505.463053, 66514.485858, 66523.508784, 66532.531831, 66541.554998, 66550.578285, 66559.601693, 
-   66568.625222, 66577.648871, 66586.672641, 66595.696532, 66604.720542, 66613.744674, 66622.768925, 66631.793298, 
-   66640.817790, 66649.842403, 66658.867137, 66667.891990, 66676.916965, 66685.942059, 66694.967274, 66703.992609, 
-   66713.018065, 66722.043641, 66731.069337, 66740.095153, 66749.121090, 66758.147147, 66767.173324, 66776.199621, 
-   66785.226039, 66794.252576, 66803.279234, 66812.306012, 66821.332911, 66830.359929, 66839.387067, 66848.414326, 
-   66857.441704, 66866.469203, 66875.496822, 66884.524561, 66893.552419, 66902.580398, 66911.608497, 66920.636716, 
-   66929.665055, 66938.693513, 66947.722092, 66956.750791, 66965.779609, 66974.808547, 66983.837606, 66992.866784, 
-   67001.896082, 67010.925500, 67019.955037, 67028.984695, 67038.014472, 67047.044369, 67056.074386, 67065.104522, 
-   67074.134779, 67083.165155, 67092.195651, 67101.226266, 67110.257001, 67119.287856, 67128.318830, 67137.349924, 
-   67146.381138, 67155.412471, 67164.443924, 67173.475497, 67182.507189, 67191.539001, 67200.570932, 67209.602982, 
-   67218.635153, 67227.667442, 67236.699851, 67245.732380, 67254.765028, 67263.797796, 67272.830683, 67281.863689, 
-   67290.896815, 67299.930060, 67308.963424, 67317.996908, 67327.030511, 67336.064234, 67345.098076, 67354.132037, 
-   67363.166117, 67372.200317, 67381.234636, 67390.269074, 67399.303631, 67408.338308, 67417.373104, 67426.408019, 
-   67435.443053, 67444.478206, 67453.513479, 67462.548870, 67471.584381, 67480.620011, 67489.655760, 67498.691628, 
-   67507.727615, 67516.763721, 67525.799946, 67534.836290, 67543.872753, 67552.909335, 67561.946036, 67570.982856, 
-   67580.019795, 67589.056853, 67598.094029, 67607.131325, 67616.168739, 67625.206273, 67634.243925, 67643.281696, 
-   67652.319586, 67661.357595, 67670.395722, 67679.433969, 67688.472334, 67697.510818, 67706.549420, 67715.588142, 
-   67724.626982, 67733.665941, 67742.705018, 67751.744214, 67760.783529, 67769.822962, 67778.862514, 67787.902185, 
-   67796.941974, 67805.981882, 67815.021909, 67824.062054, 67833.102317, 67842.142699, 67851.183200, 67860.223819, 
-   67869.264556, 67878.305413, 67887.346387, 67896.387480, 67905.428691, 67914.470021, 67923.511469, 67932.553036, 
-   67941.594721, 67950.636525, 67959.678446, 67968.720486, 67977.762645, 67986.804921, 67995.847316, 68004.889830, 
-   68013.932461, 68022.975211, 68032.018079, 68041.061065, 68050.104170, 68059.147392, 68068.190733, 68077.234192, 
-   68086.277769, 68095.321465, 68104.365278, 68113.409209, 68122.453259, 68131.497427, 68140.541713, 68149.586116, 
-   68158.630638, 68167.675278, 68176.720036, 68185.764912, 68194.809906, 68203.855018, 68212.900248, 68221.945596, 
-   68230.991061, 68240.036645, 68249.082347, 68258.128166, 68267.174103, 68276.220158, 68285.266331, 68294.312622, 
-   68303.359031, 68312.405558, 68321.452202, 68330.498964, 68339.545844, 68348.592841, 68357.639957, 68366.687190, 
-   68375.734540, 68384.782009, 68393.829595, 68402.877299, 68411.925120, 68420.973059, 68430.021116, 68439.069290, 
-   68448.117582, 68457.165992, 68466.214519, 68475.263163, 68484.311926, 68493.360805, 68502.409802, 68511.458917, 
-   68520.508149, 68529.557499, 68538.606966, 68547.656551, 68556.706253, 68565.756072, 68574.806009, 68583.856063, 
-   68592.906235, 68601.956524, 68611.006930, 68620.057454, 68629.108095, 68638.158853, 68647.209729, 68656.260722, 
-   68665.311832, 68674.363059, 68683.414404, 68692.465866, 68701.517445, 68710.569141, 68719.620955, 68728.672885, 
-   68737.724933, 68746.777098, 68755.829380, 68764.881779, 68773.934296, 68782.986929, 68792.039679, 68801.092547, 
-   68810.145531, 68819.198633, 68828.251852, 68837.305187, 68846.358640, 68855.412210, 68864.465896, 68873.519700, 
-   68882.573620, 68891.627657, 68900.681812, 68909.736083, 68918.790471, 68927.844976, 68936.899598, 68945.954336, 
-   68955.009192, 68964.064164, 68973.119253, 68982.174459, 68991.229782, 69000.285221, 69009.340777, 69018.396450, 
-   69027.452240, 69036.508146, 69045.564169, 69054.620309, 69063.676565, 69072.732938, 69081.789428, 69090.846034, 
-   69099.902757, 69108.959596, 69118.016553, 69127.073625, 69136.130814, 69145.188120, 69154.245542, 69163.303081, 
-   69172.360736, 69181.418508, 69190.476396, 69199.534401, 69208.592522, 69217.650760, 69226.709114, 69235.767584, 
-   69244.826171, 69253.884874, 69262.943694, 69272.002630, 69281.061682, 69290.120851, 69299.180136, 69308.239537, 
-   69317.299054, 69326.358688, 69335.418438, 69344.478304, 69353.538287, 69362.598385, 69371.658600, 69380.718931, 
-   69389.779379, 69398.839942, 69407.900622, 69416.961418, 69426.022329, 69435.083357, 69444.144501, 69453.205762, 
-   69462.267138, 69471.328630, 69480.390238, 69489.451963, 69498.513803, 69507.575759, 69516.637832, 69525.700020, 
-   69534.762324, 69543.824745, 69552.887281, 69561.949933, 69571.012701, 69580.075585, 69589.138585, 69598.201700, 
-   69607.264932, 69616.328279, 69625.391742, 69634.455321, 69643.519016, 69652.582827, 69661.646753, 69670.710795, 
-   69679.774953, 69688.839227, 69697.903616, 69706.968121, 69716.032742, 69725.097478, 69734.162330, 69743.227298, 
-   69752.292381, 69761.357580, 69770.422895, 69779.488325, 69788.553871, 69797.619532, 69806.685309, 69815.751202, 
-   69824.817210, 69833.883333, 69842.949572, 69852.015927, 69861.082397, 69870.148982, 69879.215683, 69888.282499, 
-   69897.349431, 69906.416478, 69915.483641, 69924.550919, 69933.618312, 69942.685821, 69951.753445, 69960.821185, 
-   69969.889039, 69978.957009, 69988.025095, 69997.093295, 70006.161611, 70015.230042, 70024.298589, 70033.367250, 
-   70042.436027, 70051.504919, 70060.573926, 70069.643049, 70078.712286, 70087.781639, 70096.851107, 70105.920690, 
-   70114.990388, 70124.060201, 70133.130129, 70142.200172, 70151.270331, 70160.340604, 70169.410992, 70178.481496, 
-   70187.552114, 70196.622848, 70205.693696, 70214.764659, 70223.835738, 70232.906931, 70241.978239, 70251.049662, 
-   70260.121200, 70269.192853, 70278.264621, 70287.336503, 70296.408501, 70305.480613, 70314.552840, 70323.625182, 
-   70332.697639, 70341.770210, 70350.842896, 70359.915697, 70368.988613, 70378.061643, 70387.134788, 70396.208048, 
-   70405.281423, 70414.354912, 70423.428516, 70432.502234, 70441.576067, 70450.650015, 70459.724078, 70468.798254, 
-   70477.872546, 70486.946952, 70496.021473, 70505.096108, 70514.170858, 70523.245722, 70532.320701, 70541.395794, 
-   70550.471002, 70559.546324, 70568.621760, 70577.697311, 70586.772977, 70595.848757, 70604.924651, 70614.000660, 
-   70623.076783, 70632.153020, 70641.229372, 70650.305838, 70659.382418, 70668.459113, 70677.535922, 70686.612845, 
-   70695.689883, 70704.767034, 70713.844300, 70722.921681, 70731.999175, 70741.076784, 70750.154507, 70759.232344, 
-   70768.310295, 70777.388360, 70786.466540, 70795.544833, 70804.623241, 70813.701763, 70822.780399, 70831.859149, 
-   70840.938013, 70850.016991, 70859.096083, 70868.175289, 70877.254609, 70886.334043, 70895.413591, 70904.493253, 
-   70913.573029, 70922.652919, 70931.732923, 70940.813041, 70949.893272, 70958.973618, 70968.054077, 70977.134651, 
-   70986.215338, 70995.296139, 71004.377054, 71013.458082, 71022.539225, 71031.620481, 71040.701851, 71049.783335, 
-   71058.864932, 71067.946644, 71077.028469, 71086.110407, 71095.192460, 71104.274626, 71113.356905, 71122.439299, 
-   71131.521806, 71140.604426, 71149.687160, 71158.770008, 71167.852970, 71176.936045, 71186.019233, 71195.102536, 
-   71204.185951, 71213.269480, 71222.353123, 71231.436879, 71240.520749, 71249.604732, 71258.688829, 71267.773039, 
-   71276.857363, 71285.941799, 71295.026350, 71304.111014, 71313.195791, 71322.280681, 71331.365685, 71340.450802, 
-   71349.536033, 71358.621377, 71367.706834, 71376.792404, 71385.878088, 71394.963885, 71404.049796, 71413.135819, 
-   71422.221956, 71431.308206, 71440.394569, 71449.481045, 71458.567635, 71467.654338, 71476.741154, 71485.828083, 
-   71494.915125, 71504.002280, 71513.089548, 71522.176930, 71531.264424, 71540.352032, 71549.439753, 71558.527586, 
-   71567.615533, 71576.703593, 71585.791766, 71594.880051, 71603.968450, 71613.056962, 71622.145586, 71631.234324, 
-   71640.323174, 71649.412138, 71658.501214, 71667.590403, 71676.679705, 71685.769120, 71694.858648, 71703.948288, 
-   71713.038042, 71722.127908, 71731.217887, 71740.307979, 71749.398184, 71758.488501, 71767.578931, 71776.669474, 
-   71785.760129, 71794.850897, 71803.941778, 71813.032772, 71822.123878, 71831.215097, 71840.306429, 71849.397873, 
-   71858.489430, 71867.581099, 71876.672881, 71885.764776, 71894.856783, 71903.948903, 71913.041135, 71922.133480, 
-   71931.225937, 71940.318507, 71949.411190, 71958.503984, 71967.596892, 71976.689911, 71985.783043, 71994.876288, 
-   72003.969645, 72013.063115, 72022.156696, 72031.250391, 72040.344197, 72049.438116, 72058.532147, 72067.626291, 
-   72076.720547, 72085.814915, 72094.909395, 72104.003988, 72113.098693, 72122.193510, 72131.288440, 72140.383482, 
-   72149.478636, 72158.573902, 72167.669280, 72176.764771, 72185.860373, 72194.956088, 72204.051915, 72213.147854, 
-   72222.243906, 72231.340069, 72240.436344, 72249.532732, 72258.629231, 72267.725843, 72276.822567, 72285.919402, 
-   72295.016350, 72304.113410, 72313.210581, 72322.307865, 72331.405261, 72340.502768, 72349.600388, 72358.698119, 
-   72367.795962, 72376.893918, 72385.991985, 72395.090164, 72404.188455, 72413.286857, 72422.385372, 72431.483998, 
-   72440.582737, 72449.681587, 72458.780548, 72467.879622, 72476.978807, 72486.078104, 72495.177513, 72504.277034, 
-   72513.376666, 72522.476410, 72531.576265, 72540.676233, 72549.776312, 72558.876502, 72567.976805, 72577.077219, 
-   72586.177744, 72595.278381, 72604.379130, 72613.479990, 72622.580962, 72631.682045, 72640.783240, 72649.884547, 
-   72658.985965, 72668.087494, 72677.189135, 72686.290888, 72695.392751, 72704.494727, 72713.596814, 72722.699012, 
-   72731.801321, 72740.903742, 72750.006275, 72759.108919, 72768.211674, 72777.314540, 72786.417518, 72795.520607, 
-   72804.623808, 72813.727120, 72822.830543, 72831.934077, 72841.037723, 72850.141480, 72859.245348, 72868.349327, 
-   72877.453418, 72886.557619, 72895.661932, 72904.766357, 72913.870892, 72922.975538, 72932.080296, 72941.185165, 
-   72950.290145, 72959.395236, 72968.500438, 72977.605751, 72986.711175, 72995.816710, 73004.922356, 73014.028114, 
-   73023.133982, 73032.239962, 73041.346052, 73050.452253, 73059.558566, 73068.664989, 73077.771523, 73086.878168, 
-   73095.984924, 73105.091791, 73114.198769, 73123.305858, 73132.413057, 73141.520368, 73150.627789, 73159.735321, 
-   73168.842964, 73177.950718, 73187.058583, 73196.166558, 73205.274644, 73214.382841, 73223.491149, 73232.599567, 
-   73241.708096, 73250.816736, 73259.925486, 73269.034348, 73278.143320, 73287.252402, 73296.361595, 73305.470899, 
-   73314.580314, 73323.689839, 73332.799474, 73341.909221, 73351.019077, 73360.129045, 73369.239123, 73378.349311, 
-   73387.459610, 73396.570020, 73405.680540, 73414.791170, 73423.901911, 73433.012763, 73442.123725, 73451.234797, 
-   73460.345980, 73469.457273, 73478.568677, 73487.680191, 73496.791815, 73505.903550, 73515.015395, 73524.127351, 
-   73533.239416, 73542.351592, 73551.463879, 73560.576276, 73569.688783, 73578.801400, 73587.914127, 73597.026965, 
-   73606.139913, 73615.252972, 73624.366140, 73633.479419, 73642.592808, 73651.706307, 73660.819916, 73669.933635, 
-   73679.047465, 73688.161404, 73697.275454, 73706.389614, 73715.503884, 73724.618264, 73733.732754, 73742.847354, 
-   73751.962064, 73761.076884, 73770.191814, 73779.306854, 73788.422005, 73797.537265, 73806.652635, 73815.768115, 
-   73824.883705, 73833.999405, 73843.115215, 73852.231135, 73861.347164, 73870.463304, 73879.579553, 73888.695913, 
-   73897.812382, 73906.928961, 73916.045650, 73925.162448, 73934.279357, 73943.396375, 73952.513503, 73961.630741, 
-   73970.748088, 73979.865545, 73988.983112, 73998.100789, 74007.218575, 74016.336472, 74025.454477, 74034.572593, 
-   74043.690818, 74052.809153, 74061.927597, 74071.046151, 74080.164814, 74089.283588, 74098.402470, 74107.521463, 
-   74116.640565, 74125.759776, 74134.879097, 74143.998528, 74153.118068, 74162.237717, 74171.357476, 74180.477344, 
-   74189.597322, 74198.717410, 74207.837607, 74216.957913, 74226.078329, 74235.198854, 74244.319488, 74253.440232, 
-   74262.561085, 74271.682048, 74280.803120, 74289.924301, 74299.045591, 74308.166991, 74317.288500, 74326.410119, 
-   74335.531847, 74344.653684, 74353.775630, 74362.897685, 74372.019850, 74381.142124, 74390.264507, 74399.386999, 
-   74408.509601, 74417.632311, 74426.755131, 74435.878060, 74445.001098, 74454.124245, 74463.247501, 74472.370867, 
-   74481.494341, 74490.617925, 74499.741617, 74508.865419, 74517.989330, 74527.113349, 74536.237478, 74545.361716, 
-   74554.486062, 74563.610518, 74572.735082, 74581.859756, 74590.984538, 74600.109430, 74609.234430, 74618.359539, 
-   74627.484758, 74636.610085, 74645.735520, 74654.861065, 74663.986719, 74673.112481, 74682.238352, 74691.364332, 
-   74700.490421, 74709.616619, 74718.742925, 74727.869340, 74736.995864, 74746.122497, 74755.249238, 74764.376088, 
-   74773.503047, 74782.630114, 74791.757290, 74800.884575, 74810.011969, 74819.139471, 74828.267082, 74837.394801, 
-   74846.522629, 74855.650565, 74864.778611, 74873.906764, 74883.035026, 74892.163397, 74901.291877, 74910.420465, 
-   74919.549161, 74928.677966, 74937.806879, 74946.935901, 74956.065031, 74965.194270, 74974.323617, 74983.453073, 
-   74992.582637, 75001.712309, 75010.842090, 75019.971980, 75029.101977, 75038.232083, 75047.362298, 75056.492620, 
-   75065.623051, 75074.753590, 75083.884238, 75093.014994, 75102.145858, 75111.276831, 75120.407911, 75129.539100, 
-   75138.670397, 75147.801803, 75156.933316, 75166.064938, 75175.196668, 75184.328506, 75193.460453, 75202.592507, 
-   75211.724670, 75220.856940, 75229.989319, 75239.121806, 75248.254401, 75257.387104, 75266.519915, 75275.652835, 
-   75284.785862, 75293.918997, 75303.052240, 75312.185592, 75321.319051, 75330.452618, 75339.586294, 75348.720077, 
-   75357.853968, 75366.987967, 75376.122074, 75385.256289, 75394.390612, 75403.525043, 75412.659582, 75421.794228, 
-   75430.928983, 75440.063845, 75449.198815, 75458.333893, 75467.469078, 75476.604372, 75485.739773, 75494.875282, 
-   75504.010899, 75513.146624, 75522.282456, 75531.418396, 75540.554444, 75549.690599, 75558.826863, 75567.963233, 
-   75577.099712, 75586.236298, 75595.372992, 75604.509793, 75613.646702, 75622.783719, 75631.920843, 75641.058075, 
-   75650.195415, 75659.332862, 75668.470417, 75677.608079, 75686.745848, 75695.883726, 75705.021710, 75714.159802, 
-   75723.298002, 75732.436309, 75741.574724, 75750.713246, 75759.851876, 75768.990613, 75778.129457, 75787.268409, 
-   75796.407468, 75805.546634, 75814.685908, 75823.825290, 75832.964778, 75842.104374, 75851.244077, 75860.383888, 
-   75869.523806, 75878.663831, 75887.803964, 75896.944203, 75906.084550, 75915.225005, 75924.365566, 75933.506235, 
-   75942.647011, 75951.787894, 75960.928884, 75970.069982, 75979.211186, 75988.352498, 75997.493917, 76006.635443, 
-   76015.777076, 76024.918816, 76034.060664, 76043.202618, 76052.344680, 76061.486848, 76070.629124, 76079.771507, 
-   76088.913996, 76098.056593, 76107.199297, 76116.342108, 76125.485025, 76134.628050, 76143.771182, 76152.914420, 
-   76162.057766, 76171.201218, 76180.344777, 76189.488444, 76198.632217, 76207.776097, 76216.920084, 76226.064177, 
-   76235.208378, 76244.352685, 76253.497100, 76262.641621, 76271.786248, 76280.930983, 76290.075824, 76299.220773, 
-   76308.365828, 76317.510989, 76326.656258, 76335.801633, 76344.947114, 76354.092703, 76363.238398, 76372.384200, 
-   76381.530108, 76390.676124, 76399.822245, 76408.968474, 76418.114809, 76427.261251, 76436.407799, 76445.554454, 
-   76454.701215, 76463.848083, 76472.995057, 76482.142138, 76491.289326, 76500.436620, 76509.584021, 76518.731528, 
-   76527.879141, 76537.026861, 76546.174688, 76555.322621, 76564.470660, 76573.618806, 76582.767058, 76591.915417, 
-   76601.063882, 76610.212453, 76619.361131, 76628.509915, 76637.658805, 76646.807802, 76655.956905, 76665.106114, 
-   76674.255430, 76683.404852, 76692.554380, 76701.704015, 76710.853755, 76720.003602, 76729.153556, 76738.303615, 
-   76747.453781, 76756.604052, 76765.754431, 76774.904915, 76784.055505, 76793.206202, 76802.357004, 76811.507913, 
-   76820.658928, 76829.810049, 76838.961276, 76848.112609, 76857.264049, 76866.415594, 76875.567245, 76884.719003, 
-   76893.870866, 76903.022836, 76912.174911, 76921.327092, 76930.479380, 76939.631773, 76948.784273, 76957.936878, 
-   76967.089589, 76976.242406, 76985.395330, 76994.548359, 77003.701493, 77012.854734, 77022.008081, 77031.161533, 
-   77040.315092, 77049.468756, 77058.622526, 77067.776402, 77076.930383, 77086.084471, 77095.238664, 77104.392963, 
-   77113.547368, 77122.701878, 77131.856495, 77141.011216, 77150.166044, 77159.320977, 77168.476017, 77177.631161, 
-   77186.786412, 77195.941768, 77205.097229, 77214.252797, 77223.408470, 77232.564248, 77241.720133, 77250.876122, 
-   77260.032218, 77269.188419, 77278.344725, 77287.501137, 77296.657655, 77305.814278, 77314.971006, 77324.127840, 
-   77333.284780, 77342.441825, 77351.598976, 77360.756232, 77369.913593, 77379.071060, 77388.228632, 77397.386310, 
-   77406.544093, 77415.701982, 77424.859976, 77434.018075, 77443.176279, 77452.334589, 77461.493005, 77470.651525, 
-   77479.810151, 77488.968883, 77498.127719, 77507.286661, 77516.445708, 77525.604860, 77534.764118, 77543.923481, 
-   77553.082949, 77562.242522, 77571.402200, 77580.561984, 77589.721873, 77598.881867, 77608.041966, 77617.202170, 
-   77626.362480, 77635.522894, 77644.683414, 77653.844039, 77663.004769, 77672.165604, 77681.326544, 77690.487589, 
-   77699.648739, 77708.809994, 77717.971354, 77727.132819, 77736.294390, 77745.456065, 77754.617845, 77763.779730, 
-   77772.941720, 77782.103815, 77791.266015, 77800.428320, 77809.590730, 77818.753245, 77827.915864, 77837.078589, 
-   77846.241418, 77855.404353, 77864.567392, 77873.730536, 77882.893784, 77892.057138, 77901.220596, 77910.384160, 
-   77919.547828, 77928.711600, 77937.875478, 77947.039460, 77956.203547, 77965.367739, 77974.532035, 77983.696436, 
-   77992.860942, 78002.025553, 78011.190268, 78020.355088, 78029.520012, 78038.685041, 78047.850175, 78057.015414, 
-   78066.180757, 78075.346204, 78084.511756, 78093.677413, 78102.843174, 78112.009040, 78121.175011, 78130.341086, 
-   78139.507265, 78148.673549, 78157.839938, 78167.006431, 78176.173028, 78185.339730, 78194.506536, 78203.673447, 
-   78212.840462, 78222.007582, 78231.174806, 78240.342135, 78249.509568, 78258.677105, 78267.844746, 78277.012492, 
-   78286.180343, 78295.348297, 78304.516356, 78313.684520, 78322.852787, 78332.021159, 78341.189635, 78350.358216, 
-   78359.526900, 78368.695689, 78377.864583, 78387.033580, 78396.202682, 78405.371887, 78414.541197, 78423.710612, 
-   78432.880130, 78442.049753, 78451.219479, 78460.389310, 78469.559245, 78478.729284, 78487.899427, 78497.069675, 
-   78506.240026, 78515.410481, 78524.581041, 78533.751704, 78542.922472, 78552.093344, 78561.264319, 78570.435399, 
-   78579.606583, 78588.777870, 78597.949262, 78607.120757, 78616.292357, 78625.464060, 78634.635868, 78643.807779, 
-   78652.979794, 78662.151914, 78671.324137, 78680.496464, 78689.668894, 78698.841429, 78708.014068, 78717.186810, 
-   78726.359656, 78735.532606, 78744.705660, 78753.878817, 78763.052079, 78772.225444, 78781.398913, 78790.572485, 
-   78799.746162, 78808.919942, 78818.093826, 78827.267813, 78836.441905, 78845.616100, 78854.790398, 78863.964800, 
-   78873.139306, 78882.313916, 78891.488629, 78900.663446, 78909.838366, 78919.013390, 78928.188518, 78937.363749, 
-   78946.539084, 78955.714522, 78964.890064, 78974.065710, 78983.241458, 78992.417311, 79001.593267, 79010.769326, 
-   79019.945489, 79029.121756, 79038.298125, 79047.474599, 79056.651175, 79065.827856, 79075.004639, 79084.181526, 
-   79093.358517, 79102.535610, 79111.712808, 79120.890108, 79130.067512, 79139.245019, 79148.422630, 79157.600344, 
-   79166.778161, 79175.956081, 79185.134105, 79194.312232, 79203.490462, 79212.668796, 79221.847233, 79231.025773, 
-   79240.204416, 79249.383163, 79258.562012, 79267.740965, 79276.920021, 79286.099181, 79295.278443, 79304.457809, 
-   79313.637277, 79322.816849, 79331.996524, 79341.176302, 79350.356183, 79359.536168, 79368.716255, 79377.896445, 
-   79387.076739, 79396.257135, 79405.437635, 79414.618237, 79423.798943, 79432.979751, 79442.160663, 79451.341678, 
-   79460.522795, 79469.704016, 79478.885339, 79488.066765, 79497.248295, 79506.429927, 79515.611662, 79524.793500, 
-   79533.975441, 79543.157485, 79552.339631, 79561.521881, 79570.704233, 79579.886688, 79589.069246, 79598.251907, 
-   79607.434671, 79616.617537, 79625.800506, 79634.983578, 79644.166753, 79653.350030, 79662.533410, 79671.716893, 
-   79680.900479, 79690.084167, 79699.267958, 79708.451852, 79717.635849, 79726.819948, 79736.004149, 79745.188454, 
-   79754.372861, 79763.557370, 79772.741982, 79781.926697, 79791.111515, 79800.296435, 79809.481457, 79818.666582, 
-   79827.851810, 79837.037140, 79846.222573, 79855.408108, 79864.593746, 79873.779486, 79882.965329, 79892.151274, 
-   79901.337322, 79910.523472, 79919.709725, 79928.896080, 79938.082537, 79947.269097, 79956.455759, 79965.642524, 
-   79974.829391, 79984.016360, 79993.203432, 80002.390606, 80011.577882, 80020.765261, 80029.952742, 80039.140326, 
-   80048.328011, 80057.515799, 80066.703690, 80075.891682, 80085.079777, 80094.267974, 80103.456273, 80112.644675, 
-   80121.833178, 80131.021784, 80140.210492, 80149.399302, 80158.588215, 80167.777229, 80176.966346, 80186.155565, 
-   80195.344886, 80204.534309, 80213.723834, 80222.913462, 80232.103191, 80241.293023, 80250.482956, 80259.672992, 
-   80268.863130, 80278.053369, 80287.243711, 80296.434155, 80305.624700, 80314.815348, 80324.006098, 80333.196950, 
-   80342.387903, 80351.578959, 80360.770116, 80369.961376, 80379.152737, 80388.344201, 80397.535766, 80406.727433, 
-   80415.919202, 80425.111073, 80434.303045, 80443.495120, 80452.687296, 80461.879575, 80471.071955, 80480.264437, 
-   80489.457020, 80498.649706, 80507.842493, 80517.035382, 80526.228373, 80535.421465, 80544.614659, 80553.807955, 
-   80563.001353, 80572.194852, 80581.388453, 80590.582156, 80599.775960, 80608.969866, 80618.163874, 80627.357984, 
-   80636.552195, 80645.746507, 80654.940921, 80664.135437, 80673.330055, 80682.524774, 80691.719594, 80700.914516, 
-   80710.109540, 80719.304665, 80728.499892, 80737.695220, 80746.890650, 80756.086181, 80765.281814, 80774.477548, 
-   80783.673384, 80792.869321, 80802.065360, 80811.261500, 80820.457741, 80829.654084, 80838.850528, 80848.047074, 
-   80857.243721, 80866.440469, 80875.637319, 80884.834270, 80894.031323, 80903.228476, 80912.425732, 80921.623088, 
-   80930.820546, 80940.018105, 80949.215765, 80958.413527, 80967.611390, 80976.809354, 80986.007419, 80995.205586, 
-   81004.403853, 81013.602222, 81022.800693, 81031.999264, 81041.197937, 81050.396710, 81059.595585, 81068.794561, 
-   81077.993638, 81087.192817, 81096.392096, 81105.591477, 81114.790958, 81123.990541, 81133.190225, 81142.390010, 
-   81151.589896, 81160.789883, 81169.989971, 81179.190160, 81188.390450, 81197.590841, 81206.791333, 81215.991926, 
-   81225.192620, 81234.393415, 81243.594311, 81252.795307, 81261.996405, 81271.197604, 81280.398904, 81289.600304, 
-   81298.801805, 81308.003408, 81317.205111, 81326.406915, 81335.608820, 81344.810826, 81354.012932, 81363.215140, 
-   81372.417448, 81381.619857, 81390.822367, 81400.024977, 81409.227689, 81418.430501, 81427.633413, 81436.836427, 
-   81446.039541, 81455.242756, 81464.446072, 81473.649489, 81482.853006, 81492.056624, 81501.260342, 81510.464161, 
-   81519.668081, 81528.872102, 81538.076223, 81547.280444, 81556.484767, 81565.689189, 81574.893713, 81584.098337, 
-   81593.303062, 81602.507887, 81611.712813, 81620.917839, 81630.122966, 81639.328193, 81648.533521, 81657.738949, 
-   81666.944478, 81676.150107, 81685.355837, 81694.561667, 81703.767598, 81712.973629, 81722.179761, 81731.385992, 
-   81740.592325, 81749.798758, 81759.005291, 81768.211924, 81777.418658, 81786.625492, 81795.832427, 81805.039462, 
-   81814.246597, 81823.453833, 81832.661168, 81841.868605, 81851.076141, 81860.283778, 81869.491515, 81878.699352, 
-   81887.907290, 81897.115327, 81906.323465, 81915.531703, 81924.740042, 81933.948480, 81943.157019, 81952.365658, 
-   81961.574397, 81970.783236, 81979.992176, 81989.201215, 81998.410355, 82007.619595, 82016.828935, 82026.038374, 
-   82035.247915, 82044.457555, 82053.667295, 82062.877135, 82072.087075, 82081.297116, 82090.507256, 82099.717496, 
-   82108.927837 
-  }; 
-
-/* Nat log values for 0.1, 0.2, 0.3, etc. */ 
+   0.000000, 0.000000, 0.693147, 1.791759, 3.178054, 4.787492, 6.579251, 8.525161,
+   10.604603, 12.801827, 15.104413, 17.502308, 19.987214, 22.552164, 25.191221, 27.899271,
+   30.671860, 33.505073, 36.395445, 39.339884, 42.335616, 45.380139, 48.471181, 51.606676,
+   54.784729, 58.003605, 61.261702, 64.557539, 67.889743, 71.257039, 74.658236, 78.092224,
+   81.557959, 85.054467, 88.580828, 92.136176, 95.719695, 99.330612, 102.968199, 106.631760,
+   110.320640, 114.034212, 117.771881, 121.533082, 125.317271, 129.123934, 132.952575, 136.802723,
+   140.673924, 144.565744, 148.477767, 152.409593, 156.360836, 160.331128, 164.320112, 168.327445,
+   172.352797, 176.395848, 180.456291, 184.533829, 188.628173, 192.739047, 196.866182, 201.009316,
+   205.168199, 209.342587, 213.532241, 217.736934, 221.956442, 226.190548, 230.439044, 234.701723,
+   238.978390, 243.268849, 247.572914, 251.890402, 256.221136, 260.564941, 264.921650, 269.291098,
+   273.673124, 278.067573, 282.474293, 286.893133, 291.323950, 295.766601, 300.220949, 304.686857,
+   309.164194, 313.652830, 318.152640, 322.663499, 327.185288, 331.717887, 336.261182, 340.815059,
+   345.379407, 349.954118, 354.539086, 359.134205, 363.739376, 368.354496, 372.979469, 377.614198,
+   382.258589, 386.912549, 391.575988, 396.248817, 400.930948, 405.622296, 410.322777, 415.032307,
+   419.750806, 424.478193, 429.214392, 433.959324, 438.712914, 443.475088, 448.245773, 453.024896,
+   457.812388, 462.608179, 467.412200, 472.224384, 477.044665, 481.872979, 486.709261, 491.553448,
+   496.405478, 501.265291, 506.132825, 511.008023, 515.890825, 520.781174, 525.679014, 530.584288,
+   535.496943, 540.416924, 545.344178, 550.278652, 555.220294, 560.169054, 565.124881, 570.087726,
+   575.057539, 580.034273, 585.017879, 590.008312, 595.005524, 600.009471, 605.020106, 610.037386,
+   615.061266, 620.091704, 625.128657, 630.172082, 635.221938, 640.278184, 645.340779, 650.409683,
+   655.484857, 660.566261, 665.653857, 670.747608, 675.847474, 680.953420, 686.065407, 691.183401,
+   696.307365, 701.437264, 706.573062, 711.714726, 716.862220, 722.015512, 727.174567, 732.339353,
+   737.509837, 742.685987, 747.867770, 753.055156, 758.248113, 763.446610, 768.650617, 773.860103,
+   779.075039, 784.295395, 789.521141, 794.752250, 799.988692, 805.230439, 810.477463, 815.729736,
+   820.987232, 826.249922, 831.517780, 836.790780, 842.068894, 847.352098, 852.640365, 857.933670,
+   863.231987, 868.535292, 873.843560, 879.156766, 884.474886, 889.797896, 895.125772, 900.458491,
+   905.796029, 911.138363, 916.485471, 921.837329, 927.193915, 932.555207, 937.921183, 943.291821,
+   948.667100, 954.046997, 959.431492, 964.820564, 970.214191, 975.612354, 981.015031, 986.422203,
+   991.833849, 997.249950, 1002.670485, 1008.095435, 1013.524780, 1018.958502, 1024.396582, 1029.838999,
+   1035.285737, 1040.736775, 1046.192096, 1051.651682, 1057.115514, 1062.583574, 1068.055844, 1073.532308,
+   1079.012947, 1084.497744, 1089.986681, 1095.479743, 1100.976911, 1106.478169, 1111.983501, 1117.492889,
+   1123.006318, 1128.523771, 1134.045232, 1139.570685, 1145.100114, 1150.633503, 1156.170838, 1161.712101,
+   1167.257279, 1172.806355, 1178.359314, 1183.916142, 1189.476824, 1195.041344, 1200.609689, 1206.181843,
+   1211.757792, 1217.337522, 1222.921018, 1228.508267, 1234.099254, 1239.693965, 1245.292387, 1250.894506,
+   1256.500308, 1262.109780, 1267.722908, 1273.339679, 1278.960080, 1284.584097, 1290.211718, 1295.842930,
+   1301.477720, 1307.116075, 1312.757982, 1318.403428, 1324.052403, 1329.704892, 1335.360884, 1341.020366,
+   1346.683326, 1352.349753, 1358.019634, 1363.692957, 1369.369711, 1375.049884, 1380.733463, 1386.420439,
+   1392.110798, 1397.804530, 1403.501624, 1409.202067, 1414.905850, 1420.612960, 1426.323387, 1432.037120,
+   1437.754148, 1443.474460, 1449.198045, 1454.924892, 1460.654992, 1466.388333, 1472.124906, 1477.864699,
+   1483.607702, 1489.353905, 1495.103298, 1500.855871, 1506.611613, 1512.370515, 1518.132566, 1523.897757,
+   1529.666078, 1535.437519, 1541.212071, 1546.989723, 1552.770467, 1558.554292, 1564.341189, 1570.131149,
+   1575.924163, 1581.720221, 1587.519313, 1593.321432, 1599.126567, 1604.934709, 1610.745850, 1616.559981,
+   1622.377092, 1628.197175, 1634.020221, 1639.846221, 1645.675166, 1651.507049, 1657.341860, 1663.179590,
+   1669.020232, 1674.863776, 1680.710215, 1686.559540, 1692.411742, 1698.266814, 1704.124747, 1709.985533,
+   1715.849165, 1721.715633, 1727.584930, 1733.457047, 1739.331978, 1745.209714, 1751.090247, 1756.973569,
+   1762.859673, 1768.748551, 1774.640196, 1780.534598, 1786.431752, 1792.331650, 1798.234283, 1804.139645,
+   1810.047728, 1815.958524, 1821.872027, 1827.788229, 1833.707123, 1839.628702, 1845.552957, 1851.479884,
+   1857.409473, 1863.341718, 1869.276612, 1875.214148, 1881.154319, 1887.097119, 1893.042539, 1898.990574,
+   1904.941217, 1910.894460, 1916.850298, 1922.808722, 1928.769728, 1934.733307, 1940.699454, 1946.668161,
+   1952.639423, 1958.613233, 1964.589584, 1970.568470, 1976.549884, 1982.533820, 1988.520272, 1994.509233,
+   2000.500698, 2006.494659, 2012.491111, 2018.490048, 2024.491463, 2030.495350, 2036.501703, 2042.510516,
+   2048.521784, 2054.535499, 2060.551656, 2066.570249, 2072.591272, 2078.614720, 2084.640586, 2090.668864,
+   2096.699550, 2102.732636, 2108.768117, 2114.805988, 2120.846243, 2126.888876, 2132.933881, 2138.981253,
+   2145.030987, 2151.083076, 2157.137515, 2163.194299, 2169.253423, 2175.314879, 2181.378665, 2187.444773,
+   2193.513198, 2199.583936, 2205.656981, 2211.732327, 2217.809969, 2223.889902, 2229.972121, 2236.056620,
+   2242.143395, 2248.232440, 2254.323750, 2260.417320, 2266.513144, 2272.611219, 2278.711537, 2284.814096,
+   2290.918889, 2297.025912, 2303.135160, 2309.246627, 2315.360309, 2321.476201, 2327.594299, 2333.714596,
+   2339.837089, 2345.961772, 2352.088641, 2358.217692, 2364.348918, 2370.482316, 2376.617881, 2382.755608,
+   2388.895493, 2395.037530, 2401.181716, 2407.328045, 2413.476513, 2419.627116, 2425.779849, 2431.934707,
+   2438.091686, 2444.250781, 2450.411988, 2456.575303, 2462.740721, 2468.908238, 2475.077848, 2481.249549,
+   2487.423335, 2493.599202, 2499.777146, 2505.957163, 2512.139248, 2518.323397, 2524.509606, 2530.697870,
+   2536.888185, 2543.080548, 2549.274953, 2555.471397, 2561.669876, 2567.870385, 2574.072920, 2580.277478,
+   2586.484054, 2592.692644, 2598.903244, 2605.115850, 2611.330458, 2617.547065, 2623.765665, 2629.986255,
+   2636.208831, 2642.433390, 2648.659926, 2654.888437, 2661.118919, 2667.351367, 2673.585777, 2679.822147,
+   2686.060472, 2692.300747, 2698.542971, 2704.787138, 2711.033244, 2717.281287, 2723.531263, 2729.783166,
+   2736.036995, 2742.292745, 2748.550413, 2754.809994, 2761.071486, 2767.334884, 2773.600185, 2779.867386,
+   2786.136482, 2792.407471, 2798.680348, 2804.955110, 2811.231753, 2817.510275, 2823.790671, 2830.072937,
+   2836.357071, 2842.643070, 2848.930928, 2855.220644, 2861.512213, 2867.805632, 2874.100898, 2880.398007,
+   2886.696957, 2892.997742, 2899.300361, 2905.604810, 2911.911085, 2918.219184, 2924.529102, 2930.840837,
+   2937.154385, 2943.469743, 2949.786908, 2956.105876, 2962.426644, 2968.749209, 2975.073568, 2981.399718,
+   2987.727655, 2994.057376, 3000.388877, 3006.722157, 3013.057211, 3019.394037, 3025.732631, 3032.072990,
+   3038.415112, 3044.758992, 3051.104629, 3057.452018, 3063.801157, 3070.152043, 3076.504672, 3082.859042,
+   3089.215150, 3095.572992, 3101.932566, 3108.293868, 3114.656896, 3121.021647, 3127.388118, 3133.756305,
+   3140.126206, 3146.497818, 3152.871137, 3159.246162, 3165.622889, 3172.001315, 3178.381438, 3184.763254,
+   3191.146760, 3197.531955, 3203.918834, 3210.307396, 3216.697636, 3223.089553, 3229.483144, 3235.878406,
+   3242.275335, 3248.673930, 3255.074188, 3261.476105, 3267.879679, 3274.284908, 3280.691788, 3287.100316,
+   3293.510491, 3299.922310, 3306.335768, 3312.750865, 3319.167598, 3325.585963, 3332.005958, 3338.427580,
+   3344.850827, 3351.275696, 3357.702184, 3364.130290, 3370.560009, 3376.991340, 3383.424280, 3389.858827,
+   3396.294977, 3402.732729, 3409.172079, 3415.613026, 3422.055566, 3428.499697, 3434.945417, 3441.392723,
+   3447.841612, 3454.292083, 3460.744132, 3467.197757, 3473.652955, 3480.109725, 3486.568063, 3493.027968,
+   3499.489436, 3505.952465, 3512.417053, 3518.883198, 3525.350897, 3531.820147, 3538.290947, 3544.763293,
+   3551.237184, 3557.712616, 3564.189589, 3570.668098, 3577.148143, 3583.629720, 3590.112827, 3596.597463,
+   3603.083624, 3609.571308, 3616.060512, 3622.551236, 3629.043476, 3635.537230, 3642.032495, 3648.529270,
+   3655.027552, 3661.527339, 3668.028629, 3674.531419, 3681.035707, 3687.541491, 3694.048769, 3700.557538,
+   3707.067797, 3713.579542, 3720.092772, 3726.607485, 3733.123678, 3739.641349, 3746.160496, 3752.681117,
+   3759.203210, 3765.726773, 3772.251802, 3778.778297, 3785.306255, 3791.835674, 3798.366551, 3804.898886,
+   3811.432675, 3817.967916, 3824.504607, 3831.042747, 3837.582333, 3844.123363, 3850.665835, 3857.209747,
+   3863.755097, 3870.301882, 3876.850101, 3883.399752, 3889.950832, 3896.503340, 3903.057274, 3909.612630,
+   3916.169409, 3922.727607, 3929.287222, 3935.848253, 3942.410697, 3948.974552, 3955.539817, 3962.106490,
+   3968.674567, 3975.244049, 3981.814932, 3988.387214, 3994.960895, 4001.535970, 4008.112440, 4014.690301,
+   4021.269553, 4027.850192, 4034.432217, 4041.015626, 4047.600417, 4054.186589, 4060.774139, 4067.363066,
+   4073.953367, 4080.545040, 4087.138085, 4093.732498, 4100.328279, 4106.925425, 4113.523934, 4120.123804,
+   4126.725034, 4133.327622, 4139.931566, 4146.536864, 4153.143514, 4159.751515, 4166.360864, 4172.971560,
+   4179.583601, 4186.196985, 4192.811711, 4199.427776, 4206.045179, 4212.663918, 4219.283991, 4225.905397,
+   4232.528133, 4239.152198, 4245.777591, 4252.404308, 4259.032350, 4265.661713, 4272.292396, 4278.924398,
+   4285.557717, 4292.192350, 4298.828297, 4305.465555, 4312.104122, 4318.743998, 4325.385180, 4332.027667,
+   4338.671457, 4345.316548, 4351.962938, 4358.610627, 4365.259611, 4371.909890, 4378.561462, 4385.214325,
+   4391.868478, 4398.523918, 4405.180645, 4411.838656, 4418.497950, 4425.158525, 4431.820380, 4438.483512,
+   4445.147921, 4451.813605, 4458.480562, 4465.148790, 4471.818288, 4478.489054, 4485.161087, 4491.834385,
+   4498.508947, 4505.184770, 4511.861853, 4518.540196, 4525.219795, 4531.900649, 4538.582758, 4545.266119,
+   4551.950731, 4558.636592, 4565.323700, 4572.012055, 4578.701654, 4585.392497, 4592.084580, 4598.777904,
+   4605.472466, 4612.168265, 4618.865299, 4625.563567, 4632.263068, 4638.963799, 4645.665759, 4652.368947,
+   4659.073361, 4665.779001, 4672.485863, 4679.193947, 4685.903251, 4692.613774, 4699.325515, 4706.038471,
+   4712.752642, 4719.468025, 4726.184620, 4732.902424, 4739.621438, 4746.341658, 4753.063083, 4759.785713,
+   4766.509546, 4773.234579, 4779.960813, 4786.688244, 4793.416873, 4800.146697, 4806.877715, 4813.609926,
+   4820.343328, 4827.077919, 4833.813700, 4840.550666, 4847.288819, 4854.028156, 4860.768675, 4867.510376,
+   4874.253256, 4880.997315, 4887.742552, 4894.488964, 4901.236550, 4907.985310, 4914.735241, 4921.486343,
+   4928.238613, 4934.992051, 4941.746655, 4948.502424, 4955.259356, 4962.017451, 4968.776706, 4975.537121,
+   4982.298694, 4989.061423, 4995.825308, 5002.590347, 5009.356539, 5016.123882, 5022.892375, 5029.662017,
+   5036.432806, 5043.204742, 5049.977822, 5056.752046, 5063.527412, 5070.303919, 5077.081566, 5083.860351,
+   5090.640273, 5097.421330, 5104.203522, 5110.986848, 5117.771305, 5124.556892, 5131.343609, 5138.131454,
+   5144.920426, 5151.710523, 5158.501745, 5165.294089, 5172.087555, 5178.882142, 5185.677848, 5192.474671,
+   5199.272612, 5206.071668, 5212.871838, 5219.673121, 5226.475515, 5233.279021, 5240.083635, 5246.889358,
+   5253.696187, 5260.504122, 5267.313161, 5274.123304, 5280.934548, 5287.746893, 5294.560338, 5301.374881,
+   5308.190521, 5315.007257, 5321.825087, 5328.644011, 5335.464028, 5342.285135, 5349.107333, 5355.930619,
+   5362.754992, 5369.580452, 5376.406998, 5383.234627, 5390.063339, 5396.893133, 5403.724007, 5410.555960,
+   5417.388992, 5424.223101, 5431.058286, 5437.894545, 5444.731878, 5451.570283, 5458.409759, 5465.250306,
+   5472.091921, 5478.934605, 5485.778355, 5492.623170, 5499.469050, 5506.315993, 5513.163998, 5520.013065,
+   5526.863191, 5533.714376, 5540.566618, 5547.419917, 5554.274272, 5561.129681, 5567.986143, 5574.843657,
+   5581.702222, 5588.561837, 5595.422500, 5602.284212, 5609.146970, 5616.010773, 5622.875621, 5629.741512,
+   5636.608445, 5643.476419, 5650.345434, 5657.215487, 5664.086579, 5670.958707, 5677.831871, 5684.706069,
+   5691.581301, 5698.457566, 5705.334862, 5712.213188, 5719.092544, 5725.972928, 5732.854339, 5739.736777,
+   5746.620240, 5753.504726, 5760.390236, 5767.276768, 5774.164320, 5781.052893, 5787.942484, 5794.833093,
+   5801.724719, 5808.617361, 5815.511017, 5822.405687, 5829.301370, 5836.198064, 5843.095769, 5849.994483,
+   5856.894207, 5863.794937, 5870.696674, 5877.599417, 5884.503164, 5891.407915, 5898.313668, 5905.220423,
+   5912.128178, 5919.036933, 5925.946687, 5932.857437, 5939.769185, 5946.681927, 5953.595665, 5960.510396,
+   5967.426119, 5974.342834, 5981.260540, 5988.179235, 5995.098919, 6002.019590, 6008.941249, 6015.863892,
+   6022.787521, 6029.712133, 6036.637729, 6043.564306, 6050.491864, 6057.420401, 6064.349918, 6071.280413,
+   6078.211885, 6085.144333, 6092.077756, 6099.012153, 6105.947523, 6112.883866, 6119.821180, 6126.759465,
+   6133.698719, 6140.638941, 6147.580131, 6154.522288, 6161.465410, 6168.409497, 6175.354548, 6182.300562,
+   6189.247538, 6196.195476, 6203.144373, 6210.094229, 6217.045044, 6223.996816, 6230.949545, 6237.903229,
+   6244.857868, 6251.813460, 6258.770006, 6265.727503, 6272.685952, 6279.645350, 6286.605698, 6293.566994,
+   6300.529237, 6307.492427, 6314.456563, 6321.421643, 6328.387668, 6335.354635, 6342.322544, 6349.291394,
+   6356.261185, 6363.231915, 6370.203584, 6377.176190, 6384.149733, 6391.124212, 6398.099626, 6405.075974,
+   6412.053255, 6419.031469, 6426.010614, 6432.990690, 6439.971696, 6446.953631, 6453.936493, 6460.920283,
+   6467.905000, 6474.890641, 6481.877208, 6488.864698, 6495.853111, 6502.842447, 6509.832703, 6516.823880,
+   6523.815976, 6530.808991, 6537.802924, 6544.797774, 6551.793541, 6558.790222, 6565.787818, 6572.786328,
+   6579.785750, 6586.786085, 6593.787330, 6600.789486, 6607.792552, 6614.796526, 6621.801408, 6628.807197,
+   6635.813892, 6642.821493, 6649.829998, 6656.839407, 6663.849719, 6670.860933, 6677.873048, 6684.886064,
+   6691.899979, 6698.914794, 6705.930506, 6712.947116, 6719.964622, 6726.983024, 6734.002320, 6741.022511,
+   6748.043595, 6755.065571, 6762.088439, 6769.112198, 6776.136847, 6783.162386, 6790.188813, 6797.216127,
+   6804.244328, 6811.273416, 6818.303389, 6825.334246, 6832.365988, 6839.398612, 6846.432118, 6853.466506,
+   6860.501775, 6867.537923, 6874.574951, 6881.612857, 6888.651641, 6895.691301, 6902.731837, 6909.773249,
+   6916.815535, 6923.858695, 6930.902728, 6937.947633, 6944.993410, 6952.040057, 6959.087574, 6966.135961,
+   6973.185215, 6980.235338, 6987.286327, 6994.338183, 7001.390904, 7008.444490, 7015.498939, 7022.554252,
+   7029.610428, 7036.667465, 7043.725362, 7050.784121, 7057.843738, 7064.904215, 7071.965549, 7079.027741,
+   7086.090789, 7093.154693, 7100.219452, 7107.285065, 7114.351532, 7121.418852, 7128.487024, 7135.556047,
+   7142.625922, 7149.696646, 7156.768219, 7163.840641, 7170.913911, 7177.988027, 7185.062991, 7192.138799,
+   7199.215453, 7206.292951, 7213.371293, 7220.450477, 7227.530504, 7234.611372, 7241.693080, 7248.775629,
+   7255.859017, 7262.943243, 7270.028307, 7277.114209, 7284.200947, 7291.288521, 7298.376929, 7305.466172,
+   7312.556249, 7319.647159, 7326.738901, 7333.831475, 7340.924880, 7348.019114, 7355.114179, 7362.210072,
+   7369.306793, 7376.404342, 7383.502718, 7390.601920, 7397.701947, 7404.802799, 7411.904475, 7419.006974,
+   7426.110296, 7433.214440, 7440.319406, 7447.425192, 7454.531798, 7461.639223, 7468.747468, 7475.856530,
+   7482.966409, 7490.077105, 7497.188617, 7504.300945, 7511.414087, 7518.528043, 7525.642812, 7532.758395,
+   7539.874789, 7546.991994, 7554.110010, 7561.228837, 7568.348472, 7575.468917, 7582.590169, 7589.712229,
+   7596.835096, 7603.958769, 7611.083247, 7618.208530, 7625.334617, 7632.461508, 7639.589202, 7646.717698,
+   7653.846995, 7660.977094, 7668.107992, 7675.239691, 7682.372189, 7689.505485, 7696.639578, 7703.774469,
+   7710.910156, 7718.046640, 7725.183918, 7732.321991, 7739.460858, 7746.600518, 7753.740971, 7760.882217,
+   7768.024253, 7775.167081, 7782.310698, 7789.455105, 7796.600301, 7803.746286, 7810.893058, 7818.040617,
+   7825.188963, 7832.338095, 7839.488012, 7846.638713, 7853.790199, 7860.942467, 7868.095519, 7875.249353,
+   7882.403968, 7889.559364, 7896.715541, 7903.872497, 7911.030233, 7918.188747, 7925.348039, 7932.508108,
+   7939.668954, 7946.830576, 7953.992973, 7961.156146, 7968.320093, 7975.484813, 7982.650306, 7989.816572,
+   7996.983610, 8004.151419, 8011.319999, 8018.489349, 8025.659469, 8032.830357, 8040.002014, 8047.174439,
+   8054.347631, 8061.521589, 8068.696313, 8075.871803, 8083.048057, 8090.225076, 8097.402859, 8104.581404,
+   8111.760712, 8118.940782, 8126.121613, 8133.303205, 8140.485557, 8147.668669, 8154.852540, 8162.037169,
+   8169.222556, 8176.408700, 8183.595601, 8190.783258, 8197.971671, 8205.160839, 8212.350761, 8219.541437,
+   8226.732866, 8233.925048, 8241.117983, 8248.311668, 8255.506105, 8262.701293, 8269.897230, 8277.093916,
+   8284.291352, 8291.489535, 8298.688466, 8305.888145, 8313.088570, 8320.289741, 8327.491657, 8334.694318,
+   8341.897724, 8349.101873, 8356.306765, 8363.512401, 8370.718778, 8377.925897, 8385.133757, 8392.342357,
+   8399.551697, 8406.761777, 8413.972595, 8421.184152, 8428.396447, 8435.609478, 8442.823246, 8450.037751,
+   8457.252991, 8464.468966, 8471.685675, 8478.903119, 8486.121296, 8493.340205, 8500.559847, 8507.780221,
+   8515.001326, 8522.223162, 8529.445728, 8536.669024, 8543.893049, 8551.117802, 8558.343284, 8565.569493,
+   8572.796429, 8580.024091, 8587.252480, 8594.481593, 8601.711432, 8608.941995, 8616.173282, 8623.405293,
+   8630.638026, 8637.871481, 8645.105658, 8652.340557, 8659.576176, 8666.812515, 8674.049574, 8681.287353,
+   8688.525849, 8695.765064, 8703.004997, 8710.245647, 8717.487013, 8724.729095, 8731.971893, 8739.215406,
+   8746.459634, 8753.704575, 8760.950230, 8768.196598, 8775.443679, 8782.691472, 8789.939976, 8797.189191,
+   8804.439116, 8811.689752, 8818.941097, 8826.193151, 8833.445913, 8840.699383, 8847.953561, 8855.208446,
+   8862.464037, 8869.720335, 8876.977337, 8884.235045, 8891.493457, 8898.752573, 8906.012393, 8913.272915,
+   8920.534141, 8927.796068, 8935.058696, 8942.322026, 8949.586056, 8956.850786, 8964.116216, 8971.382345,
+   8978.649172, 8985.916697, 8993.184920, 9000.453841, 9007.723457, 9014.993770, 9022.264779, 9029.536483,
+   9036.808881, 9044.081973, 9051.355760, 9058.630239, 9065.905412, 9073.181276, 9080.457833, 9087.735080,
+   9095.013019, 9102.291648, 9109.570967, 9116.850975, 9124.131672, 9131.413058, 9138.695132, 9145.977893,
+   9153.261341, 9160.545476, 9167.830297, 9175.115803, 9182.401995, 9189.688871, 9196.976432, 9204.264676,
+   9211.553604, 9218.843215, 9226.133507, 9233.424482, 9240.716138, 9248.008476, 9255.301493, 9262.595191,
+   9269.889568, 9277.184625, 9284.480360, 9291.776773, 9299.073864, 9306.371632, 9313.670077, 9320.969199,
+   9328.268996, 9335.569469, 9342.870617, 9350.172439, 9357.474936, 9364.778106, 9372.081949, 9379.386465,
+   9386.691653, 9393.997513, 9401.304045, 9408.611247, 9415.919120, 9423.227662, 9430.536875, 9437.846756,
+   9445.157306, 9452.468525, 9459.780411, 9467.092965, 9474.406185, 9481.720072, 9489.034625, 9496.349843,
+   9503.665726, 9510.982275, 9518.299487, 9525.617363, 9532.935903, 9540.255105, 9547.574970, 9554.895497,
+   9562.216686, 9569.538535, 9576.861046, 9584.184217, 9591.508047, 9598.832537, 9606.157686, 9613.483494,
+   9620.809959, 9628.137082, 9635.464863, 9642.793300, 9650.122394, 9657.452144, 9664.782549, 9672.113609,
+   9679.445324, 9686.777694, 9694.110717, 9701.444393, 9708.778722, 9716.113704, 9723.449338, 9730.785624,
+   9738.122561, 9745.460148, 9752.798387, 9760.137275, 9767.476812, 9774.816999, 9782.157835, 9789.499319,
+   9796.841450, 9804.184230, 9811.527656, 9818.871729, 9826.216448, 9833.561813, 9840.907823, 9848.254478,
+   9855.601778, 9862.949721, 9870.298309, 9877.647540, 9884.997414, 9892.347930, 9899.699088, 9907.050888,
+   9914.403329, 9921.756411, 9929.110133, 9936.464495, 9943.819497, 9951.175138, 9958.531418, 9965.888337,
+   9973.245893, 9980.604087, 9987.962917, 9995.322385, 10002.682489, 10010.043229, 10017.404604, 10024.766615,
+   10032.129260, 10039.492540, 10046.856453, 10054.221000, 10061.586180, 10068.951993, 10076.318438, 10083.685515,
+   10091.053224, 10098.421564, 10105.790534, 10113.160135, 10120.530366, 10127.901226, 10135.272715, 10142.644833,
+   10150.017579, 10157.390954, 10164.764956, 10172.139585, 10179.514840, 10186.890722, 10194.267231, 10201.644364,
+   10209.022123, 10216.400507, 10223.779515, 10231.159147, 10238.539403, 10245.920282, 10253.301784, 10260.683908,
+   10268.066655, 10275.450023, 10282.834012, 10290.218623, 10297.603854, 10304.989705, 10312.376176, 10319.763266,
+   10327.150975, 10334.539303, 10341.928249, 10349.317813, 10356.707994, 10364.098793, 10371.490208, 10378.882240,
+   10386.274887, 10393.668150, 10401.062029, 10408.456522, 10415.851629, 10423.247351, 10430.643686, 10438.040635,
+   10445.438196, 10452.836370, 10460.235157, 10467.634555, 10475.034564, 10482.435185, 10489.836416, 10497.238258,
+   10504.640709, 10512.043770, 10519.447441, 10526.851720, 10534.256607, 10541.662103, 10549.068206, 10556.474917,
+   10563.882235, 10571.290159, 10578.698690, 10586.107826, 10593.517568, 10600.927915, 10608.338867, 10615.750423,
+   10623.162584, 10630.575348, 10637.988715, 10645.402685, 10652.817258, 10660.232433, 10667.648210, 10675.064589,
+   10682.481568, 10689.899149, 10697.317330, 10704.736111, 10712.155491, 10719.575471, 10726.996050, 10734.417227,
+   10741.839003, 10749.261377, 10756.684348, 10764.107917, 10771.532082, 10778.956844, 10786.382202, 10793.808155,
+   10801.234704, 10808.661848, 10816.089587, 10823.517920, 10830.946848, 10838.376369, 10845.806483, 10853.237190,
+   10860.668489, 10868.100381, 10875.532865, 10882.965940, 10890.399607, 10897.833864, 10905.268712, 10912.704150,
+   10920.140178, 10927.576795, 10935.014002, 10942.451797, 10949.890180, 10957.329152, 10964.768711, 10972.208858,
+   10979.649592, 10987.090912, 10994.532819, 11001.975312, 11009.418390, 11016.862054, 11024.306302, 11031.751136,
+   11039.196553, 11046.642555, 11054.089140, 11061.536308, 11068.984059, 11076.432393, 11083.881309, 11091.330807,
+   11098.780887, 11106.231548, 11113.682789, 11121.134612, 11128.587014, 11136.039996, 11143.493558, 11150.947699,
+   11158.402419, 11165.857718, 11173.313594, 11180.770049, 11188.227081, 11195.684690, 11203.142876, 11210.601639,
+   11218.060978, 11225.520893, 11232.981383, 11240.442449, 11247.904089, 11255.366304, 11262.829093, 11270.292456,
+   11277.756393, 11285.220903, 11292.685985, 11300.151641, 11307.617868, 11315.084668, 11322.552039, 11330.019981,
+   11337.488494, 11344.957578, 11352.427232, 11359.897457, 11367.368250, 11374.839613, 11382.311546, 11389.784046,
+   11397.257115, 11404.730752, 11412.204957, 11419.679729, 11427.155069, 11434.630975, 11442.107447, 11449.584486,
+   11457.062090, 11464.540259, 11472.018994, 11479.498294, 11486.978158, 11494.458586, 11501.939579, 11509.421134,
+   11516.903253, 11524.385935, 11531.869179, 11539.352986, 11546.837355, 11554.322285, 11561.807777, 11569.293829,
+   11576.780443, 11584.267616, 11591.755350, 11599.243644, 11606.732496, 11614.221909, 11621.711879, 11629.202409,
+   11636.693496, 11644.185142, 11651.677345, 11659.170105, 11666.663423, 11674.157296, 11681.651727, 11689.146713,
+   11696.642255, 11704.138352, 11711.635005, 11719.132212, 11726.629974, 11734.128289, 11741.627159, 11749.126582,
+   11756.626559, 11764.127088, 11771.628171, 11779.129805, 11786.631991, 11794.134730, 11801.638019, 11809.141860,
+   11816.646252, 11824.151194, 11831.656686, 11839.162728, 11846.669320, 11854.176461, 11861.684151, 11869.192390,
+   11876.701177, 11884.210512, 11891.720395, 11899.230826, 11906.741804, 11914.253328, 11921.765400, 11929.278017,
+   11936.791181, 11944.304890, 11951.819145, 11959.333944, 11966.849289, 11974.365178, 11981.881611, 11989.398589,
+   11996.916109, 12004.434174, 12011.952781, 12019.471931, 12026.991623, 12034.511858, 12042.032634, 12049.553952,
+   12057.075811, 12064.598212, 12072.121152, 12079.644634, 12087.168655, 12094.693216, 12102.218317, 12109.743957,
+   12117.270136, 12124.796854, 12132.324110, 12139.851904, 12147.380235, 12154.909105, 12162.438511, 12169.968454,
+   12177.498934, 12185.029951, 12192.561503, 12200.093591, 12207.626215, 12215.159374, 12222.693067, 12230.227296,
+   12237.762058, 12245.297355, 12252.833186, 12260.369549, 12267.906447, 12275.443877, 12282.981839, 12290.520334,
+   12298.059361, 12305.598920, 12313.139010, 12320.679632, 12328.220784, 12335.762468, 12343.304681, 12350.847425,
+   12358.390698, 12365.934501, 12373.478833, 12381.023694, 12388.569084, 12396.115002, 12403.661448, 12411.208422,
+   12418.755924, 12426.303953, 12433.852509, 12441.401592, 12448.951201, 12456.501336, 12464.051997, 12471.603184,
+   12479.154896, 12486.707134, 12494.259896, 12501.813182, 12509.366993, 12516.921328, 12524.476187, 12532.031569,
+   12539.587474, 12547.143902, 12554.700852, 12562.258325, 12569.816320, 12577.374837, 12584.933875, 12592.493435,
+   12600.053515, 12607.614116, 12615.175238, 12622.736880, 12630.299041, 12637.861722, 12645.424923, 12652.988643,
+   12660.552881, 12668.117638, 12675.682913, 12683.248707, 12690.815018, 12698.381846, 12705.949192, 12713.517054,
+   12721.085434, 12728.654329, 12736.223741, 12743.793669, 12751.364112, 12758.935071, 12766.506544, 12774.078533,
+   12781.651036, 12789.224053, 12796.797584, 12804.371629, 12811.946188, 12819.521259, 12827.096844, 12834.672941,
+   12842.249551, 12849.826673, 12857.404307, 12864.982452, 12872.561109, 12880.140277, 12887.719956, 12895.300146,
+   12902.880845, 12910.462055, 12918.043775, 12925.626004, 12933.208742, 12940.791990, 12948.375746, 12955.960011,
+   12963.544784, 12971.130065, 12978.715854, 12986.302150, 12993.888954, 13001.476264, 13009.064082, 13016.652405,
+   13024.241235, 13031.830571, 13039.420413, 13047.010759, 13054.601612, 13062.192969, 13069.784830, 13077.377196,
+   13084.970067, 13092.563441, 13100.157319, 13107.751700, 13115.346584, 13122.941972, 13130.537862, 13138.134254,
+   13145.731148, 13153.328545, 13160.926443, 13168.524842, 13176.123742, 13183.723144, 13191.323046, 13198.923448,
+   13206.524351, 13214.125753, 13221.727655, 13229.330056, 13236.932957, 13244.536356, 13252.140254, 13259.744650,
+   13267.349545, 13274.954937, 13282.560827, 13290.167214, 13297.774099, 13305.381480, 13312.989359, 13320.597733,
+   13328.206604, 13335.815970, 13343.425832, 13351.036190, 13358.647043, 13366.258390, 13373.870233, 13381.482570,
+   13389.095401, 13396.708726, 13404.322544, 13411.936857, 13419.551662, 13427.166960, 13434.782751, 13442.399035,
+   13450.015811, 13457.633079, 13465.250838, 13472.869089, 13480.487832, 13488.107065, 13495.726789, 13503.347004,
+   13510.967709, 13518.588904, 13526.210589, 13533.832764, 13541.455428, 13549.078581, 13556.702223, 13564.326353,
+   13571.950972, 13579.576080, 13587.201675, 13594.827757, 13602.454328, 13610.081385, 13617.708929, 13625.336960,
+   13632.965478, 13640.594482, 13648.223972, 13655.853948, 13663.484409, 13671.115355, 13678.746787, 13686.378704,
+   13694.011105, 13701.643990, 13709.277360, 13716.911213, 13724.545551, 13732.180371, 13739.815675, 13747.451462,
+   13755.087732, 13762.724484, 13770.361718, 13777.999435, 13785.637633, 13793.276313, 13800.915474, 13808.555116,
+   13816.195239, 13823.835843, 13831.476927, 13839.118492, 13846.760536, 13854.403060, 13862.046064, 13869.689547,
+   13877.333509, 13884.977950, 13892.622869, 13900.268267, 13907.914143, 13915.560496, 13923.207328, 13930.854637,
+   13938.502423, 13946.150686, 13953.799425, 13961.448642, 13969.098334, 13976.748503, 13984.399148, 13992.050268,
+   13999.701863, 14007.353934, 14015.006480, 14022.659500, 14030.312995, 14037.966964, 14045.621407, 14053.276325,
+   14060.931715, 14068.587579, 14076.243916, 14083.900726, 14091.558009, 14099.215765, 14106.873992, 14114.532692,
+   14122.191863, 14129.851506, 14137.511620, 14145.172206, 14152.833262, 14160.494789, 14168.156787, 14175.819255,
+   14183.482192, 14191.145600, 14198.809477, 14206.473824, 14214.138640, 14221.803924, 14229.469678, 14237.135900,
+   14244.802590, 14252.469748, 14260.137374, 14267.805468, 14275.474029, 14283.143057, 14290.812553, 14298.482515,
+   14306.152943, 14313.823838, 14321.495199, 14329.167026, 14336.839318, 14344.512076, 14352.185299, 14359.858987,
+   14367.533140, 14375.207758, 14382.882840, 14390.558386, 14398.234396, 14405.910869, 14413.587806, 14421.265207,
+   14428.943070, 14436.621397, 14444.300186, 14451.979437, 14459.659151, 14467.339326, 14475.019964, 14482.701063,
+   14490.382623, 14498.064645, 14505.747127, 14513.430070, 14521.113474, 14528.797338, 14536.481662, 14544.166446,
+   14551.851690, 14559.537393, 14567.223555, 14574.910176, 14582.597256, 14590.284795, 14597.972792, 14605.661248,
+   14613.350161, 14621.039532, 14628.729361, 14636.419647, 14644.110390, 14651.801590, 14659.493247, 14667.185360,
+   14674.877930, 14682.570956, 14690.264437, 14697.958375, 14705.652767, 14713.347616, 14721.042919, 14728.738677,
+   14736.434889, 14744.131556, 14751.828678, 14759.526253, 14767.224282, 14774.922765, 14782.621701, 14790.321091,
+   14798.020933, 14805.721228, 14813.421976, 14821.123176, 14828.824829, 14836.526933, 14844.229489, 14851.932497,
+   14859.635956, 14867.339866, 14875.044227, 14882.749039, 14890.454302, 14898.160014, 14905.866177, 14913.572790,
+   14921.279853, 14928.987365, 14936.695327, 14944.403737, 14952.112597, 14959.821905, 14967.531662, 14975.241867,
+   14982.952521, 14990.663622, 14998.375171, 15006.087167, 15013.799611, 15021.512502, 15029.225840, 15036.939625,
+   15044.653856, 15052.368533, 15060.083657, 15067.799226, 15075.515242, 15083.231702, 15090.948609, 15098.665960,
+   15106.383756, 15114.101997, 15121.820683, 15129.539812, 15137.259386, 15144.979404, 15152.699866, 15160.420771,
+   15168.142120, 15175.863912, 15183.586146, 15191.308824, 15199.031944, 15206.755506, 15214.479511, 15222.203958,
+   15229.928846, 15237.654176, 15245.379948, 15253.106160, 15260.832814, 15268.559908, 15276.287444, 15284.015419,
+   15291.743835, 15299.472691, 15307.201986, 15314.931722, 15322.661897, 15330.392511, 15338.123564, 15345.855056,
+   15353.586986, 15361.319356, 15369.052163, 15376.785409, 15384.519092, 15392.253214, 15399.987773, 15407.722769,
+   15415.458202, 15423.194072, 15430.930380, 15438.667123, 15446.404303, 15454.141920, 15461.879972, 15469.618460,
+   15477.357384, 15485.096743, 15492.836537, 15500.576767, 15508.317431, 15516.058530, 15523.800064, 15531.542032,
+   15539.284434, 15547.027270, 15554.770540, 15562.514243, 15570.258380, 15578.002949, 15585.747952, 15593.493388,
+   15601.239256, 15608.985557, 15616.732290, 15624.479455, 15632.227051, 15639.975080, 15647.723540, 15655.472431,
+   15663.221754, 15670.971507, 15678.721691, 15686.472306, 15694.223351, 15701.974826, 15709.726732, 15717.479067,
+   15725.231832, 15732.985026, 15740.738650, 15748.492702, 15756.247184, 15764.002094, 15771.757433, 15779.513200,
+   15787.269395, 15795.026019, 15802.783070, 15810.540549, 15818.298455, 15826.056788, 15833.815549, 15841.574736,
+   15849.334350, 15857.094391, 15864.854858, 15872.615751, 15880.377070, 15888.138815, 15895.900986, 15903.663582,
+   15911.426603, 15919.190050, 15926.953921, 15934.718217, 15942.482938, 15950.248083, 15958.013652, 15965.779645,
+   15973.546062, 15981.312902, 15989.080166, 15996.847853, 16004.615964, 16012.384497, 16020.153453, 16027.922832,
+   16035.692633, 16043.462856, 16051.233501, 16059.004568, 16066.776057, 16074.547967, 16082.320299, 16090.093052,
+   16097.866225, 16105.639820, 16113.413835, 16121.188270, 16128.963126, 16136.738402, 16144.514098, 16152.290213,
+   16160.066748, 16167.843703, 16175.621076, 16183.398869, 16191.177080, 16198.955710, 16206.734759, 16214.514226,
+   16222.294111, 16230.074414, 16237.855135, 16245.636274, 16253.417830, 16261.199803, 16268.982193, 16276.765000,
+   16284.548224, 16292.331865, 16300.115922, 16307.900395, 16315.685285, 16323.470590, 16331.256311, 16339.042447,
+   16346.828999, 16354.615966, 16362.403348, 16370.191145, 16377.979356, 16385.767982, 16393.557023, 16401.346477,
+   16409.136346, 16416.926628, 16424.717324, 16432.508434, 16440.299957, 16448.091893, 16455.884242, 16463.677003,
+   16471.470178, 16479.263764, 16487.057764, 16494.852175, 16502.646998, 16510.442233, 16518.237879, 16526.033937,
+   16533.830407, 16541.627287, 16549.424578, 16557.222280, 16565.020393, 16572.818916, 16580.617849, 16588.417193,
+   16596.216946, 16604.017109, 16611.817682, 16619.618664, 16627.420055, 16635.221855, 16643.024065, 16650.826683,
+   16658.629710, 16666.433145, 16674.236988, 16682.041239, 16689.845899, 16697.650966, 16705.456440, 16713.262322,
+   16721.068612, 16728.875308, 16736.682411, 16744.489921, 16752.297838, 16760.106161, 16767.914890, 16775.724026,
+   16783.533567, 16791.343514, 16799.153867, 16806.964625, 16814.775788, 16822.587357, 16830.399330, 16838.211708,
+   16846.024491, 16853.837678, 16861.651270, 16869.465266, 16877.279665, 16885.094469, 16892.909676, 16900.725286,
+   16908.541300, 16916.357717, 16924.174537, 16931.991760, 16939.809385, 16947.627413, 16955.445844, 16963.264676,
+   16971.083910, 16978.903547, 16986.723585, 16994.544024, 17002.364865, 17010.186107, 17018.007750, 17025.829794,
+   17033.652239, 17041.475084, 17049.298330, 17057.121976, 17064.946022, 17072.770468, 17080.595314, 17088.420559,
+   17096.246204, 17104.072248, 17111.898691, 17119.725533, 17127.552774, 17135.380413, 17143.208451, 17151.036888,
+   17158.865722, 17166.694955, 17174.524585, 17182.354613, 17190.185039, 17198.015862, 17205.847082, 17213.678699,
+   17221.510714, 17229.343124, 17237.175932, 17245.009136, 17252.842736, 17260.676733, 17268.511125, 17276.345913,
+   17284.181097, 17292.016676, 17299.852651, 17307.689020, 17315.525785, 17323.362945, 17331.200499, 17339.038448,
+   17346.876791, 17354.715529, 17362.554661, 17370.394186, 17378.234105, 17386.074418, 17393.915125, 17401.756225,
+   17409.597718, 17417.439604, 17425.281882, 17433.124554, 17440.967618, 17448.811074, 17456.654923, 17464.499164,
+   17472.343796, 17480.188821, 17488.034237, 17495.880044, 17503.726243, 17511.572833, 17519.419814, 17527.267186,
+   17535.114948, 17542.963101, 17550.811645, 17558.660579, 17566.509902, 17574.359616, 17582.209720, 17590.060213,
+   17597.911096, 17605.762368, 17613.614029, 17621.466079, 17629.318518, 17637.171346, 17645.024562, 17652.878167,
+   17660.732160, 17668.586541, 17676.441311, 17684.296468, 17692.152012, 17700.007944, 17707.864264, 17715.720971,
+   17723.578065, 17731.435545, 17739.293413, 17747.151667, 17755.010308, 17762.869335, 17770.728748, 17778.588547,
+   17786.448732, 17794.309303, 17802.170259, 17810.031601, 17817.893328, 17825.755440, 17833.617938, 17841.480820,
+   17849.344086, 17857.207738, 17865.071773, 17872.936193, 17880.800997, 17888.666185, 17896.531757, 17904.397712,
+   17912.264051, 17920.130774, 17927.997879, 17935.865368, 17943.733239, 17951.601493, 17959.470130, 17967.339150,
+   17975.208551, 17983.078335, 17990.948501, 17998.819049, 18006.689979, 18014.561290, 18022.432983, 18030.305056,
+   18038.177512, 18046.050348, 18053.923565, 18061.797163, 18069.671141, 18077.545500, 18085.420239, 18093.295358,
+   18101.170858, 18109.046737, 18116.922996, 18124.799634, 18132.676652, 18140.554049, 18148.431825, 18156.309981,
+   18164.188515, 18172.067428, 18179.946719, 18187.826389, 18195.706438, 18203.586864, 18211.467668, 18219.348850,
+   18227.230410, 18235.112348, 18242.994663, 18250.877355, 18258.760424, 18266.643871, 18274.527694, 18282.411894,
+   18290.296470, 18298.181423, 18306.066752, 18313.952458, 18321.838539, 18329.724997, 18337.611830, 18345.499038,
+   18353.386622, 18361.274582, 18369.162916, 18377.051626, 18384.940710, 18392.830169, 18400.720003, 18408.610211,
+   18416.500794, 18424.391750, 18432.283081, 18440.174786, 18448.066864, 18455.959316, 18463.852142, 18471.745341,
+   18479.638913, 18487.532858, 18495.427176, 18503.321867, 18511.216930, 18519.112366, 18527.008175, 18534.904355,
+   18542.800908, 18550.697833, 18558.595129, 18566.492797, 18574.390837, 18582.289248, 18590.188030, 18598.087184,
+   18605.986708, 18613.886604, 18621.786870, 18629.687506, 18637.588513, 18645.489891, 18653.391638, 18661.293756,
+   18669.196243, 18677.099100, 18685.002327, 18692.905923, 18700.809889, 18708.714224, 18716.618928, 18724.524001,
+   18732.429442, 18740.335253, 18748.241431, 18756.147979, 18764.054894, 18771.962178, 18779.869829, 18787.777849,
+   18795.686236, 18803.594991, 18811.504113, 18819.413602, 18827.323459, 18835.233683, 18843.144273, 18851.055231,
+   18858.966555, 18866.878245, 18874.790302, 18882.702725, 18890.615515, 18898.528670, 18906.442191, 18914.356077,
+   18922.270330, 18930.184947, 18938.099930, 18946.015279, 18953.930992, 18961.847070, 18969.763513, 18977.680320,
+   18985.597492, 18993.515029, 19001.432929, 19009.351194, 19017.269823, 19025.188815, 19033.108171, 19041.027891,
+   19048.947974, 19056.868421, 19064.789230, 19072.710403, 19080.631939, 19088.553837, 19096.476098, 19104.398722,
+   19112.321708, 19120.245056, 19128.168766, 19136.092839, 19144.017273, 19151.942069, 19159.867226, 19167.792745,
+   19175.718626, 19183.644867, 19191.571470, 19199.498433, 19207.425758, 19215.353443, 19223.281488, 19231.209894,
+   19239.138661, 19247.067787, 19254.997274, 19262.927120, 19270.857326, 19278.787892, 19286.718817, 19294.650102,
+   19302.581746, 19310.513749, 19318.446112, 19326.378833, 19334.311912, 19342.245351, 19350.179148, 19358.113303,
+   19366.047816, 19373.982688, 19381.917917, 19389.853505, 19397.789450, 19405.725753, 19413.662413, 19421.599430,
+   19429.536805, 19437.474537, 19445.412625, 19453.351071, 19461.289873, 19469.229032, 19477.168547, 19485.108419,
+   19493.048647, 19500.989230, 19508.930170, 19516.871466, 19524.813117, 19532.755124, 19540.697486, 19548.640204,
+   19556.583276, 19564.526704, 19572.470487, 19580.414624, 19588.359116, 19596.303963, 19604.249164, 19612.194720,
+   19620.140629, 19628.086893, 19636.033511, 19643.980482, 19651.927807, 19659.875485, 19667.823517, 19675.771903,
+   19683.720641, 19691.669733, 19699.619177, 19707.568974, 19715.519124, 19723.469627, 19731.420482, 19739.371689,
+   19747.323248, 19755.275159, 19763.227423, 19771.180038, 19779.133005, 19787.086323, 19795.039993, 19802.994014,
+   19810.948386, 19818.903109, 19826.858184, 19834.813609, 19842.769385, 19850.725511, 19858.681988, 19866.638815,
+   19874.595992, 19882.553520, 19890.511397, 19898.469624, 19906.428201, 19914.387128, 19922.346403, 19930.306029,
+   19938.266003, 19946.226327, 19954.187000, 19962.148021, 19970.109391, 19978.071110, 19986.033177, 19993.995593,
+   20001.958357, 20009.921469, 20017.884929, 20025.848737, 20033.812893, 20041.777396, 20049.742247, 20057.707445,
+   20065.672991, 20073.638884, 20081.605123, 20089.571710, 20097.538644, 20105.505924, 20113.473550, 20121.441524,
+   20129.409843, 20137.378509, 20145.347521, 20153.316878, 20161.286582, 20169.256631, 20177.227026, 20185.197767,
+   20193.168852, 20201.140283, 20209.112059, 20217.084181, 20225.056647, 20233.029457, 20241.002613, 20248.976113,
+   20256.949957, 20264.924146, 20272.898679, 20280.873556, 20288.848776, 20296.824341, 20304.800249, 20312.776501,
+   20320.753097, 20328.730036, 20336.707318, 20344.684943, 20352.662911, 20360.641222, 20368.619875, 20376.598872,
+   20384.578211, 20392.557892, 20400.537916, 20408.518281, 20416.498989, 20424.480039, 20432.461431, 20440.443164,
+   20448.425239, 20456.407655, 20464.390413, 20472.373512, 20480.356952, 20488.340733, 20496.324855, 20504.309317,
+   20512.294121, 20520.279265, 20528.264749, 20536.250574, 20544.236739, 20552.223244, 20560.210089, 20568.197273,
+   20576.184798, 20584.172662, 20592.160865, 20600.149408, 20608.138291, 20616.127512, 20624.117073, 20632.106972,
+   20640.097210, 20648.087787, 20656.078702, 20664.069956, 20672.061549, 20680.053479, 20688.045748, 20696.038354,
+   20704.031299, 20712.024581, 20720.018201, 20728.012159, 20736.006454, 20744.001086, 20751.996056, 20759.991362,
+   20767.987006, 20775.982986, 20783.979304, 20791.975958, 20799.972948, 20807.970275, 20815.967938, 20823.965937,
+   20831.964273, 20839.962944, 20847.961951, 20855.961294, 20863.960973, 20871.960987, 20879.961336, 20887.962021,
+   20895.963041, 20903.964396, 20911.966086, 20919.968111, 20927.970470, 20935.973165, 20943.976193, 20951.979556,
+   20959.983254, 20967.987285, 20975.991651, 20983.996350, 20992.001384, 21000.006751, 21008.012451, 21016.018485,
+   21024.024853, 21032.031554, 21040.038588, 21048.045955, 21056.053655, 21064.061688, 21072.070053, 21080.078752,
+   21088.087782, 21096.097145, 21104.106841, 21112.116868, 21120.127228, 21128.137919, 21136.148943, 21144.160298,
+   21152.171985, 21160.184003, 21168.196352, 21176.209033, 21184.222045, 21192.235389, 21200.249063, 21208.263068,
+   21216.277404, 21224.292070, 21232.307067, 21240.322394, 21248.338052, 21256.354040, 21264.370357, 21272.387005,
+   21280.403983, 21288.421291, 21296.438928, 21304.456894, 21312.475191, 21320.493816, 21328.512771, 21336.532055,
+   21344.551667, 21352.571609, 21360.591879, 21368.612479, 21376.633406, 21384.654663, 21392.676247, 21400.698160,
+   21408.720401, 21416.742970, 21424.765867, 21432.789091, 21440.812644, 21448.836524, 21456.860731, 21464.885266,
+   21472.910128, 21480.935317, 21488.960834, 21496.986677, 21505.012847, 21513.039344, 21521.066168, 21529.093318,
+   21537.120795, 21545.148597, 21553.176726, 21561.205182, 21569.233963, 21577.263070, 21585.292503, 21593.322261,
+   21601.352345, 21609.382755, 21617.413490, 21625.444550, 21633.475935, 21641.507646, 21649.539681, 21657.572041,
+   21665.604726, 21673.637736, 21681.671070, 21689.704728, 21697.738711, 21705.773018, 21713.807649, 21721.842604,
+   21729.877883, 21737.913485, 21745.949412, 21753.985662, 21762.022235, 21770.059132, 21778.096352, 21786.133895,
+   21794.171761, 21802.209950, 21810.248462, 21818.287297, 21826.326455, 21834.365934, 21842.405737, 21850.445862,
+   21858.486308, 21866.527077, 21874.568168, 21882.609581, 21890.651316, 21898.693372, 21906.735750, 21914.778450,
+   21922.821471, 21930.864813, 21938.908476, 21946.952461, 21954.996766, 21963.041392, 21971.086339, 21979.131607,
+   21987.177195, 21995.223104, 22003.269333, 22011.315883, 22019.362752, 22027.409942, 22035.457451, 22043.505281,
+   22051.553430, 22059.601898, 22067.650687, 22075.699794, 22083.749222, 22091.798968, 22099.849033, 22107.899418,
+   22115.950121, 22124.001143, 22132.052484, 22140.104144, 22148.156122, 22156.208418, 22164.261033, 22172.313966,
+   22180.367217, 22188.420787, 22196.474674, 22204.528879, 22212.583401, 22220.638241, 22228.693399, 22236.748874,
+   22244.804667, 22252.860776, 22260.917203, 22268.973947, 22277.031008, 22285.088385, 22293.146079, 22301.204090,
+   22309.262417, 22317.321061, 22325.380021, 22333.439297, 22341.498890, 22349.558798, 22357.619022, 22365.679562,
+   22373.740418, 22381.801589, 22389.863076, 22397.924879, 22405.986996, 22414.049429, 22422.112177, 22430.175240,
+   22438.238618, 22446.302310, 22454.366318, 22462.430639, 22470.495276, 22478.560227, 22486.625492, 22494.691071,
+   22502.756965, 22510.823173, 22518.889694, 22526.956529, 22535.023678, 22543.091141, 22551.158917, 22559.227007,
+   22567.295410, 22575.364126, 22583.433155, 22591.502498, 22599.572153, 22607.642121, 22615.712402, 22623.782996,
+   22631.853902, 22639.925120, 22647.996651, 22656.068494, 22664.140650, 22672.213117, 22680.285896, 22688.358988,
+   22696.432391, 22704.506105, 22712.580131, 22720.654469, 22728.729118, 22736.804078, 22744.879350, 22752.954933,
+   22761.030826, 22769.107031, 22777.183546, 22785.260372, 22793.337509, 22801.414956, 22809.492714, 22817.570781,
+   22825.649160, 22833.727848, 22841.806846, 22849.886154, 22857.965772, 22866.045700, 22874.125937, 22882.206484,
+   22890.287341, 22898.368507, 22906.449982, 22914.531766, 22922.613859, 22930.696261, 22938.778972, 22946.861992,
+   22954.945321, 22963.028958, 22971.112904, 22979.197158, 22987.281720, 22995.366591, 23003.451770, 23011.537257,
+   23019.623051, 23027.709154, 23035.795564, 23043.882282, 23051.969308, 23060.056640, 23068.144281, 23076.232228,
+   23084.320483, 23092.409045, 23100.497914, 23108.587089, 23116.676572, 23124.766361, 23132.856457, 23140.946859,
+   23149.037568, 23157.128583, 23165.219904, 23173.311531, 23181.403465, 23189.495704, 23197.588250, 23205.681101,
+   23213.774257, 23221.867720, 23229.961487, 23238.055560, 23246.149939, 23254.244623, 23262.339611, 23270.434905,
+   23278.530504, 23286.626407, 23294.722616, 23302.819129, 23310.915946, 23319.013068, 23327.110494, 23335.208225,
+   23343.306260, 23351.404598, 23359.503241, 23367.602188, 23375.701439, 23383.800993, 23391.900851, 23400.001012,
+   23408.101477, 23416.202245, 23424.303317, 23432.404692, 23440.506369, 23448.608350, 23456.710634, 23464.813220,
+   23472.916109, 23481.019301, 23489.122795, 23497.226592, 23505.330691, 23513.435092, 23521.539796, 23529.644801,
+   23537.750109, 23545.855718, 23553.961629, 23562.067842, 23570.174357, 23578.281173, 23586.388290, 23594.495709,
+   23602.603429, 23610.711450, 23618.819773, 23626.928396, 23635.037320, 23643.146545, 23651.256071, 23659.365897,
+   23667.476024, 23675.586451, 23683.697179, 23691.808206, 23699.919534, 23708.031163, 23716.143091, 23724.255319,
+   23732.367846, 23740.480674, 23748.593801, 23756.707228, 23764.820954, 23772.934979, 23781.049304, 23789.163928,
+   23797.278851, 23805.394073, 23813.509594, 23821.625413, 23829.741532, 23837.857949, 23845.974664, 23854.091678,
+   23862.208991, 23870.326602, 23878.444511, 23886.562718, 23894.681223, 23902.800026, 23910.919127, 23919.038525,
+   23927.158221, 23935.278215, 23943.398507, 23951.519095, 23959.639981, 23967.761165, 23975.882645, 23984.004422,
+   23992.126497, 24000.248868, 24008.371536, 24016.494501, 24024.617762, 24032.741320, 24040.865174, 24048.989325,
+   24057.113772, 24065.238515, 24073.363554, 24081.488889, 24089.614520, 24097.740447, 24105.866669, 24113.993187,
+   24122.120001, 24130.247110, 24138.374515, 24146.502215, 24154.630210, 24162.758500, 24170.887085, 24179.015965,
+   24187.145140, 24195.274610, 24203.404374, 24211.534433, 24219.664787, 24227.795435, 24235.926377, 24244.057614,
+   24252.189144, 24260.320969, 24268.453088, 24276.585501, 24284.718207, 24292.851207, 24300.984501, 24309.118089,
+   24317.251970, 24325.386144, 24333.520611, 24341.655372, 24349.790426, 24357.925773, 24366.061413, 24374.197346,
+   24382.333571, 24390.470090, 24398.606900, 24406.744004, 24414.881400, 24423.019088, 24431.157068, 24439.295341,
+   24447.433906, 24455.572762, 24463.711911, 24471.851352, 24479.991084, 24488.131108, 24496.271423, 24504.412030,
+   24512.552929, 24520.694119, 24528.835600, 24536.977372, 24545.119435, 24553.261789, 24561.404435, 24569.547371,
+   24577.690597, 24585.834115, 24593.977923, 24602.122021, 24610.266410, 24618.411089, 24626.556059, 24634.701318,
+   24642.846868, 24650.992708, 24659.138837, 24667.285256, 24675.431965, 24683.578964, 24691.726252, 24699.873830,
+   24708.021697, 24716.169854, 24724.318299, 24732.467034, 24740.616058, 24748.765371, 24756.914973, 24765.064863,
+   24773.215042, 24781.365510, 24789.516267, 24797.667312, 24805.818645, 24813.970267, 24822.122177, 24830.274375,
+   24838.426861, 24846.579635, 24854.732697, 24862.886046, 24871.039684, 24879.193609, 24887.347822, 24895.502322,
+   24903.657110, 24911.812184, 24919.967547, 24928.123196, 24936.279132, 24944.435355, 24952.591866, 24960.748663,
+   24968.905746, 24977.063117, 24985.220774, 24993.378717, 25001.536947, 25009.695464, 25017.854266, 25026.013355,
+   25034.172730, 25042.332390, 25050.492337, 25058.652569, 25066.813088, 25074.973892, 25083.134981, 25091.296356,
+   25099.458017, 25107.619962, 25115.782193, 25123.944710, 25132.107511, 25140.270597, 25148.433969, 25156.597625,
+   25164.761566, 25172.925791, 25181.090302, 25189.255097, 25197.420176, 25205.585539, 25213.751187, 25221.917120,
+   25230.083336, 25238.249836, 25246.416620, 25254.583689, 25262.751041, 25270.918676, 25279.086596, 25287.254799,
+   25295.423285, 25303.592055, 25311.761108, 25319.930444, 25328.100064, 25336.269967, 25344.440152, 25352.610621,
+   25360.781372, 25368.952406, 25377.123723, 25385.295323, 25393.467205, 25401.639369, 25409.811816, 25417.984545,
+   25426.157556, 25434.330850, 25442.504425, 25450.678283, 25458.852422, 25467.026843, 25475.201546, 25483.376531,
+   25491.551797, 25499.727344, 25507.903173, 25516.079284, 25524.255675, 25532.432348, 25540.609302, 25548.786537,
+   25556.964053, 25565.141849, 25573.319927, 25581.498285, 25589.676924, 25597.855843, 25606.035043, 25614.214523,
+   25622.394284, 25630.574324, 25638.754645, 25646.935246, 25655.116127, 25663.297288, 25671.478729, 25679.660449,
+   25687.842449, 25696.024729, 25704.207288, 25712.390127, 25720.573245, 25728.756642, 25736.940319, 25745.124275,
+   25753.308510, 25761.493023, 25769.677816, 25777.862887, 25786.048238, 25794.233867, 25802.419774, 25810.605960,
+   25818.792424, 25826.979167, 25835.166188, 25843.353488, 25851.541065, 25859.728920, 25867.917054, 25876.105465,
+   25884.294154, 25892.483121, 25900.672366, 25908.861888, 25917.051687, 25925.241764, 25933.432119, 25941.622750,
+   25949.813659, 25958.004845, 25966.196308, 25974.388048, 25982.580065, 25990.772359, 25998.964930, 26007.157777,
+   26015.350900, 26023.544301, 26031.737977, 26039.931930, 26048.126160, 26056.320665, 26064.515447, 26072.710504,
+   26080.905838, 26089.101448, 26097.297333, 26105.493494, 26113.689931, 26121.886643, 26130.083631, 26138.280895,
+   26146.478434, 26154.676248, 26162.874337, 26171.072701, 26179.271341, 26187.470255, 26195.669444, 26203.868909,
+   26212.068648, 26220.268661, 26228.468950, 26236.669512, 26244.870350, 26253.071461, 26261.272847, 26269.474507,
+   26277.676442, 26285.878650, 26294.081133, 26302.283889, 26310.486919, 26318.690223, 26326.893801, 26335.097652,
+   26343.301777, 26351.506176, 26359.710848, 26367.915793, 26376.121011, 26384.326503, 26392.532267, 26400.738305,
+   26408.944616, 26417.151200, 26425.358056, 26433.565185, 26441.772587, 26449.980261, 26458.188208, 26466.396428,
+   26474.604919, 26482.813684, 26491.022720, 26499.232028, 26507.441609, 26515.651461, 26523.861586, 26532.071982,
+   26540.282650, 26548.493590, 26556.704801, 26564.916284, 26573.128038, 26581.340064, 26589.552361, 26597.764930,
+   26605.977769, 26614.190880, 26622.404262, 26630.617914, 26638.831838, 26647.046032, 26655.260498, 26663.475233,
+   26671.690240, 26679.905517, 26688.121064, 26696.336882, 26704.552970, 26712.769328, 26720.985957, 26729.202855,
+   26737.420024, 26745.637463, 26753.855171, 26762.073149, 26770.291397, 26778.509915, 26786.728702, 26794.947759,
+   26803.167085, 26811.386680, 26819.606545, 26827.826679, 26836.047082, 26844.267754, 26852.488695, 26860.709905,
+   26868.931384, 26877.153132, 26885.375148, 26893.597433, 26901.819987, 26910.042809, 26918.265900, 26926.489259,
+   26934.712886, 26942.936781, 26951.160945, 26959.385376, 26967.610076, 26975.835043, 26984.060279, 26992.285782,
+   27000.511553, 27008.737591, 27016.963897, 27025.190470, 27033.417311, 27041.644420, 27049.871795, 27058.099438,
+   27066.327348, 27074.555525, 27082.783968, 27091.012679, 27099.241657, 27107.470901, 27115.700412, 27123.930190,
+   27132.160234, 27140.390545, 27148.621123, 27156.851966, 27165.083076, 27173.314452, 27181.546094, 27189.778002,
+   27198.010177, 27206.242617, 27214.475323, 27222.708295, 27230.941532, 27239.175035, 27247.408804, 27255.642838,
+   27263.877138, 27272.111703, 27280.346533, 27288.581629, 27296.816989, 27305.052615, 27313.288506, 27321.524661,
+   27329.761082, 27337.997767, 27346.234717, 27354.471932, 27362.709411, 27370.947155, 27379.185163, 27387.423436,
+   27395.661973, 27403.900774, 27412.139839, 27420.379169, 27428.618762, 27436.858620, 27445.098741, 27453.339126,
+   27461.579775, 27469.820687, 27478.061864, 27486.303303, 27494.545006, 27502.786973, 27511.029203, 27519.271696,
+   27527.514452, 27535.757472, 27544.000754, 27552.244300, 27560.488108, 27568.732180, 27576.976514, 27585.221110,
+   27593.465970, 27601.711092, 27609.956476, 27618.202123, 27626.448032, 27634.694204, 27642.940638, 27651.187334,
+   27659.434292, 27667.681512, 27675.928994, 27684.176738, 27692.424743, 27700.673011, 27708.921540, 27717.170331,
+   27725.419383, 27733.668697, 27741.918272, 27750.168108, 27758.418206, 27766.668565, 27774.919185, 27783.170066,
+   27791.421208, 27799.672611, 27807.924275, 27816.176200, 27824.428385, 27832.680832, 27840.933538, 27849.186505,
+   27857.439733, 27865.693221, 27873.946969, 27882.200978, 27890.455247, 27898.709776, 27906.964565, 27915.219614,
+   27923.474922, 27931.730491, 27939.986319, 27948.242408, 27956.498755, 27964.755363, 27973.012230, 27981.269356,
+   27989.526741, 27997.784386, 28006.042291, 28014.300454, 28022.558876, 28030.817558, 28039.076498, 28047.335698,
+   28055.595156, 28063.854873, 28072.114849, 28080.375083, 28088.635576, 28096.896327, 28105.157337, 28113.418605,
+   28121.680131, 28129.941916, 28138.203959, 28146.466260, 28154.728819, 28162.991636, 28171.254711, 28179.518043,
+   28187.781634, 28196.045482, 28204.309588, 28212.573951, 28220.838572, 28229.103450, 28237.368586, 28245.633979,
+   28253.899629, 28262.165536, 28270.431701, 28278.698122, 28286.964801, 28295.231736, 28303.498928, 28311.766377,
+   28320.034083, 28328.302045, 28336.570264, 28344.838739, 28353.107471, 28361.376459, 28369.645704, 28377.915205,
+   28386.184962, 28394.454975, 28402.725244, 28410.995769, 28419.266550, 28427.537587, 28435.808879, 28444.080428,
+   28452.352232, 28460.624291, 28468.896606, 28477.169177, 28485.442003, 28493.715084, 28501.988421, 28510.262013,
+   28518.535860, 28526.809962, 28535.084319, 28543.358931, 28551.633798, 28559.908919, 28568.184296, 28576.459927,
+   28584.735812, 28593.011952, 28601.288347, 28609.564996, 28617.841900, 28626.119058, 28634.396470, 28642.674136,
+   28650.952056, 28659.230230, 28667.508659, 28675.787341, 28684.066277, 28692.345466, 28700.624910, 28708.904607,
+   28717.184558, 28725.464762, 28733.745220, 28742.025931, 28750.306895, 28758.588113, 28766.869584, 28775.151308,
+   28783.433285, 28791.715515, 28799.997998, 28808.280734, 28816.563722, 28824.846964, 28833.130458, 28841.414205,
+   28849.698204, 28857.982456, 28866.266960, 28874.551717, 28882.836726, 28891.121987, 28899.407500, 28907.693265,
+   28915.979283, 28924.265552, 28932.552074, 28940.838847, 28949.125872, 28957.413149, 28965.700677, 28973.988457,
+   28982.276489, 28990.564772, 28998.853306, 29007.142092, 29015.431129, 29023.720417, 29032.009957, 29040.299748,
+   29048.589789, 29056.880082, 29065.170625, 29073.461420, 29081.752465, 29090.043761, 29098.335307, 29106.627104,
+   29114.919152, 29123.211450, 29131.503998, 29139.796797, 29148.089846, 29156.383146, 29164.676695, 29172.970495,
+   29181.264545, 29189.558844, 29197.853394, 29206.148193, 29214.443242, 29222.738541, 29231.034090, 29239.329888,
+   29247.625935, 29255.922232, 29264.218779, 29272.515575, 29280.812620, 29289.109914, 29297.407458, 29305.705251,
+   29314.003292, 29322.301583, 29330.600122, 29338.898911, 29347.197948, 29355.497234, 29363.796768, 29372.096552,
+   29380.396583, 29388.696863, 29396.997392, 29405.298169, 29413.599194, 29421.900468, 29430.201989, 29438.503759,
+   29446.805777, 29455.108043, 29463.410557, 29471.713318, 29480.016327, 29488.319585, 29496.623089, 29504.926842,
+   29513.230842, 29521.535089, 29529.839584, 29538.144326, 29546.449316, 29554.754553, 29563.060037, 29571.365768,
+   29579.671746, 29587.977971, 29596.284444, 29604.591163, 29612.898129, 29621.205341, 29629.512800, 29637.820506,
+   29646.128459, 29654.436658, 29662.745104, 29671.053795, 29679.362734, 29687.671918, 29695.981349, 29704.291026,
+   29712.600949, 29720.911118, 29729.221533, 29737.532194, 29745.843101, 29754.154253, 29762.465651, 29770.777295,
+   29779.089185, 29787.401320, 29795.713701, 29804.026327, 29812.339198, 29820.652315, 29828.965677, 29837.279284,
+   29845.593136, 29853.907233, 29862.221576, 29870.536163, 29878.850995, 29887.166072, 29895.481394, 29903.796960,
+   29912.112772, 29920.428827, 29928.745128, 29937.061672, 29945.378461, 29953.695495, 29962.012773, 29970.330295,
+   29978.648061, 29986.966071, 29995.284325, 30003.602824, 30011.921566, 30020.240552, 30028.559782, 30036.879256,
+   30045.198973, 30053.518934, 30061.839139, 30070.159587, 30078.480278, 30086.801213, 30095.122392, 30103.443813,
+   30111.765478, 30120.087386, 30128.409537, 30136.731931, 30145.054568, 30153.377448, 30161.700571, 30170.023937,
+   30178.347545, 30186.671397, 30194.995490, 30203.319827, 30211.644406, 30219.969227, 30228.294290, 30236.619597,
+   30244.945145, 30253.270935, 30261.596968, 30269.923243, 30278.249760, 30286.576518, 30294.903519, 30303.230762,
+   30311.558246, 30319.885972, 30328.213940, 30336.542150, 30344.870601, 30353.199293, 30361.528227, 30369.857403,
+   30378.186820, 30386.516478, 30394.846377, 30403.176517, 30411.506899, 30419.837522, 30428.168385, 30436.499490,
+   30444.830835, 30453.162422, 30461.494249, 30469.826316, 30478.158625, 30486.491174, 30494.823963, 30503.156993,
+   30511.490263, 30519.823774, 30528.157525, 30536.491516, 30544.825748, 30553.160219, 30561.494931, 30569.829882,
+   30578.165074, 30586.500506, 30594.836177, 30603.172088, 30611.508239, 30619.844629, 30628.181259, 30636.518129,
+   30644.855238, 30653.192587, 30661.530175, 30669.868002, 30678.206068, 30686.544374, 30694.882919, 30703.221703,
+   30711.560726, 30719.899988, 30728.239489, 30736.579229, 30744.919207, 30753.259425, 30761.599881, 30769.940575,
+   30778.281508, 30786.622680, 30794.964090, 30803.305739, 30811.647626, 30819.989751, 30828.332115, 30836.674716,
+   30845.017556, 30853.360634, 30861.703950, 30870.047504, 30878.391296, 30886.735325, 30895.079592, 30903.424098,
+   30911.768840, 30920.113821, 30928.459039, 30936.804494, 30945.150187, 30953.496117, 30961.842285, 30970.188690,
+   30978.535332, 30986.882211, 30995.229327, 31003.576681, 31011.924271, 31020.272098, 31028.620163, 31036.968464,
+   31045.317002, 31053.665776, 31062.014787, 31070.364035, 31078.713519, 31087.063240, 31095.413198, 31103.763391,
+   31112.113821, 31120.464487, 31128.815390, 31137.166529, 31145.517903, 31153.869514, 31162.221361, 31170.573443,
+   31178.925762, 31187.278316, 31195.631106, 31203.984132, 31212.337394, 31220.690891, 31229.044624, 31237.398592,
+   31245.752795, 31254.107234, 31262.461908, 31270.816818, 31279.171963, 31287.527343, 31295.882958, 31304.238808,
+   31312.594893, 31320.951213, 31329.307767, 31337.664557, 31346.021582, 31354.378841, 31362.736335, 31371.094063,
+   31379.452026, 31387.810223, 31396.168655, 31404.527322, 31412.886222, 31421.245357, 31429.604726, 31437.964329,
+   31446.324167, 31454.684238, 31463.044544, 31471.405083, 31479.765856, 31488.126863, 31496.488104, 31504.849579,
+   31513.211287, 31521.573229, 31529.935405, 31538.297814, 31546.660456, 31555.023332, 31563.386441, 31571.749784,
+   31580.113359, 31588.477168, 31596.841210, 31605.205485, 31613.569993, 31621.934734, 31630.299708, 31638.664915,
+   31647.030355, 31655.396027, 31663.761932, 31672.128070, 31680.494440, 31688.861043, 31697.227878, 31705.594946,
+   31713.962246, 31722.329779, 31730.697543, 31739.065540, 31747.433769, 31755.802230, 31764.170924, 31772.539849,
+   31780.909006, 31789.278395, 31797.648016, 31806.017868, 31814.387953, 31822.758269, 31831.128816, 31839.499595,
+   31847.870606, 31856.241848, 31864.613322, 31872.985027, 31881.356963, 31889.729130, 31898.101529, 31906.474159,
+   31914.847019, 31923.220111, 31931.593434, 31939.966988, 31948.340772, 31956.714788, 31965.089034, 31973.463511,
+   31981.838218, 31990.213157, 31998.588325, 32006.963725, 32015.339354, 32023.715214, 32032.091305, 32040.467625,
+   32048.844176, 32057.220957, 32065.597968, 32073.975209, 32082.352681, 32090.730382, 32099.108313, 32107.486474,
+   32115.864865, 32124.243485, 32132.622336, 32141.001415, 32149.380725, 32157.760264, 32166.140032, 32174.520030,
+   32182.900258, 32191.280714, 32199.661400, 32208.042316, 32216.423460, 32224.804833, 32233.186436, 32241.568267,
+   32249.950328, 32258.332617, 32266.715136, 32275.097883, 32283.480859, 32291.864063, 32300.247496, 32308.631158,
+   32317.015049, 32325.399167, 32333.783515, 32342.168090, 32350.552894, 32358.937927, 32367.323187, 32375.708676,
+   32384.094393, 32392.480338, 32400.866510, 32409.252911, 32417.639540, 32426.026397, 32434.413481, 32442.800794,
+   32451.188334, 32459.576101, 32467.964097, 32476.352319, 32484.740770, 32493.129447, 32501.518353, 32509.907485,
+   32518.296845, 32526.686432, 32535.076246, 32543.466288, 32551.856556, 32560.247052, 32568.637774, 32577.028724,
+   32585.419900, 32593.811303, 32602.202933, 32610.594790, 32618.986873, 32627.379183, 32635.771720, 32644.164483,
+   32652.557473, 32660.950689, 32669.344131, 32677.737800, 32686.131695, 32694.525816, 32702.920163, 32711.314737,
+   32719.709536, 32728.104562, 32736.499813, 32744.895291, 32753.290994, 32761.686923, 32770.083078, 32778.479459,
+   32786.876065, 32795.272897, 32803.669954, 32812.067237, 32820.464745, 32828.862479, 32837.260438, 32845.658623,
+   32854.057032, 32862.455667, 32870.854527, 32879.253612, 32887.652922, 32896.052457, 32904.452218, 32912.852203,
+   32921.252412, 32929.652847, 32938.053506, 32946.454390, 32954.855499, 32963.256832, 32971.658390, 32980.060173,
+   32988.462179, 32996.864411, 33005.266866, 33013.669546, 33022.072450, 33030.475578, 33038.878931, 33047.282507,
+   33055.686308, 33064.090332, 33072.494581, 33080.899053, 33089.303749, 33097.708669, 33106.113813, 33114.519180,
+   33122.924771, 33131.330586, 33139.736624, 33148.142885, 33156.549370, 33164.956079, 33173.363011, 33181.770166,
+   33190.177544, 33198.585146, 33206.992970, 33215.401018, 33223.809289, 33232.217783, 33240.626499, 33249.035439,
+   33257.444601, 33265.853987, 33274.263595, 33282.673425, 33291.083479, 33299.493754, 33307.904253, 33316.314974,
+   33324.725917, 33333.137083, 33341.548471, 33349.960082, 33358.371914, 33366.783969, 33375.196246, 33383.608745,
+   33392.021466, 33400.434410, 33408.847575, 33417.260962, 33425.674571, 33434.088401, 33442.502454, 33450.916728,
+   33459.331224, 33467.745941, 33476.160880, 33484.576041, 33492.991422, 33501.407026, 33509.822850, 33518.238897,
+   33526.655164, 33535.071652, 33543.488362, 33551.905293, 33560.322445, 33568.739817, 33577.157411, 33585.575226,
+   33593.993262, 33602.411518, 33610.829995, 33619.248693, 33627.667612, 33636.086751, 33644.506111, 33652.925691,
+   33661.345492, 33669.765513, 33678.185755, 33686.606217, 33695.026899, 33703.447802, 33711.868925, 33720.290267,
+   33728.711830, 33737.133613, 33745.555616, 33753.977839, 33762.400282, 33770.822945, 33779.245827, 33787.668930,
+   33796.092252, 33804.515793, 33812.939555, 33821.363535, 33829.787736, 33838.212156, 33846.636795, 33855.061653,
+   33863.486731, 33871.912028, 33880.337545, 33888.763280, 33897.189235, 33905.615409, 33914.041802, 33922.468414,
+   33930.895244, 33939.322294, 33947.749562, 33956.177050, 33964.604756, 33973.032680, 33981.460824, 33989.889186,
+   33998.317766, 34006.746565, 34015.175583, 34023.604819, 34032.034273, 34040.463946, 34048.893836, 34057.323946,
+   34065.754273, 34074.184818, 34082.615582, 34091.046563, 34099.477763, 34107.909180, 34116.340815, 34124.772669,
+   34133.204739, 34141.637028, 34150.069535, 34158.502259, 34166.935200, 34175.368359, 34183.801736, 34192.235330,
+   34200.669142, 34209.103171, 34217.537417, 34225.971881, 34234.406561, 34242.841459, 34251.276574, 34259.711907,
+   34268.147456, 34276.583222, 34285.019205, 34293.455405, 34301.891822, 34310.328456, 34318.765306, 34327.202373,
+   34335.639657, 34344.077158, 34352.514874, 34360.952808, 34369.390958, 34377.829324, 34386.267907, 34394.706706,
+   34403.145722, 34411.584953, 34420.024401, 34428.464065, 34436.903945, 34445.344041, 34453.784354, 34462.224882,
+   34470.665626, 34479.106586, 34487.547761, 34495.989153, 34504.430760, 34512.872583, 34521.314621, 34529.756875,
+   34538.199345, 34546.642030, 34555.084931, 34563.528047, 34571.971378, 34580.414925, 34588.858687, 34597.302664,
+   34605.746856, 34614.191264, 34622.635886, 34631.080724, 34639.525776, 34647.971044, 34656.416526, 34664.862223,
+   34673.308135, 34681.754262, 34690.200603, 34698.647159, 34707.093930, 34715.540915, 34723.988115, 34732.435530,
+   34740.883158, 34749.331001, 34757.779059, 34766.227331, 34774.675817, 34783.124517, 34791.573431, 34800.022560,
+   34808.471902, 34816.921459, 34825.371229, 34833.821214, 34842.271412, 34850.721824, 34859.172450, 34867.623290,
+   34876.074343, 34884.525610, 34892.977091, 34901.428785, 34909.880693, 34918.332814, 34926.785149, 34935.237697,
+   34943.690458, 34952.143433, 34960.596620, 34969.050021, 34977.503636, 34985.957463, 34994.411503, 35002.865757,
+   35011.320223, 35019.774902, 35028.229795, 35036.684900, 35045.140217, 35053.595748, 35062.051491, 35070.507447,
+   35078.963615, 35087.419997, 35095.876590, 35104.333396, 35112.790415, 35121.247645, 35129.705089, 35138.162744,
+   35146.620612, 35155.078692, 35163.536984, 35171.995488, 35180.454204, 35188.913133, 35197.372273, 35205.831625,
+   35214.291189, 35222.750965, 35231.210953, 35239.671152, 35248.131563, 35256.592186, 35265.053021, 35273.514067,
+   35281.975324, 35290.436793, 35298.898474, 35307.360366, 35315.822469, 35324.284783, 35332.747309, 35341.210046,
+   35349.672994, 35358.136154, 35366.599524, 35375.063106, 35383.526898, 35391.990901, 35400.455116, 35408.919541,
+   35417.384177, 35425.849023, 35434.314081, 35442.779349, 35451.244828, 35459.710517, 35468.176417, 35476.642527,
+   35485.108848, 35493.575379, 35502.042121, 35510.509073, 35518.976235, 35527.443608, 35535.911191, 35544.378983,
+   35552.846986, 35561.315199, 35569.783622, 35578.252255, 35586.721098, 35595.190151, 35603.659414, 35612.128886,
+   35620.598568, 35629.068460, 35637.538562, 35646.008873, 35654.479394, 35662.950124, 35671.421064, 35679.892213,
+   35688.363572, 35696.835140, 35705.306917, 35713.778904, 35722.251100, 35730.723505, 35739.196119, 35747.668942,
+   35756.141974, 35764.615216, 35773.088666, 35781.562325, 35790.036193, 35798.510270, 35806.984556, 35815.459050,
+   35823.933753, 35832.408665, 35840.883786, 35849.359115, 35857.834652, 35866.310398, 35874.786353, 35883.262515,
+   35891.738887, 35900.215466, 35908.692254, 35917.169250, 35925.646454, 35934.123866, 35942.601487, 35951.079315,
+   35959.557352, 35968.035596, 35976.514049, 35984.992709, 35993.471577, 36001.950653, 36010.429936, 36018.909428,
+   36027.389127, 36035.869033, 36044.349147, 36052.829469, 36061.309998, 36069.790735, 36078.271679, 36086.752831,
+   36095.234189, 36103.715755, 36112.197529, 36120.679509, 36129.161697, 36137.644091, 36146.126693, 36154.609502,
+   36163.092517, 36171.575740, 36180.059170, 36188.542806, 36197.026649, 36205.510699, 36213.994956, 36222.479419,
+   36230.964089, 36239.448966, 36247.934049, 36256.419339, 36264.904835, 36273.390537, 36281.876446, 36290.362561,
+   36298.848883, 36307.335411, 36315.822145, 36324.309085, 36332.796231, 36341.283584, 36349.771142, 36358.258906,
+   36366.746877, 36375.235053, 36383.723435, 36392.212023, 36400.700817, 36409.189816, 36417.679021, 36426.168432,
+   36434.658048, 36443.147870, 36451.637898, 36460.128131, 36468.618569, 36477.109213, 36485.600063, 36494.091117,
+   36502.582377, 36511.073842, 36519.565512, 36528.057388, 36536.549468, 36545.041754, 36553.534244, 36562.026940,
+   36570.519840, 36579.012946, 36587.506256, 36595.999771, 36604.493491, 36612.987415, 36621.481545, 36629.975878,
+   36638.470417, 36646.965160, 36655.460108, 36663.955260, 36672.450616, 36680.946177, 36689.441942, 36697.937912,
+   36706.434086, 36714.930464, 36723.427046, 36731.923832, 36740.420823, 36748.918017, 36757.415416, 36765.913019,
+   36774.410825, 36782.908835, 36791.407050, 36799.905468, 36808.404089, 36816.902915, 36825.401944, 36833.901177,
+   36842.400614, 36850.900254, 36859.400097, 36867.900144, 36876.400395, 36884.900848, 36893.401506, 36901.902366,
+   36910.403430, 36918.904697, 36927.406167, 36935.907841, 36944.409717, 36952.911797, 36961.414079, 36969.916565,
+   36978.419253, 36986.922145, 36995.425239, 37003.928536, 37012.432036, 37020.935739, 37029.439644, 37037.943752,
+   37046.448062, 37054.952576, 37063.457291, 37071.962209, 37080.467330, 37088.972653, 37097.478178, 37105.983906,
+   37114.489836, 37122.995968, 37131.502303, 37140.008839, 37148.515578, 37157.022519, 37165.529662, 37174.037007,
+   37182.544554, 37191.052302, 37199.560253, 37208.068405, 37216.576760, 37225.085316, 37233.594073, 37242.103033,
+   37250.612194, 37259.121556, 37267.631120, 37276.140886, 37284.650853, 37293.161022, 37301.671392, 37310.181963,
+   37318.692736, 37327.203710, 37335.714885, 37344.226261, 37352.737838, 37361.249617, 37369.761597, 37378.273777,
+   37386.786159, 37395.298742, 37403.811525, 37412.324509, 37420.837695, 37429.351080, 37437.864667, 37446.378455,
+   37454.892443, 37463.406631, 37471.921021, 37480.435610, 37488.950401, 37497.465391, 37505.980583, 37514.495974,
+   37523.011566, 37531.527358, 37540.043351, 37548.559544, 37557.075936, 37565.592529, 37574.109323, 37582.626316,
+   37591.143509, 37599.660902, 37608.178495, 37616.696288, 37625.214281, 37633.732474, 37642.250866, 37650.769458,
+   37659.288250, 37667.807242, 37676.326433, 37684.845824, 37693.365414, 37701.885204, 37710.405193, 37718.925382,
+   37727.445770, 37735.966357, 37744.487144, 37753.008130, 37761.529315, 37770.050700, 37778.572283, 37787.094066,
+   37795.616048, 37804.138228, 37812.660608, 37821.183187, 37829.705964, 37838.228941, 37846.752116, 37855.275490,
+   37863.799063, 37872.322834, 37880.846805, 37889.370973, 37897.895341, 37906.419907, 37914.944671, 37923.469634,
+   37931.994796, 37940.520155, 37949.045713, 37957.571470, 37966.097424, 37974.623577, 37983.149929, 37991.676478,
+   38000.203225, 38008.730171, 38017.257314, 38025.784656, 38034.312195, 38042.839933, 38051.367868, 38059.896001,
+   38068.424332, 38076.952861, 38085.481587, 38094.010511, 38102.539633, 38111.068952, 38119.598469, 38128.128184,
+   38136.658096, 38145.188205, 38153.718512, 38162.249016, 38170.779718, 38179.310617, 38187.841713, 38196.373006,
+   38204.904497, 38213.436184, 38221.968069, 38230.500151, 38239.032430, 38247.564905, 38256.097578, 38264.630448,
+   38273.163514, 38281.696778, 38290.230238, 38298.763895, 38307.297748, 38315.831799, 38324.366046, 38332.900489,
+   38341.435129, 38349.969966, 38358.504999, 38367.040229, 38375.575655, 38384.111277, 38392.647096, 38401.183110,
+   38409.719322, 38418.255729, 38426.792333, 38435.329132, 38443.866128, 38452.403320, 38460.940708, 38469.478292,
+   38478.016072, 38486.554047, 38495.092219, 38503.630586, 38512.169150, 38520.707909, 38529.246863, 38537.786014,
+   38546.325360, 38554.864901, 38563.404638, 38571.944571, 38580.484699, 38589.025023, 38597.565542, 38606.106256,
+   38614.647166, 38623.188271, 38631.729571, 38640.271067, 38648.812757, 38657.354643, 38665.896724, 38674.439000,
+   38682.981471, 38691.524137, 38700.066998, 38708.610054, 38717.153305, 38725.696750, 38734.240391, 38742.784226,
+   38751.328256, 38759.872480, 38768.416899, 38776.961513, 38785.506321, 38794.051324, 38802.596522, 38811.141913,
+   38819.687500, 38828.233280, 38836.779255, 38845.325425, 38853.871788, 38862.418346, 38870.965098, 38879.512044,
+   38888.059184, 38896.606519, 38905.154047, 38913.701770, 38922.249686, 38930.797796, 38939.346100, 38947.894598,
+   38956.443290, 38964.992176, 38973.541255, 38982.090528, 38990.639995, 38999.189656, 39007.739510, 39016.289557,
+   39024.839798, 39033.390233, 39041.940861, 39050.491682, 39059.042697, 39067.593905, 39076.145306, 39084.696901,
+   39093.248689, 39101.800670, 39110.352844, 39118.905211, 39127.457771, 39136.010525, 39144.563471, 39153.116610,
+   39161.669943, 39170.223468, 39178.777186, 39187.331097, 39195.885200, 39204.439496, 39212.993985, 39221.548667,
+   39230.103541, 39238.658608, 39247.213867, 39255.769319, 39264.324964, 39272.880801, 39281.436830, 39289.993051,
+   39298.549465, 39307.106071, 39315.662870, 39324.219861, 39332.777043, 39341.334418, 39349.891985, 39358.449745,
+   39367.007696, 39375.565839, 39384.124174, 39392.682701, 39401.241420, 39409.800331, 39418.359434, 39426.918728,
+   39435.478214, 39444.037892, 39452.597761, 39461.157822, 39469.718075, 39478.278519, 39486.839155, 39495.399982,
+   39503.961001, 39512.522211, 39521.083612, 39529.645205, 39538.206989, 39546.768965, 39555.331131, 39563.893489,
+   39572.456038, 39581.018778, 39589.581709, 39598.144831, 39606.708144, 39615.271648, 39623.835343, 39632.399229,
+   39640.963306, 39649.527574, 39658.092032, 39666.656681, 39675.221521, 39683.786551, 39692.351773, 39700.917184,
+   39709.482787, 39718.048580, 39726.614563, 39735.180737, 39743.747101, 39752.313656, 39760.880401, 39769.447336,
+   39778.014461, 39786.581777, 39795.149283, 39803.716979, 39812.284866, 39820.852942, 39829.421209, 39837.989665,
+   39846.558311, 39855.127148, 39863.696174, 39872.265390, 39880.834797, 39889.404392, 39897.974178, 39906.544153,
+   39915.114319, 39923.684673, 39932.255218, 39940.825952, 39949.396875, 39957.967988, 39966.539291, 39975.110783,
+   39983.682464, 39992.254335, 40000.826395, 40009.398644, 40017.971083, 40026.543711, 40035.116528, 40043.689534,
+   40052.262730, 40060.836114, 40069.409688, 40077.983450, 40086.557402, 40095.131542, 40103.705871, 40112.280390,
+   40120.855097, 40129.429993, 40138.005077, 40146.580351, 40155.155813, 40163.731464, 40172.307303, 40180.883331,
+   40189.459548, 40198.035953, 40206.612546, 40215.189328, 40223.766298, 40232.343457, 40240.920804, 40249.498340,
+   40258.076063, 40266.653975, 40275.232076, 40283.810364, 40292.388840, 40300.967505, 40309.546357, 40318.125398,
+   40326.704627, 40335.284043, 40343.863648, 40352.443440, 40361.023420, 40369.603588, 40378.183944, 40386.764487,
+   40395.345218, 40403.926137, 40412.507244, 40421.088538, 40429.670020, 40438.251689, 40446.833546, 40455.415590,
+   40463.997821, 40472.580240, 40481.162847, 40489.745640, 40498.328621, 40506.911789, 40515.495145, 40524.078687,
+   40532.662417, 40541.246334, 40549.830438, 40558.414729, 40566.999207, 40575.583872, 40584.168723, 40592.753762,
+   40601.338988, 40609.924400, 40618.509999, 40627.095785, 40635.681758, 40644.267918, 40652.854264, 40661.440796,
+   40670.027515, 40678.614421, 40687.201514, 40695.788792, 40704.376258, 40712.963909, 40721.551747, 40730.139772,
+   40738.727982, 40747.316379, 40755.904963, 40764.493732, 40773.082687, 40781.671829, 40790.261157, 40798.850671,
+   40807.440371, 40816.030257, 40824.620328, 40833.210586, 40841.801030, 40850.391659, 40858.982475, 40867.573476,
+   40876.164663, 40884.756035, 40893.347594, 40901.939337, 40910.531267, 40919.123382, 40927.715683, 40936.308169,
+   40944.900841, 40953.493698, 40962.086740, 40970.679968, 40979.273381, 40987.866980, 40996.460764, 41005.054733,
+   41013.648887, 41022.243226, 41030.837751, 41039.432460, 41048.027355, 41056.622435, 41065.217700, 41073.813149,
+   41082.408784, 41091.004603, 41099.600608, 41108.196797, 41116.793171, 41125.389730, 41133.986473, 41142.583401,
+   41151.180514, 41159.777812, 41168.375294, 41176.972960, 41185.570811, 41194.168847, 41202.767067, 41211.365471,
+   41219.964060, 41228.562833, 41237.161791, 41245.760933, 41254.360259, 41262.959769, 41271.559463, 41280.159342,
+   41288.759405, 41297.359651, 41305.960082, 41314.560697, 41323.161496, 41331.762478, 41340.363645, 41348.964995,
+   41357.566530, 41366.168248, 41374.770150, 41383.372236, 41391.974505, 41400.576958, 41409.179595, 41417.782415,
+   41426.385419, 41434.988606, 41443.591977, 41452.195531, 41460.799269, 41469.403190, 41478.007295, 41486.611583,
+   41495.216054, 41503.820708, 41512.425546, 41521.030567, 41529.635771, 41538.241158, 41546.846729, 41555.452482,
+   41564.058418, 41572.664538, 41581.270840, 41589.877325, 41598.483994, 41607.090845, 41615.697879, 41624.305095,
+   41632.912495, 41641.520077, 41650.127842, 41658.735789, 41667.343920, 41675.952232, 41684.560728, 41693.169406,
+   41701.778266, 41710.387309, 41718.996534, 41727.605942, 41736.215532, 41744.825304, 41753.435259, 41762.045396,
+   41770.655715, 41779.266216, 41787.876900, 41796.487766, 41805.098813, 41813.710043, 41822.321455, 41830.933049,
+   41839.544825, 41848.156783, 41856.768922, 41865.381244, 41873.993747, 41882.606432, 41891.219299, 41899.832348,
+   41908.445578, 41917.058990, 41925.672584, 41934.286359, 41942.900316, 41951.514455, 41960.128774, 41968.743276,
+   41977.357959, 41985.972823, 41994.587868, 42003.203095, 42011.818504, 42020.434093, 42029.049864, 42037.665816,
+   42046.281949, 42054.898263, 42063.514759, 42072.131435, 42080.748293, 42089.365331, 42097.982551, 42106.599951,
+   42115.217532, 42123.835295, 42132.453238, 42141.071362, 42149.689666, 42158.308152, 42166.926818, 42175.545665,
+   42184.164692, 42192.783900, 42201.403289, 42210.022858, 42218.642608, 42227.262539, 42235.882649, 42244.502940,
+   42253.123412, 42261.744064, 42270.364896, 42278.985909, 42287.607101, 42296.228474, 42304.850028, 42313.471761,
+   42322.093674, 42330.715768, 42339.338042, 42347.960495, 42356.583129, 42365.205943, 42373.828936, 42382.452110,
+   42391.075463, 42399.698997, 42408.322710, 42416.946602, 42425.570675, 42434.194927, 42442.819359, 42451.443971,
+   42460.068762, 42468.693733, 42477.318883, 42485.944213, 42494.569722, 42503.195411, 42511.821279, 42520.447327,
+   42529.073554, 42537.699960, 42546.326546, 42554.953310, 42563.580254, 42572.207378, 42580.834680, 42589.462162,
+   42598.089822, 42606.717662, 42615.345681, 42623.973879, 42632.602255, 42641.230811, 42649.859545, 42658.488459,
+   42667.117551, 42675.746822, 42684.376272, 42693.005901, 42701.635708, 42710.265694, 42718.895859, 42727.526202,
+   42736.156724, 42744.787424, 42753.418303, 42762.049361, 42770.680597, 42779.312011, 42787.943604, 42796.575375,
+   42805.207324, 42813.839452, 42822.471758, 42831.104242, 42839.736905, 42848.369745, 42857.002764, 42865.635961,
+   42874.269336, 42882.902889, 42891.536620, 42900.170529, 42908.804616, 42917.438881, 42926.073323, 42934.707944,
+   42943.342743, 42951.977719, 42960.612873, 42969.248204, 42977.883714, 42986.519401, 42995.155266, 43003.791308,
+   43012.427528, 43021.063925, 43029.700500, 43038.337253, 43046.974183, 43055.611290, 43064.248575, 43072.886037,
+   43081.523676, 43090.161493, 43098.799486, 43107.437658, 43116.076006, 43124.714531, 43133.353234, 43141.992114,
+   43150.631170, 43159.270404, 43167.909815, 43176.549403, 43185.189168, 43193.829109, 43202.469228, 43211.109523,
+   43219.749995, 43228.390644, 43237.031470, 43245.672473, 43254.313652, 43262.955008, 43271.596540, 43280.238249,
+   43288.880135, 43297.522197, 43306.164436, 43314.806851, 43323.449442, 43332.092210, 43340.735155, 43349.378276,
+   43358.021573, 43366.665046, 43375.308696, 43383.952521, 43392.596524, 43401.240702, 43409.885056, 43418.529586,
+   43427.174293, 43435.819176, 43444.464234, 43453.109469, 43461.754879, 43470.400466, 43479.046228, 43487.692166,
+   43496.338280, 43504.984570, 43513.631035, 43522.277677, 43530.924493, 43539.571486, 43548.218654, 43556.865998,
+   43565.513518, 43574.161213, 43582.809083, 43591.457129, 43600.105351, 43608.753748, 43617.402320, 43626.051067,
+   43634.699990, 43643.349089, 43651.998362, 43660.647811, 43669.297435, 43677.947234, 43686.597208, 43695.247358,
+   43703.897682, 43712.548182, 43721.198856, 43729.849706, 43738.500731, 43747.151930, 43755.803304, 43764.454854,
+   43773.106578, 43781.758477, 43790.410550, 43799.062799, 43807.715222, 43816.367820, 43825.020592, 43833.673539,
+   43842.326661, 43850.979957, 43859.633428, 43868.287073, 43876.940893, 43885.594887, 43894.249056, 43902.903399,
+   43911.557917, 43920.212608, 43928.867474, 43937.522514, 43946.177729, 43954.833118, 43963.488681, 43972.144418,
+   43980.800329, 43989.456414, 43998.112673, 44006.769106, 44015.425714, 44024.082495, 44032.739450, 44041.396579,
+   44050.053882, 44058.711359, 44067.369009, 44076.026833, 44084.684831, 44093.343003, 44102.001349, 44110.659868,
+   44119.318561, 44127.977427, 44136.636467, 44145.295680, 44153.955067, 44162.614628, 44171.274362, 44179.934269,
+   44188.594350, 44197.254604, 44205.915031, 44214.575632, 44223.236406, 44231.897353, 44240.558473, 44249.219767,
+   44257.881233, 44266.542873, 44275.204686, 44283.866672, 44292.528831, 44301.191163, 44309.853668, 44318.516346,
+   44327.179196, 44335.842220, 44344.505416, 44353.168786, 44361.832328, 44370.496043, 44379.159930, 44387.823991,
+   44396.488223, 44405.152629, 44413.817207, 44422.481958, 44431.146881, 44439.811977, 44448.477245, 44457.142686,
+   44465.808299, 44474.474085, 44483.140043, 44491.806173, 44500.472476, 44509.138951, 44517.805598, 44526.472417,
+   44535.139409, 44543.806573, 44552.473908, 44561.141416, 44569.809096, 44578.476948, 44587.144973, 44595.813169,
+   44604.481537, 44613.150077, 44621.818788, 44630.487672, 44639.156728, 44647.825955, 44656.495354, 44665.164925,
+   44673.834668, 44682.504582, 44691.174668, 44699.844925, 44708.515355, 44717.185955, 44725.856728, 44734.527671,
+   44743.198787, 44751.870073, 44760.541531, 44769.213161, 44777.884962, 44786.556934, 44795.229078, 44803.901393,
+   44812.573879, 44821.246536, 44829.919364, 44838.592364, 44847.265535, 44855.938877, 44864.612390, 44873.286074,
+   44881.959929, 44890.633955, 44899.308152, 44907.982519, 44916.657058, 44925.331768, 44934.006648, 44942.681700,
+   44951.356922, 44960.032314, 44968.707878, 44977.383612, 44986.059517, 44994.735593, 45003.411839, 45012.088255,
+   45020.764843, 45029.441600, 45038.118529, 45046.795627, 45055.472896, 45064.150336, 45072.827946, 45081.505726,
+   45090.183677, 45098.861798, 45107.540089, 45116.218550, 45124.897182, 45133.575983, 45142.254955, 45150.934097,
+   45159.613409, 45168.292891, 45176.972543, 45185.652366, 45194.332358, 45203.012520, 45211.692852, 45220.373353,
+   45229.054025, 45237.734866, 45246.415878, 45255.097059, 45263.778410, 45272.459930, 45281.141620, 45289.823480,
+   45298.505509, 45307.187709, 45315.870077, 45324.552615, 45333.235323, 45341.918200, 45350.601247, 45359.284462,
+   45367.967848, 45376.651403, 45385.335127, 45394.019020, 45402.703083, 45411.387315, 45420.071716, 45428.756286,
+   45437.441025, 45446.125934, 45454.811012, 45463.496258, 45472.181674, 45480.867259, 45489.553013, 45498.238936,
+   45506.925028, 45515.611288, 45524.297718, 45532.984316, 45541.671083, 45550.358019, 45559.045124, 45567.732397,
+   45576.419840, 45585.107450, 45593.795230, 45602.483178, 45611.171295, 45619.859580, 45628.548034, 45637.236656,
+   45645.925447, 45654.614406, 45663.303534, 45671.992830, 45680.682294, 45689.371927, 45698.061728, 45706.751697,
+   45715.441835, 45724.132141, 45732.822615, 45741.513257, 45750.204067, 45758.895046, 45767.586192, 45776.277507,
+   45784.968989, 45793.660640, 45802.352458, 45811.044445, 45819.736599, 45828.428921, 45837.121412, 45845.814070,
+   45854.506895, 45863.199889, 45871.893050, 45880.586379, 45889.279876, 45897.973540, 45906.667372, 45915.361372,
+   45924.055539, 45932.749874, 45941.444376, 45950.139045, 45958.833883, 45967.528887, 45976.224059, 45984.919399,
+   45993.614905, 46002.310579, 46011.006421, 46019.702429, 46028.398605, 46037.094948, 46045.791458, 46054.488136,
+   46063.184980, 46071.881992, 46080.579171, 46089.276516, 46097.974029, 46106.671709, 46115.369556, 46124.067569,
+   46132.765750, 46141.464097, 46150.162611, 46158.861292, 46167.560140, 46176.259155, 46184.958336, 46193.657684,
+   46202.357199, 46211.056880, 46219.756728, 46228.456743, 46237.156924, 46245.857272, 46254.557786, 46263.258467,
+   46271.959314, 46280.660328, 46289.361508, 46298.062854, 46306.764367, 46315.466046, 46324.167891, 46332.869903,
+   46341.572081, 46350.274425, 46358.976935, 46367.679612, 46376.382454, 46385.085463, 46393.788638, 46402.491978,
+   46411.195485, 46419.899158, 46428.602997, 46437.307001, 46446.011172, 46454.715508, 46463.420011, 46472.124679,
+   46480.829513, 46489.534512, 46498.239678, 46506.945009, 46515.650506, 46524.356168, 46533.061996, 46541.767990,
+   46550.474149, 46559.180474, 46567.886964, 46576.593620, 46585.300442, 46594.007428, 46602.714581, 46611.421898,
+   46620.129381, 46628.837029, 46637.544843, 46646.252822, 46654.960966, 46663.669275, 46672.377749, 46681.086389,
+   46689.795194, 46698.504164, 46707.213299, 46715.922599, 46724.632064, 46733.341694, 46742.051489, 46750.761449,
+   46759.471574, 46768.181864, 46776.892319, 46785.602938, 46794.313722, 46803.024672, 46811.735785, 46820.447064,
+   46829.158507, 46837.870115, 46846.581888, 46855.293825, 46864.005927, 46872.718194, 46881.430625, 46890.143220,
+   46898.855980, 46907.568904, 46916.281993, 46924.995247, 46933.708664, 46942.422246, 46951.135993, 46959.849903,
+   46968.563978, 46977.278217, 46985.992621, 46994.707188, 47003.421920, 47012.136816, 47020.851876, 47029.567100,
+   47038.282488, 47046.998040, 47055.713756, 47064.429636, 47073.145680, 47081.861888, 47090.578260, 47099.294796,
+   47108.011495, 47116.728359, 47125.445386, 47134.162577, 47142.879932, 47151.597450, 47160.315132, 47169.032978,
+   47177.750987, 47186.469160, 47195.187496, 47203.905996, 47212.624660, 47221.343487, 47230.062478, 47238.781632,
+   47247.500949, 47256.220430, 47264.940074, 47273.659881, 47282.379852, 47291.099986, 47299.820283, 47308.540744,
+   47317.261368, 47325.982154, 47334.703104, 47343.424218, 47352.145494, 47360.866933, 47369.588536, 47378.310301,
+   47387.032229, 47395.754321, 47404.476575, 47413.198992, 47421.921572, 47430.644315, 47439.367220, 47448.090289,
+   47456.813520, 47465.536914, 47474.260471, 47482.984190, 47491.708073, 47500.432117, 47509.156325, 47517.880695,
+   47526.605227, 47535.329922, 47544.054780, 47552.779800, 47561.504982, 47570.230327, 47578.955835, 47587.681504,
+   47596.407336, 47605.133331, 47613.859487, 47622.585806, 47631.312288, 47640.038931, 47648.765737, 47657.492704,
+   47666.219834, 47674.947126, 47683.674580, 47692.402197, 47701.129975, 47709.857915, 47718.586017, 47727.314281,
+   47736.042707, 47744.771295, 47753.500045, 47762.228957, 47770.958031, 47779.687266, 47788.416663, 47797.146222,
+   47805.875943, 47814.605825, 47823.335869, 47832.066074, 47840.796442, 47849.526970, 47858.257661, 47866.988513,
+   47875.719526, 47884.450701, 47893.182037, 47901.913535, 47910.645194, 47919.377015, 47928.108997, 47936.841140,
+   47945.573445, 47954.305911, 47963.038538, 47971.771326, 47980.504275, 47989.237386, 47997.970658, 48006.704091,
+   48015.437685, 48024.171440, 48032.905356, 48041.639434, 48050.373672, 48059.108071, 48067.842631, 48076.577352,
+   48085.312234, 48094.047277, 48102.782480, 48111.517845, 48120.253370, 48128.989056, 48137.724902, 48146.460910,
+   48155.197078, 48163.933407, 48172.669896, 48181.406546, 48190.143356, 48198.880328, 48207.617459, 48216.354751,
+   48225.092204, 48233.829817, 48242.567590, 48251.305524, 48260.043618, 48268.781873, 48277.520288, 48286.258863,
+   48294.997599, 48303.736494, 48312.475550, 48321.214766, 48329.954143, 48338.693679, 48347.433376, 48356.173232,
+   48364.913249, 48373.653426, 48382.393762, 48391.134259, 48399.874916, 48408.615732, 48417.356709, 48426.097845,
+   48434.839142, 48443.580598, 48452.322214, 48461.063989, 48469.805925, 48478.548020, 48487.290275, 48496.032689,
+   48504.775264, 48513.517998, 48522.260891, 48531.003944, 48539.747157, 48548.490529, 48557.234060, 48565.977752,
+   48574.721602, 48583.465612, 48592.209782, 48600.954110, 48609.698598, 48618.443246, 48627.188053, 48635.933019,
+   48644.678144, 48653.423428, 48662.168872, 48670.914475, 48679.660237, 48688.406158, 48697.152238, 48705.898477,
+   48714.644876, 48723.391433, 48732.138150, 48740.885025, 48749.632059, 48758.379252, 48767.126604, 48775.874115,
+   48784.621785, 48793.369614, 48802.117601, 48810.865747, 48819.614052, 48828.362516, 48837.111138, 48845.859919,
+   48854.608859, 48863.357957, 48872.107214, 48880.856629, 48889.606203, 48898.355936, 48907.105827, 48915.855876,
+   48924.606084, 48933.356450, 48942.106975, 48950.857658, 48959.608499, 48968.359499, 48977.110657, 48985.861973,
+   48994.613448, 49003.365080, 49012.116871, 49020.868820, 49029.620928, 49038.373193, 49047.125616, 49055.878198,
+   49064.630937, 49073.383835, 49082.136890, 49090.890104, 49099.643475, 49108.397005, 49117.150692, 49125.904537,
+   49134.658540, 49143.412701, 49152.167019, 49160.921495, 49169.676129, 49178.430921, 49187.185871, 49195.940978,
+   49204.696243, 49213.451665, 49222.207245, 49230.962982, 49239.718877, 49248.474930, 49257.231140, 49265.987508,
+   49274.744033, 49283.500715, 49292.257555, 49301.014552, 49309.771707, 49318.529019, 49327.286488, 49336.044114,
+   49344.801898, 49353.559839, 49362.317937, 49371.076192, 49379.834604, 49388.593174, 49397.351900, 49406.110784,
+   49414.869825, 49423.629023, 49432.388377, 49441.147889, 49449.907558, 49458.667383, 49467.427366, 49476.187505,
+   49484.947801, 49493.708254, 49502.468864, 49511.229631, 49519.990554, 49528.751634, 49537.512871, 49546.274265,
+   49555.035815, 49563.797522, 49572.559385, 49581.321405, 49590.083581, 49598.845915, 49607.608404, 49616.371050,
+   49625.133853, 49633.896811, 49642.659927, 49651.423199, 49660.186627, 49668.950211, 49677.713952, 49686.477849,
+   49695.241902, 49704.006112, 49712.770477, 49721.534999, 49730.299677, 49739.064511, 49747.829502, 49756.594648,
+   49765.359951, 49774.125409, 49782.891024, 49791.656794, 49800.422721, 49809.188803, 49817.955042, 49826.721436,
+   49835.487986, 49844.254692, 49853.021554, 49861.788572, 49870.555745, 49879.323074, 49888.090559, 49896.858200,
+   49905.625996, 49914.393948, 49923.162055, 49931.930318, 49940.698737, 49949.467311, 49958.236041, 49967.004927,
+   49975.773967, 49984.543164, 49993.312515, 50002.082022, 50010.851685, 50019.621503, 50028.391476, 50037.161605,
+   50045.931888, 50054.702327, 50063.472922, 50072.243671, 50081.014576, 50089.785636, 50098.556851, 50107.328221,
+   50116.099747, 50124.871427, 50133.643262, 50142.415253, 50151.187398, 50159.959699, 50168.732154, 50177.504764,
+   50186.277529, 50195.050450, 50203.823525, 50212.596754, 50221.370139, 50230.143678, 50238.917372, 50247.691221,
+   50256.465225, 50265.239383, 50274.013696, 50282.788164, 50291.562786, 50300.337563, 50309.112494, 50317.887580,
+   50326.662821, 50335.438216, 50344.213765, 50352.989469, 50361.765327, 50370.541340, 50379.317507, 50388.093828,
+   50396.870304, 50405.646934, 50414.423719, 50423.200657, 50431.977750, 50440.754997, 50449.532399, 50458.309954,
+   50467.087664, 50475.865527, 50484.643545, 50493.421717, 50502.200043, 50510.978523, 50519.757157, 50528.535945,
+   50537.314887, 50546.093983, 50554.873232, 50563.652636, 50572.432193, 50581.211905, 50589.991770, 50598.771789,
+   50607.551961, 50616.332288, 50625.112768, 50633.893402, 50642.674189, 50651.455130, 50660.236225, 50669.017473,
+   50677.798875, 50686.580431, 50695.362140, 50704.144002, 50712.926018, 50721.708187, 50730.490510, 50739.272987,
+   50748.055616, 50756.838399, 50765.621336, 50774.404425, 50783.187668, 50791.971064, 50800.754614, 50809.538317,
+   50818.322173, 50827.106182, 50835.890344, 50844.674659, 50853.459128, 50862.243749, 50871.028524, 50879.813451,
+   50888.598532, 50897.383766, 50906.169152, 50914.954692, 50923.740384, 50932.526230, 50941.312228, 50950.098379,
+   50958.884683, 50967.671139, 50976.457749, 50985.244511, 50994.031426, 51002.818494, 51011.605714, 51020.393087,
+   51029.180613, 51037.968291, 51046.756122, 51055.544105, 51064.332241, 51073.120529, 51081.908970, 51090.697564,
+   51099.486310, 51108.275208, 51117.064259, 51125.853462, 51134.642817, 51143.432325, 51152.221985, 51161.011798,
+   51169.801762, 51178.591879, 51187.382148, 51196.172569, 51204.963143, 51213.753869, 51222.544746, 51231.335776,
+   51240.126958, 51248.918292, 51257.709778, 51266.501416, 51275.293206, 51284.085148, 51292.877242, 51301.669488,
+   51310.461886, 51319.254435, 51328.047137, 51336.839990, 51345.632995, 51354.426152, 51363.219461, 51372.012921,
+   51380.806533, 51389.600297, 51398.394212, 51407.188279, 51415.982498, 51424.776868, 51433.571390, 51442.366064,
+   51451.160889, 51459.955865, 51468.750993, 51477.546272, 51486.341703, 51495.137285, 51503.933019, 51512.728904,
+   51521.524940, 51530.321128, 51539.117467, 51547.913957, 51556.710598, 51565.507391, 51574.304335, 51583.101430,
+   51591.898676, 51600.696074, 51609.493622, 51618.291322, 51627.089172, 51635.887174, 51644.685327, 51653.483631,
+   51662.282085, 51671.080691, 51679.879447, 51688.678355, 51697.477413, 51706.276623, 51715.075983, 51723.875494,
+   51732.675155, 51741.474968, 51750.274931, 51759.075045, 51767.875310, 51776.675725, 51785.476291, 51794.277007,
+   51803.077875, 51811.878893, 51820.680061, 51829.481380, 51838.282849, 51847.084469, 51855.886240, 51864.688161,
+   51873.490232, 51882.292454, 51891.094826, 51899.897348, 51908.700021, 51917.502844, 51926.305818, 51935.108942,
+   51943.912216, 51952.715640, 51961.519214, 51970.322939, 51979.126814, 51987.930838, 51996.735013, 52005.539339,
+   52014.343814, 52023.148439, 52031.953214, 52040.758140, 52049.563215, 52058.368440, 52067.173815, 52075.979340,
+   52084.785015, 52093.590840, 52102.396815, 52111.202939, 52120.009213, 52128.815637, 52137.622211, 52146.428935,
+   52155.235808, 52164.042831, 52172.850004, 52181.657326, 52190.464798, 52199.272419, 52208.080190, 52216.888111,
+   52225.696181, 52234.504401, 52243.312770, 52252.121289, 52260.929957, 52269.738774, 52278.547741, 52287.356857,
+   52296.166123, 52304.975538, 52313.785102, 52322.594816, 52331.404678, 52340.214690, 52349.024852, 52357.835162,
+   52366.645622, 52375.456231, 52384.266989, 52393.077896, 52401.888952, 52410.700157, 52419.511511, 52428.323014,
+   52437.134667, 52445.946468, 52454.758418, 52463.570517, 52472.382765, 52481.195162, 52490.007708, 52498.820402,
+   52507.633246, 52516.446238, 52525.259379, 52534.072669, 52542.886107, 52551.699695, 52560.513430, 52569.327315,
+   52578.141348, 52586.955530, 52595.769860, 52604.584339, 52613.398967, 52622.213743, 52631.028668, 52639.843741,
+   52648.658962, 52657.474332, 52666.289851, 52675.105518, 52683.921333, 52692.737296, 52701.553408, 52710.369668,
+   52719.186077, 52728.002634, 52736.819339, 52745.636192, 52754.453193, 52763.270343, 52772.087641, 52780.905087,
+   52789.722681, 52798.540423, 52807.358313, 52816.176351, 52824.994538, 52833.812872, 52842.631354, 52851.449984,
+   52860.268763, 52869.087689, 52877.906763, 52886.725985, 52895.545354, 52904.364872, 52913.184537, 52922.004350,
+   52930.824311, 52939.644420, 52948.464676, 52957.285080, 52966.105632, 52974.926331, 52983.747178, 52992.568173,
+   53001.389315, 53010.210605, 53019.032042, 53027.853627, 53036.675360, 53045.497240, 53054.319267, 53063.141442,
+   53071.963764, 53080.786233, 53089.608850, 53098.431615, 53107.254526, 53116.077585, 53124.900791, 53133.724145,
+   53142.547646, 53151.371294, 53160.195089, 53169.019031, 53177.843121, 53186.667357, 53195.491741, 53204.316272,
+   53213.140950, 53221.965775, 53230.790747, 53239.615866, 53248.441131, 53257.266544, 53266.092104, 53274.917811,
+   53283.743665, 53292.569665, 53301.395813, 53310.222107, 53319.048548, 53327.875136, 53336.701870, 53345.528752,
+   53354.355780, 53363.182955, 53372.010276, 53380.837744, 53389.665359, 53398.493120, 53407.321028, 53416.149083,
+   53424.977284, 53433.805631, 53442.634126, 53451.462766, 53460.291553, 53469.120487, 53477.949567, 53486.778793,
+   53495.608166, 53504.437685, 53513.267350, 53522.097162, 53530.927120, 53539.757224, 53548.587475, 53557.417872,
+   53566.248415, 53575.079104, 53583.909939, 53592.740921, 53601.572049, 53610.403322, 53619.234742, 53628.066308,
+   53636.898020, 53645.729878, 53654.561882, 53663.394032, 53672.226328, 53681.058769, 53689.891357, 53698.724091,
+   53707.556970, 53716.389995, 53725.223167, 53734.056483, 53742.889946, 53751.723555, 53760.557309, 53769.391209,
+   53778.225254, 53787.059446, 53795.893783, 53804.728265, 53813.562894, 53822.397667, 53831.232587, 53840.067652,
+   53848.902862, 53857.738218, 53866.573720, 53875.409367, 53884.245159, 53893.081097, 53901.917180, 53910.753408,
+   53919.589782, 53928.426302, 53937.262966, 53946.099776, 53954.936731, 53963.773832, 53972.611077, 53981.448468,
+   53990.286004, 53999.123685, 54007.961512, 54016.799483, 54025.637600, 54034.475862, 54043.314268, 54052.152820,
+   54060.991517, 54069.830359, 54078.669346, 54087.508477, 54096.347754, 54105.187176, 54114.026742, 54122.866453,
+   54131.706310, 54140.546311, 54149.386457, 54158.226747, 54167.067183, 54175.907763, 54184.748488, 54193.589357,
+   54202.430372, 54211.271531, 54220.112834, 54228.954283, 54237.795875, 54246.637613, 54255.479495, 54264.321521,
+   54273.163692, 54282.006008, 54290.848468, 54299.691073, 54308.533821, 54317.376715, 54326.219753, 54335.062935,
+   54343.906261, 54352.749732, 54361.593347, 54370.437106, 54379.281010, 54388.125058, 54396.969250, 54405.813586,
+   54414.658067, 54423.502692, 54432.347460, 54441.192373, 54450.037430, 54458.882631, 54467.727977, 54476.573466,
+   54485.419099, 54494.264876, 54503.110798, 54511.956863, 54520.803072, 54529.649425, 54538.495922, 54547.342563,
+   54556.189347, 54565.036276, 54573.883348, 54582.730564, 54591.577924, 54600.425428, 54609.273075, 54618.120866,
+   54626.968801, 54635.816879, 54644.665102, 54653.513467, 54662.361977, 54671.210629, 54680.059426, 54688.908366,
+   54697.757449, 54706.606676, 54715.456047, 54724.305561, 54733.155218, 54742.005019, 54750.854963, 54759.705051,
+   54768.555282, 54777.405656, 54786.256174, 54795.106835, 54803.957639, 54812.808586, 54821.659677, 54830.510911,
+   54839.362288, 54848.213808, 54857.065472, 54865.917278, 54874.769228, 54883.621321, 54892.473557, 54901.325936,
+   54910.178457, 54919.031122, 54927.883930, 54936.736881, 54945.589975, 54954.443212, 54963.296591, 54972.150114,
+   54981.003779, 54989.857588, 54998.711539, 55007.565633, 55016.419869, 55025.274249, 55034.128771, 55042.983436,
+   55051.838244, 55060.693194, 55069.548287, 55078.403523, 55087.258901, 55096.114422, 55104.970085, 55113.825891,
+   55122.681840, 55131.537931, 55140.394164, 55149.250540, 55158.107059, 55166.963720, 55175.820523, 55184.677469,
+   55193.534557, 55202.391787, 55211.249160, 55220.106675, 55228.964333, 55237.822133, 55246.680075, 55255.538159,
+   55264.396385, 55273.254754, 55282.113265, 55290.971918, 55299.830713, 55308.689650, 55317.548729, 55326.407951,
+   55335.267314, 55344.126820, 55352.986467, 55361.846257, 55370.706188, 55379.566261, 55388.426477, 55397.286834,
+   55406.147333, 55415.007974, 55423.868757, 55432.729682, 55441.590749, 55450.451957, 55459.313307, 55468.174799,
+   55477.036432, 55485.898208, 55494.760125, 55503.622183, 55512.484384, 55521.346726, 55530.209209, 55539.071834,
+   55547.934601, 55556.797509, 55565.660559, 55574.523751, 55583.387083, 55592.250558, 55601.114174, 55609.977931,
+   55618.841829, 55627.705869, 55636.570051, 55645.434373, 55654.298837, 55663.163443, 55672.028190, 55680.893077,
+   55689.758107, 55698.623277, 55707.488589, 55716.354042, 55725.219636, 55734.085371, 55742.951247, 55751.817264,
+   55760.683423, 55769.549722, 55778.416163, 55787.282745, 55796.149467, 55805.016331, 55813.883336, 55822.750481,
+   55831.617768, 55840.485195, 55849.352764, 55858.220473, 55867.088323, 55875.956314, 55884.824445, 55893.692718,
+   55902.561131, 55911.429685, 55920.298380, 55929.167216, 55938.036192, 55946.905309, 55955.774566, 55964.643964,
+   55973.513503, 55982.383182, 55991.253002, 56000.122963, 56008.993064, 56017.863305, 56026.733688, 56035.604210,
+   56044.474873, 56053.345677, 56062.216620, 56071.087705, 56079.958929, 56088.830294, 56097.701800, 56106.573445,
+   56115.445231, 56124.317158, 56133.189224, 56142.061431, 56150.933778, 56159.806265, 56168.678892, 56177.551660,
+   56186.424568, 56195.297615, 56204.170803, 56213.044131, 56221.917599, 56230.791207, 56239.664956, 56248.538844,
+   56257.412872, 56266.287040, 56275.161348, 56284.035796, 56292.910384, 56301.785112, 56310.659979, 56319.534987,
+   56328.410134, 56337.285421, 56346.160848, 56355.036415, 56363.912121, 56372.787967, 56381.663953, 56390.540079,
+   56399.416344, 56408.292749, 56417.169294, 56426.045978, 56434.922801, 56443.799765, 56452.676868, 56461.554110,
+   56470.431492, 56479.309014, 56488.186674, 56497.064475, 56505.942415, 56514.820494, 56523.698713, 56532.577071,
+   56541.455568, 56550.334205, 56559.212981, 56568.091896, 56576.970951, 56585.850145, 56594.729478, 56603.608950,
+   56612.488562, 56621.368313, 56630.248203, 56639.128232, 56648.008400, 56656.888708, 56665.769154, 56674.649740,
+   56683.530464, 56692.411328, 56701.292330, 56710.173472, 56719.054753, 56727.936172, 56736.817731, 56745.699428,
+   56754.581264, 56763.463239, 56772.345354, 56781.227606, 56790.109998, 56798.992529, 56807.875198, 56816.758006,
+   56825.640953, 56834.524038, 56843.407263, 56852.290625, 56861.174127, 56870.057767, 56878.941546, 56887.825464,
+   56896.709520, 56905.593714, 56914.478047, 56923.362519, 56932.247129, 56941.131878, 56950.016765, 56958.901791,
+   56967.786955, 56976.672258, 56985.557699, 56994.443278, 57003.328995, 57012.214851, 57021.100846, 57029.986978,
+   57038.873249, 57047.759658, 57056.646206, 57065.532892, 57074.419715, 57083.306677, 57092.193778, 57101.081016,
+   57109.968392, 57118.855907, 57127.743560, 57136.631350, 57145.519279, 57154.407346, 57163.295551, 57172.183894,
+   57181.072375, 57189.960994, 57198.849750, 57207.738645, 57216.627678, 57225.516848, 57234.406156, 57243.295602,
+   57252.185186, 57261.074908, 57269.964768, 57278.854765, 57287.744900, 57296.635173, 57305.525584, 57314.416132,
+   57323.306818, 57332.197641, 57341.088603, 57349.979702, 57358.870938, 57367.762312, 57376.653824, 57385.545473,
+   57394.437259, 57403.329183, 57412.221245, 57421.113444, 57430.005781, 57438.898255, 57447.790866, 57456.683615,
+   57465.576501, 57474.469524, 57483.362685, 57492.255983, 57501.149419, 57510.042992, 57518.936702, 57527.830549,
+   57536.724533, 57545.618655, 57554.512914, 57563.407310, 57572.301843, 57581.196513, 57590.091320, 57598.986265,
+   57607.881346, 57616.776565, 57625.671921, 57634.567413, 57643.463043, 57652.358809, 57661.254713, 57670.150754,
+   57679.046931, 57687.943245, 57696.839696, 57705.736285, 57714.633009, 57723.529871, 57732.426870, 57741.324005,
+   57750.221277, 57759.118686, 57768.016232, 57776.913914, 57785.811733, 57794.709689, 57803.607781, 57812.506010,
+   57821.404376, 57830.302878, 57839.201517, 57848.100292, 57856.999204, 57865.898252, 57874.797437, 57883.696759,
+   57892.596217, 57901.495811, 57910.395542, 57919.295409, 57928.195413, 57937.095553, 57945.995829, 57954.896242,
+   57963.796791, 57972.697476, 57981.598298, 57990.499255, 57999.400350, 58008.301580, 58017.202946, 58026.104449,
+   58035.006088, 58043.907863, 58052.809774, 58061.711822, 58070.614005, 58079.516325, 58088.418780, 58097.321372,
+   58106.224100, 58115.126963, 58124.029963, 58132.933099, 58141.836370, 58150.739778, 58159.643321, 58168.547001,
+   58177.450816, 58186.354767, 58195.258854, 58204.163076, 58213.067435, 58221.971929, 58230.876559, 58239.781325,
+   58248.686227, 58257.591264, 58266.496437, 58275.401746, 58284.307190, 58293.212770, 58302.118486, 58311.024337,
+   58319.930324, 58328.836446, 58337.742704, 58346.649097, 58355.555626, 58364.462291, 58373.369090, 58382.276026,
+   58391.183097, 58400.090303, 58408.997644, 58417.905121, 58426.812734, 58435.720481, 58444.628364, 58453.536383,
+   58462.444536, 58471.352825, 58480.261249, 58489.169809, 58498.078503, 58506.987333, 58515.896298, 58524.805398,
+   58533.714633, 58542.624004, 58551.533509, 58560.443150, 58569.352926, 58578.262836, 58587.172882, 58596.083063,
+   58604.993379, 58613.903829, 58622.814415, 58631.725136, 58640.635991, 58649.546982, 58658.458107, 58667.369368,
+   58676.280763, 58685.192293, 58694.103957, 58703.015757, 58711.927691, 58720.839760, 58729.751964, 58738.664303,
+   58747.576776, 58756.489384, 58765.402127, 58774.315004, 58783.228016, 58792.141162, 58801.054444, 58809.967859,
+   58818.881410, 58827.795094, 58836.708914, 58845.622868, 58854.536956, 58863.451179, 58872.365536, 58881.280028,
+   58890.194654, 58899.109414, 58908.024309, 58916.939339, 58925.854502, 58934.769800, 58943.685232, 58952.600799,
+   58961.516500, 58970.432335, 58979.348304, 58988.264408, 58997.180645, 59006.097017, 59015.013523, 59023.930164,
+   59032.846938, 59041.763846, 59050.680889, 59059.598066, 59068.515376, 59077.432821, 59086.350400, 59095.268113,
+   59104.185959, 59113.103940, 59122.022055, 59130.940303, 59139.858686, 59148.777202, 59157.695852, 59166.614637,
+   59175.533555, 59184.452606, 59193.371792, 59202.291111, 59211.210565, 59220.130151, 59229.049872, 59237.969726,
+   59246.889715, 59255.809836, 59264.730092, 59273.650481, 59282.571003, 59291.491660, 59300.412450, 59309.333373,
+   59318.254430, 59327.175621, 59336.096945, 59345.018402, 59353.939993, 59362.861718, 59371.783576, 59380.705567,
+   59389.627692, 59398.549950, 59407.472342, 59416.394867, 59425.317525, 59434.240317, 59443.163242, 59452.086300,
+   59461.009491, 59469.932816, 59478.856274, 59487.779865, 59496.703590, 59505.627447, 59514.551438, 59523.475562,
+   59532.399819, 59541.324209, 59550.248732, 59559.173389, 59568.098178, 59577.023100, 59585.948156, 59594.873344,
+   59603.798666, 59612.724120, 59621.649707, 59630.575428, 59639.501281, 59648.427267, 59657.353386, 59666.279638,
+   59675.206023, 59684.132540, 59693.059190, 59701.985973, 59710.912889, 59719.839938, 59728.767119, 59737.694433,
+   59746.621880, 59755.549460, 59764.477172, 59773.405017, 59782.332994, 59791.261104, 59800.189347, 59809.117722,
+   59818.046230, 59826.974870, 59835.903643, 59844.832549, 59853.761587, 59862.690757, 59871.620060, 59880.549495,
+   59889.479063, 59898.408763, 59907.338596, 59916.268560, 59925.198658, 59934.128887, 59943.059249, 59951.989743,
+   59960.920370, 59969.851128, 59978.782019, 59987.713043, 59996.644198, 60005.575486, 60014.506906, 60023.438458,
+   60032.370142, 60041.301958, 60050.233906, 60059.165987, 60068.098199, 60077.030544, 60085.963020, 60094.895629,
+   60103.828370, 60112.761242, 60121.694247, 60130.627383, 60139.560652, 60148.494052, 60157.427585, 60166.361249,
+   60175.295045, 60184.228973, 60193.163032, 60202.097224, 60211.031547, 60219.966002, 60228.900589, 60237.835308,
+   60246.770158, 60255.705140, 60264.640254, 60273.575499, 60282.510876, 60291.446385, 60300.382025, 60309.317797,
+   60318.253701, 60327.189736, 60336.125903, 60345.062201, 60353.998631, 60362.935192, 60371.871884, 60380.808709,
+   60389.745664, 60398.682751, 60407.619970, 60416.557320, 60425.494801, 60434.432413, 60443.370157, 60452.308033,
+   60461.246039, 60470.184177, 60479.122446, 60488.060847, 60496.999378, 60505.938041, 60514.876835, 60523.815760,
+   60532.754817, 60541.694005, 60550.633323, 60559.572773, 60568.512354, 60577.452066, 60586.391909, 60595.331883,
+   60604.271989, 60613.212225, 60622.152592, 60631.093090, 60640.033720, 60648.974480, 60657.915371, 60666.856393,
+   60675.797546, 60684.738829, 60693.680244, 60702.621789, 60711.563466, 60720.505273, 60729.447211, 60738.389279,
+   60747.331479, 60756.273809, 60765.216270, 60774.158862, 60783.101584, 60792.044437, 60800.987421, 60809.930535,
+   60818.873780, 60827.817155, 60836.760662, 60845.704298, 60854.648066, 60863.591963, 60872.535992, 60881.480151,
+   60890.424440, 60899.368860, 60908.313410, 60917.258091, 60926.202902, 60935.147843, 60944.092915, 60953.038117,
+   60961.983450, 60970.928913, 60979.874506, 60988.820230, 60997.766084, 61006.712068, 61015.658182, 61024.604427,
+   61033.550802, 61042.497307, 61051.443942, 61060.390707, 61069.337603, 61078.284628, 61087.231784, 61096.179070,
+   61105.126486, 61114.074032, 61123.021708, 61131.969514, 61140.917450, 61149.865516, 61158.813712, 61167.762038,
+   61176.710494, 61185.659080, 61194.607796, 61203.556642, 61212.505618, 61221.454723, 61230.403958, 61239.353323,
+   61248.302818, 61257.252443, 61266.202198, 61275.152082, 61284.102096, 61293.052240, 61302.002513, 61310.952916,
+   61319.903449, 61328.854112, 61337.804904, 61346.755826, 61355.706877, 61364.658058, 61373.609369, 61382.560809,
+   61391.512378, 61400.464077, 61409.415906, 61418.367864, 61427.319952, 61436.272169, 61445.224516, 61454.176992,
+   61463.129597, 61472.082332, 61481.035196, 61489.988189, 61498.941312, 61507.894564, 61516.847946, 61525.801457,
+   61534.755097, 61543.708866, 61552.662764, 61561.616792, 61570.570949, 61579.525235, 61588.479651, 61597.434195,
+   61606.388869, 61615.343672, 61624.298603, 61633.253664, 61642.208854, 61651.164173, 61660.119622, 61669.075199,
+   61678.030905, 61686.986740, 61695.942704, 61704.898797, 61713.855019, 61722.811370, 61731.767850, 61740.724459,
+   61749.681196, 61758.638063, 61767.595058, 61776.552182, 61785.509435, 61794.466817, 61803.424327, 61812.381967,
+   61821.339735, 61830.297631, 61839.255657, 61848.213811, 61857.172094, 61866.130505, 61875.089045, 61884.047714,
+   61893.006512, 61901.965437, 61910.924492, 61919.883675, 61928.842987, 61937.802427, 61946.761995, 61955.721693,
+   61964.681518, 61973.641472, 61982.601555, 61991.561766, 62000.522105, 62009.482573, 62018.443169, 62027.403894,
+   62036.364746, 62045.325728, 62054.286837, 62063.248075, 62072.209441, 62081.170935, 62090.132558, 62099.094309,
+   62108.056188, 62117.018195, 62125.980330, 62134.942594, 62143.904985, 62152.867505, 62161.830153, 62170.792929,
+   62179.755833, 62188.718866, 62197.682026, 62206.645314, 62215.608730, 62224.572275, 62233.535947, 62242.499747,
+   62251.463675, 62260.427732, 62269.391916, 62278.356228, 62287.320667, 62296.285235, 62305.249931, 62314.214754,
+   62323.179705, 62332.144784, 62341.109991, 62350.075326, 62359.040788, 62368.006378, 62376.972096, 62385.937941,
+   62394.903915, 62403.870015, 62412.836244, 62421.802600, 62430.769084, 62439.735695, 62448.702434, 62457.669301,
+   62466.636295, 62475.603416, 62484.570666, 62493.538042, 62502.505547, 62511.473178, 62520.440937, 62529.408824,
+   62538.376838, 62547.344979, 62556.313248, 62565.281644, 62574.250168, 62583.218819, 62592.187597, 62601.156503,
+   62610.125535, 62619.094696, 62628.063983, 62637.033398, 62646.002940, 62654.972609, 62663.942405, 62672.912328,
+   62681.882379, 62690.852557, 62699.822862, 62708.793294, 62717.763853, 62726.734539, 62735.705353, 62744.676293,
+   62753.647361, 62762.618555, 62771.589876, 62780.561325, 62789.532900, 62798.504603, 62807.476432, 62816.448388,
+   62825.420472, 62834.392682, 62843.365019, 62852.337482, 62861.310073, 62870.282791, 62879.255635, 62888.228606,
+   62897.201704, 62906.174929, 62915.148280, 62924.121758, 62933.095363, 62942.069095, 62951.042953, 62960.016938,
+   62968.991049, 62977.965288, 62986.939652, 62995.914144, 63004.888762, 63013.863507, 63022.838378, 63031.813375,
+   63040.788500, 63049.763750, 63058.739128, 63067.714631, 63076.690262, 63085.666018, 63094.641901, 63103.617911,
+   63112.594047, 63121.570309, 63130.546697, 63139.523212, 63148.499854, 63157.476621, 63166.453515, 63175.430535,
+   63184.407682, 63193.384955, 63202.362354, 63211.339879, 63220.317530, 63229.295308, 63238.273212, 63247.251242,
+   63256.229398, 63265.207680, 63274.186088, 63283.164623, 63292.143283, 63301.122070, 63310.100982, 63319.080021,
+   63328.059186, 63337.038476, 63346.017893, 63354.997435, 63363.977104, 63372.956898, 63381.936819, 63390.916865,
+   63399.897037, 63408.877335, 63417.857759, 63426.838309, 63435.818985, 63444.799786, 63453.780713, 63462.761766,
+   63471.742945, 63480.724250, 63489.705680, 63498.687236, 63507.668917, 63516.650725, 63525.632658, 63534.614716,
+   63543.596901, 63552.579211, 63561.561646, 63570.544207, 63579.526894, 63588.509706, 63597.492644, 63606.475707,
+   63615.458896, 63624.442210, 63633.425650, 63642.409215, 63651.392906, 63660.376722, 63669.360664, 63678.344730,
+   63687.328923, 63696.313240, 63705.297684, 63714.282252, 63723.266946, 63732.251765, 63741.236709, 63750.221778,
+   63759.206973, 63768.192293, 63777.177739, 63786.163309, 63795.149005, 63804.134826, 63813.120772, 63822.106843,
+   63831.093039, 63840.079361, 63849.065807, 63858.052379, 63867.039075, 63876.025897, 63885.012844, 63893.999916,
+   63902.987113, 63911.974434, 63920.961881, 63929.949453, 63938.937150, 63947.924971, 63956.912918, 63965.900989,
+   63974.889186, 63983.877507, 63992.865953, 64001.854524, 64010.843219, 64019.832040, 64028.820985, 64037.810055,
+   64046.799250, 64055.788570, 64064.778014, 64073.767583, 64082.757277, 64091.747095, 64100.737038, 64109.727106,
+   64118.717298, 64127.707615, 64136.698057, 64145.688623, 64154.679313, 64163.670129, 64172.661069, 64181.652133,
+   64190.643322, 64199.634635, 64208.626073, 64217.617635, 64226.609322, 64235.601133, 64244.593069, 64253.585129,
+   64262.577313, 64271.569622, 64280.562055, 64289.554612, 64298.547294, 64307.540100, 64316.533030, 64325.526085,
+   64334.519264, 64343.512567, 64352.505994, 64361.499546, 64370.493222, 64379.487022, 64388.480946, 64397.474994,
+   64406.469167, 64415.463463, 64424.457884, 64433.452429, 64442.447097, 64451.441890, 64460.436807, 64469.431848,
+   64478.427013, 64487.422302, 64496.417715, 64505.413252, 64514.408913, 64523.404698, 64532.400607, 64541.396639,
+   64550.392796, 64559.389076, 64568.385481, 64577.382009, 64586.378661, 64595.375437, 64604.372336, 64613.369360,
+   64622.366507, 64631.363778, 64640.361172, 64649.358691, 64658.356333, 64667.354098, 64676.351988, 64685.350001,
+   64694.348138, 64703.346398, 64712.344782, 64721.343290, 64730.341921, 64739.340676, 64748.339554, 64757.338556,
+   64766.337681, 64775.336930, 64784.336303, 64793.335799, 64802.335418, 64811.335161, 64820.335027, 64829.335016,
+   64838.335130, 64847.335366, 64856.335726, 64865.336209, 64874.336815, 64883.337545, 64892.338398, 64901.339375,
+   64910.340475, 64919.341698, 64928.343044, 64937.344513, 64946.346106, 64955.347822, 64964.349661, 64973.351623,
+   64982.353709, 64991.355917, 65000.358249, 65009.360704, 65018.363282, 65027.365983, 65036.368807, 65045.371754,
+   65054.374824, 65063.378017, 65072.381334, 65081.384773, 65090.388335, 65099.392020, 65108.395828, 65117.399759,
+   65126.403813, 65135.407990, 65144.412290, 65153.416712, 65162.421258, 65171.425926, 65180.430717, 65189.435631,
+   65198.440668, 65207.445827, 65216.451110, 65225.456515, 65234.462042, 65243.467693, 65252.473466, 65261.479362,
+   65270.485381, 65279.491522, 65288.497786, 65297.504172, 65306.510681, 65315.517313, 65324.524067, 65333.530944,
+   65342.537944, 65351.545066, 65360.552310, 65369.559677, 65378.567167, 65387.574779, 65396.582513, 65405.590370,
+   65414.598350, 65423.606451, 65432.614676, 65441.623022, 65450.631491, 65459.640082, 65468.648796, 65477.657632,
+   65486.666590, 65495.675671, 65504.684874, 65513.694199, 65522.703647, 65531.713216, 65540.722908, 65549.732722,
+   65558.742659, 65567.752717, 65576.762898, 65585.773200, 65594.783625, 65603.794172, 65612.804842, 65621.815633,
+   65630.826546, 65639.837582, 65648.848739, 65657.860019, 65666.871420, 65675.882944, 65684.894589, 65693.906357,
+   65702.918246, 65711.930257, 65720.942391, 65729.954646, 65738.967023, 65747.979522, 65756.992143, 65766.004886,
+   65775.017750, 65784.030737, 65793.043845, 65802.057075, 65811.070427, 65820.083900, 65829.097495, 65838.111213,
+   65847.125051, 65856.139012, 65865.153094, 65874.167298, 65883.181623, 65892.196070, 65901.210639, 65910.225329,
+   65919.240141, 65928.255075, 65937.270130, 65946.285307, 65955.300605, 65964.316025, 65973.331566, 65982.347229,
+   65991.363013, 66000.378919, 66009.394946, 66018.411095, 66027.427365, 66036.443756, 66045.460269, 66054.476904,
+   66063.493659, 66072.510536, 66081.527534, 66090.544654, 66099.561895, 66108.579257, 66117.596741, 66126.614346,
+   66135.632072, 66144.649919, 66153.667887, 66162.685977, 66171.704188, 66180.722520, 66189.740973, 66198.759548,
+   66207.778243, 66216.797060, 66225.815997, 66234.835056, 66243.854236, 66252.873537, 66261.892959, 66270.912502,
+   66279.932166, 66288.951951, 66297.971857, 66306.991884, 66316.012032, 66325.032301, 66334.052690, 66343.073201,
+   66352.093833, 66361.114585, 66370.135459, 66379.156453, 66388.177568, 66397.198804, 66406.220160, 66415.241638,
+   66424.263236, 66433.284955, 66442.306795, 66451.328755, 66460.350837, 66469.373038, 66478.395361, 66487.417804,
+   66496.440368, 66505.463053, 66514.485858, 66523.508784, 66532.531831, 66541.554998, 66550.578285, 66559.601693,
+   66568.625222, 66577.648871, 66586.672641, 66595.696532, 66604.720542, 66613.744674, 66622.768925, 66631.793298,
+   66640.817790, 66649.842403, 66658.867137, 66667.891990, 66676.916965, 66685.942059, 66694.967274, 66703.992609,
+   66713.018065, 66722.043641, 66731.069337, 66740.095153, 66749.121090, 66758.147147, 66767.173324, 66776.199621,
+   66785.226039, 66794.252576, 66803.279234, 66812.306012, 66821.332911, 66830.359929, 66839.387067, 66848.414326,
+   66857.441704, 66866.469203, 66875.496822, 66884.524561, 66893.552419, 66902.580398, 66911.608497, 66920.636716,
+   66929.665055, 66938.693513, 66947.722092, 66956.750791, 66965.779609, 66974.808547, 66983.837606, 66992.866784,
+   67001.896082, 67010.925500, 67019.955037, 67028.984695, 67038.014472, 67047.044369, 67056.074386, 67065.104522,
+   67074.134779, 67083.165155, 67092.195651, 67101.226266, 67110.257001, 67119.287856, 67128.318830, 67137.349924,
+   67146.381138, 67155.412471, 67164.443924, 67173.475497, 67182.507189, 67191.539001, 67200.570932, 67209.602982,
+   67218.635153, 67227.667442, 67236.699851, 67245.732380, 67254.765028, 67263.797796, 67272.830683, 67281.863689,
+   67290.896815, 67299.930060, 67308.963424, 67317.996908, 67327.030511, 67336.064234, 67345.098076, 67354.132037,
+   67363.166117, 67372.200317, 67381.234636, 67390.269074, 67399.303631, 67408.338308, 67417.373104, 67426.408019,
+   67435.443053, 67444.478206, 67453.513479, 67462.548870, 67471.584381, 67480.620011, 67489.655760, 67498.691628,
+   67507.727615, 67516.763721, 67525.799946, 67534.836290, 67543.872753, 67552.909335, 67561.946036, 67570.982856,
+   67580.019795, 67589.056853, 67598.094029, 67607.131325, 67616.168739, 67625.206273, 67634.243925, 67643.281696,
+   67652.319586, 67661.357595, 67670.395722, 67679.433969, 67688.472334, 67697.510818, 67706.549420, 67715.588142,
+   67724.626982, 67733.665941, 67742.705018, 67751.744214, 67760.783529, 67769.822962, 67778.862514, 67787.902185,
+   67796.941974, 67805.981882, 67815.021909, 67824.062054, 67833.102317, 67842.142699, 67851.183200, 67860.223819,
+   67869.264556, 67878.305413, 67887.346387, 67896.387480, 67905.428691, 67914.470021, 67923.511469, 67932.553036,
+   67941.594721, 67950.636525, 67959.678446, 67968.720486, 67977.762645, 67986.804921, 67995.847316, 68004.889830,
+   68013.932461, 68022.975211, 68032.018079, 68041.061065, 68050.104170, 68059.147392, 68068.190733, 68077.234192,
+   68086.277769, 68095.321465, 68104.365278, 68113.409209, 68122.453259, 68131.497427, 68140.541713, 68149.586116,
+   68158.630638, 68167.675278, 68176.720036, 68185.764912, 68194.809906, 68203.855018, 68212.900248, 68221.945596,
+   68230.991061, 68240.036645, 68249.082347, 68258.128166, 68267.174103, 68276.220158, 68285.266331, 68294.312622,
+   68303.359031, 68312.405558, 68321.452202, 68330.498964, 68339.545844, 68348.592841, 68357.639957, 68366.687190,
+   68375.734540, 68384.782009, 68393.829595, 68402.877299, 68411.925120, 68420.973059, 68430.021116, 68439.069290,
+   68448.117582, 68457.165992, 68466.214519, 68475.263163, 68484.311926, 68493.360805, 68502.409802, 68511.458917,
+   68520.508149, 68529.557499, 68538.606966, 68547.656551, 68556.706253, 68565.756072, 68574.806009, 68583.856063,
+   68592.906235, 68601.956524, 68611.006930, 68620.057454, 68629.108095, 68638.158853, 68647.209729, 68656.260722,
+   68665.311832, 68674.363059, 68683.414404, 68692.465866, 68701.517445, 68710.569141, 68719.620955, 68728.672885,
+   68737.724933, 68746.777098, 68755.829380, 68764.881779, 68773.934296, 68782.986929, 68792.039679, 68801.092547,
+   68810.145531, 68819.198633, 68828.251852, 68837.305187, 68846.358640, 68855.412210, 68864.465896, 68873.519700,
+   68882.573620, 68891.627657, 68900.681812, 68909.736083, 68918.790471, 68927.844976, 68936.899598, 68945.954336,
+   68955.009192, 68964.064164, 68973.119253, 68982.174459, 68991.229782, 69000.285221, 69009.340777, 69018.396450,
+   69027.452240, 69036.508146, 69045.564169, 69054.620309, 69063.676565, 69072.732938, 69081.789428, 69090.846034,
+   69099.902757, 69108.959596, 69118.016553, 69127.073625, 69136.130814, 69145.188120, 69154.245542, 69163.303081,
+   69172.360736, 69181.418508, 69190.476396, 69199.534401, 69208.592522, 69217.650760, 69226.709114, 69235.767584,
+   69244.826171, 69253.884874, 69262.943694, 69272.002630, 69281.061682, 69290.120851, 69299.180136, 69308.239537,
+   69317.299054, 69326.358688, 69335.418438, 69344.478304, 69353.538287, 69362.598385, 69371.658600, 69380.718931,
+   69389.779379, 69398.839942, 69407.900622, 69416.961418, 69426.022329, 69435.083357, 69444.144501, 69453.205762,
+   69462.267138, 69471.328630, 69480.390238, 69489.451963, 69498.513803, 69507.575759, 69516.637832, 69525.700020,
+   69534.762324, 69543.824745, 69552.887281, 69561.949933, 69571.012701, 69580.075585, 69589.138585, 69598.201700,
+   69607.264932, 69616.328279, 69625.391742, 69634.455321, 69643.519016, 69652.582827, 69661.646753, 69670.710795,
+   69679.774953, 69688.839227, 69697.903616, 69706.968121, 69716.032742, 69725.097478, 69734.162330, 69743.227298,
+   69752.292381, 69761.357580, 69770.422895, 69779.488325, 69788.553871, 69797.619532, 69806.685309, 69815.751202,
+   69824.817210, 69833.883333, 69842.949572, 69852.015927, 69861.082397, 69870.148982, 69879.215683, 69888.282499,
+   69897.349431, 69906.416478, 69915.483641, 69924.550919, 69933.618312, 69942.685821, 69951.753445, 69960.821185,
+   69969.889039, 69978.957009, 69988.025095, 69997.093295, 70006.161611, 70015.230042, 70024.298589, 70033.367250,
+   70042.436027, 70051.504919, 70060.573926, 70069.643049, 70078.712286, 70087.781639, 70096.851107, 70105.920690,
+   70114.990388, 70124.060201, 70133.130129, 70142.200172, 70151.270331, 70160.340604, 70169.410992, 70178.481496,
+   70187.552114, 70196.622848, 70205.693696, 70214.764659, 70223.835738, 70232.906931, 70241.978239, 70251.049662,
+   70260.121200, 70269.192853, 70278.264621, 70287.336503, 70296.408501, 70305.480613, 70314.552840, 70323.625182,
+   70332.697639, 70341.770210, 70350.842896, 70359.915697, 70368.988613, 70378.061643, 70387.134788, 70396.208048,
+   70405.281423, 70414.354912, 70423.428516, 70432.502234, 70441.576067, 70450.650015, 70459.724078, 70468.798254,
+   70477.872546, 70486.946952, 70496.021473, 70505.096108, 70514.170858, 70523.245722, 70532.320701, 70541.395794,
+   70550.471002, 70559.546324, 70568.621760, 70577.697311, 70586.772977, 70595.848757, 70604.924651, 70614.000660,
+   70623.076783, 70632.153020, 70641.229372, 70650.305838, 70659.382418, 70668.459113, 70677.535922, 70686.612845,
+   70695.689883, 70704.767034, 70713.844300, 70722.921681, 70731.999175, 70741.076784, 70750.154507, 70759.232344,
+   70768.310295, 70777.388360, 70786.466540, 70795.544833, 70804.623241, 70813.701763, 70822.780399, 70831.859149,
+   70840.938013, 70850.016991, 70859.096083, 70868.175289, 70877.254609, 70886.334043, 70895.413591, 70904.493253,
+   70913.573029, 70922.652919, 70931.732923, 70940.813041, 70949.893272, 70958.973618, 70968.054077, 70977.134651,
+   70986.215338, 70995.296139, 71004.377054, 71013.458082, 71022.539225, 71031.620481, 71040.701851, 71049.783335,
+   71058.864932, 71067.946644, 71077.028469, 71086.110407, 71095.192460, 71104.274626, 71113.356905, 71122.439299,
+   71131.521806, 71140.604426, 71149.687160, 71158.770008, 71167.852970, 71176.936045, 71186.019233, 71195.102536,
+   71204.185951, 71213.269480, 71222.353123, 71231.436879, 71240.520749, 71249.604732, 71258.688829, 71267.773039,
+   71276.857363, 71285.941799, 71295.026350, 71304.111014, 71313.195791, 71322.280681, 71331.365685, 71340.450802,
+   71349.536033, 71358.621377, 71367.706834, 71376.792404, 71385.878088, 71394.963885, 71404.049796, 71413.135819,
+   71422.221956, 71431.308206, 71440.394569, 71449.481045, 71458.567635, 71467.654338, 71476.741154, 71485.828083,
+   71494.915125, 71504.002280, 71513.089548, 71522.176930, 71531.264424, 71540.352032, 71549.439753, 71558.527586,
+   71567.615533, 71576.703593, 71585.791766, 71594.880051, 71603.968450, 71613.056962, 71622.145586, 71631.234324,
+   71640.323174, 71649.412138, 71658.501214, 71667.590403, 71676.679705, 71685.769120, 71694.858648, 71703.948288,
+   71713.038042, 71722.127908, 71731.217887, 71740.307979, 71749.398184, 71758.488501, 71767.578931, 71776.669474,
+   71785.760129, 71794.850897, 71803.941778, 71813.032772, 71822.123878, 71831.215097, 71840.306429, 71849.397873,
+   71858.489430, 71867.581099, 71876.672881, 71885.764776, 71894.856783, 71903.948903, 71913.041135, 71922.133480,
+   71931.225937, 71940.318507, 71949.411190, 71958.503984, 71967.596892, 71976.689911, 71985.783043, 71994.876288,
+   72003.969645, 72013.063115, 72022.156696, 72031.250391, 72040.344197, 72049.438116, 72058.532147, 72067.626291,
+   72076.720547, 72085.814915, 72094.909395, 72104.003988, 72113.098693, 72122.193510, 72131.288440, 72140.383482,
+   72149.478636, 72158.573902, 72167.669280, 72176.764771, 72185.860373, 72194.956088, 72204.051915, 72213.147854,
+   72222.243906, 72231.340069, 72240.436344, 72249.532732, 72258.629231, 72267.725843, 72276.822567, 72285.919402,
+   72295.016350, 72304.113410, 72313.210581, 72322.307865, 72331.405261, 72340.502768, 72349.600388, 72358.698119,
+   72367.795962, 72376.893918, 72385.991985, 72395.090164, 72404.188455, 72413.286857, 72422.385372, 72431.483998,
+   72440.582737, 72449.681587, 72458.780548, 72467.879622, 72476.978807, 72486.078104, 72495.177513, 72504.277034,
+   72513.376666, 72522.476410, 72531.576265, 72540.676233, 72549.776312, 72558.876502, 72567.976805, 72577.077219,
+   72586.177744, 72595.278381, 72604.379130, 72613.479990, 72622.580962, 72631.682045, 72640.783240, 72649.884547,
+   72658.985965, 72668.087494, 72677.189135, 72686.290888, 72695.392751, 72704.494727, 72713.596814, 72722.699012,
+   72731.801321, 72740.903742, 72750.006275, 72759.108919, 72768.211674, 72777.314540, 72786.417518, 72795.520607,
+   72804.623808, 72813.727120, 72822.830543, 72831.934077, 72841.037723, 72850.141480, 72859.245348, 72868.349327,
+   72877.453418, 72886.557619, 72895.661932, 72904.766357, 72913.870892, 72922.975538, 72932.080296, 72941.185165,
+   72950.290145, 72959.395236, 72968.500438, 72977.605751, 72986.711175, 72995.816710, 73004.922356, 73014.028114,
+   73023.133982, 73032.239962, 73041.346052, 73050.452253, 73059.558566, 73068.664989, 73077.771523, 73086.878168,
+   73095.984924, 73105.091791, 73114.198769, 73123.305858, 73132.413057, 73141.520368, 73150.627789, 73159.735321,
+   73168.842964, 73177.950718, 73187.058583, 73196.166558, 73205.274644, 73214.382841, 73223.491149, 73232.599567,
+   73241.708096, 73250.816736, 73259.925486, 73269.034348, 73278.143320, 73287.252402, 73296.361595, 73305.470899,
+   73314.580314, 73323.689839, 73332.799474, 73341.909221, 73351.019077, 73360.129045, 73369.239123, 73378.349311,
+   73387.459610, 73396.570020, 73405.680540, 73414.791170, 73423.901911, 73433.012763, 73442.123725, 73451.234797,
+   73460.345980, 73469.457273, 73478.568677, 73487.680191, 73496.791815, 73505.903550, 73515.015395, 73524.127351,
+   73533.239416, 73542.351592, 73551.463879, 73560.576276, 73569.688783, 73578.801400, 73587.914127, 73597.026965,
+   73606.139913, 73615.252972, 73624.366140, 73633.479419, 73642.592808, 73651.706307, 73660.819916, 73669.933635,
+   73679.047465, 73688.161404, 73697.275454, 73706.389614, 73715.503884, 73724.618264, 73733.732754, 73742.847354,
+   73751.962064, 73761.076884, 73770.191814, 73779.306854, 73788.422005, 73797.537265, 73806.652635, 73815.768115,
+   73824.883705, 73833.999405, 73843.115215, 73852.231135, 73861.347164, 73870.463304, 73879.579553, 73888.695913,
+   73897.812382, 73906.928961, 73916.045650, 73925.162448, 73934.279357, 73943.396375, 73952.513503, 73961.630741,
+   73970.748088, 73979.865545, 73988.983112, 73998.100789, 74007.218575, 74016.336472, 74025.454477, 74034.572593,
+   74043.690818, 74052.809153, 74061.927597, 74071.046151, 74080.164814, 74089.283588, 74098.402470, 74107.521463,
+   74116.640565, 74125.759776, 74134.879097, 74143.998528, 74153.118068, 74162.237717, 74171.357476, 74180.477344,
+   74189.597322, 74198.717410, 74207.837607, 74216.957913, 74226.078329, 74235.198854, 74244.319488, 74253.440232,
+   74262.561085, 74271.682048, 74280.803120, 74289.924301, 74299.045591, 74308.166991, 74317.288500, 74326.410119,
+   74335.531847, 74344.653684, 74353.775630, 74362.897685, 74372.019850, 74381.142124, 74390.264507, 74399.386999,
+   74408.509601, 74417.632311, 74426.755131, 74435.878060, 74445.001098, 74454.124245, 74463.247501, 74472.370867,
+   74481.494341, 74490.617925, 74499.741617, 74508.865419, 74517.989330, 74527.113349, 74536.237478, 74545.361716,
+   74554.486062, 74563.610518, 74572.735082, 74581.859756, 74590.984538, 74600.109430, 74609.234430, 74618.359539,
+   74627.484758, 74636.610085, 74645.735520, 74654.861065, 74663.986719, 74673.112481, 74682.238352, 74691.364332,
+   74700.490421, 74709.616619, 74718.742925, 74727.869340, 74736.995864, 74746.122497, 74755.249238, 74764.376088,
+   74773.503047, 74782.630114, 74791.757290, 74800.884575, 74810.011969, 74819.139471, 74828.267082, 74837.394801,
+   74846.522629, 74855.650565, 74864.778611, 74873.906764, 74883.035026, 74892.163397, 74901.291877, 74910.420465,
+   74919.549161, 74928.677966, 74937.806879, 74946.935901, 74956.065031, 74965.194270, 74974.323617, 74983.453073,
+   74992.582637, 75001.712309, 75010.842090, 75019.971980, 75029.101977, 75038.232083, 75047.362298, 75056.492620,
+   75065.623051, 75074.753590, 75083.884238, 75093.014994, 75102.145858, 75111.276831, 75120.407911, 75129.539100,
+   75138.670397, 75147.801803, 75156.933316, 75166.064938, 75175.196668, 75184.328506, 75193.460453, 75202.592507,
+   75211.724670, 75220.856940, 75229.989319, 75239.121806, 75248.254401, 75257.387104, 75266.519915, 75275.652835,
+   75284.785862, 75293.918997, 75303.052240, 75312.185592, 75321.319051, 75330.452618, 75339.586294, 75348.720077,
+   75357.853968, 75366.987967, 75376.122074, 75385.256289, 75394.390612, 75403.525043, 75412.659582, 75421.794228,
+   75430.928983, 75440.063845, 75449.198815, 75458.333893, 75467.469078, 75476.604372, 75485.739773, 75494.875282,
+   75504.010899, 75513.146624, 75522.282456, 75531.418396, 75540.554444, 75549.690599, 75558.826863, 75567.963233,
+   75577.099712, 75586.236298, 75595.372992, 75604.509793, 75613.646702, 75622.783719, 75631.920843, 75641.058075,
+   75650.195415, 75659.332862, 75668.470417, 75677.608079, 75686.745848, 75695.883726, 75705.021710, 75714.159802,
+   75723.298002, 75732.436309, 75741.574724, 75750.713246, 75759.851876, 75768.990613, 75778.129457, 75787.268409,
+   75796.407468, 75805.546634, 75814.685908, 75823.825290, 75832.964778, 75842.104374, 75851.244077, 75860.383888,
+   75869.523806, 75878.663831, 75887.803964, 75896.944203, 75906.084550, 75915.225005, 75924.365566, 75933.506235,
+   75942.647011, 75951.787894, 75960.928884, 75970.069982, 75979.211186, 75988.352498, 75997.493917, 76006.635443,
+   76015.777076, 76024.918816, 76034.060664, 76043.202618, 76052.344680, 76061.486848, 76070.629124, 76079.771507,
+   76088.913996, 76098.056593, 76107.199297, 76116.342108, 76125.485025, 76134.628050, 76143.771182, 76152.914420,
+   76162.057766, 76171.201218, 76180.344777, 76189.488444, 76198.632217, 76207.776097, 76216.920084, 76226.064177,
+   76235.208378, 76244.352685, 76253.497100, 76262.641621, 76271.786248, 76280.930983, 76290.075824, 76299.220773,
+   76308.365828, 76317.510989, 76326.656258, 76335.801633, 76344.947114, 76354.092703, 76363.238398, 76372.384200,
+   76381.530108, 76390.676124, 76399.822245, 76408.968474, 76418.114809, 76427.261251, 76436.407799, 76445.554454,
+   76454.701215, 76463.848083, 76472.995057, 76482.142138, 76491.289326, 76500.436620, 76509.584021, 76518.731528,
+   76527.879141, 76537.026861, 76546.174688, 76555.322621, 76564.470660, 76573.618806, 76582.767058, 76591.915417,
+   76601.063882, 76610.212453, 76619.361131, 76628.509915, 76637.658805, 76646.807802, 76655.956905, 76665.106114,
+   76674.255430, 76683.404852, 76692.554380, 76701.704015, 76710.853755, 76720.003602, 76729.153556, 76738.303615,
+   76747.453781, 76756.604052, 76765.754431, 76774.904915, 76784.055505, 76793.206202, 76802.357004, 76811.507913,
+   76820.658928, 76829.810049, 76838.961276, 76848.112609, 76857.264049, 76866.415594, 76875.567245, 76884.719003,
+   76893.870866, 76903.022836, 76912.174911, 76921.327092, 76930.479380, 76939.631773, 76948.784273, 76957.936878,
+   76967.089589, 76976.242406, 76985.395330, 76994.548359, 77003.701493, 77012.854734, 77022.008081, 77031.161533,
+   77040.315092, 77049.468756, 77058.622526, 77067.776402, 77076.930383, 77086.084471, 77095.238664, 77104.392963,
+   77113.547368, 77122.701878, 77131.856495, 77141.011216, 77150.166044, 77159.320977, 77168.476017, 77177.631161,
+   77186.786412, 77195.941768, 77205.097229, 77214.252797, 77223.408470, 77232.564248, 77241.720133, 77250.876122,
+   77260.032218, 77269.188419, 77278.344725, 77287.501137, 77296.657655, 77305.814278, 77314.971006, 77324.127840,
+   77333.284780, 77342.441825, 77351.598976, 77360.756232, 77369.913593, 77379.071060, 77388.228632, 77397.386310,
+   77406.544093, 77415.701982, 77424.859976, 77434.018075, 77443.176279, 77452.334589, 77461.493005, 77470.651525,
+   77479.810151, 77488.968883, 77498.127719, 77507.286661, 77516.445708, 77525.604860, 77534.764118, 77543.923481,
+   77553.082949, 77562.242522, 77571.402200, 77580.561984, 77589.721873, 77598.881867, 77608.041966, 77617.202170,
+   77626.362480, 77635.522894, 77644.683414, 77653.844039, 77663.004769, 77672.165604, 77681.326544, 77690.487589,
+   77699.648739, 77708.809994, 77717.971354, 77727.132819, 77736.294390, 77745.456065, 77754.617845, 77763.779730,
+   77772.941720, 77782.103815, 77791.266015, 77800.428320, 77809.590730, 77818.753245, 77827.915864, 77837.078589,
+   77846.241418, 77855.404353, 77864.567392, 77873.730536, 77882.893784, 77892.057138, 77901.220596, 77910.384160,
+   77919.547828, 77928.711600, 77937.875478, 77947.039460, 77956.203547, 77965.367739, 77974.532035, 77983.696436,
+   77992.860942, 78002.025553, 78011.190268, 78020.355088, 78029.520012, 78038.685041, 78047.850175, 78057.015414,
+   78066.180757, 78075.346204, 78084.511756, 78093.677413, 78102.843174, 78112.009040, 78121.175011, 78130.341086,
+   78139.507265, 78148.673549, 78157.839938, 78167.006431, 78176.173028, 78185.339730, 78194.506536, 78203.673447,
+   78212.840462, 78222.007582, 78231.174806, 78240.342135, 78249.509568, 78258.677105, 78267.844746, 78277.012492,
+   78286.180343, 78295.348297, 78304.516356, 78313.684520, 78322.852787, 78332.021159, 78341.189635, 78350.358216,
+   78359.526900, 78368.695689, 78377.864583, 78387.033580, 78396.202682, 78405.371887, 78414.541197, 78423.710612,
+   78432.880130, 78442.049753, 78451.219479, 78460.389310, 78469.559245, 78478.729284, 78487.899427, 78497.069675,
+   78506.240026, 78515.410481, 78524.581041, 78533.751704, 78542.922472, 78552.093344, 78561.264319, 78570.435399,
+   78579.606583, 78588.777870, 78597.949262, 78607.120757, 78616.292357, 78625.464060, 78634.635868, 78643.807779,
+   78652.979794, 78662.151914, 78671.324137, 78680.496464, 78689.668894, 78698.841429, 78708.014068, 78717.186810,
+   78726.359656, 78735.532606, 78744.705660, 78753.878817, 78763.052079, 78772.225444, 78781.398913, 78790.572485,
+   78799.746162, 78808.919942, 78818.093826, 78827.267813, 78836.441905, 78845.616100, 78854.790398, 78863.964800,
+   78873.139306, 78882.313916, 78891.488629, 78900.663446, 78909.838366, 78919.013390, 78928.188518, 78937.363749,
+   78946.539084, 78955.714522, 78964.890064, 78974.065710, 78983.241458, 78992.417311, 79001.593267, 79010.769326,
+   79019.945489, 79029.121756, 79038.298125, 79047.474599, 79056.651175, 79065.827856, 79075.004639, 79084.181526,
+   79093.358517, 79102.535610, 79111.712808, 79120.890108, 79130.067512, 79139.245019, 79148.422630, 79157.600344,
+   79166.778161, 79175.956081, 79185.134105, 79194.312232, 79203.490462, 79212.668796, 79221.847233, 79231.025773,
+   79240.204416, 79249.383163, 79258.562012, 79267.740965, 79276.920021, 79286.099181, 79295.278443, 79304.457809,
+   79313.637277, 79322.816849, 79331.996524, 79341.176302, 79350.356183, 79359.536168, 79368.716255, 79377.896445,
+   79387.076739, 79396.257135, 79405.437635, 79414.618237, 79423.798943, 79432.979751, 79442.160663, 79451.341678,
+   79460.522795, 79469.704016, 79478.885339, 79488.066765, 79497.248295, 79506.429927, 79515.611662, 79524.793500,
+   79533.975441, 79543.157485, 79552.339631, 79561.521881, 79570.704233, 79579.886688, 79589.069246, 79598.251907,
+   79607.434671, 79616.617537, 79625.800506, 79634.983578, 79644.166753, 79653.350030, 79662.533410, 79671.716893,
+   79680.900479, 79690.084167, 79699.267958, 79708.451852, 79717.635849, 79726.819948, 79736.004149, 79745.188454,
+   79754.372861, 79763.557370, 79772.741982, 79781.926697, 79791.111515, 79800.296435, 79809.481457, 79818.666582,
+   79827.851810, 79837.037140, 79846.222573, 79855.408108, 79864.593746, 79873.779486, 79882.965329, 79892.151274,
+   79901.337322, 79910.523472, 79919.709725, 79928.896080, 79938.082537, 79947.269097, 79956.455759, 79965.642524,
+   79974.829391, 79984.016360, 79993.203432, 80002.390606, 80011.577882, 80020.765261, 80029.952742, 80039.140326,
+   80048.328011, 80057.515799, 80066.703690, 80075.891682, 80085.079777, 80094.267974, 80103.456273, 80112.644675,
+   80121.833178, 80131.021784, 80140.210492, 80149.399302, 80158.588215, 80167.777229, 80176.966346, 80186.155565,
+   80195.344886, 80204.534309, 80213.723834, 80222.913462, 80232.103191, 80241.293023, 80250.482956, 80259.672992,
+   80268.863130, 80278.053369, 80287.243711, 80296.434155, 80305.624700, 80314.815348, 80324.006098, 80333.196950,
+   80342.387903, 80351.578959, 80360.770116, 80369.961376, 80379.152737, 80388.344201, 80397.535766, 80406.727433,
+   80415.919202, 80425.111073, 80434.303045, 80443.495120, 80452.687296, 80461.879575, 80471.071955, 80480.264437,
+   80489.457020, 80498.649706, 80507.842493, 80517.035382, 80526.228373, 80535.421465, 80544.614659, 80553.807955,
+   80563.001353, 80572.194852, 80581.388453, 80590.582156, 80599.775960, 80608.969866, 80618.163874, 80627.357984,
+   80636.552195, 80645.746507, 80654.940921, 80664.135437, 80673.330055, 80682.524774, 80691.719594, 80700.914516,
+   80710.109540, 80719.304665, 80728.499892, 80737.695220, 80746.890650, 80756.086181, 80765.281814, 80774.477548,
+   80783.673384, 80792.869321, 80802.065360, 80811.261500, 80820.457741, 80829.654084, 80838.850528, 80848.047074,
+   80857.243721, 80866.440469, 80875.637319, 80884.834270, 80894.031323, 80903.228476, 80912.425732, 80921.623088,
+   80930.820546, 80940.018105, 80949.215765, 80958.413527, 80967.611390, 80976.809354, 80986.007419, 80995.205586,
+   81004.403853, 81013.602222, 81022.800693, 81031.999264, 81041.197937, 81050.396710, 81059.595585, 81068.794561,
+   81077.993638, 81087.192817, 81096.392096, 81105.591477, 81114.790958, 81123.990541, 81133.190225, 81142.390010,
+   81151.589896, 81160.789883, 81169.989971, 81179.190160, 81188.390450, 81197.590841, 81206.791333, 81215.991926,
+   81225.192620, 81234.393415, 81243.594311, 81252.795307, 81261.996405, 81271.197604, 81280.398904, 81289.600304,
+   81298.801805, 81308.003408, 81317.205111, 81326.406915, 81335.608820, 81344.810826, 81354.012932, 81363.215140,
+   81372.417448, 81381.619857, 81390.822367, 81400.024977, 81409.227689, 81418.430501, 81427.633413, 81436.836427,
+   81446.039541, 81455.242756, 81464.446072, 81473.649489, 81482.853006, 81492.056624, 81501.260342, 81510.464161,
+   81519.668081, 81528.872102, 81538.076223, 81547.280444, 81556.484767, 81565.689189, 81574.893713, 81584.098337,
+   81593.303062, 81602.507887, 81611.712813, 81620.917839, 81630.122966, 81639.328193, 81648.533521, 81657.738949,
+   81666.944478, 81676.150107, 81685.355837, 81694.561667, 81703.767598, 81712.973629, 81722.179761, 81731.385992,
+   81740.592325, 81749.798758, 81759.005291, 81768.211924, 81777.418658, 81786.625492, 81795.832427, 81805.039462,
+   81814.246597, 81823.453833, 81832.661168, 81841.868605, 81851.076141, 81860.283778, 81869.491515, 81878.699352,
+   81887.907290, 81897.115327, 81906.323465, 81915.531703, 81924.740042, 81933.948480, 81943.157019, 81952.365658,
+   81961.574397, 81970.783236, 81979.992176, 81989.201215, 81998.410355, 82007.619595, 82016.828935, 82026.038374,
+   82035.247915, 82044.457555, 82053.667295, 82062.877135, 82072.087075, 82081.297116, 82090.507256, 82099.717496,
+   82108.927837
+  };
+
+/* Nat log values for 0.1, 0.2, 0.3, etc. */
 /* Used instead of repeatedly calculating them. */
-double log_win10[] = 
+double log_win10[] =
 {
    0.0, -2.30258509, -1.60943791, -1.203982804, -0.91629073, -0.6931478, -0.510825623, -0.356674944,
    -0.22314355, -0.105360515, 0.0
-}; 
+};
 
 
 
@@ -1346,7 +1343,7 @@ typedef struct SSequence
    Boolean punctuation;        /**< FIXME: always FALSE, never set to TRUE? */
    Int4* composition;          /**< totals number of each type of residue */
    Int4* state;                /**< "state vector as described on pg. 151 of Wootton and Federhen
-                                  (Comput. Chem. 17, 149 (1993)).  Tracks number of each residue, 
+                                  (Comput. Chem. 17, 149 (1993)).  Tracks number of each residue,
                                   like composition, but without gaps in array. */
    double entropy;             /**< entropy of what this array refers to. */
 } SSequence;
@@ -1360,7 +1357,7 @@ typedef struct SSeg
   } SSeg;
 
 /** Initializes SSequence structure */
-static SSequence* 
+static SSequence*
 s_SSequenceNew(void)
 {
    SSequence* seq;
@@ -1388,7 +1385,7 @@ s_SSequenceNew(void)
 /** Frees the Alpha structure and underlying structures.
  * @param palpha the object to be freed [in]
  */
-static void 
+static void
 s_AlphaFree (Alpha* palpha)
 
   {
@@ -1406,7 +1403,7 @@ s_AlphaFree (Alpha* palpha)
 /** Frees the SSequence structure and the underlying structure
  * @param seq the object to be freed [in]
  */
-static void 
+static void
 s_SSequenceFree(SSequence* seq)
 {
    if (seq==NULL) return;
@@ -1424,7 +1421,7 @@ s_SSequenceFree(SSequence* seq)
 /** Frees the SSeg structure
  * @param seg the object to be freed [in]
  */
-static void 
+static void
 s_SegFree(SSeg* seg)
 {
    SSeg* nextseg;
@@ -1445,7 +1442,7 @@ s_SegFree(SSeg* seg)
  * @param win SSequence structure for a piece of a sequence [in]
  * @return TRUE if dash is found in the sequence, otherwise FALSE [in]
  */
-static Boolean 
+static Boolean
 s_HasDash(SSequence* win)
 {
 	char	*seq, *seqmax;
@@ -1463,7 +1460,7 @@ s_HasDash(SSequence* win)
 /*------------------------------------------------------------(state_cmp)---*/
 
 /** State comparison function */
-static int 
+static int
 s_StateCmp(const void* s1, const void* s2)
 {
 	int *np1, *np2;
@@ -1476,10 +1473,10 @@ s_StateCmp(const void* s1, const void* s2)
 
 /*---------------------------------------------------------------(compon)---*/
 
-/** Calculates sequence composition array values. 
+/** Calculates sequence composition array values.
  * @param win the object to be analyzed [in]
  */
-static void 
+static void
 s_CompOn(SSequence* win)
 
 {
@@ -1503,7 +1500,7 @@ s_CompOn(SSequence* win)
 		letter = *seq++;
 		if (!alphaflag[letter])
 			comp[alphaindex[letter]]++;
-                else 
+                else
                         win->bogus++;
 	}
 
@@ -1512,10 +1509,10 @@ s_CompOn(SSequence* win)
 
 /*--------------------------------------------------------------(stateon)---*/
 
-/** Calculates state array values 
+/** Calculates state array values
  * @param win the object to be analyzed [in]
  */
-static void 
+static void
 s_StateOn(SSequence* win)
 
 {
@@ -1551,7 +1548,7 @@ s_StateOn(SSequence* win)
  * @param length Window length in parent [in]
  * @return Pointer to the resulting SSequence structure.
  */
-static SSequence* 
+static SSequence*
 s_OpenWin(SSequence* parent, Int4 start, Int4 length)
 {
    SSequence* win;
@@ -1588,11 +1585,11 @@ s_OpenWin(SSequence* parent, Int4 start, Int4 length)
 
 /*--------------------------------------------------------------(s_Entropy)---*/
 
-/** Calculates entropy of an integer array 
+/** Calculates entropy of an integer array
  * @param sv array to be analyzed [in]
  * @return the entropy
  */
-static double 
+static double
 s_Entropy(Int4* sv)
 {
    double ent;
@@ -1612,7 +1609,7 @@ s_Entropy(Int4* sv)
      	{
       		ent += ((double)sv[i])*log_win10[sv[i]]/NCBIMATH_LN2;
      	}
-	
+
    }
    else
    {
@@ -1636,7 +1633,7 @@ s_Entropy(Int4* sv)
  * @param sv the array to be examined and decremented [in|out]
  * @param class criteria for decrementing an element [in]
  */
-static void 
+static void
 s_DecrementSV(Int4* sv, Int4 class)
 
 {
@@ -1654,7 +1651,7 @@ s_DecrementSV(Int4* sv, Int4 class)
  * @param sv the array to be examined and incremented [in|out]
  * @param class criteria for incrementing an element [in]
  */
-static void 
+static void
 s_IncrementSV(Int4* sv, Int4 class)
 
 {
@@ -1672,48 +1669,53 @@ s_IncrementSV(Int4* sv, Int4 class)
  * @return FALSE if nothing done, TRUE otherwise
  */
 
-static Boolean 
+static Boolean
 s_ShiftWin1(SSequence* win)
 {
-	Int4 j, length;
-	Int4* comp;
-        Int4* alphaindex;
-        unsigned char* alphaflag;
+    Uint4 j, length;
+    Int4* comp;
+    Int4* alphaindex;
+    unsigned char* alphaflag;
 
-	length = win->length;
-	comp = win->composition;
-        alphaindex = win->palpha->alphaindex;
-        alphaflag = win->palpha->alphaflag;
+    length = (Uint4) win->length;
+    comp = win->composition;
+    alphaindex = win->palpha->alphaindex;
+    alphaflag = win->palpha->alphaflag;
 
-	if ((++win->start + length) > win->parent->length) {
-		--win->start;
-		return FALSE;
-	}
+    if ((Uint1) win->seq[length] == FENCE_SENTRY) {
+        return FALSE;
+    }
+    if ((++win->start + length) > win->parent->length) {
+        --win->start;
+        return FALSE;
+    }
+
+    j = (Uint1) win->seq[0];        /* prevent sign-extension */
 
-	if (!alphaflag[j = win->seq[0]])
-		s_DecrementSV(win->state, comp[alphaindex[j]]--);
-        else win->bogus--;
+    if (!alphaflag[j])
+        s_DecrementSV(win->state, comp[alphaindex[j]]--);
+    else win->bogus--;
 
-	j = win->seq[length];
-	++win->seq;
+    j = (Uint1) win->seq[length];   /* prevent sign-extension */
+    ++win->seq;
 
-	if (!alphaflag[j])
-		s_IncrementSV(win->state, comp[alphaindex[j]]++);
-        else win->bogus++;
+    if (!alphaflag[j])
+        s_IncrementSV(win->state, comp[alphaindex[j]]++);
+    else win->bogus++;
 
-	if (win->entropy > -2.)
-		win->entropy = s_Entropy(win->state);
+    if (win->entropy > -2.)
+        win->entropy = s_Entropy(win->state);
 
-	return TRUE;
+    return TRUE;
 }
 
 /*-------------------------------------------------------------(closewin)---*/
 
-/** Frees the SSequence structure corresponding to a sequence window 
+/** Frees the SSequence structure corresponding to a sequence window
  * Does not free palpha like s_SSequenceFree (two functions needed?).
  * @param win object to be freed
  */
-static void 
+static void
 s_CloseWin(SSequence* win)
 {
    if (win==NULL) return;
@@ -1727,10 +1729,10 @@ s_CloseWin(SSequence* win)
 
 /*----------------------------------------------------------------(enton)---*/
 
-/** Calculates entropy of a sequence window 
+/** Calculates entropy of a sequence window
  * @param win object to be analyzed [in]
  */
-static void 
+static void
 s_EntropyOn(SSequence* win)
 
   {
@@ -1742,13 +1744,13 @@ s_EntropyOn(SSequence* win)
   }
 
 /** Calculates entropy for a given sequence and window
- * 
+ *
  * @param seq Sequence to examine [in]
  * @param window amount of sequence to examine at once [in]
  * @param maxbogus limit on non-allowed (e.g., X) characters [in]
  * @return calculated entropy
  */
-static double* 
+static double*
 s_SeqEntropy(SSequence* seq, Int4 window, Int4 maxbogus)
 {
    SSequence* win;
@@ -1861,8 +1863,8 @@ s_lnfact(Int4 n) {
  * @param sv state vector [in]
  * @param window_length length of window being examined
  * @return K2
- */ 
-static double 
+ */
+static double
 s_LnPerm(const Int4* sv, Int4 window_length)
 
   {
@@ -1871,7 +1873,7 @@ s_LnPerm(const Int4* sv, Int4 window_length)
 
    ans = s_lnfact(window_length);
 
-   for (i=0; sv[i]!=0; i++) 
+   for (i=0; sv[i]!=0; i++)
      {
       ans -= s_lnfact(sv[i]);
      }
@@ -1887,7 +1889,7 @@ s_LnPerm(const Int4* sv, Int4 window_length)
  * @param alphasize total letters in alphabet [in]
  * @return number of compositions as described above
  */
-static double 
+static double
 s_LnAss(const Int4* sv, Int4 alphasize)
 
 {
@@ -1931,14 +1933,14 @@ s_LnAss(const Int4* sv, Int4 alphasize)
 }
 
 
-/** This function calculates the natural log of the value P sub 0 from 
+/** This function calculates the natural log of the value P sub 0 from
  * equation 3 of Wootton and Federhen (Methods Enzymol. 1996;266:554-71).
  * @param sv state vector [in]
  * @param total window length of area examined [in]
  * @param palpha structure for alphabet information [in]
  * @return log of P sub 0 as mentioned above
  */
-static double 
+static double
 s_GetProb(const Int4* sv, Int4 total, const Alpha* palpha)
 
   {
@@ -1968,7 +1970,7 @@ s_GetProb(const Int4* sv, Int4 total, const Alpha* palpha)
  * @param rightend right-most end of sequence [in|out]
  * @param sparamsp the SEG parameters [in]
  */
-static Int2 
+static Int2
 s_Trim(SSequence* seq, Int4* leftend, Int4* rightend, const SegParameters* sparamsp)
 
 {
@@ -1983,7 +1985,7 @@ s_Trim(SSequence* seq, Int4* leftend, Int4* rightend, const SegParameters* spara
    rend = seq->length - 1;
    minlen = 1;
    maxtrim = sparamsp->maxtrim;
-   if ((seq->length-maxtrim)>minlen) 
+   if ((seq->length-maxtrim)>minlen)
         minlen = seq->length-maxtrim;
 
    minprob = 1.;
@@ -2015,16 +2017,16 @@ s_Trim(SSequence* seq, Int4* leftend, Int4* rightend, const SegParameters* spara
    return status;
 }
 
-/** High-level function to perform calculations to find 
- * low-complexity segments.  Thi function calls itself 
+/** High-level function to perform calculations to find
+ * low-complexity segments.  Thi function calls itself
  * recursively
- * 
+ *
  * @param seq sequence to be checked [in]
  * @param sparamsp seg parameters [in]
  * @param segs low-complexity segments found [out]
  * @param offset offset of sequence passed in [in]
  */
-static Int2 
+static Int2
 s_SegSeq(SSequence* seq, SegParameters* sparamsp, SSeg **segs,
                    Int4 offset)
 {
@@ -2047,10 +2049,10 @@ s_SegSeq(SSequence* seq, SegParameters* sparamsp, SSeg **segs,
    hicut = sparamsp->hicut;
    downset = (window+1)/2 - 1;
    upset = window - downset;
-      
+
    H = s_SeqEntropy(seq, window, sparamsp->maxbogus);
 
-   if (H == NULL) 
+   if (H == NULL)
       return status;
 
    first = downset;
@@ -2114,12 +2116,12 @@ s_SegSeq(SSequence* seq, SegParameters* sparamsp, SSeg **segs,
 }
 
 /*------------------------------------------------------------(mergesegs)---*/
-/** merge together overlapping segments, 
+/** merge together overlapping segments,
  * hilenmin also does something, but we need to ask Scott Federhen what?
  * @param seq information about sequence [in]
  * @param segs segment information [in]
 */
-static void 
+static void
 s_MergeSegs(SSequence* seq, SSeg* segs)
 {
    SSeg* seg,* nextseg;
@@ -2129,7 +2131,7 @@ s_MergeSegs(SSequence* seq, SSeg* segs)
 
    if (segs==NULL) return;
 
-   if (seq->length -1 - segs->end < hilenmin) 
+   if (seq->length -1 - segs->end < hilenmin)
        segs->end = seq->length -1;
 
    seg = segs;
@@ -2159,7 +2161,7 @@ s_MergeSegs(SSequence* seq, SSeg* segs)
  * @param seg_locs the new BLAST specific representation [out]
  * @return 0 on success, -1 if memory allocation failed.
  */
-static Int2 
+static Int2
 s_SegsToBlastSeqLoc(SSeg* segs, Int4 offset, BlastSeqLoc** seg_locs)
 {
    for ( ; segs; segs = segs->next) {
@@ -2170,7 +2172,7 @@ s_SegsToBlastSeqLoc(SSeg* segs, Int4 offset, BlastSeqLoc** seg_locs)
       loc->next = *seg_locs;
       *seg_locs = loc;
    }
-   /* If not all segs have been processed, it means that memory allocation 
+   /* If not all segs have been processed, it means that memory allocation
       failed, hence return error status. */
    if (segs) {
        *seg_locs = BlastSeqLocFree(*seg_locs);
@@ -2180,10 +2182,10 @@ s_SegsToBlastSeqLoc(SSeg* segs, Int4 offset, BlastSeqLoc** seg_locs)
    return 0;
 }
 
-/** Creats the Alphabet structure for standard protein alphabet. 
+/** Creats the Alphabet structure for standard protein alphabet.
  * @return pointer to the alphabet structure.
  */
-static Alpha* 
+static Alpha*
 s_AA20alphaStd (void)
 {
    Alpha* palpha;
@@ -2205,8 +2207,8 @@ s_AA20alphaStd (void)
    for (c=0, i=0; c<kCharSet; c++)
      {
         if (c == 1 || (c >= 3 && c <= 20) || c == 22) {
-           alphaflag[c] = FALSE; 
-           alphaindex[c] = i; 
+           alphaflag[c] = FALSE;
+           alphaindex[c] = i;
            ++i;
         } else {
            alphaflag[c] = TRUE; alphaindex[c] = 20;
@@ -2238,10 +2240,10 @@ SegParameters* SegParametersNewAa (void)
    return (sparamsp);
 }
 
-/** Checks SeqParameter struct for proteins, sets default values if not set. 
+/** Checks SeqParameter struct for proteins, sets default values if not set.
  * @param sparamsp parameters to check [in]
  */
-static void 
+static void
 s_SegParametersCheck (SegParameters* sparamsp)
 {
    if (!sparamsp) return;
@@ -2269,7 +2271,7 @@ s_SegParametersCheck (SegParameters* sparamsp)
 /* Comments in blast_seg.h */
 void SegParametersFree(SegParameters* sparamsp)
 {
-   if (!sparamsp) 
+   if (!sparamsp)
       return;
    sfree(sparamsp);
    return;
@@ -2283,9 +2285,9 @@ Int2 SeqBufferSeg (Uint1* sequence, Int4 length, Int4 offset,
    SSeg* segs;
    Boolean params_allocated = FALSE;
    Int2 status = 0;
-   
+
    s_SegParametersCheck (sparamsp);
-   
+
    /* check seg parameters */
    if (!sparamsp) {
       params_allocated = TRUE;
@@ -2296,16 +2298,16 @@ Int2 SeqBufferSeg (Uint1* sequence, Int4 length, Int4 offset,
    }
 
    /* make an old-style genwin sequence window object */
-    
+
    seqwin = s_SSequenceNew();
    seqwin->seq = (char*) sequence;
    seqwin->length = length;
    seqwin->palpha = s_AA20alphaStd();
 
    *seg_locs = NULL;
-   
+
    /* seg the sequence */
-   
+
    segs = (SSeg*) NULL;
    status = s_SegSeq (seqwin, sparamsp, &segs, 0);
    if (status < 0)
@@ -2320,8 +2322,8 @@ Int2 SeqBufferSeg (Uint1* sequence, Int4 length, Int4 offset,
       s_MergeSegs(seqwin, segs);
 
    /* convert segs to seqlocs */
-   s_SegsToBlastSeqLoc(segs, offset, seg_locs);   
-   
+   s_SegsToBlastSeqLoc(segs, offset, seg_locs);
+
    /* clean up & return */
    seqwin->seq = NULL;
    s_SSequenceFree (seqwin);
@@ -2329,7 +2331,7 @@ Int2 SeqBufferSeg (Uint1* sequence, Int4 length, Int4 offset,
 
    if(params_allocated)
        SegParametersFree(sparamsp);
-   
+
    return 0;
 }
 
diff --git a/c++/src/algo/blast/core/blast_seqsrc.c b/c++/src/algo/blast/core/blast_seqsrc.c
index 0ae743e..87677c0 100644
--- a/c++/src/algo/blast/core/blast_seqsrc.c
+++ b/c++/src/algo/blast/core/blast_seqsrc.c
@@ -1,4 +1,4 @@
-/*  $Id: blast_seqsrc.c 461918 2015-03-13 16:38:36Z vasilche $
+/*  $Id: blast_seqsrc.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -33,13 +33,6 @@
  * low level details of the implementation of the BlastSeqSrc framework.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_seqsrc.c 461918 2015-03-13 16:38:36Z vasilche $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-#endif
-
 #include <algo/blast/core/blast_seqsrc.h>
 #include <algo/blast/core/blast_seqsrc_impl.h>
 
diff --git a/c++/src/algo/blast/core/blast_setup.c b/c++/src/algo/blast/core/blast_setup.c
index 4b072cf..f9ff394 100644
--- a/c++/src/algo/blast/core/blast_setup.c
+++ b/c++/src/algo/blast/core/blast_setup.c
@@ -1,4 +1,4 @@
-/* $Id: blast_setup.c 496012 2016-03-23 11:30:57Z ivanov $
+/* $Id: blast_setup.c 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  */
 
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_setup.c 496012 2016-03-23 11:30:57Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_setup.h>
 #include <algo/blast/core/blast_util.h>
 #include <algo/blast/core/blast_filter.h>
@@ -118,7 +113,7 @@ Blast_ScoreBlkKbpGappedCalc(BlastScoreBlk * sbp,
 
         /* For right now, copy the contents from kbp_gap_std to 
          * kbp_gap_psi (as in old code - BLASTSetUpSearchInternalByLoc) */
-        if (program != eBlastTypeBlastn) {
+        if (program != eBlastTypeBlastn && program != eBlastTypeMapping) {
             sbp->kbp_gap_psi[index] = Blast_KarlinBlkNew();
             Blast_KarlinBlkCopy(sbp->kbp_gap_psi[index], 
                                 sbp->kbp_gap_std[index]);
@@ -348,7 +343,8 @@ Blast_ScoreBlkMatrixInit(EBlastProgramType program_number,
        currently only turned on in RMBlastN -RMH-  */
     sbp->matrix_only_scoring = FALSE;
 
-    if (program_number == eBlastTypeBlastn) {
+    if (program_number == eBlastTypeBlastn ||
+        program_number == eBlastTypeMapping) {
 
         BLAST_ScoreSetAmbigRes(sbp, 'N');
         BLAST_ScoreSetAmbigRes(sbp, '-');
@@ -396,6 +392,66 @@ Blast_ScoreBlkMatrixInit(EBlastProgramType program_number,
     return status;
 }
 
+static Int2
+s_JumperScoreBlkFill(BlastScoreBlk* sbp, const BlastQueryInfo* query_info,
+                     Blast_Message** error_return)
+{
+    Int4 context;
+    Blast_KarlinBlk* kbp;
+    Int2 status;
+
+    /* Create ungapped block */
+    status = Blast_ScoreBlkKbpIdealCalc(sbp);
+    if (status) {
+        return status;
+    }
+
+    for (context = query_info->first_context;
+         context <= query_info->last_context; ++context) {
+
+        if (!query_info->contexts[context].is_valid) {
+            continue;
+        }
+
+        sbp->sfp[context] = NULL;
+        sbp->kbp_std[context] = Blast_KarlinBlkNew();
+        Blast_KarlinBlkCopy(sbp->kbp_std[context], sbp->kbp_ideal);
+    }
+    sbp->kbp = sbp->kbp_std;
+
+    /* Create gapped block */
+    context = query_info->first_context;
+    while (!query_info->contexts[context].is_valid) {
+        context++;
+    }
+
+    sbp->kbp_gap_std[context] = kbp = Blast_KarlinBlkNew();
+    status = Blast_KarlinBlkNuclGappedCalc(kbp, BLAST_GAP_OPEN_MEGABLAST,
+                                           BLAST_GAP_EXTN_MEGABLAST,
+                                           BLAST_REWARD,
+                                           BLAST_PENALTY,
+                                           sbp->kbp_std[context],
+                                           &(sbp->round_down),
+                                           error_return);
+    if (status){
+        return status;
+    }
+
+    for (++context;context <= query_info->last_context; ++context) {
+
+        if (!query_info->contexts[context].is_valid) {
+            continue;
+        }
+
+        sbp->kbp_gap_std[context] = Blast_KarlinBlkNew();
+        Blast_KarlinBlkCopy(sbp->kbp_gap_std[context], kbp);
+    }
+    sbp->kbp_gap = sbp->kbp_gap_std;
+
+    return status;
+}
+
+
 Int2 
 BlastSetup_ScoreBlkInit(BLAST_SequenceBlk* query_blk, 
                         const BlastQueryInfo* query_info, 
@@ -413,7 +469,9 @@ BlastSetup_ScoreBlkInit(BLAST_SequenceBlk* query_blk,
     if (sbpp == NULL)
        return 1;
 
-    if (program_number == eBlastTypeBlastn) {
+    if (program_number == eBlastTypeBlastn ||
+        program_number == eBlastTypeMapping) {
+
        sbp = BlastScoreBlkNew(BLASTNA_SEQ_CODE, query_info->last_context + 1);
        /* disable new FSC rules for nucleotide case for now */
        if (sbp && sbp->gbp) {
@@ -446,6 +504,12 @@ BlastSetup_ScoreBlkInit(BLAST_SequenceBlk* query_blk,
     /* Fills in block for gapped blast. */
     if (Blast_ProgramIsPhiBlast(program_number)) {
        status = s_PHIScoreBlkFill(sbp, scoring_options, blast_message, get_path);
+    } else if (Blast_ProgramIsMapping(program_number)) {
+        /* Create fake score blocks for each query without computing base
+           frequencies. We do not compute e-values for mapping, so the
+           KA statistics are not needed, but the data structures are checked
+           and used in BLAST engine. */
+        status = s_JumperScoreBlkFill(sbp, query_info, blast_message);
     } else {
        status = Blast_ScoreBlkKbpUngappedCalc(program_number, sbp, query_blk->sequence, 
                query_info, blast_message);
@@ -675,6 +739,17 @@ Int2 BLAST_CalcEffLengths (EBlastProgramType program_number,
    else
       db_num_seqs = eff_len_params->real_num_seqs;
    
+   /* Mapping does not need length correction */
+   if (Blast_ProgramIsMapping(program_number)) {
+        for (index = query_info->first_context;
+           index <= query_info->last_context;
+           index++) {
+           query_info->contexts[index].eff_searchsp = db_length;
+        }
+
+        return 0;
+   }
+
    /* PHI BLAST search space calculation is different. */
    if (Blast_ProgramIsPhiBlast(program_number))
    {
diff --git a/c++/src/algo/blast/core/blast_stat.c b/c++/src/algo/blast/core/blast_stat.c
index 771ca7a..af37711 100644
--- a/c++/src/algo/blast/core/blast_stat.c
+++ b/c++/src/algo/blast/core/blast_stat.c
@@ -1,4 +1,4 @@
-/* $Id: blast_stat.c 500367 2016-05-04 12:06:01Z ivanov $
+/* $Id: blast_stat.c 505944 2016-06-30 12:29:20Z madden $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -48,11 +48,6 @@
  *
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_stat.c 500367 2016-05-04 12:06:01Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_stat.h>
 #include <algo/blast/core/ncbi_math.h>
 #include "boost_erf.h"
@@ -1431,7 +1426,6 @@ BlastScoreBlkProteinMatrixRead(BlastScoreBlk* sbp, FILE *fp)
         if ((lp = (char*)strtok(buf, kTokenStr)) == NULL)
             continue;
         ch = *lp;
-        cp = (char*) lp;
         if ((cp = strtok(NULL, kTokenStr)) == NULL) {
             return 2;
         }
diff --git a/c++/src/algo/blast/core/blast_sw.c b/c++/src/algo/blast/core/blast_sw.c
index 69e80bf..0fde35b 100644
--- a/c++/src/algo/blast/core/blast_sw.c
+++ b/c++/src/algo/blast/core/blast_sw.c
@@ -1,4 +1,4 @@
-/* $Id: blast_sw.c 148871 2009-01-05 16:51:12Z camacho $
+/* $Id: blast_sw.c 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                     PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  * @sa blast_sw.h
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-   "$Id: blast_sw.c 148871 2009-01-05 16:51:12Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_sw.h>
 #include <algo/blast/core/blast_util.h> /* for NCBI2NA_UNPACK_BASE */
 
@@ -656,7 +651,8 @@ Int2 BLAST_SmithWatermanGetGappedScore (EBlastProgramType program_number,
       return 1;
 
    is_prot = (program_number != eBlastTypeBlastn &&
-              program_number != eBlastTypePhiBlastn);
+              program_number != eBlastTypePhiBlastn &&
+              program_number != eBlastTypeMapping);
 
    if (Blast_ProgramIsRpsBlast(program_number)) {
       Int4 rps_context = subject->oid;
diff --git a/c++/src/algo/blast/core/blast_traceback.c b/c++/src/algo/blast/core/blast_traceback.c
index 2c7299e..ed75f6e 100644
--- a/c++/src/algo/blast/core/blast_traceback.c
+++ b/c++/src/algo/blast/core/blast_traceback.c
@@ -1,4 +1,4 @@
-/* $Id: blast_traceback.c 500444 2016-05-04 17:46:06Z ivanov $
+/* $Id: blast_traceback.c 511802 2016-08-24 17:30:32Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -48,11 +48,6 @@
  * </pre>
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_traceback.c 500444 2016-05-04 17:46:06Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_traceback.h>
 #include <algo/blast/core/blast_util.h>
 #include <algo/blast/core/blast_encoding.h>
@@ -454,7 +449,8 @@ Blast_TracebackFromHSPList(EBlastProgramType program_number,
                   optimization for OOF */
                gap_align->subject_start = 0;
                gap_align->query_start = 0;
-            } else if (program_number == eBlastTypeBlastn) {
+            } else if (program_number == eBlastTypeBlastn ||
+                       program_number == eBlastTypeMapping) {
                /* Find the optimal starting offset */
                BlastGetStartForGappedAlignmentNucl(query, subject, hsp);
             }
@@ -1170,7 +1166,19 @@ Int2 s_RPSComputeTraceback(EBlastProgramType program_number,
          (if not a translated search) */
 
       if (program_number == eBlastTypeRpsTblastn) {
-         sbp->psi_matrix->pssm->data = rpsblast_pssms + db_seq_start;
+         if (ext_params->options->compositionBasedStats > 0) {
+         const double* karlin_k = rps_info->aux_info.karlin_k;
+
+        	 sbp->psi_matrix->pssm->data = (Int4**)_PSIAllocateMatrix(
+                                                        seq_arg.seq->length,
+                                                        BLASTAA_SIZE,
+                                                        sizeof(Int4));
+             sbp->kbp_gap[0]->K = RPS_K_MULT * karlin_k[hsp_list->oid];
+             sbp->kbp_gap[0]->logK = log(RPS_K_MULT * karlin_k[hsp_list->oid]);
+         }
+         else {
+        	 sbp->psi_matrix->pssm->data = rpsblast_pssms + db_seq_start;
+         }
       } else {
          const double* karlin_k = rps_info->aux_info.karlin_k;
 
@@ -1247,7 +1255,10 @@ Int2 s_RPSComputeTraceback(EBlastProgramType program_number,
       if (ext_params->options->compositionBasedStats > 0) {
          _PSIDeallocateMatrix((void**)sbp->psi_matrix->freq_ratios,
                               seq_arg.seq->length);
-
+      	 if (program_number == eBlastTypeRpsTblastn) {
+         	_PSIDeallocateMatrix((void**)sbp->psi_matrix->pssm->data,
+                              seq_arg.seq->length);
+      	}
       }
       if (hsp_list->hspcnt == 0) {
          hsp_list = Blast_HSPListFree(hsp_list);
diff --git a/c++/src/algo/blast/core/blast_traceback_mt_priv.c b/c++/src/algo/blast/core/blast_traceback_mt_priv.c
index 571dec1..bca2ad1 100644
--- a/c++/src/algo/blast/core/blast_traceback_mt_priv.c
+++ b/c++/src/algo/blast/core/blast_traceback_mt_priv.c
@@ -1,4 +1,4 @@
-/* $Id: blast_traceback_mt_priv.c 496008 2016-03-23 11:29:15Z ivanov $
+/* $Id: blast_traceback_mt_priv.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
  *  Private interface to support the multi-threaded traceback
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_traceback_mt_priv.c 496008 2016-03-23 11:29:15Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_setup.h>
 #include "blast_traceback_mt_priv.h"
 #include "blast_hspstream_mt_utils.h"
diff --git a/c++/src/algo/blast/core/blast_tune.c b/c++/src/algo/blast/core/blast_tune.c
index 7ea5af5..af50ab5 100644
--- a/c++/src/algo/blast/core/blast_tune.c
+++ b/c++/src/algo/blast/core/blast_tune.c
@@ -1,4 +1,4 @@
-/* $Id: blast_tune.c 94064 2006-11-21 17:19:42Z papadopo $
+/* $Id: blast_tune.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -33,11 +33,6 @@
  * percent identity.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blast_tune.c 94064 2006-11-21 17:19:42Z papadopo $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_util.h>
 #include <algo/blast/core/blast_tune.h>
 
diff --git a/c++/src/algo/blast/core/blast_util.c b/c++/src/algo/blast/core/blast_util.c
index d5027f5..ae7ecd9 100644
--- a/c++/src/algo/blast/core/blast_util.c
+++ b/c++/src/algo/blast/core/blast_util.c
@@ -1,4 +1,4 @@
-/* $Id: blast_util.c 473564 2015-07-21 15:29:04Z madden $
+/* $Id: blast_util.c 516334 2016-10-12 17:30:52Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  */
 
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_util.c 473564 2015-07-21 15:29:04Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_util.h>
 #include <algo/blast/core/blast_filter.h>
 #include <algo/blast/core/blast_stat.h>
@@ -308,6 +303,8 @@ Int2 BlastProgram2Number(const char *program, EBlastProgramType *number)
         *number = eBlastTypePhiBlastn;
     else if (strcasecmp("phiblastp", program) == 0)
         *number = eBlastTypePhiBlastp;
+    else if (strcasecmp("mapper", program) == 0)
+        *number = eBlastTypeMapping;
 
 	return 0;
 }
@@ -352,6 +349,9 @@ Int2 BlastNumber2Program(EBlastProgramType number, char* *program)
         case eBlastTypePhiBlastn:
 			*program = strdup("phiblastn");
 			break;
+        case eBlastTypeMapping:
+            *program = strdup("mapper");
+            break;
         default:
 			*program = strdup("unknown");
 			break;
@@ -811,8 +811,12 @@ Int2 GetReverseNuclSequence(const Uint1* sequence, Int4 length,
    Int4 index;
    /* Conversion table from forward to reverse strand residue in the blastna 
       encoding */
-   Uint1 conversion_table[17] = 
-      { 0, 8, 4, 12, 2, 10, 9, 14, 1, 6, 5, 13, 3, 11, 7, 15 };
+   Uint1 conversion_table[16] = {
+     0,  8, 4, 12,
+     2, 10, 6, 14,
+     1,  9, 5, 13,
+     3, 11, 7, 15
+   };
 
    if (!rev_sequence_ptr)
       return -1;
@@ -836,7 +840,7 @@ Int1 BLAST_ContextToFrame(EBlastProgramType prog_number, Uint4 context_number)
 {
    Int1 frame = INT1_MAX;	/* INT1_MAX is used to indicate error */
 
-   if (prog_number == eBlastTypeBlastn) {
+   if (prog_number == eBlastTypeBlastn || prog_number == eBlastTypeMapping) {
       if (context_number % NUM_STRANDS == 0)
          frame = 1;
       else
@@ -934,6 +938,8 @@ Int2 BLAST_CreateMixedFrameDNATranslation(BLAST_SequenceBlk* query_blk,
 
    /* Allocate 1 extra byte for a final sentinel. */ 
    buffer = (Uint1*) malloc(total_length+1);
+   if (!buffer)
+	return -1;
 
    for (index = 0; index <= query_info->last_context; index += CODON_LENGTH) {
       int i;
@@ -962,7 +968,8 @@ Int2 BLAST_CreateMixedFrameDNATranslation(BLAST_SequenceBlk* query_blk,
       }
    }
    /* Add a sentinel null byte at the end. */
-   *seq = NULLB;
+   if (seq)
+   	*seq = NULLB;
 
    /* The mixed-frame protein sequence buffer will be saved in 
       'sequence_start' */
diff --git a/c++/src/algo/blast/core/boost_erf.c b/c++/src/algo/blast/core/boost_erf.c
index 7ddf0fe..36fae17 100644
--- a/c++/src/algo/blast/core/boost_erf.c
+++ b/c++/src/algo/blast/core/boost_erf.c
@@ -1,4 +1,4 @@
-/*  $Id: boost_erf.c 498724 2016-04-19 13:36:57Z ivanov $
+/*  $Id: boost_erf.c 498248 2016-04-14 15:42:26Z boratyng $
 * ===========================================================================
 *
 * This code is ported from the open source C++ library Boost, for which
diff --git a/c++/src/algo/blast/core/boost_erf.h b/c++/src/algo/blast/core/boost_erf.h
index 3b5f2ed..8dd980b 100644
--- a/c++/src/algo/blast/core/boost_erf.h
+++ b/c++/src/algo/blast/core/boost_erf.h
@@ -1,4 +1,4 @@
-/*  $Id: boost_erf.h 498724 2016-04-19 13:36:57Z ivanov $
+/*  $Id: boost_erf.h 498248 2016-04-14 15:42:26Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/core/gapinfo.c b/c++/src/algo/blast/core/gapinfo.c
index 5f48210..1ed2b0c 100644
--- a/c++/src/algo/blast/core/gapinfo.c
+++ b/c++/src/algo/blast/core/gapinfo.c
@@ -1,4 +1,4 @@
-/* $Id: gapinfo.c 94064 2006-11-21 17:19:42Z papadopo $
+/* $Id: gapinfo.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  */
 
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: gapinfo.c 94064 2006-11-21 17:19:42Z papadopo $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_def.h>
 #include <algo/blast/core/gapinfo.h>
 
diff --git a/c++/src/algo/blast/core/gencode_singleton.c b/c++/src/algo/blast/core/gencode_singleton.c
index 3560fbd..a4a11a3 100644
--- a/c++/src/algo/blast/core/gencode_singleton.c
+++ b/c++/src/algo/blast/core/gencode_singleton.c
@@ -1,4 +1,4 @@
-/*  $Id: gencode_singleton.c 103491 2007-05-04 17:18:18Z kazimird $
+/*  $Id: gencode_singleton.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Implementation of the genetic code singleton
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: gencode_singleton.c 103491 2007-05-04 17:18:18Z kazimird $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/gencode_singleton.h>
 #include "blast_dynarray.h"
 
diff --git a/c++/src/algo/blast/core/greedy_align.c b/c++/src/algo/blast/core/greedy_align.c
index 3ae44a1..7ccace3 100644
--- a/c++/src/algo/blast/core/greedy_align.c
+++ b/c++/src/algo/blast/core/greedy_align.c
@@ -1,4 +1,4 @@
-/* $Id: greedy_align.c 480534 2015-10-01 15:21:48Z madden $
+/* $Id: greedy_align.c 505944 2016-06-30 12:29:20Z madden $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -34,11 +34,6 @@
  * Journal of Computational Biology vol 7 pp 203-214
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: greedy_align.c 480534 2015-10-01 15:21:48Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/greedy_align.h>
 #include <algo/blast/core/ncbi_math.h>
 #include <algo/blast/core/blast_util.h> /* for NCBI2NA_UNPACK_BASE macros */
@@ -690,7 +685,6 @@ Int4 BLAST_GreedyAlign(const Uint1* seq1, Int4 len1,
     /* perform traceback */
 
     d = best_dist; 
-    seq1_index = *seq1_align_len;
     seq2_index = *seq2_align_len; 
 
     /* for all positive distances */
diff --git a/c++/src/algo/blast/core/hspfilter_besthit.c b/c++/src/algo/blast/core/hspfilter_besthit.c
index b1d8951..ddf02ad 100644
--- a/c++/src/algo/blast/core/hspfilter_besthit.c
+++ b/c++/src/algo/blast/core/hspfilter_besthit.c
@@ -1,4 +1,4 @@
-/*  $Id: hspfilter_besthit.c 458578 2015-02-06 15:11:29Z fongah2 $
+/*  $Id: hspfilter_besthit.c 506193 2016-07-05 14:14:58Z madden $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  * a BLAST search, and subsequently return them in sorted order.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: hspfilter_besthit.c 458578 2015-02-06 15:11:29Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 
 #include <algo/blast/core/hspfilter_besthit.h>
 #include <algo/blast/core/blast_util.h>
@@ -70,10 +65,11 @@ typedef struct BlastHSPBestHitData {
  * @param results The HSP results to operate on  [in]
  */ 
 static int 
-s_BlastHSPBestHitInit(void* data, BlastHSPResults* results)
+s_BlastHSPBestHitInit(void* data, void* hsp_results)
 {
    int i;
    BlastHSPBestHitData * bh_data = data;
+   BlastHSPResults* results = (BlastHSPResults*)hsp_results;
    bh_data->best_list = calloc(results->num_queries, sizeof(LinkedHSP_BH *));
    bh_data->num_hsps = calloc(results->num_queries, sizeof(Int4));
    bh_data->max_hsps = calloc(results->num_queries, sizeof(Int4));
@@ -196,10 +192,11 @@ s_ImportFromHitlist(int qid,
  * @param results The HSP results to propagate [in][out]
  */ 
 static int 
-s_BlastHSPBestHitFinal(void* data, BlastHSPResults* results)
+s_BlastHSPBestHitFinal(void* data, void* hsp_results)
 {
    int qid, sid;
    BlastHSPBestHitData *bh_data = data;
+   BlastHSPResults* results = (BlastHSPResults*)hsp_results;
    LinkedHSP_BH **best_list = bh_data->best_list;
    BlastHitList* hitlist;
 
@@ -485,7 +482,8 @@ s_BlastHSPBestHitFree(BlastHSPWriter* writer)
  */
 static
 BlastHSPWriter* 
-s_BlastHSPBestHitNew(void* params, BlastQueryInfo* query_info)
+s_BlastHSPBestHitNew(void* params, BlastQueryInfo* query_info,
+                     BLAST_SequenceBlk* sequence)
 {
    BlastHSPWriter * writer = NULL;
    BlastHSPBestHitData data;
@@ -606,7 +604,7 @@ BlastHSPBestHitParamsNew(const BlastHitSavingOptions* hit_options,
                                    prelim_hitlist_size + 50);
 
     retval = (BlastHSPBestHitParams*) malloc(sizeof(BlastHSPBestHitParams));
-    retval->prelim_hitlist_size = MAX(hit_options->hitlist_size, 10);
+    retval->prelim_hitlist_size = MAX(prelim_hitlist_size, 10);
     retval->hsp_num_max = BlastHspNumMax(gapped_calculation, hit_options);
     retval->program = hit_options->program_number;
     retval->overhang = best_hit_opts->overhang;
diff --git a/c++/src/algo/blast/core/hspfilter_collector.c b/c++/src/algo/blast/core/hspfilter_collector.c
index dc89a52..2180c03 100644
--- a/c++/src/algo/blast/core/hspfilter_collector.c
+++ b/c++/src/algo/blast/core/hspfilter_collector.c
@@ -1,4 +1,4 @@
-/*  $Id: hspfilter_collector.c 443210 2014-08-12 13:55:24Z fongah2 $
+/*  $Id: hspfilter_collector.c 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  * a BLAST search, and subsequently return them in sorted order.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: hspfilter_collector.c 443210 2014-08-12 13:55:24Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 
 #include <algo/blast/core/hspfilter_collector.h>
 #include <algo/blast/core/blast_util.h>
@@ -56,9 +51,10 @@ typedef struct BlastHSPCollectorData {
  * @param results The HSP results to operate on  [in]
  */ 
 static int 
-s_BlastHSPCollectorInit(void* data, BlastHSPResults* results)
+s_BlastHSPCollectorInit(void* data, void* hsp_results)
 {
    BlastHSPCollectorData * col_data = data;
+   BlastHSPResults* results = (BlastHSPResults*)hsp_results;
    /* grab the results as destination to store collected hsps */
    col_data->results = results;
    return 0;
@@ -69,7 +65,7 @@ s_BlastHSPCollectorInit(void* data, BlastHSPResults* results)
  * @param results The HSP results to propagate [in][out]
  */ 
 static int 
-s_BlastHSPCollectorFinal(void* data, BlastHSPResults* results)
+s_BlastHSPCollectorFinal(void* data, void* results)
 {
    BlastHSPCollectorData * col_data = data;
    /* results already stored during run, no action needed */
@@ -296,7 +292,8 @@ s_BlastHSPCollectorFree(BlastHSPWriter* writer)
  */
 static
 BlastHSPWriter* 
-s_BlastHSPCollectorNew(void* params, BlastQueryInfo* query_info)
+s_BlastHSPCollectorNew(void* params, BlastQueryInfo* query_info,
+                       BLAST_SequenceBlk* sequence)
 {
    BlastHSPWriter * writer = NULL;
    BlastHSPCollectorData * data = NULL;
diff --git a/c++/src/algo/blast/core/hspfilter_culling.c b/c++/src/algo/blast/core/hspfilter_culling.c
index 114f930..2912a96 100644
--- a/c++/src/algo/blast/core/hspfilter_culling.c
+++ b/c++/src/algo/blast/core/hspfilter_culling.c
@@ -1,4 +1,4 @@
-/*  $Id: hspfilter_culling.c 429223 2014-03-12 17:13:31Z fongah2 $
+/*  $Id: hspfilter_culling.c 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -39,11 +39,6 @@
  * 10890403.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: hspfilter_culling.c 429223 2014-03-12 17:13:31Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 
 #include <algo/blast/core/hspfilter_culling.h>
 #include <algo/blast/core/hspfilter_collector.h>
@@ -501,7 +496,7 @@ typedef struct BlastHSPCullingData {
  * @param results The HSP results to operate on  [in]
  */ 
 static int 
-s_BlastHSPCullingInit(void* data, BlastHSPResults* results)
+s_BlastHSPCullingInit(void* data, void* results)
 {
     BlastHSPCullingData * cull_data = data;
     cull_data->c_tree = calloc(cull_data->num_contexts, sizeof(CTreeNode *));
@@ -513,10 +508,11 @@ s_BlastHSPCullingInit(void* data, BlastHSPResults* results)
  * @param results The HSP results to propagate [in][out]
  */ 
 static int 
-s_BlastHSPCullingFinal(void* data, BlastHSPResults* results)
+s_BlastHSPCullingFinal(void* data, void* hsp_results)
 {
    int cid, qid, sid, id, new_allocated;
    BlastHSPCullingData* cull_data = data;
+   BlastHSPResults* results = (BlastHSPResults*)hsp_results;
    BlastHSPCullingParams* params = cull_data->params;
    CTreeNode **c_tree = cull_data->c_tree;
    LinkedHSP *cull_list, *p;
@@ -675,7 +671,8 @@ s_BlastHSPCullingFree(BlastHSPWriter* writer)
  */
 static
 BlastHSPWriter* 
-s_BlastHSPCullingNew(void* params, BlastQueryInfo* query_info)
+s_BlastHSPCullingNew(void* params, BlastQueryInfo* query_info,
+                     BLAST_SequenceBlk* sequence)
 {
    BlastHSPWriter * writer = NULL;
    BlastHSPCullingData data;
diff --git a/c++/src/algo/blast/core/hspfilter_mapper.c b/c++/src/algo/blast/core/hspfilter_mapper.c
new file mode 100644
index 0000000..1eacbd3
--- /dev/null
+++ b/c++/src/algo/blast/core/hspfilter_mapper.c
@@ -0,0 +1,4353 @@
+/*  $Id: hspfilter_mapper.c 517510 2016-10-25 17:24:24Z ivanov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  Greg Boratyn
+ *
+ */
+
+/** @file hspfilter_mapper.c
+ * Implementation of the BlastHSPWriter interface to save only the best scoring * chains of HSPs for aligning RNA-Seq sequences to a genome.
+ */
+
+#include <algo/blast/core/hspfilter_mapper.h>
+#include <algo/blast/core/blast_util.h>
+#include <algo/blast/core/blast_hits.h>
+#include "jumper.h"
+
+/* Pair configurations, in the order of prefernece */
+#define PAIR_CONVERGENT 0
+#define PAIR_DIVERGENT 1
+#define PAIR_PARALLEL 2
+#define PAIR_NONE 3
+
+/* A container to create a list of HSPs */
+typedef struct HSPContainer
+{
+    BlastHSP* hsp;
+    struct HSPContainer* next;    
+} HSPContainer;
+
+
+/* Create HSPContainer and take ownership of the HSP */
+static HSPContainer* HSPContainerNew(BlastHSP** hsp)
+{
+    HSPContainer* retval = calloc(1, sizeof(HSPContainer));
+    if (!retval) {
+        return NULL;
+    }
+    retval->hsp = *hsp;
+    /* take ownership of this HSP */
+    *hsp = NULL;
+
+    return retval;
+}
+
+/* Free the list of HSPs, along with the stored HSPs */
+static HSPContainer* HSPContainerFree(HSPContainer* hc)
+{
+    HSPContainer* h = hc;
+    while (h) {
+        HSPContainer* next = h->next;
+        if (h->hsp) {
+            Blast_HSPFree(h->hsp);
+        }
+
+        sfree(h);
+        h = next;
+    }
+
+    return NULL;
+}
+
+/* Clone a list of HSP containers */
+static HSPContainer* HSPContainerDup(HSPContainer* inh)
+{
+    HSPContainer* retval = NULL;
+    HSPContainer* hi = NULL, *ho = NULL;
+    BlastHSP* new_hsp = NULL;
+
+    if (!inh || !inh->hsp) {
+        return NULL;
+    }
+
+    new_hsp = Blast_HSPClone(inh->hsp);
+    if (!new_hsp) {
+        return NULL;
+    }
+    retval = HSPContainerNew(&new_hsp);
+    if (!retval) {
+        Blast_HSPFree(new_hsp);
+        return NULL;
+    }
+
+    hi = inh->next;
+    ho = retval;
+    for (; hi; hi = hi->next, ho = ho->next) {
+        new_hsp = Blast_HSPClone(hi->hsp);
+        if (!new_hsp) {
+            Blast_HSPFree(new_hsp);
+            HSPContainerFree(retval);
+            return NULL;
+        }
+        ho->next = HSPContainerNew(&new_hsp);
+        if (!ho->next) {
+            Blast_HSPFree(new_hsp);
+            HSPContainerFree(retval);
+            return NULL;
+        }
+    }
+
+    return retval;
+}
+
+/* A chain of HSPs: gene transcript sequence aligned to exons */
+typedef struct HSPChain
+{
+    Int4 context;  /* query context */
+    Int4 oid;      /* subject oid */
+    Int4 score;    /* score for the whole chain */
+    HSPContainer* hsps;  /* list of HSPs that belong to this chain */
+    Int4 compartment;    /* compartment number for the chain (needed
+                            for reporting results) */
+    
+    Int4 count;    /* number of chains with the same or larger score found
+                      for the same query */
+    struct HSPChain* pair;  /* pointer to the pair (for paired reads) */
+    Uint1 pair_conf;        /* pair configuration */
+
+    Int4 adapter;  /* adapter start position */
+    Int4 polyA;    /* start of polyA tail */
+    struct HSPChain* next;
+} HSPChain;
+
+
+static HSPChain* HSPChainFree(HSPChain* chain_list)
+{
+    HSPChain* chain = chain_list;
+    while (chain) {
+        HSPChain* next = chain->next;
+        if (chain->pair) {
+            chain->pair->pair = NULL;
+        }
+        ASSERT(chain->hsps);
+        chain->hsps = HSPContainerFree(chain->hsps);
+        sfree(chain);
+        chain = next;
+    }
+
+    return NULL;
+}
+
+static HSPChain* HSPChainNew(Int4 context)
+{
+    HSPChain* retval = calloc(1, sizeof(HSPChain));
+    if (!retval) {
+        return NULL;
+    }
+    retval->context = context;
+    retval->compartment = -1;
+    retval->adapter = -1;
+
+    return retval;
+}
+
+
+/* Insert a single chain into the list so that the list is sorted in decending
+   order of chain scores. */
+static Int4 s_HSPChainListInsertOne(HSPChain** list, HSPChain* chain,
+                                    Boolean check_for_duplicates)
+{
+    HSPChain* ch = NULL;
+
+    if (!list || !chain) {
+        return -1;
+    }
+    ASSERT(!chain->next);
+
+    if (!*list) {
+        *list = chain;
+        return 0;
+    }
+
+    ch = *list;
+    if (ch->score < chain->score) {
+        chain->next = ch;
+        *list = chain;
+        return 0;
+    }
+
+    /* check for duplicate chain: the new chains may be the same as already
+       saved; this may come from writing HSPs to HSP stream for each chunk */
+    if (check_for_duplicates &&
+        ch->oid == chain->oid && ch->score == chain->score &&
+        ch->hsps->hsp->query.frame == chain->hsps->hsp->query.frame &&
+        ch->hsps->hsp->subject.offset ==
+        chain->hsps->hsp->subject.offset) {
+
+        chain->next = NULL;
+        chain = HSPChainFree(chain);
+        return 0;
+    }
+
+    while (ch->next && ch->next->score >= chain->score){
+
+        /* check for duplicate chain: the new chains may be the same as already
+           saved; this may come from writing HSPs to HSP stream for each chunk */
+        if (check_for_duplicates &&
+            ch->next->oid == chain->oid && ch->next->score == chain->score &&
+            ch->next->hsps->hsp->query.frame == chain->hsps->hsp->query.frame &&
+            ch->next->hsps->hsp->subject.offset ==
+            chain->hsps->hsp->subject.offset) {
+
+            chain->next = NULL;
+            chain = HSPChainFree(chain);
+            return 0;
+        }
+
+        ch = ch->next;
+    }
+    ASSERT(ch);
+    chain->next = ch->next;
+    ch->next = chain;
+
+    return 0;
+}
+
+/* Insert chains into the list so that the list is sorted in descending order
+   of chain scores. If chain is a list, each element is added separately. The
+   list must be sorted before adding chain */
+static Int4 HSPChainListInsert(HSPChain** list, HSPChain* chain,
+                               Boolean check_for_duplicates)
+{
+    HSPChain* ch = NULL;
+    Int4 status = 0;
+
+    if (!list || !chain) {
+        return -1;
+    }
+
+    ch = chain;
+    while (ch) {
+        HSPChain* next = ch->next;
+        ch->next = NULL;
+        status = s_HSPChainListInsertOne(list, ch, check_for_duplicates);
+        if (status) {
+            return status;
+        }
+        ch = next;
+
+    }
+
+    return 0;
+}
+
+/* Remove from the list chains with scores lower than the best one by at least
+   the given margin. The list must be sorted in descending order of scores. */
+static Int4 HSPChainListTrim(HSPChain* list, Int4 margin)
+{
+    HSPChain* ch = NULL;
+    Int4 best_score;
+
+    if (!list) {
+        return -1;
+    }
+
+    best_score = list->score;
+    ch = list;
+    while (ch->next && best_score - ch->next->score <= margin) {
+        ASSERT(best_score - ch->next->score >= 0);
+        ch = ch->next;
+    }
+    ASSERT(ch);
+
+    ch->next = HSPChainFree(ch->next);
+
+    return 0;
+}
+
+
+/* Clone a single HSP chain */
+static HSPChain* s_CloneChain(const HSPChain* chain)
+{
+    HSPChain* retval = NULL;
+
+    if (!chain) {
+        return NULL;
+    }
+    
+    retval = HSPChainNew(chain->context);
+    if (!retval) {
+        return NULL;
+    }
+    retval->hsps = HSPContainerDup(chain->hsps);
+    if (!retval->hsps) {
+        HSPChainFree(retval);
+        return NULL;
+    }
+    retval->oid = chain->oid;
+    retval->score = chain->score;
+    retval->adapter = chain->adapter;
+    retval->polyA = chain->polyA;
+
+    return retval;
+}
+
+/* Test that all pointers in the chain are set */
+static Boolean s_TestChains(HSPChain* chain)
+{
+    HSPContainer* hc;
+
+    ASSERT(chain);
+    hc = chain->hsps;
+    ASSERT(hc);
+    ASSERT(hc->hsp);
+    ASSERT(hc->hsp->context == chain->context);
+
+    ASSERT(hc->hsp->gap_info->size > 1 ||
+           hc->hsp->query.end - hc->hsp->query.offset ==
+           hc->hsp->subject.end - hc->hsp->subject.offset);
+
+    hc = hc->next;
+    while (hc) {
+        ASSERT(hc->hsp);
+        ASSERT(hc->hsp->context == chain->context);
+
+        ASSERT(hc->hsp->gap_info->size > 1 ||
+               hc->hsp->query.end - hc->hsp->query.offset ==
+               hc->hsp->subject.end - hc->hsp->subject.offset);
+
+        if (hc->next) {
+            ASSERT(hc->hsp->query.offset < hc->next->hsp->query.offset);
+            ASSERT(hc->hsp->subject.offset < hc->next->hsp->subject.offset);
+        }
+        hc = hc->next;
+    }
+
+    chain = chain->next;
+    while (chain) {
+        hc = chain->hsps;
+        ASSERT(hc);
+        ASSERT(hc->hsp);
+        ASSERT(hc->hsp->context == chain->context);
+
+        ASSERT(hc->hsp->gap_info->size > 1 ||
+               hc->hsp->query.end - hc->hsp->query.offset ==
+               hc->hsp->subject.end - hc->hsp->subject.offset);
+
+        hc = hc->next;
+        while (hc) {
+            ASSERT(hc);
+            ASSERT(hc->hsp);
+            ASSERT(hc->hsp->context == chain->context);
+
+            ASSERT(hc->hsp->gap_info->size > 1 ||
+                   hc->hsp->query.end - hc->hsp->query.offset ==
+                   hc->hsp->subject.end - hc->hsp->subject.offset);
+
+            if (hc->next) {
+                ASSERT(hc->hsp->query.offset < hc->next->hsp->query.offset);
+                ASSERT(hc->hsp->subject.offset < hc->next->hsp->subject.offset);
+            }
+
+            hc = hc->next;
+        }
+        chain = chain->next;
+    }
+
+    return TRUE;
+}
+
+#if _DEBUG
+static Boolean s_TestChainsSorted(HSPChain* chain)
+{
+    HSPChain* prev;
+
+    s_TestChains(chain);
+
+    prev = chain;
+    chain = chain->next;
+    for (; chain; chain = chain->next, prev = prev->next) {
+        ASSERT(prev->score >= chain->score);
+    }
+
+    return TRUE;
+}
+#endif
+
+/** Data structure used by the writer */
+typedef struct BlastHSPMapperData {
+   BlastHSPMapperParams* params;         /**< how many hits to save */
+   BLAST_SequenceBlk* query;              /**< query sequence */
+   BlastQueryInfo* query_info;            /**< information about queries */
+   HSPChain** saved_chains;               /**< HSP chains are stored here */
+} BlastHSPMapperData;
+
+/*************************************************************/
+/** The following are implementations for BlastHSPWriter ADT */
+
+/** Perform pre-run stage-specific initialization 
+ * @param data The internal data structure [in][out]
+ * @param results The HSP results to operate on  [in]
+ */ 
+static int 
+s_BlastHSPMapperPairedInit(void* data, void* results)
+{
+   BlastHSPMapperData * spl_data = data;
+   BlastHSPResults* r = (BlastHSPResults*)results;
+   spl_data->saved_chains = calloc(r->num_queries, sizeof(HSPChain*));
+
+   return 0;
+}
+
+
+/* Get subject start position */
+static Int4 s_FindFragmentStart(HSPChain* chain)
+{
+    Int2 frame;
+    HSPContainer* hc = NULL;
+    ASSERT(chain);
+    ASSERT(chain->hsps);
+    ASSERT(chain->hsps->hsp);
+
+    frame = chain->hsps->hsp->query.frame;
+    if (frame > 0) {
+        return chain->hsps->hsp->subject.offset;
+    }
+
+    hc = chain->hsps;
+    while (hc->next) {
+        hc = hc->next;
+    }
+    ASSERT(hc);
+
+    return hc->hsp->subject.end - 1;
+}
+
+
+/* Get subject end position */
+/* Not used
+static Int4 s_FindFragmentEnd(HSPChain* chain)
+{
+    Int2 frame;
+    HSPContainer* hc = NULL;
+    ASSERT(chain);
+    ASSERT(chain->hsps);
+    ASSERT(chain->hsps->hsp);
+
+    frame = chain->hsps->hsp->query.frame;
+    if (frame < 0) {
+        return chain->hsps->hsp->subject.offset;
+    }
+
+    hc = chain->hsps;
+    while (hc->next) {
+        hc = hc->next;
+    }
+    ASSERT(hc);
+
+    return hc->hsp->subject.end - 1;
+}
+*/
+
+/* Compute HSP alignment score from Jumper edit script */
+static Int4 s_ComputeAlignmentScore(BlastHSP* hsp, Int4 mismatch_score,
+                                    Int4 gap_open_score, Int4 gap_extend_score)
+{
+    Int4 i;
+    Int4 last_pos = hsp->query.offset;
+    Int4 score = 0;
+    const Int4 kGap = 15;
+
+    for (i = 0;i < hsp->map_info->edits->num_edits;i++) {
+        JumperEdit* e = &(hsp->map_info->edits->edits[i]);
+        Int4 num_matches = e->query_pos - last_pos;
+        ASSERT(num_matches >= 0);
+        last_pos = e->query_pos;
+        score += num_matches;
+
+        if (e->query_base == kGap) {
+            ASSERT(e->subject_base != kGap);
+            if (num_matches > 0 ||
+                (i > 0 && hsp->map_info->edits->edits[i - 1].query_base !=
+                 kGap)) {
+
+                score += gap_open_score;
+            }
+            score += gap_extend_score;
+        }
+        else if (e->subject_base == kGap) {
+            if (num_matches > 0 ||
+                (i > 0 && hsp->map_info->edits->edits[i - 1].subject_base !=
+                 kGap)) {
+
+                score += gap_open_score;
+            }
+            score += gap_extend_score;
+            last_pos++;
+        }
+        else {
+            score += mismatch_score;
+            last_pos++;
+        }
+    }
+
+    score += hsp->query.end - last_pos;
+    return score;
+}
+
+
+/* Find the cost of chain HSPs overlapping on the query, as the smaller score
+   of the overlapping region */
+static Int4 s_GetOverlapCost(const BlastHSP* a, const BlastHSP* b,
+                             Int4 edit_penalty)
+{
+    Int4 i;
+    Int4 overlap_f, overlap_s;
+    const BlastHSP* f;
+    const BlastHSP* s;
+
+    /* if one HSP in contained within the other on the query, return the
+       smaller score */
+    if ((a->query.offset <= b->query.offset && a->query.end >= b->query.end) ||
+        (a->query.offset >= b->query.offset && a->query.end <= b->query.end)) {
+
+        return MIN(a->score, b->score);
+    }
+
+    /* if the two HSPs are mutually exclusive on the query, there is no cost */
+    if ((a->query.end < b->query.offset && a->query.offset < b->query.end) ||
+        (b->query.end < a->query.offset && b->query.offset < a->query.end)) {
+
+        return 0;
+    }
+
+    /* otherwise the HSPs partially overlap; reurn the the smaller score for
+       the overlap region */
+
+    /* find which HSP precedes which on the query */
+    if (a->query.offset <= b->query.offset) {
+        f = a;
+        s = b;
+    }
+    else {
+        f = b;
+        s = a;
+    }
+
+    /* this is the overlap score assuming perfect matches in the overlap */
+    overlap_f = overlap_s = f->query.end - s->query.offset;
+    ASSERT(overlap_f >= 0 && overlap_s >= 0);
+    /* subtract penalties for mismatches and gaps in the overlap region */
+    for (i = 0;i < f->map_info->edits->num_edits;i++) {
+        if (f->map_info->edits->edits[i].query_pos >= s->query.offset) {
+            overlap_f -= edit_penalty;
+        }
+    }
+    for (i = 0;i < s->map_info->edits->num_edits;i++) {
+        if (s->map_info->edits->edits[i].query_pos < f->query.end) {
+            overlap_s -= edit_penalty;
+        }
+    }
+
+    return MIN(overlap_f, overlap_s);
+}
+
+
+/* Compute chain score */
+static Int4 s_ComputeChainScore(HSPChain* chain,
+                                const ScoringOptions* score_options,
+                                Int4 query_len,
+                                Boolean comp_hsp_score)
+{
+    Int4 retval;
+    HSPContainer* h = NULL;
+    HSPContainer* prev = NULL;
+
+    if (!chain || !score_options) {
+        return -1;
+    }
+
+    h = chain->hsps;
+    if (comp_hsp_score) {
+        h->hsp->score = s_ComputeAlignmentScore(h->hsp, score_options->penalty,
+                                                score_options->gap_open,
+                                                score_options->gap_extend);
+    }
+    retval = h->hsp->score;
+    if (h->hsp->query.offset > 0 &&
+        (h->hsp->map_info->left_edge & MAPPER_SPLICE_SIGNAL) == 0) {
+
+        retval += score_options->no_splice_signal;
+    }
+    if (h->hsp->query.end < query_len &&
+        (h->hsp->map_info->right_edge & MAPPER_SPLICE_SIGNAL) == 0) {
+
+        retval += score_options->no_splice_signal;
+    }
+
+    prev = h;
+    h = h->next;
+
+    for (; h; h = h->next, prev = prev->next) {
+        /* HSPs must be sorted by query positon */
+        ASSERT(h->hsp->query.offset >= prev->hsp->query.offset);
+
+        if (comp_hsp_score) {
+
+            h->hsp->score = s_ComputeAlignmentScore(h->hsp,
+                                                    score_options->penalty,
+                                                    score_options->gap_open,
+                                                    score_options->gap_extend);
+        }
+        retval += h->hsp->score;
+
+        if (h->hsp->query.offset > 0 &&
+            (h->hsp->map_info->left_edge & MAPPER_SPLICE_SIGNAL) == 0) {
+
+            retval += score_options->no_splice_signal;
+        }
+        if (h->hsp->query.end < query_len &&
+            (h->hsp->map_info->right_edge & MAPPER_SPLICE_SIGNAL) == 0) {
+
+            retval += score_options->no_splice_signal;
+        }
+    }
+
+    return retval;
+}
+
+#if _DEBUG
+static Boolean s_TestHSPRanges(const BlastHSP* hsp)
+{
+    Int4 i;
+    Int4 d = 0;
+    for (i=0;i < hsp->gap_info->size;i++) {
+        switch (hsp->gap_info->op_type[i]) {
+        case eGapAlignIns:
+            d -= hsp->gap_info->num[i];
+            break;
+
+        case eGapAlignDel:
+            d += hsp->gap_info->num[i];
+            break;
+
+        default:
+            break;
+        }
+    }
+    if (hsp->query.end - hsp->query.offset + d !=
+        hsp->subject.end - hsp->subject.offset) {
+
+        return FALSE;
+    }
+
+    return TRUE;
+}
+#endif
+
+/* Trim HSP by a number of bases on query or subject, either from the start or
+   from the end */
+static Int4 s_TrimHSP(BlastHSP* hsp, Int4 num, Boolean is_query,
+                      Boolean is_start, Int4 mismatch_score,
+                      Int4 gap_open_score, Int4 gap_extend_score)
+{
+    Int4 num_left = num;
+    Int4 i = is_start ? 0 : hsp->gap_info->size - 1;
+    Int4 d = is_start ? 1 : -1;
+    Int4 end = is_start ? hsp->gap_info->size : -1;
+    Int4 delta_query = 0, delta_subject = 0;
+    Boolean is_subject = !is_query;
+    Boolean is_end = !is_start;
+    Int4 k;
+
+    ASSERT(hsp /* */ && num > 0 /* */);
+    ASSERT((is_query && num <= hsp->query.end - hsp->query.offset) ||
+           (!is_query && num <= hsp->subject.end - hsp->subject.offset));
+
+#if _DEBUG
+    ASSERT(s_TestHSPRanges(hsp));
+#endif
+
+    if (num == 0) {
+        return 0;
+    }
+
+
+    /* itereate over the edit script and remove the required number
+       of subject bases */
+    while (i != end && num_left > 0) {
+        switch (hsp->gap_info->op_type[i]) {
+        case eGapAlignSub:
+            if (hsp->gap_info->num[i] > num_left) {
+                hsp->gap_info->num[i] -= num_left;
+                delta_query += num_left;
+                delta_subject += num_left;
+                num_left = 0;
+            }
+            else {
+                Int4 n = hsp->gap_info->num[i];
+
+                delta_query += n;
+                delta_subject += n;
+                num_left -= n;
+                i += d;
+            }
+            break;
+
+        case eGapAlignDel:
+            if (is_subject) {
+                if (hsp->gap_info->num[i] > num_left) {
+                    hsp->gap_info->num[i] -= num_left;
+                    delta_subject += num_left;
+                    num_left = 0;
+                }
+                else {
+                    delta_subject += hsp->gap_info->num[i];
+                    num_left -= hsp->gap_info->num[i];
+                    i += d;
+                }
+            }
+            else {
+                delta_subject += hsp->gap_info->num[i];
+                i += d;
+            }
+            break;
+
+        case eGapAlignIns:
+            if (is_query) {
+                if (hsp->gap_info->num[i] > num_left) {
+                    hsp->gap_info->num[i] -= num_left;
+                    delta_query += num_left;
+                    num_left = 0;
+                }
+                else {
+                    delta_query += hsp->gap_info->num[i];
+                    num_left -= hsp->gap_info->num[i];
+                    i += d;
+                }
+            }
+            else {
+                delta_query += hsp->gap_info->num[i];
+                i += d;
+            }
+            break;
+
+        default:
+            ASSERT(0);
+            break;
+        }
+    }
+
+    /* shift edit script elements to fill the removed ones */
+    if (is_start && i > 0) {
+        for (k = 0;k < hsp->gap_info->size - i;k++) {
+            hsp->gap_info->op_type[k] = hsp->gap_info->op_type[k + i];
+            hsp->gap_info->num[k] = hsp->gap_info->num[k + i];
+        }
+        hsp->gap_info->size -= i;
+    }
+
+    if (is_end) {
+        hsp->gap_info->size = i + 1;
+    }
+
+    /* update the Jumper edit script */
+    if (is_start) {
+        Int4 pos = hsp->query.offset + delta_query;
+        i = 0;
+        while (i < hsp->map_info->edits->num_edits &&
+               hsp->map_info->edits->edits[i].query_pos < pos) {
+            i++;
+        }
+        if (i > 0) {
+            for (k = 0;k < hsp->map_info->edits->num_edits - i;k++) {
+                hsp->map_info->edits->edits[k] =
+                    hsp->map_info->edits->edits[k + i];
+            }
+            hsp->map_info->edits->num_edits -= i;
+        }
+    }
+    else {
+        Int4 pos = hsp->query.end - delta_query - 1;
+        i = hsp->map_info->edits->num_edits - 1;
+        while (i >= 0 && hsp->map_info->edits->edits[i].query_pos > pos) {
+            i--;
+        }
+        hsp->map_info->edits->num_edits = i + 1;
+    }
+
+    /* update HSP start positions */
+    if (is_start) {
+        hsp->query.offset += delta_query;
+        hsp->subject.offset += delta_subject;
+    }
+    else {
+        hsp->query.end -= delta_query;
+        hsp->subject.end -= delta_subject;
+    }
+    
+    /* update HSP score */
+    hsp->score = s_ComputeAlignmentScore(hsp, mismatch_score, gap_open_score,
+                                         gap_extend_score);
+
+#if _DEBUG
+    ASSERT(s_TestHSPRanges(hsp));
+#endif
+
+    return 0;
+}
+
+
+#define NUM_ADAPTERS 4
+#define MAX_ADAPTER_LEN 20
+
+/* Find adapeter on the 5' end in a single sequence. The search will start
+   towards the end of the last HSP (from, to) */
+static Int4 s_FindAdapterInSequence(Int4 hsp_from, Int4 hsp_to, Uint1* query,
+                                    Int4 query_len)
+{
+    Uint1 adapters_tab[NUM_ADAPTERS][MAX_ADAPTER_LEN] = {
+        /* Contaminants from FastQC config file:
+           http://www.bioinformatics.babraham.ac.uk/projects/fastqc/ */
+        /* Illumina universal adapter: AGATCGGAAGAG */
+        {0, 2, 0, 3, 1, 2, 2, 0, 0, 2, 0, 2},
+        /* Illumina small RNA adapter: ATGGAATTCTCG */
+        {0, 3, 2, 2, 0, 0, 3, 3, 1, 3, 1, 2},
+        /* Nextera transosase sequence: CTGTCTCTTATA */
+        {1, 3, 2, 3, 1, 3, 1, 3, 3, 0, 3, 0},
+        /* Illumina multiplexing adapter 1: GATCGGAAGAGCACACGTCT */
+        {2, 0, 3, 1, 2, 2, 0, 0, 2, 0, 2, 1, 0, 1, 0, 1, 2, 3, 1, 3}};
+
+    int lengths[NUM_ADAPTERS] = {12, 12, 12, 20};
+    Boolean found = FALSE;
+    Int4 adapter_start = -1;
+    int adptr_idx;
+    Int4 from = hsp_from, to = hsp_to;
+    const Int4 kMaxErrors = 1; /* max number of mismaches allowed for matching
+                                  the adapter sequence + 1*/
+
+    
+    if (!query) {
+        return -1;
+    }
+
+    for (adptr_idx = 0;!found && adptr_idx < NUM_ADAPTERS;adptr_idx++) {
+        Uint1* adapter = adapters_tab[adptr_idx];
+        Uint4 word = *(Uint4*)adapter;
+        Int4 q = MAX(to - lengths[adptr_idx], from);
+        int i = 0;
+        while (q < query_len - 4 && q + i < query_len && i < lengths[adptr_idx]) {
+            while (q < query_len - 4 && *(Uint4*)(query + q) != word) {
+                q++;
+            }
+            if (q < query_len - 4) {
+                Int4 errors = kMaxErrors + 1;
+                i = 0;
+                while (q + i < query_len && i < lengths[adptr_idx] &&
+                       errors) {
+
+                    if (query[q + i] != adapter[i]) {
+                        errors--;
+                    }
+                    i++;
+                }
+                if (q + i == query_len || i == lengths[adptr_idx]) {
+                    adapter_start = q;
+                    found = TRUE;
+                    break;
+                }
+
+                q++;
+            }
+        }
+    }
+
+    ASSERT(adapter_start <= query_len);
+    return adapter_start;
+}
+
+
+/* Set adapter position in the chain and trim alignments that span beyond
+   adapter start position */
+static Int2 s_SetAdapter(HSPChain** chains_ptr, Int4 adapter_pos,
+                         Int4 query_len, const ScoringOptions* scores)
+{
+    HSPChain* head = NULL;
+    HSPChain* chain = NULL;
+    const Int4 kMinAdapterLen = 3;
+
+    if (!chains_ptr || !*chains_ptr || adapter_pos < 0) {
+        return -1;
+    }
+
+    head = *chains_ptr;
+    chain = *chains_ptr;
+    /* iterate over chains */
+    while (chain) {
+        BlastHSP* hsp = chain->hsps->hsp;
+
+        /* check the 3' alignment extent on the query and skip this chain
+           if the query is covered almost to the end */
+        if (hsp->query.frame > 0) {
+            /* for positive strand, check the last query position */
+            HSPContainer* h = chain->hsps;
+            while (h->next) {
+                h = h->next;
+            }
+            ASSERT(h);
+            if (query_len - h->hsp->query.end < kMinAdapterLen) {
+                chain = chain->next;
+                continue;
+            }
+        }
+        else {
+            /* for negative strand, check the first query position */
+            ASSERT(hsp);
+            if (hsp->query.offset < kMinAdapterLen) {
+                chain = chain->next;
+                continue;
+            }
+        }
+
+        /* set adapter start position in the chain */
+        chain->adapter = adapter_pos;
+
+        /* Trim alignment that covers part of the adapter */
+        /* for query on the positive strand */
+        if (hsp->query.frame > 0) {
+            HSPContainer* h = chain->hsps;
+
+            /* if all HSPs are behind the adapter, delete this chain;
+               we require that HSP without adapter is at least 5 bases long */
+            if (h->hsp->query.offset >= adapter_pos - 5) {
+                HSPChain* prev = head;
+                HSPChain* next = chain->next;
+                while (prev && prev->next != chain) {
+                    prev =prev->next;
+                }
+
+                chain->next = NULL;
+                HSPChainFree(chain);
+                chain = next;
+                if (prev) {
+                    prev->next = next;
+                }
+                else {
+                    head = chain;
+                }
+
+                continue;
+            }
+
+            /* find the first HSP with end position after adapter */
+            while (h && h->hsp->query.end <= adapter_pos) {
+                h = h->next;
+            }
+
+            /* if one is found */
+            if (h) {
+                HSPContainer* hh = NULL;
+                hsp = h->hsp;
+
+                /* if adapter is with in the HSP trim the HSP */
+                if (hsp->query.offset < adapter_pos ) {
+                    Int4 old_score = hsp->score;
+                    ASSERT(hsp->query.end - adapter_pos > 0);
+                    s_TrimHSP(hsp, hsp->query.end - adapter_pos, TRUE,
+                              FALSE, scores->penalty, scores->gap_open,
+                              scores->gap_extend);
+                    chain->score += hsp->score - old_score;
+
+                    /* remove HSPs after h as they are past the adapter */
+                    if (h->next) {
+                        h->next = HSPContainerFree(h->next);
+                    }
+                }
+                else {
+                    /* otherwise delete h and everything after it */
+                    hh = chain->hsps;
+                    while (hh && hh->next != h) {
+                        hh = hh->next;
+                    }
+                    ASSERT(hh);
+                    hh->next = HSPContainerFree(hh->next);
+                }
+
+                /* compute the new chain score */
+                chain->score = s_ComputeChainScore(chain, scores, query_len,
+                                                   FALSE);
+            }
+
+            /* mark adapter in the HSPs */
+            h = chain->hsps;
+            while (h->next) {
+                h = h->next;
+            }
+            h->hsp->map_info->right_edge |= MAPPER_ADAPTER;
+            h->hsp->map_info->right_edge |= MAPPER_EXON;
+        }
+        else {
+            /* negative strand: adapter is in the beginning of the chain */
+            Int4 pos_minus = query_len - adapter_pos - 1;
+            HSPContainer* h = chain->hsps;
+
+            /* find the first HSP with end position after adapter;
+               we require that HSP without adapter is at least 5 bases long */
+            while (h && h->hsp->query.end <= pos_minus + 5) {
+                h = h->next;
+            }
+
+            /* if all HSPs are before the adapter, delete this chain */
+            if (!h) {
+                /* remove chain */
+                HSPChain* prev = head;
+                HSPChain* next = chain->next;
+                while (prev && prev->next != chain) {
+                    prev =prev->next;
+                }
+
+                chain->next = NULL;
+                HSPChainFree(chain);
+                chain = next;
+                if (prev) {
+                    prev->next = next;
+                }
+                else {
+                    head = chain;
+                }
+
+                continue;
+            }
+
+            /* if h is not the first HSP in the chain, remove all HSPs before
+               h */
+            if (h != chain->hsps) {
+                HSPContainer* hh = chain->hsps;
+                while (hh && hh->next != h) {
+                    hh = hh->next;
+                }
+                ASSERT(hh);
+                hh->next = NULL;
+                HSPContainerFree(chain->hsps);
+                chain->hsps = h;
+
+                /* compute new chain score */
+                chain->score = s_ComputeChainScore(chain, scores, query_len,
+                                                   FALSE);
+            }
+            ASSERT(h);
+
+            /* set adapter information */
+            hsp = chain->hsps->hsp;
+            hsp->map_info->left_edge |= MAPPER_ADAPTER;
+            hsp->map_info->left_edge |= MAPPER_EXON;
+ 
+            /* trim HSP if necessary */
+            if (pos_minus >= hsp->query.offset) {
+                Int4 old_score = hsp->score;
+                ASSERT(pos_minus - hsp->query.offset + 1 > 0);
+                s_TrimHSP(hsp, pos_minus - hsp->query.offset + 1,
+                          TRUE, TRUE, scores->penalty, scores->gap_open, 
+                          scores->gap_extend);
+                chain->score += hsp->score - old_score;
+            }
+        }
+
+        chain = chain->next;
+    }
+
+    ASSERT(!head || s_TestChains(head));
+    *chains_ptr = head;
+
+    return 0;
+}
+
+
+static Int4 s_FindAdapters(HSPChain** saved,
+                           const BLAST_SequenceBlk* query_blk,
+                           const BlastQueryInfo* query_info,
+                           const ScoringOptions* score_opts)
+{
+    Int4 query_idx;
+
+    for (query_idx = 0;query_idx < query_info->num_queries;query_idx++) {
+        HSPChain* chain = NULL;
+        HSPChain* ch = NULL;
+        Uint1* query = NULL;
+        Int4 query_len;
+        Int4 from = -1, to = -1;
+        BlastHSP* hsp = NULL;
+        Int4 overhang = 0;
+        Int4 adapter_pos = -1;
+
+        if (!saved[query_idx]) {
+            continue;
+        }
+        
+        /* we search for adapters and  only in the plus strand of the query */
+        query = query_blk->sequence +
+            query_info->contexts[query_idx * NUM_STRANDS].query_offset;
+        ASSERT(query);
+        query_len = query_info->contexts[query_idx * NUM_STRANDS].query_length;
+
+        /* find the best scoring chain */
+        chain = saved[query_idx];
+        ch = chain->next;
+        for (; ch; ch = ch->next) {
+            if (ch->score > chain->score) {
+                chain = ch;
+            }
+        }
+        ASSERT(chain);
+
+        /* find query coverage by the whole chain */
+        if (chain->hsps->hsp->query.frame > 0) {
+            HSPContainer* h = chain->hsps;
+            from = h->hsp->query.offset;
+            while (h->next) {
+                h = h->next;
+            }
+            to = h->hsp->query.end;
+        }
+        else {
+            HSPContainer* h = chain->hsps;
+            to = query_len - h->hsp->query.offset;
+            while (h->next) {
+                h = h->next;
+            }
+            from = query_len - h->hsp->query.end;
+        }
+        ASSERT(from >= 0 && to >= 0);
+
+        /* do not search for adapters if the query is mostly covered by the
+           best scoring chain */
+        if (from < 20 && to > query_len - 3) {
+            continue;
+        }
+
+        /* find the chain with the longest overhang */
+        chain = saved[query_idx];
+        ch = chain->next;
+        for (; ch; ch = ch->next) {
+            HSPContainer* h = ch->hsps;
+            if (h->hsp->query.frame > 0) {
+                while (h->next) {
+                    h = h->next;
+                }
+                if (query_len - h->hsp->query.end > overhang) {
+                    overhang = query_len - h->hsp->query.end;
+                    chain = ch;
+                }
+            }
+            else {
+                if (h->hsp->query.offset + 1 > overhang) {
+                    overhang = h->hsp->query.offset + 1;
+                    chain = ch;
+                }
+            }
+        }
+        ASSERT(chain);
+
+        /* find location from where to search for the adapter */
+        hsp = chain->hsps->hsp;
+        if (hsp->query.frame > 0) {
+            HSPContainer* h = chain->hsps;
+            while (h->next) {
+                h = h->next;
+            }
+            hsp = h->hsp;
+        }
+        ASSERT(hsp);
+
+        if (hsp->query.frame > 0) {
+            from = hsp->query.offset;
+            to  = hsp->query.end;
+        }
+        else {
+            from = query_len - hsp->query.end;
+            to = query_len - hsp->query.offset;
+        }
+
+        /* do not search for adapters if the read aligns almost to the end */
+        if (to >= query_len - 3) {
+            continue;
+        }
+
+        /* search for adapters */
+        adapter_pos = s_FindAdapterInSequence(from, to, query, query_len);
+
+        /* set adapter information in all chains and trim HSPs that extend
+           into the adapter */
+        if (adapter_pos >= 0) {
+            s_SetAdapter(&(saved[query_idx]), adapter_pos, query_len,
+                         score_opts);
+        }
+    }
+
+    return 0;
+}
+
+
+/* Search for polyA tail at the end of a sequence and return the start position */
+static Int4 s_FindPolyAInSequence(Uint1* sequence, Int4 length)
+{
+    Int4 i;
+    const Uint1 kBaseA = 0;
+    Int4 num_a = 0;
+    Int4 err = 0;
+    const Int4 kMaxErrors = 3;
+
+    if (!sequence) {
+        return -1;
+    }
+
+    /* iterate over positions untile kMaxErrors non A bases are found */
+    i = length - 1;
+    while (i >= 0 && err < kMaxErrors) {
+        if (sequence[i] != kBaseA) {
+            err++;
+        }
+
+        i--;
+    }
+    i++;
+
+    /* find the beginnig of the string of As */
+    while (i < length - 1 &&
+           (sequence[i] != kBaseA || sequence[i + 1] != kBaseA)) {
+
+        if (sequence[i] != kBaseA) {
+            err--;
+        }
+        i++;
+    }
+
+    num_a = length - i - err;
+
+    /* short tails must have no errors */
+    if (num_a < 3 || (num_a < 5 && err > 0)) {
+        return -1;
+    }
+
+    return i;
+}
+
+
+/* Set PolyA information in HSP chains */
+static Int4 s_SetPolyATail(HSPChain* chains, Int4 positive_start,
+                           Int4 negative_start, Int4 query_len)
+{
+    HSPChain* ch = NULL;
+
+    if (!chains) {
+        return -1;
+    }
+
+    for (ch = chains; ch; ch = ch->next) {
+        HSPContainer* h = ch->hsps;
+        while (h->next) {
+            h = h->next;
+        }
+
+        if (query_len - h->hsp->query.end < 5) {
+            continue;
+        }
+
+        if ((h->hsp->query.frame < 0 && negative_start >= 0) ||
+            (h->hsp->query.frame > 0 && positive_start >= 0)) {
+
+            h->hsp->map_info->right_edge |= MAPPER_POLY_A;
+            h->hsp->map_info->right_edge |= MAPPER_EXON;
+
+            if (h->hsp->query.frame > 0) {
+                ch->polyA = MAX(positive_start, h->hsp->query.end);
+            }
+            else {
+                ch->polyA = MAX(negative_start, h->hsp->query.end);
+            }
+        }
+    }
+
+    return 0;
+}
+
+
+static Int4 s_FindPolyATails(HSPChain** saved,
+                             const BLAST_SequenceBlk* query_blk,
+                             const BlastQueryInfo* query_info)
+{
+    Int4 query_idx;
+
+    /* for each query */
+    for (query_idx = 0;query_idx < query_info->num_queries;query_idx++) {
+        HSPChain* chain = NULL;
+        HSPChain* ch = NULL;
+        Uint1* query = NULL;
+        Int4 query_len;
+        Int4 from = -1, to = -1;
+        Int4 positive_start, negative_start;
+
+        /* skip queries with no results and those with adapters */
+        if (!saved[query_idx] || saved[query_idx]->adapter >= 0) {
+            continue;
+        }
+        
+        query_len = query_info->contexts[query_idx * NUM_STRANDS].query_length;
+
+        /* find the best scoring chain */
+        chain = saved[query_idx];
+        ch = chain->next;
+        for (; ch; ch = ch->next) {
+            if (ch->score > chain->score) {
+                chain = ch;
+            }
+        }
+        ASSERT(chain);
+
+        /* find query coverage by the whole chain */
+        if (chain->hsps->hsp->query.frame > 0) {
+            HSPContainer* h = chain->hsps;
+            from = h->hsp->query.offset;
+            while (h->next) {
+                h = h->next;
+            }
+            to = h->hsp->query.end;
+        }
+        else {
+            HSPContainer* h = chain->hsps;
+            to = query_len - h->hsp->query.offset;
+            while (h->next) {
+                h = h->next;
+            }
+            from = query_len - h->hsp->query.end;
+        }
+        ASSERT(from >= 0 && to >= 0);
+
+        /* do not search for polyA tails if the query is mostly covered by the
+           best scoring chain */
+        if (from < 4 && to > query_len - 3) {
+            continue;
+        }
+        
+        /* search for polyA tail on the positive strand */
+        query = query_blk->sequence +
+            query_info->contexts[query_idx * NUM_STRANDS].query_offset;
+        positive_start = s_FindPolyAInSequence(query, query_len);
+
+        /* search for the polyA tail on the negative strand */
+        query = query_blk->sequence +
+            query_info->contexts[query_idx * NUM_STRANDS + 1].query_offset;
+        negative_start = s_FindPolyAInSequence(query, query_len);
+
+        /* set polyA start positions and HSP flags in the saved chains */
+        if (positive_start >= 0 || negative_start >= 0) {
+            s_SetPolyATail(saved[query_idx], positive_start, negative_start,
+                           query_len);
+        }
+    }
+
+    return 0;
+}
+
+
+/* Merge two HSPs into one. The two HSPs may only be separated by at most
+   one gap or mismatch. Function returns NULL is the HSPs cannon be merged */
+static BlastHSP* s_MergeHSPs(const BlastHSP* first, const BlastHSP* second,
+                             const Uint1* query,
+                             const ScoringOptions* score_opts)
+{
+    BlastHSP* merged_hsp = NULL;  /* this will be the result */
+    const BlastHSP* hsp = second;
+    Int4 query_gap;
+    Int4 subject_gap;
+    Int4 mismatches = 0;
+    Int4 gap_info_size;
+    Int4 edits_size;
+    Int4 k;
+
+    if (!first || !second || !query || !score_opts) {
+        return NULL;
+    }
+
+    merged_hsp = Blast_HSPClone(first);
+    if (!merged_hsp) {
+        return NULL;
+    }
+
+    query_gap = second->query.offset - first->query.end;
+    subject_gap = second->subject.offset - first->subject.end;
+
+    if (query_gap < 0 || subject_gap < 0 || query_gap > 1 ||
+        query_gap != subject_gap) {
+
+        return NULL;
+    }
+
+    gap_info_size = first->gap_info->size + second->gap_info->size +
+        MAX(query_gap, subject_gap);
+
+    edits_size = first->map_info->edits->num_edits +
+        second->map_info->edits->num_edits + MAX(query_gap, subject_gap);
+
+    /* FIXME: should be done through an API */
+    /* reallocate memory for edit scripts */
+    merged_hsp->gap_info->op_type = realloc(merged_hsp->gap_info->op_type,
+                                            gap_info_size *
+                                            sizeof(EGapAlignOpType));
+
+    merged_hsp->gap_info->num = realloc(merged_hsp->gap_info->num,
+                                        gap_info_size *
+                                        sizeof(Int4));
+
+    merged_hsp->map_info->edits->edits = realloc(
+                                       merged_hsp->map_info->edits->edits,
+                                       edits_size * sizeof(JumperEdit));
+
+    if (!merged_hsp->gap_info->op_type ||
+        !merged_hsp->gap_info->num ||
+        !merged_hsp->map_info->edits->edits) {
+
+        Blast_HSPFree(merged_hsp);
+        return NULL;
+    }
+
+    if (query_gap == subject_gap) {
+        mismatches = query_gap;
+    }
+    
+    /* add mismatches to gap_info */
+    if (mismatches > 0) {
+        if (merged_hsp->gap_info->op_type[merged_hsp->gap_info->size - 1]
+            == eGapAlignSub) {
+            merged_hsp->gap_info->num[merged_hsp->gap_info->size - 1] +=
+                mismatches;
+        }
+        else {
+            merged_hsp->gap_info->op_type[merged_hsp->gap_info->size] =
+                eGapAlignSub;
+            merged_hsp->gap_info->num[merged_hsp->gap_info->size] =
+                mismatches;
+            merged_hsp->gap_info->size++;
+        }
+        ASSERT(merged_hsp->gap_info->size <= gap_info_size);
+    }
+
+    /* merge gap_info */
+    for (k = 0;k < hsp->gap_info->size;k++) {
+
+        if (merged_hsp->gap_info->op_type[merged_hsp->gap_info->size - 1]
+            == hsp->gap_info->op_type[k]) {
+
+            merged_hsp->gap_info->num[merged_hsp->gap_info->size - 1] +=
+                hsp->gap_info->num[k];
+        }
+        else {
+            merged_hsp->gap_info->op_type[merged_hsp->gap_info->size]
+                = hsp->gap_info->op_type[k];
+
+            merged_hsp->gap_info->num[merged_hsp->gap_info->size++]
+                = hsp->gap_info->num[k];
+        }
+        ASSERT(merged_hsp->gap_info->size <= gap_info_size);
+    }
+
+    /* add mismatches to jumper edits */
+    if (mismatches > 0) {
+        JumperEdit* edit = merged_hsp->map_info->edits->edits +
+            merged_hsp->map_info->edits->num_edits++;
+        edit->query_pos = merged_hsp->query.end;
+        /* FIXME: Mismatch bases cannot be currently set because there is
+           no access to query or subject sequence in this function. */
+        edit->query_base = query[edit->query_pos];
+        edit->subject_base = edit->query_base;
+
+        ASSERT(merged_hsp->map_info->edits->num_edits <= edits_size);
+    }
+
+    /* merge jumper edits */
+    if (hsp->map_info->edits->num_edits) {
+        JumperEdit* edit = merged_hsp->map_info->edits->edits +
+            merged_hsp->map_info->edits->num_edits;
+
+        ASSERT(merged_hsp->map_info->edits->num_edits +
+               hsp->map_info->edits->num_edits <= edits_size);
+
+        memcpy(edit, hsp->map_info->edits->edits,
+               hsp->map_info->edits->num_edits * sizeof(JumperEdit));
+
+        merged_hsp->map_info->edits->num_edits +=
+            hsp->map_info->edits->num_edits;
+    }
+
+    /* update alignment extents, scores, etc */
+    merged_hsp->query.end = hsp->query.end;
+    merged_hsp->subject.end = hsp->subject.end;
+    merged_hsp->score = s_ComputeAlignmentScore(merged_hsp,
+                                                score_opts->penalty,
+                                                score_opts->gap_open,
+                                                score_opts->gap_extend);
+    merged_hsp->num_ident += hsp->num_ident;
+
+    merged_hsp->map_info->right_edge = hsp->map_info->right_edge;
+    if (!merged_hsp->map_info->subject_overhangs) {
+        return merged_hsp;
+    }
+
+    if (!hsp->map_info->subject_overhangs ||
+        !hsp->map_info->subject_overhangs->right_len ||
+        !hsp->map_info->subject_overhangs->right) {
+
+        merged_hsp->map_info->subject_overhangs->right_len = 0;
+        if (merged_hsp->map_info->subject_overhangs->right) {
+            sfree(merged_hsp->map_info->subject_overhangs->right);
+            merged_hsp->map_info->subject_overhangs->right = NULL;
+        }
+    }
+    else {
+        Int4 new_right_len = hsp->map_info->subject_overhangs->right_len;
+        if (merged_hsp->map_info->subject_overhangs->right_len <
+            new_right_len) {
+
+            merged_hsp->map_info->subject_overhangs->right =
+                realloc(merged_hsp->map_info->subject_overhangs->right,
+                        new_right_len * sizeof(Uint1));
+        }
+        memcpy(merged_hsp->map_info->subject_overhangs->right,
+               hsp->map_info->subject_overhangs->right,
+               new_right_len * sizeof(Uint1));
+    }
+
+    return merged_hsp;
+}
+
+
+/* Find paired reads mapped to different database sequences */
+static int s_FindRearrangedPairs(HSPChain** saved,
+                                 const BlastQueryInfo* query_info)
+{
+    Int4 query_idx;
+
+    /* iterate over single reads from each pair */
+    for (query_idx = 0;query_idx + 1 < query_info->num_queries; query_idx++) {
+        HSPChain* chain = saved[query_idx];
+        HSPChain* thepair = saved[query_idx + 1];
+
+        /* skip queries with no results */
+        if (!chain || !thepair) {
+            continue;
+        }
+
+        /* skip queries that do not have pairs */
+        if (query_info->contexts[query_idx * NUM_STRANDS].segment_flags !=
+            eFirstSegment) {
+
+            continue;
+        }
+
+        /* skip queries with more than one saved chain and ones that already
+           have a pair */
+        if (chain->next || chain->pair || thepair->next) {
+            continue;
+        }
+
+        /* skip chains aligned to the same subject; these are taken care of
+           elsewhere */
+        if (chain->oid == thepair->oid) {
+            continue;
+        }
+
+        /* skip HSP chains aligned on the same strands */
+        if (SIGN(chain->hsps->hsp->query.frame) ==
+            SIGN(thepair->hsps->hsp->query.frame)) {
+            continue;
+        }
+
+        /* mark the pair */
+        chain->pair = thepair;
+        thepair->pair = chain;
+
+        chain->pair_conf = PAIR_PARALLEL;
+        thepair->pair_conf = PAIR_PARALLEL;
+    }
+
+    return 0;
+}
+
+
+/* Sort chains by score in descending order */
+static int s_CompareChainsByScore(const void* cha, const void* chb)
+{
+    const HSPChain* a = *((HSPChain**)cha);
+    const HSPChain* b = *((HSPChain**)chb);
+
+    if (a->score < b->score) {
+        return 1;
+    }
+    else if (a->score > b->score) {
+        return -1;
+    }
+    else {
+        return 0;
+    }
+}
+
+/* Remove chains with scores below the these of the best ones considering
+   score bonus for pairs and count the number of chains with same of better
+   score for each chain */
+static int s_PruneChains(HSPChain** saved, Int4 num_queries, Int4 pair_bonus)
+
+{
+    Int4 query_idx;
+    Int4 array_size = 10;
+    HSPChain** array = calloc(array_size, sizeof(HSPChain*));
+
+    /* Prunning is done in two passes: first considering single chains,
+       then considering pairs. The first pass breaks pairs where there is much
+       better chain with no pair. The second pass selects the best scoring
+       chains giving preference to pairs. Pairs are preferable, so they get
+       additional score. Two passes are requires, because we compare single
+       chains with single chains and pairs with pairs. This is to avoid
+       breaking pairs in situations with two pairs with one high scoring
+       chain. */
+
+    /* first pass: for each query remove poor scoring chains that may split
+       pairs */
+    for (query_idx = 0; query_idx < num_queries; query_idx++) {
+        HSPChain* chain = saved[query_idx];
+        HSPChain* prev = NULL;
+        Int4 best_score = 0;
+
+        if (!chain || !chain->next) {
+            continue;
+        }
+
+        /* find the best single chain score */
+        for (chain = saved[query_idx]; chain; chain = chain->next) {
+            if (chain->score > best_score) {
+                best_score = chain->score;
+            }
+        }
+
+        /* remove chains with poor scores, considering pair bonus */
+        chain = saved[query_idx];
+        while (chain) {
+            Int4 score = (chain->pair ? chain->score + pair_bonus : chain->score);
+
+            if (score < best_score) {
+                HSPChain* next = chain->next;
+
+                chain->next = NULL;
+                HSPChainFree(chain);
+                chain = next;
+
+                if (prev) {
+                    prev->next = next;
+                }
+                else {
+                    saved[query_idx] = next;
+                }
+            }
+            else {
+                prev = chain;
+                chain = chain->next;
+            }
+        }
+        
+    }
+
+    /* second pass: for each query remove chains scoring poorer than the best
+       ones considering pair bonus */
+    for (query_idx = 0; query_idx < num_queries; query_idx++) {
+        HSPChain* chain = saved[query_idx];
+        HSPChain* prev = NULL;
+        Int4 best_score = 0;
+        Int4 best_pair_score = 0;
+        Int4 i;
+        Int4 count = 0;
+        Int4 num_chains = 0;
+
+        if (!chain) {
+            continue;
+        }
+
+        if (!chain->next) {
+            chain->count = 1;
+            continue;
+        }
+
+        /* find the best scores for single chains and pairs */
+        for (chain = saved[query_idx]; chain; chain = chain->next) {
+            Int4 score = (chain->pair ? chain->score + pair_bonus : chain->score);
+            if (score >= best_score) {
+                best_score = score;
+            }
+
+            if (chain->pair &&
+                chain->score + chain->pair->score >= best_pair_score) {
+
+                best_pair_score = chain->score + chain->pair->score;
+            }
+            
+            /* collect chains in the array */
+            if (num_chains >= array_size) {
+                array_size *= 2;
+                array = realloc(array, array_size * sizeof(HSPChain*));
+                if (!array) {
+                    return -1;
+                }
+            }
+            array[num_chains++] = chain;
+        }
+
+        /* sort chains by scores in descending order */
+        ASSERT(num_chains > 1);
+        qsort(array, num_chains, sizeof(HSPChain*), s_CompareChainsByScore);
+
+        /* find multiplicity for each chain: number of chains with same or
+           larger score */
+        /* Note that multiplicity is currently not reported. Only the number
+           of returned hits for each query is reported */
+        for (i = 0;i < num_chains; i++) {
+            Int4  k;
+
+            count++;
+            /* check for chains with the same score */
+            k = i + 1;
+            while (k < num_chains && array[k]->score == array[i]->score) {
+                k++;
+                count++;
+            }
+
+            /* save multiplicity */
+            for (;i < k;i++) {
+                array[i]->count = count;
+            }
+            i--;
+        }
+
+
+        /* remove chains with poor score and count chains with equal or better
+           score to the minimum pair one */
+        chain = saved[query_idx];
+        while (chain) {
+            Int4 score = (chain->pair ? chain->score + pair_bonus : chain->score);
+
+            /* We compare single chains with single chains and pairs with
+               pairs. There may be pairs with one strong and one weak hit.
+               Comparing single chain scores we can be left with single chains
+               from different pairs. This comparison aviods that. The first
+               pass ensures that pairs with poor scoring chains are removed,
+               so we do not have to compare singles with pairs. */
+            if ((!chain->pair && score < best_score) ||
+                (chain->pair && chain->score + chain->pair->score <
+                 best_pair_score)) {
+
+                HSPChain* next = chain->next;
+
+                chain->next = NULL;
+                HSPChainFree(chain);
+                chain = next;
+
+                if (prev) {
+                    prev->next = next;
+                }
+                else {
+                    saved[query_idx] = next;
+                }
+            }
+            else {
+                prev = chain;
+                chain = chain->next;
+            }
+        }
+    }
+
+    if (array) {
+        sfree(array);
+    }
+
+    return 0;
+}
+
+
+/* Compare chains by subject oid and offfset */
+static int s_CompareChainsByOid(const void* cha, const void* chb)
+{
+    const HSPChain* a = *((HSPChain**)cha);
+    const HSPChain* b = *((HSPChain**)chb);
+
+    if (a->oid > b->oid) {
+        return 1;
+    }
+    else if (a->oid < b->oid) {
+        return -1;
+    }
+    else if (a->hsps->hsp->subject.offset > b->hsps->hsp->subject.offset) {
+        return 1;
+    }
+    else if (a->hsps->hsp->subject.offset < b->hsps->hsp->subject.offset) {
+        return -1;
+    }
+
+    return 0;
+}
+
+/* Sort chains by subject oid and position and HSPs in the chains by query and
+   subject positions */
+static Int4 s_SortChains(HSPChain** saved, Int4 num_queries,
+                         int(*comp)(const void*, const void*))
+{
+    Int4 i;
+    Int4 array_size = 50;
+    HSPChain** chain_array = NULL;
+
+    if (!saved || num_queries < 0) {
+        return -1;
+    }
+
+    chain_array = calloc(array_size, sizeof(HSPChain*));
+    if (!chain_array) {
+        return -1;
+    }
+
+    /* for each query */
+    for (i = 0;i < num_queries;i++) {
+        HSPChain* chain = saved[i];
+        Int4 num_chains = 0;
+        Int4 k;
+
+        if (!chain) {
+            continue;
+        }
+
+        /* create an array of pointer to chains */
+        for (; chain; chain = chain->next) {
+            if (num_chains >= array_size) {
+                array_size *= 2;
+                chain_array = realloc(chain_array, array_size *
+                                      sizeof(HSPChain*));
+
+                ASSERT(chain_array);
+                if (!chain_array) {
+                    return -1;
+                }
+            }
+            chain_array[num_chains++] = chain;
+        }
+
+        if (num_chains > 1) {
+            /* sort chains */
+            qsort(chain_array, num_chains, sizeof(HSPChain*), comp);
+
+            /* create the list of chains in the new order */
+            for (k = 0;k < num_chains - 1;k++) {
+                chain_array[k]->next = chain_array[k + 1];
+            }
+            chain_array[num_chains - 1]->next = NULL;
+
+            saved[i] = chain_array[0];
+            ASSERT(saved[i]);
+        }
+    }
+
+    if (chain_array) {
+        free(chain_array);
+    }
+
+    return 0;
+}
+
+/* Convert internal HSPChain structure to BlastHSPChain used to report results */
+static BlastHSPChain* s_HSPChainToBlastHSPChain(HSPChain* chain)
+{
+    BlastHSPChain* new_chain = NULL;
+    HSPContainer* h = NULL;
+    Int4 num_hsps = 0;
+    Int4 index = 0;
+
+    if (!chain || !chain->hsps) {
+        return NULL;
+    }
+
+    new_chain = Blast_HSPChainNew();
+    if (!new_chain) {
+        return NULL;
+    }
+
+    new_chain->query_index = chain->context / NUM_STRANDS;
+    new_chain->oid = chain->oid;
+    new_chain->score = chain->score;
+    new_chain->adapter = chain->adapter;
+    new_chain->polyA = chain->polyA;
+
+    /* move hsps */
+    for (h = chain->hsps; h; h = h->next) {
+        num_hsps++;
+    }
+    new_chain->num_hsps = num_hsps;
+    new_chain->hsp_array = calloc(num_hsps, sizeof(BlastHSP*));
+    if (!new_chain->hsp_array) {
+        return NULL;
+    }
+    for (h = chain->hsps; h; h = h->next) {
+        new_chain->hsp_array[index++] = h->hsp;
+        h->hsp = NULL;
+    }
+
+    return new_chain;
+}
+
+/* Separate HSPs that overlap on the query to different chains (most output
+   formats do not support query overlaps) */
+static int s_RemoveOverlaps(HSPChain* chain, const ScoringOptions* score_opts,
+                            Int4 query_len)
+{
+    HSPContainer* h = NULL;
+    HSPContainer* prev = NULL;
+    HSPChain* tail = chain->next;
+    HSPChain* head = chain;
+    Boolean rescore = FALSE;
+
+    if (!chain) {
+        return -1;
+    }
+
+    /* current and previous HSP */
+    h = chain->hsps->next;
+    prev = chain->hsps;
+
+    for (; h; h = h->next) {
+        
+        /* if HSPs overlap on the query */
+        if (prev->hsp->query.end > h->hsp->query.offset) {
+            /* do a flat copy of the chain */
+            HSPChain* new_chain = HSPChainNew(chain->context);
+            memcpy(new_chain, chain, sizeof(HSPChain));
+            new_chain->pair = NULL;
+            new_chain->next = NULL;
+
+            /* new chain starts with h */
+            new_chain->hsps = h;
+
+            /* the original chain ends on the previous HSP */
+            prev->next = NULL;
+
+            /* add new chain to the list */
+            head->next = new_chain;
+            head = new_chain;
+
+            rescore = TRUE;
+        }
+        prev = h;
+    }
+
+    /* compute chains scores */
+    if (rescore) {
+        for (; chain; chain = chain->next) {
+            chain->score = s_ComputeChainScore(chain, score_opts, query_len,
+                                               FALSE);
+        }
+    }
+
+    /* re-attach other chains to the list */
+    head->next = tail;
+
+    return 0;
+}
+
+/* Populate HSP data and save final results */
+static int s_Finalize(HSPChain** saved, BlastMappingResults* results,
+                      const BlastQueryInfo* query_info,
+                      const BLAST_SequenceBlk* query_blk,
+                      const ScoringOptions* score_opts,
+                      Boolean is_paired)
+{
+    Int4 query_idx;
+    Int4 num_results = 0;
+    Int4 num = 0;
+    const Int4 kPairBonus = 21;
+    Int4* num_unique_chains = NULL;
+
+    /* remove poor scoring chains and find chain multiplicity */
+    if (!getenv("MAPPER_NO_PRUNNING")) {
+        s_PruneChains(saved, query_info->num_queries, kPairBonus);
+    }
+
+    /* find adapters in query sequences */
+    s_FindAdapters(saved, query_blk, query_info, score_opts);
+
+    /* find polyA tails in query sequences */
+    s_FindPolyATails(saved, query_blk, query_info);
+
+    /* find pairs of chains aligned to different subjects */
+    s_FindRearrangedPairs(saved, query_info);
+
+    /* sort chains by subject oid to ensure stable results for multithreaded
+       runs; sorting must be done here so that compartment numbers are stable */
+    /* FIXME: this may not be needed */
+    s_SortChains(saved, query_info->num_queries, s_CompareChainsByOid);
+
+    /* Compute number of results to store, and number of unique mappings for
+       each query (some chains may be copied to create pairs) */
+
+    num_unique_chains = calloc(query_info->num_queries, sizeof(Int4));
+    if (!num_unique_chains) {
+        return -1;
+    }
+
+    /* count number of unique mappings */
+    for (query_idx = 0; query_idx < query_info->num_queries; query_idx++) {
+        HSPChain* chain = saved[query_idx];
+        HSPChain* prev = chain;
+
+        if (!chain) {
+            continue;
+        }
+
+        num_unique_chains[query_idx]++;
+
+        chain = chain->next;
+        for (; chain; chain = chain->next, prev = prev->next) {
+            if (prev->oid != chain->oid ||
+                s_FindFragmentStart(prev) != s_FindFragmentStart(chain)) {
+
+                num_unique_chains[query_idx]++;
+            }
+        }
+    }
+
+    /* separate HSPs that overlap on the query into different chains */
+    if (getenv("MAPPER_NO_OVERLAPPED_HSP_MERGE")) {
+        for (query_idx = 0; query_idx < query_info->num_queries; query_idx++) {
+            HSPChain* chain = saved[query_idx];
+            Int4 query_len;
+
+            if (!chain) {
+                continue;
+            }
+
+            query_len = query_info->contexts[chain->context].query_length;
+            for (; chain; chain = chain->next) {
+                s_RemoveOverlaps(chain, score_opts, query_len);
+            }
+
+        }
+    }
+
+    /* count number of chains to report */
+    for (query_idx = 0; query_idx < query_info->num_queries; query_idx++) {
+        HSPChain* chain = saved[query_idx];
+
+        for (; chain; chain = chain->next) {
+            num_results++;
+        }
+    }
+
+    results->chain_array = calloc(num_results, sizeof(BlastHSPChain*));
+    if (!results->chain_array) {
+        if (num_unique_chains) {
+            free(num_unique_chains);
+        }
+        return -1;
+    }
+    results->num_results = num_results;
+
+    /* iterate over queries */
+    for (query_idx = 0;query_idx < query_info->num_queries;query_idx++) {
+        HSPChain* chain = saved[query_idx];
+
+        /* skip queries for which there are no saved results */
+        if (!chain) {
+            continue;
+        }
+
+        for (; chain; chain = chain->next) {
+            BlastHSPChain* new_chain = NULL;
+            BlastHSPChain* pair = NULL;
+            
+            /* pairs are processed together so that we can store their pointers
+               so a chain whose pair's context is smaller was already processed
+            */
+            if (chain->pair && chain->context > chain->pair->context) {
+                continue;
+            }
+            
+            new_chain = s_HSPChainToBlastHSPChain(chain);
+            ASSERT(new_chain);
+            if (!new_chain) {
+                return -1;
+            }
+            new_chain->multiplicity = num_unique_chains[new_chain->query_index];
+
+            results->chain_array[num++] = new_chain;
+
+            if (chain->pair) {
+                pair = s_HSPChainToBlastHSPChain(chain->pair);
+                chain->pair->compartment = -1;
+
+                new_chain->pair = pair;
+                pair->pair = new_chain;
+                pair->multiplicity = num_unique_chains[pair->query_index];
+                results->chain_array[num++] = pair;
+            }
+        }
+
+    }
+    ASSERT(num == results->num_results);
+
+    for (query_idx = 0; query_idx < query_info->num_queries; query_idx++) {
+        saved[query_idx] = HSPChainFree(saved[query_idx]);
+    }
+
+    if (num_unique_chains) {
+        sfree(num_unique_chains);
+    }
+
+    return 0;
+}
+
+/** Perform post-run clean-ups
+ * @param data The buffered data structure [in]
+ * @param results The HSP results to propagate [in][out]
+ */ 
+static int 
+s_BlastHSPMapperFinal(void* data, void* mapping_results)
+{
+    BlastHSPMapperData* spl_data = data;
+    BlastHSPMapperParams* params = spl_data->params;
+    BlastMappingResults* results = (BlastMappingResults*)mapping_results;
+
+    if (spl_data->saved_chains) {
+        s_Finalize(spl_data->saved_chains, results, spl_data->query_info,
+                   spl_data->query, &params->scoring_options, params->paired);
+    }
+
+    if (spl_data->saved_chains) {
+        sfree(spl_data->saved_chains);
+    }
+
+   return 0;
+}
+
+
+/* A node representing an HSP for finding the best chain of HSPs for RNA-seq */
+typedef struct HSPNode {
+    BlastHSP** hsp;     /* pointer to the entry in hsp_list */
+    Int4 best_score;    /* score for path that starts at this node */
+    struct HSPNode* path_next; /* next node in the path */
+} HSPNode;
+
+
+/* Copy a array of HSP nodes */
+static int s_HSPNodeArrayCopy(HSPNode* dest, HSPNode* source, Int4 num)
+{
+    int i;
+
+    if (!dest || !source) {
+        return -1;
+    }
+
+    for (i = 0;i < num;i++) {
+        dest[i] = source[i];
+        if (source[i].path_next) {
+            dest[i].path_next = dest + (source[i].path_next - source);
+        }
+    }
+   
+    return 0;
+}
+
+
+/* Maximum number of top scoring HSP chains to report for a single read and
+   strand */
+#define MAX_NUM_HSP_PATHS 40
+
+/* A chain of HSPs aligning a spliced RNA-Seq read to a genome */
+typedef struct HSPPath {
+    HSPNode** start;  /* array of chain starting nodes */
+    int num_paths;    /* number of chains */
+    Int4 score;       /* all chains in start have this cumulative score */
+} HSPPath;
+
+
+static HSPPath* HSPPathFree(HSPPath* path)
+{
+    if (path) {
+        if (path->start) {
+            free(path->start);
+        }
+        free(path);
+    }
+
+    return NULL;
+}
+
+static HSPPath* HSPPathNew(void)
+{
+    HSPPath* retval = calloc(1, sizeof(HSPPath));
+    if (!retval) {
+        return NULL;
+    }
+
+    retval->start = calloc(MAX_NUM_HSP_PATHS, sizeof(HSPNode*));
+    if (!retval->start) {
+        free(retval);
+        return NULL;
+    }
+
+    return retval;
+}
+
+
+#define NUM_SIGNALS 14
+
+/* Find a split for HSPs overlapping on the query by finding splice signals in
+   the subject sequence. The first HSP must have smaller query offset than the
+   second one. Subject is recreated from the query sequence and information
+   in an HSP.
+   @param first HSP with smaller query offset [in|out]
+   @param second HSP with larger query offset [in|out]
+   @param query Query sequence [in]
+   @return Status
+ */
+static Int4
+s_FindSpliceJunctionsForOverlaps(BlastHSP* first, BlastHSP* second,
+                                 Uint1* query, Int4 query_len)
+{
+    Int4 i, k;
+    /* splice signal pairs from PMC3167048 and spline output */
+    Uint1 signals[NUM_SIGNALS] = {0xb2, /* GTAG */
+                                  0x71, /* CTAC (reverse complement) */
+                                  0x72, /* CTAG */
+                                  0x92, /* GCAG */
+                                  0x9e, /* GCTG */
+                                  0x90, /* GCAA */
+                                  0x9a, /* GCGG */
+                                  0xbe, /* GTTG */
+                                  0xb0, /* GTAA */
+                                  0x31, /* ATAC */
+                                  0x30, /* ATAA */
+                                  0x32, /* ATAG */
+                                  0x33, /* ATAT */
+                                  
+                                  /*0x45, */ /* CACC */
+                                  0x1f  /* ACTT */};
+    Boolean found = FALSE;
+    Uint1* subject = NULL;
+    Int4 overlap_len;
+    const Uint1 kGap = 15;
+
+    /* HSPs must be sorted and must overlap only on the query */
+    ASSERT(first->query.offset < second->query.offset);
+    ASSERT(second->query.offset <= first->query.end);
+    ASSERT(first->subject.offset < second->subject.offset);
+
+
+    /* if there are edits within the overlap region, then try to maximize
+       the chain score by assigning a part of the overlap region to the
+       HSP that has fewer edits in the overlap */
+    if ((first->map_info->edits->num_edits > 0 &&
+         first->map_info->edits->edits[
+                        first->map_info->edits->num_edits - 1].query_pos >=
+            second->query.offset)
+        || (second->map_info->edits->num_edits > 0 &&
+            second->map_info->edits->edits[0].query_pos <= first->query.end)) {
+
+        /* find nummer of  edits in both HSPs within the overlap and assign
+           overlap to the HSP that has fewer edits */
+        Int4 num_first = 0;
+        Int4 num_second = 0;
+
+        /* find number of edits */
+        for (i = first->map_info->edits->num_edits - 1;i >= 0;i--) {
+            JumperEdit* edits = first->map_info->edits->edits;
+            if (edits[i].query_pos < second->query.offset) {
+                break;
+            }
+            num_first++;
+        }
+
+        for (i = 0;i < second->map_info->edits->num_edits;i++) {
+            JumperEdit* edits = second->map_info->edits->edits;
+            if (edits[i].query_pos >= first->query.end) {
+                break;
+            }
+            num_second++;
+        }
+
+        if (num_first > num_second) {
+            while (first->map_info->edits->num_edits > 0 &&
+                   first->map_info->edits->edits[
+                          first->map_info->edits->num_edits - 1].query_pos >=
+                   second->query.offset) {
+
+                JumperEdit* edits = first->map_info->edits->edits;
+                Uint1 edge = first->map_info->right_edge;
+                Int4 num_edits = first->map_info->edits->num_edits;
+                Int4 trim_by;
+                
+                if (edits[num_edits - 1].query_pos == query_len - 1) {
+                    edge >>= 2;
+                    edge |= edits[num_edits - 1].subject_base << 2;
+                }
+                else {
+                    edge = (edits[num_edits - 1].subject_base << 2) |
+                        query[edits[num_edits - 1].query_pos + 1];
+                }
+
+                trim_by = first->query.end -  edits[
+                            first->map_info->edits->num_edits - 1].query_pos;
+                /* if the edit is an insert in the genome, count genome bases
+                   when trimming the HSP */
+                if (edits[num_edits - 1].query_base == kGap) {
+                    trim_by++;
+                    /* FIXME: use proper scores here */
+                    s_TrimHSP(first, trim_by, FALSE, FALSE, -4, -4, -4);
+                }
+                else {
+                    s_TrimHSP(first, trim_by, TRUE, FALSE, -4, -4, -4);
+                }
+                first->map_info->right_edge = edge;
+            }
+        }
+        else if (num_second > num_first) {
+            while (second->map_info->edits->num_edits > 0 &&
+                   second->map_info->edits->edits[0].query_pos <
+                   first->query.end) {
+
+                JumperEdit* edits = second->map_info->edits->edits;
+                Uint1 edge = second->map_info->left_edge;
+                Int4 trim_by;
+
+                if (edits[0].query_pos == 0) {
+                    edge <<= 2;
+                    edge |= edits[0].subject_base;
+                }
+                else {
+                    edge = (query[edits[0].query_pos - 1] << 2) |
+                        edits[0].subject_base;
+                }
+
+                trim_by = edits[0].query_pos - second->query.offset + 1;
+                /* if the edit is an insert in the genome, count genome bases
+                   when trimming the HSP */
+                if (edits[0].query_base == kGap) {
+                    trim_by++;
+                    /* FIXME: use proper scores here */
+                    s_TrimHSP(second,
+                              edits[0].query_pos - second->query.offset + 1,
+                              FALSE, TRUE, -4, -4, -4);
+                }
+                else {
+                    s_TrimHSP(second,
+                              edits[0].query_pos - second->query.offset + 1,
+                              TRUE, TRUE, -4, -4, -4);
+                }
+                second->map_info->left_edge = edge;
+            }
+        }
+        else {
+            /* if the number of edits is the same we do not know how to
+               divide the overlap */
+            return 0;
+        }
+    }
+
+    /* give up if there are gaps in the alignments or mismatches still left in
+       the overlapping parts */
+    if ((first->map_info->edits->num_edits > 0 &&
+         first->map_info->edits->edits[
+                        first->map_info->edits->num_edits - 1].query_pos >=
+            second->query.offset)
+        || (second->map_info->edits->num_edits > 0 &&
+            second->map_info->edits->edits[0].query_pos <= first->query.end)) {
+
+        return 0;
+    }
+
+    /* recreate the subject sequence plus two bases on each side */
+    overlap_len = first->query.end - second->query.offset;
+    subject = calloc(overlap_len + 4, sizeof(Uint1));
+    if (!subject) {
+        return -1;
+    }
+
+    /* FIXME: lef_edge and right_edge should be changed to subject_overhangs */
+    subject[0] = (second->map_info->left_edge & 0xf) >> 2;
+    subject[1] = second->map_info->left_edge & 3;
+    memcpy(subject + 2, query + second->query.offset,
+           overlap_len * sizeof(Uint1));
+
+    subject[2 + overlap_len] = (first->map_info->right_edge & 0xf) >> 2;
+    subject[2 + overlap_len + 1] = first->map_info->right_edge & 3;
+
+    /* search for matching splice signals in the subject sequence */
+    for (k = 0;k < NUM_SIGNALS;k++) {
+
+        for (i = 0;i <= overlap_len && !found;i++) {
+
+            Uint1 seq = (subject[i] << 2) | subject[i + 1] |
+                (subject[i + 2] << 6) | (subject[i + 3] << 4);
+
+            /* if a splice signals are found, update HSPs */
+            if (seq == signals[k]) {
+                Int4 d = first->query.end - (second->query.offset + i);
+                first->query.end -= d;
+                first->subject.end -= d;
+                first->gap_info->num[first->gap_info->size - 1] -= d;
+                first->score -= d;
+                first->map_info->right_edge = (seq & 0xf0) >> 4;
+                first->map_info->right_edge |= MAPPER_SPLICE_SIGNAL;
+
+                d = i;
+                second->query.offset += d;
+                second->subject.offset += d;
+                second->gap_info->num[0] -= d;
+                second->score -= d;
+                second->map_info->left_edge = seq & 0xf;
+                second->map_info->left_edge |= MAPPER_SPLICE_SIGNAL;
+
+                ASSERT(first->gap_info->size > 1 ||
+                       first->query.end - first->query.offset ==
+                       first->subject.end - first->subject.offset);
+
+                ASSERT(second->gap_info->size > 1 ||
+                       second->query.end - second->query.offset ==
+                       second->subject.end - second->subject.offset);
+
+                found = TRUE;
+                break;
+            }
+        }
+    }
+
+    if (!found) {
+        first->map_info->right_edge &= ~MAPPER_SPLICE_SIGNAL;
+        second->map_info->left_edge &= ~MAPPER_SPLICE_SIGNAL;
+    }
+
+    if (subject) {
+        sfree(subject);
+    }
+
+    ASSERT(first->query.offset < first->query.end);
+    ASSERT(second->query.offset < second->query.end);
+
+    return 0;
+}
+
+static void s_ExtendAlignmentCleanup(Uint1* subject,
+                                     BlastGapAlignStruct* gap_align,
+                                     GapEditScript* edit_script,
+                                     JumperEditsBlock* edits)
+{
+    if (subject) {
+        free(subject);
+    }
+
+    BLAST_GapAlignStructFree(gap_align);
+    GapEditScriptDelete(edit_script);
+    JumperEditsBlockFree(edits);
+}
+
+/* Extend alignment on one side of an HSP up to a given point (a splice site)
+*/
+static Int4 s_ExtendAlignment(BlastHSP* hsp, const Uint1* query,
+                              Int4 query_from, Int4 query_to,
+                              Int4 subject_from, Int4 subject_to,
+                              const ScoringOptions* score_options,
+                              Boolean is_left)
+{
+    Int4 o_len;
+    Uint1* o_seq = NULL;
+    Uint1* subject = NULL;
+    BlastGapAlignStruct* gap_align = NULL;
+    GapEditScript* edit_script = NULL;
+    JumperEditsBlock* edits = NULL;
+    Int4 i, k, s;
+    /* number of query bases to align */
+    Int4 query_gap = query_to - query_from + 1;
+    /* number of subject bases to align */
+    Int4 subject_gap = subject_to - subject_from + 1;
+    Int4 num_identical;
+    Int4 query_ext_len, subject_ext_len;
+    Int4 ungapped_ext_len;
+
+    JUMP* jumper_table = NULL;
+
+    JUMP jumper_mismatch[] = {{1, 1, 0, 0}};
+
+    JUMP jumper_insertion[] = {{1, 1, 2, 0},
+                               {1, 0, 1, 0},
+                               {1, 1, 0, 0}};
+
+    JUMP jumper_deletion[] = {{1, 1, 2, 0},
+                              {0, 1, 1, 0},
+                              {1, 1, 0, 0}};
+                            
+    if (!hsp || !query || !hsp->map_info ||
+        !hsp->map_info->subject_overhangs) {
+        return -1;
+    }
+
+    /* length of the subject overgang sequence saved in the HSP */
+    o_len = is_left ? hsp->map_info->subject_overhangs->left_len :
+        hsp->map_info->subject_overhangs->right_len;
+    /* subject sequence */
+    o_seq = is_left ? hsp->map_info->subject_overhangs->left :
+        hsp->map_info->subject_overhangs->right;
+    ASSERT(o_seq);
+
+    /* compressed subject sequence (needed for computig jumper edits) */
+    subject = calloc(o_len / 4 + 1, sizeof(Uint1));
+    if (!subject) {
+        return -1;
+    }
+
+    /* compress subject sequence  */
+    k = 6;
+    s = 0;
+    for (i = 0;i < o_len;i++, k-=2) {
+        subject[s] |= o_seq[i] << k;
+        if (k == 0) {
+            s++;
+            k = 8;
+        }
+    }
+
+    /* gap_align is needed in jumper alignment API calls, we only allocate
+       fields that will be needed in these calls */
+    gap_align = calloc(1, sizeof(BlastGapAlignStruct));
+    if (!gap_align) {
+        s_ExtendAlignmentCleanup(subject, NULL, edit_script, edits);
+        return -1;
+    }
+    gap_align->jumper = JumperGapAlignNew(o_len * 2);
+    if (!gap_align->jumper) {
+        s_ExtendAlignmentCleanup(subject, gap_align, edit_script, edits);
+        return -1;
+    }
+
+    /* select jumper table based on the number of expected indels; we allow
+       only insertions or only deletions */
+    switch (SIGN(query_gap - subject_gap)) {
+    case 0: jumper_table = jumper_mismatch;
+        break;
+
+    case -1: jumper_table = jumper_deletion;
+        break;
+    
+    case 1: jumper_table = jumper_insertion;
+        break;
+
+    default:
+        ASSERT(0);
+        s_ExtendAlignmentCleanup(subject, gap_align, edit_script, edits);
+        return -1;
+    };
+
+    /* Compute alignment. We always do right extension as this is typically
+       a short alignment. This is global alignment, hence the large max number
+       of errors and no penalties for mismatches or gaps. The jumper table
+       specifies costs for alignment errors. The penalty socres specify
+       required number of macthes at the ends of the alignment. */
+    JumperExtendRightWithTraceback(query + query_from, o_seq + subject_from,
+                                   query_gap, subject_gap,
+                                   1, 0, 0, 0,
+                                   20, 20,
+                                   &query_ext_len, &subject_ext_len,
+                                   gap_align->jumper->right_prelim_block,
+                                   &num_identical,
+                                   FALSE,
+                                   &ungapped_ext_len,
+                                   jumper_table);
+
+    ASSERT(query_ext_len <= query_gap);
+    ASSERT(subject_ext_len <= subject_gap);
+    
+    /* Because this is a global alignment a gap may exist after the last query
+       or subject base which causes jumper extension to stop prematurely. If
+       this is the case, add the missing indel */
+    while (query_ext_len < query_gap) {
+        JumperPrelimEditBlockAdd(gap_align->jumper->right_prelim_block,
+                                 JUMPER_INSERTION);
+
+        query_ext_len++;
+    }
+
+    while (subject_ext_len < subject_gap) {
+        JumperPrelimEditBlockAdd(gap_align->jumper->right_prelim_block,
+                                 JUMPER_DELETION);
+
+        subject_ext_len++;
+    }
+    ASSERT(query_ext_len == query_gap);
+    ASSERT(subject_ext_len == subject_gap);
+
+    /* update gap info in the HSP */
+    edit_script = JumperPrelimEditBlockToGapEditScript(
+                                        gap_align->jumper->left_prelim_block,
+                                        gap_align->jumper->right_prelim_block);
+    if (!edit_script) {
+        s_ExtendAlignmentCleanup(subject, gap_align, edit_script, edits);
+        return -1;
+    }
+
+    if (is_left) {
+        hsp->gap_info = GapEditScriptCombine(&edit_script, &hsp->gap_info);
+    }
+    else {
+        hsp->gap_info = GapEditScriptCombine(&hsp->gap_info, &edit_script);
+        ASSERT(!edit_script);
+    }
+    ASSERT(hsp->gap_info);
+    if (!hsp->gap_info) {
+        s_ExtendAlignmentCleanup(subject, gap_align, edit_script, edits);
+        return -1;
+    }
+
+    /* update jumper edits */
+    gap_align->query_start = query_from;
+    gap_align->query_stop = query_from + query_ext_len;
+    gap_align->subject_start = subject_from;
+    gap_align->subject_stop = subject_from + subject_ext_len;
+    edits = JumperFindEdits(query, subject, gap_align);
+    ASSERT(edits);
+    if (!edits) {
+        s_ExtendAlignmentCleanup(subject, gap_align, NULL, edits);
+        return -1;
+    }
+ 
+    if (is_left) {
+        hsp->map_info->edits = JumperEditsBlockCombine(&edits,
+                                                   &hsp->map_info->edits);
+    }
+    else {
+        hsp->map_info->edits = JumperEditsBlockCombine(
+                                                    &hsp->map_info->edits,
+                                                    &edits);
+        ASSERT(!edits);
+    }
+    ASSERT(hsp->map_info->edits);
+    if (!hsp->map_info->edits) {
+        s_ExtendAlignmentCleanup(subject, gap_align, NULL, edits);
+        return -1;
+    }
+
+    if (is_left) {
+        hsp->query.offset -= query_ext_len;
+        hsp->subject.offset -= subject_ext_len;
+    }
+    else {
+        hsp->query.end += query_ext_len;
+        hsp->subject.end += subject_ext_len;
+    }
+
+    /* compute new HSP score */
+    hsp->score = s_ComputeAlignmentScore(hsp, score_options->penalty,
+                                         score_options->gap_open,
+                                         score_options->gap_extend);
+
+    ASSERT(hsp->gap_info);
+    ASSERT(hsp->map_info->edits);
+
+    ASSERT(subject);
+
+
+    if (subject) {
+        free(subject);
+    }
+    BLAST_GapAlignStructFree(gap_align);
+
+    return 0;
+}
+
+#define NUM_SIGNALS_CONSENSUS 2
+
+/* Find splcie junctions and extend HSP alignment if there are unaligned query
+   bases in the middle of a chain.
+*/
+static Int4
+s_FindSpliceJunctionsForGap(BlastHSP* first, BlastHSP* second,
+                            Uint1* query, Int4 query_len,
+                            const ScoringOptions* score_options)
+{
+    Int4 query_gap;
+    Int4 first_len, second_len;
+    Boolean found = FALSE;
+    Int4 k;
+    Int4 q;
+    Uint1 signal = 0;
+    /* use only cannonical splice signals here */
+    Uint1 signals[NUM_SIGNALS_CONSENSUS] = {0xb2, /* GTAG */
+                                            0x71  /* CTAC */};
+
+    if (!first || !second) {
+        return -1;
+    }
+
+    if (!first->map_info->subject_overhangs ||
+        !first->map_info->subject_overhangs->right ||
+        !second->map_info->subject_overhangs ||
+        !second->map_info->subject_overhangs->left) {
+        return -1;
+    }
+
+    /* number of query bases that fall between the HSPs */
+    query_gap = second->query.offset - first->query.end;
+
+    /* we do not have enough subject sequence saved */
+    if (query_gap > first->map_info->subject_overhangs->right_len ||
+        query_gap > second->map_info->subject_overhangs->left_len) {
+        return 0;
+    }
+
+    first_len = first->map_info->subject_overhangs->right_len;
+    second_len = second->map_info->subject_overhangs->left_len;
+
+    /* assume that the begining of intron was found, search for the splice
+       signal at the end of the first HSP */
+    for (q = 0; !found && q < 4;q++) {
+
+        if (first->query.end - q <= first->query.offset) {
+            break;
+        }
+
+        for (k = 0;k < NUM_SIGNALS_CONSENSUS && !found;k++) {
+            Int4 i;
+            Int4 status = 0;
+            Int4 start;
+            Uint1 seq;
+
+            if (q == 0) {
+                seq = (first->map_info->subject_overhangs->right[0] << 6) |
+                    (first->map_info->subject_overhangs->right[1] << 4);
+            }
+            else if (q == 1) {
+                seq = (query[first->query.end - 1] << 6) |
+                    (first->map_info->subject_overhangs->right[0] << 4);
+            }
+            else if (q > 1) {
+                seq = (query[first->query.end - q] << 6) |
+                    (query[first->query.end - q + 1] << 4);
+            }
+            else {
+                return -1;
+            }
+        
+            if (seq != (signals[k] & 0xf0)) {
+                continue;
+            }
+
+            /* location of the splice signa in subject overhang if there are no
+               indels */
+            start = second->map_info->subject_overhangs->left_len - 1 -
+                query_gap - 2 - q;
+
+            /* search for the splice signal at the end of intron;
+               allow for up to 1 indel */
+            for (i = MAX(start - 1, 0);i <= MIN(start + 1, second_len);i++) {
+                seq &= 0xf0;
+                seq |= (second->map_info->subject_overhangs->left[i] << 2) |
+                    second->map_info->subject_overhangs->left[i + 1];
+
+                /* if the splice signal found extend the alignment */
+                if (seq == signals[k]) {
+                    Int4 subject_gap = second_len - (i + 2) + q;
+                    if (query_gap - subject_gap < -1 ||
+                        query_gap - subject_gap > 1) {
+
+                        continue;
+                    }
+
+                    found = TRUE;
+                    if (q > 0) {
+                        s_TrimHSP(first, q, TRUE, FALSE,
+                                  score_options->penalty,
+                                  score_options->gap_open,
+                                  score_options->gap_extend);
+                    }
+
+                    status = s_ExtendAlignment(second, query,
+                             first->query.end,
+                             second->query.offset - 1,
+                             i + 2,
+                             second->map_info->subject_overhangs->left_len - 1,
+                             score_options,
+                             TRUE);
+
+                    ASSERT(status == 0);
+                    if (status) {
+                        return status;
+                    }
+
+                    signal = seq;
+                    break;
+                }
+            }
+        }
+    }
+
+    /* assume that end of the intron was found, search for the splice signal
+       at the beginning of the intron */
+    for (q = 0; !found && q < 4;q++) {
+
+        if (second->query.offset + q >= second->query.end) {
+            break;
+        }
+
+        for (k = 0;k < NUM_SIGNALS_CONSENSUS && !found;k++) {
+            Int4 i;
+            Int4 end;
+            Uint1 seq;
+            if (q == 0) {
+                seq =
+                    (second->map_info->subject_overhangs->left[second_len - 2] << 2) |
+                    second->map_info->subject_overhangs->left[second_len - 1];
+            }
+            else if (q == 1) {
+                seq = (second->map_info->subject_overhangs->left[second_len - 1] << 2) | query[second->query.offset];
+
+
+            }
+            else if (q > 1) {
+
+                if (second->map_info->edits->num_edits > 0 &&
+                    second->map_info->edits->edits[0].query_pos < q - 2) {
+
+                    break;
+                }
+
+                seq = (query[second->query.offset + q - 2] << 2) |
+                    query[second->query.offset + q + 1 - 2];
+            }
+            else {
+                return -1;
+            }
+
+            if (seq != (signals[k] & 0xf)) {
+                continue;
+            }
+
+            /* location of the splice signal in the subject overhang if there are
+               no indels */
+            end = query_gap + q;
+
+            /* allow for up to 1 indel */
+            for (i = MAX(end - 1, 0);i <= MIN(end + 1, first_len);i++) {
+                seq &= 0xf;
+                seq |= (first->map_info->subject_overhangs->right[i] << 6) |
+                    (first->map_info->subject_overhangs->right[i + 1] << 4);
+
+                if (seq == signals[k]) {
+                    Int4 status = 0;
+                    Int4 subject_gap = i - q;
+                    if (query_gap - subject_gap < -1 ||
+                        query_gap - subject_gap > 1) {
+
+                        continue;
+                    }
+
+                    found = TRUE;
+                    if (q > 0) {
+                        s_TrimHSP(second, q, TRUE, TRUE,
+                                  score_options->penalty,
+                                  score_options->gap_open,
+                                  score_options->gap_extend);
+                    }
+
+                    status = s_ExtendAlignment(first, query,
+                                               first->query.end,
+                                               second->query.offset - 1,
+                                               0, i - 1,
+                                               score_options,
+                                               FALSE);
+                    ASSERT(status == 0);
+                    if (status) {
+                        return status;
+                    }
+
+                    signal = seq;
+                    break;
+                }
+            }
+        }
+    }
+
+    if (found) {
+        first->map_info->right_edge = (signal & 0xf0) >> 4;
+        first->map_info->right_edge |= MAPPER_SPLICE_SIGNAL;
+        second->map_info->left_edge = signal & 0xf;
+        second->map_info->left_edge |= MAPPER_SPLICE_SIGNAL;
+
+        ASSERT(first->gap_info->size > 1 ||
+               first->query.end - first->query.offset ==
+               first->subject.end - first->subject.offset);
+
+        ASSERT(second->gap_info->size > 1 ||
+               second->query.end - second->query.offset ==
+               second->subject.end - second->subject.offset);
+    }
+    else {
+        first->map_info->right_edge &= ~MAPPER_SPLICE_SIGNAL;
+        second->map_info->left_edge &= ~MAPPER_SPLICE_SIGNAL;        
+    }
+
+    return 0;
+}
+
+
+#define NUM_SINGLE_SIGNALS 8
+
+/* Record subject bases pre and post alignment in HSP as possible splice
+   signals and set a flag for recognized signals */
+static Int4 s_FindSpliceSignals(BlastHSP* hsp, Uint1* query, Int4 query_len)
+{
+    SequenceOverhangs* overhangs = NULL;
+    /* splice signals in the order of preference */
+    Uint1 signals[NUM_SINGLE_SIGNALS] = {2,  /* AG */
+                                         11, /* GT */
+                                         13, /* TC */
+                                         7,  /* CT */
+                                         1,  /* AC */
+                                         4,  /* CA */
+                                         8,  /* GA */
+                                         14  /* TG */};
+
+    if (!hsp || !query) {
+        return -1;
+    }
+
+    overhangs = hsp->map_info->subject_overhangs;
+    ASSERT(overhangs);
+
+    if (!overhangs) {
+        return -1;
+    }
+
+    /* FIXME: check for polyA and adapters */
+
+    /* search for a splice signal on the left edge, unless the query is aligned
+       from the beginning */
+    if (hsp->query.offset == 0) {
+        hsp->map_info->left_edge = MAPPER_EXON;
+    }
+    else {
+        int k, i;
+        Boolean found = FALSE;
+
+        if (overhangs->left_len >= 2) {
+            Uint1 signal = (overhangs->left[overhangs->left_len - 2] << 2) |
+                overhangs->left[overhangs->left_len - 1];
+            
+            for (k = 0;k < NUM_SINGLE_SIGNALS;k++) {
+                if (signal == signals[k]) {
+                    hsp->map_info->left_edge = signal;
+                    hsp->map_info->left_edge |= MAPPER_SPLICE_SIGNAL;
+
+                    found = TRUE;
+                    break;
+                }
+            }
+        }
+
+        if (!found && overhangs->left_len >= 1) {
+            Uint1 signal = (overhangs->left[overhangs->left_len - 1] << 2) |
+                query[hsp->query.offset];
+
+            for (k = 0;k < NUM_SINGLE_SIGNALS;k++) {
+                if (signal == signals[k]) {
+                    hsp->map_info->left_edge = signal;
+                    hsp->map_info->left_edge |= MAPPER_SPLICE_SIGNAL;
+
+                    /* trim alignment */
+                    s_TrimHSP(hsp, 1, TRUE, TRUE, -8, 0, -8);
+
+                    /* update score at some point */
+                    found = TRUE;
+                    break;
+                }
+            }
+        }
+
+        for (i = hsp->query.offset;!found && i < 4;i++) {
+            Uint1 signal = (query[i] << 2) | query[i + 1];
+            for (k = 0;k < NUM_SINGLE_SIGNALS;k++) {
+                if (signal == signals[k]) {
+                    hsp->map_info->left_edge = signal;
+                    hsp->map_info->left_edge |= MAPPER_SPLICE_SIGNAL;
+
+                    /* trim alignment */
+                    s_TrimHSP(hsp, i + 2, TRUE, TRUE, -8, 0, -8);
+
+                    found = TRUE;
+                    break;
+                }
+            }
+        }
+    }
+
+    /* search for the splice signal on the right edge, unless the query is
+       aligned to the end */
+    if (hsp->query.end == query_len) {
+        hsp->map_info->right_edge = MAPPER_EXON;
+    }
+    else {
+        int k, i;
+        Boolean found = FALSE;
+
+        if (overhangs->right_len >= 2) {
+            Uint1 signal = (overhangs->right[0] << 2) | overhangs->right[1];
+            for (k = 0;k < NUM_SINGLE_SIGNALS;k++) {
+                if (signal == signals[k]) {
+                    hsp->map_info->right_edge = signal;
+                    hsp->map_info->right_edge |= MAPPER_SPLICE_SIGNAL;
+
+                    found = TRUE;
+                    break;
+                }
+            }
+            
+        }
+
+        if (!found && overhangs->right_len >= 1) {
+            Uint1 signal = (query[hsp->query.end - 1] << 2) |
+                overhangs->right[0];
+
+            for (k = 0;k < NUM_SINGLE_SIGNALS;k++) {
+                if (signal == signals[k]) {
+                    hsp->map_info->right_edge = signal;
+                    hsp->map_info->right_edge |= MAPPER_SPLICE_SIGNAL;
+
+                    /* update HSP */
+                    s_TrimHSP(hsp, 1, TRUE, FALSE, -8, 0, -8);
+
+                    /* update score at some point */
+                    found = TRUE;
+                    break;
+                }
+            }
+
+        }
+
+        for (i = hsp->query.end - 2;!found && i > hsp->query.end - 2 - 4;i--) {
+            Uint1 signal = (query[i] << 2) | query[i + 1];
+            for (k = 0;k < NUM_SINGLE_SIGNALS;k++) {
+                if (signal == signals[k]) {
+                    hsp->map_info->right_edge = signal;
+                    hsp->map_info->right_edge |= MAPPER_SPLICE_SIGNAL;
+
+                    /* update HSP */
+                    s_TrimHSP(hsp, hsp->query.end - i, TRUE, FALSE, -8, 0, -8);
+
+                    found = TRUE;
+                    break;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+
+/* Search for splice signals between two HSPs in a chain. The HSPs in the
+   chain must be sorted by query position in asceding order.
+*/
+static Int4
+s_FindSpliceJunctions(HSPChain* chains,
+                      const BLAST_SequenceBlk* query_blk,
+                      const BlastQueryInfo* query_info,
+                      const ScoringOptions* scoring_opts)
+{
+    HSPChain* ch = NULL;
+
+    if (!chains || !query_blk || !query_info || !scoring_opts) {
+        return -1;
+    }
+
+    /* iterate over HSPs in the chain */
+    for (ch = chains; ch; ch = ch->next) {
+        HSPContainer* h = ch->hsps;
+        Boolean searched = FALSE;
+        Uint1* query = NULL;
+        Int4 context;
+        Int4 query_len;
+        ASSERT(h);
+
+        context = h->hsp->context;
+        query = query_blk->sequence +
+            query_info->contexts[context].query_offset;
+        query_len = query_info->contexts[context].query_length;
+
+
+        /* FIXME: check the overhangs of the first and last HSP and try finding
+           splice signal within a few bases in the HSP */
+        if (!h->next) {
+
+            s_FindSpliceSignals(h->hsp, query, query_len);
+            searched = TRUE;
+        }
+
+        while (h->next) {
+            HSPContainer* next = h->next;
+            ASSERT(next);
+
+            /* process overlap if found */
+            if (next->hsp->query.offset <= h->hsp->query.end &&
+                next->hsp->query.offset > h->hsp->query.offset) {
+
+                s_FindSpliceJunctionsForOverlaps(h->hsp, next->hsp, query,
+                                                 query_len);
+                searched = TRUE;
+                h = h->next;
+            }
+            /* if not a spliced alignment */
+            else if (next->hsp->query.offset - h->hsp->query.end < 10 &&
+                     next->hsp->query.offset - h->hsp->query.end ==
+                     next->hsp->subject.offset - h->hsp->subject.end) {
+
+                /* save pointer to hsps after next */
+                HSPContainer* following = h->next->next;
+                BlastHSP* new_hsp = NULL;
+
+                /* duplicate HSPContainer with the two HSPs */
+                h->next->next = NULL;
+
+                /* extend the first HSP to cover the gap between HSPs */
+                if (next->hsp->query.offset - h->hsp->query.end > 1) {
+                    BlastHSP* first = h->hsp;
+                    BlastHSP* second = h->next->hsp;
+
+                    s_ExtendAlignment(first, query, first->query.end,
+                              second->query.offset - 1, 0,
+                              second->subject.offset - 1 - first->subject.end,
+                              scoring_opts, FALSE);
+                }
+
+                /* merge HSPs */
+                new_hsp = s_MergeHSPs(h->hsp, h->next->hsp, query,
+                                      scoring_opts);
+
+                if (new_hsp) {
+
+                    /* replace the two processed HSPs with the combined one */
+                    Blast_HSPFree(h->hsp);
+                    HSPContainerFree(h->next);
+                    h->hsp = new_hsp;
+                    h->next = following;
+                }
+                else {
+                    /* something went wrong with merging, use the initial
+                       HSPs */
+                    h->next->next = following; 
+                    h = h->next;
+                }
+            }
+            else if (next->hsp->query.offset - h->hsp->query.end > 0) {
+                s_FindSpliceJunctionsForGap(h->hsp, next->hsp, query,
+                                            query_len, scoring_opts);
+                searched = TRUE;
+                h = h->next;
+            }
+            else {
+                h = h->next;
+            }
+
+            /* FIXME: if a splice junction cannot be found, we can try looking
+               for the split between perfect matches */
+        }
+
+        /* Remove HSPs that have the same start position on the query or
+           subject within a chain. They may arise from modified HSP extents. */
+        h = ch->hsps;
+        while (h->next) {
+            if (h->hsp->query.offset >= h->next->hsp->query.offset ||
+                h->hsp->subject.offset >= h->next->hsp->subject.offset) {
+
+                if (h->hsp->score >= h->next->hsp->score) {
+                    HSPContainer* remove = h->next;
+                    h->next = h->next->next;
+                    remove->next = NULL;
+                    HSPContainerFree(remove);
+                }
+                else {
+                    HSPContainer* remove = h;
+                    HSPContainer* prev = ch->hsps;
+                    if (remove == ch->hsps) {
+                        ch->hsps = remove->next;
+                        h = ch->hsps;
+                    }
+                    else {
+                        while (prev->next && prev->next != h) {
+                            prev = prev->next;
+                        }
+                        ASSERT(prev->next && prev->next == remove);
+
+                        prev->next = remove->next;
+                        h = prev;
+                    }
+                    remove->next = NULL;
+                    HSPContainerFree(remove);
+                }
+
+                continue;
+
+            }
+            h = h->next;
+        }
+
+        /* recalculated chain score if splice sites were searched */
+        if (searched) {
+            ch->score = s_ComputeChainScore(ch, scoring_opts, query_len, FALSE);
+        }
+    }
+
+    s_TestChains(chains);
+    
+    return 0;
+}
+
+
+/* Find the best scoring chain of HSPs for aligning a single RNA-Seq read to
+   a genome on a single strand, returns all top scoring chains */
+static HSPChain* s_FindBestPath(HSPNode* nodes, Int4 num, HSPPath* path,
+                                Int4 oid, Boolean is_spliced,
+                                const BLAST_SequenceBlk* query_blk,
+                                const BlastQueryInfo* query_info,
+                                const ScoringOptions* scoring_opts)
+{
+    int i, k;
+    Int4 best_score = 0;
+    const Int4 kMaxIntronLength = 900000;
+    /* FIXME: use mismatch and/or gap extend penalty here */
+    HSPChain* retval = NULL;
+
+    if (!path || !nodes || !num) {
+        return NULL;
+    }
+    path->num_paths = 0;
+    path->score = 0;
+
+    for (i = num - 1;i >= 0;i--) {
+
+        BlastHSP* hsp = *(nodes[i].hsp);
+        int self_score = nodes[i].best_score;
+        /* FIXME: the is_spliced condition is a hack */
+        for (k = i + 1;k < num && is_spliced;k++) {
+
+            BlastHSP* newhsp = *(nodes[k].hsp);
+            Int4 new_score = nodes[k].best_score + self_score -
+                s_GetOverlapCost(newhsp, *(nodes[i].hsp), 4);
+
+            /* FIXME: some of the conditions double others */
+            const Int4 hsp_len = hsp->query.end - hsp->query.offset;
+            const Int4 newhsp_len = newhsp->query.end - newhsp->query.offset;
+            const Int4 overlap_len = MAX(MIN(hsp->query.end, newhsp->query.end) -
+                              MAX(hsp->query.offset, newhsp->query.offset), 0);
+
+            /* add next HSP to the path only if there is fewer than 10 query
+               bases unaligned between HSPs, newhsp is not contained within
+               hsp, newhsp aligns to the subject behind hsp, and score improves */
+            /* FIXME: there should be a penalty if new hsp->query.offset >
+               hsp->query.end */
+            if (newhsp->query.offset - hsp->query.end < 10 &&
+                newhsp->query.offset > hsp->query.offset &&
+                newhsp->query.end > hsp->query.end &&
+                newhsp->subject.offset - hsp->subject.end >=
+                   /* the difference on query may be smaller than zero,
+                      this will let as combine HSPs of which extension stopped
+                      too soon (not real introns) */
+                   newhsp->query.offset - hsp->query.end &&
+                newhsp->subject.offset - hsp->subject.end < kMaxIntronLength &&
+                (double)overlap_len / hsp_len < 0.75 &&
+                (double)overlap_len / newhsp_len < 0.75 &&
+                new_score > nodes[i].best_score) {
+
+                /* prefer paths with identified splice sites to those without
+                   ones */
+                /* FIXME: add min intron length to the condition below */
+                if (newhsp->subject.offset - hsp->subject.end > 1) {
+                    /* FIXME: The function that finds splice signals modifies
+                       HSPs, so we need to clone HSPs here. */
+                    BlastHSP* hsp_copy = Blast_HSPClone(hsp);
+                    BlastHSP* newhsp_copy = Blast_HSPClone(newhsp);
+
+                    HSPChain* chain = HSPChainNew(hsp->context);
+                    chain->hsps = HSPContainerNew(&hsp_copy);
+                    chain->hsps->next = HSPContainerNew(&newhsp_copy);
+
+                    s_FindSpliceJunctions(chain, query_blk, query_info,
+                                          scoring_opts);
+
+                    if ((chain->hsps->hsp->map_info->right_edge &
+                         MAPPER_SPLICE_SIGNAL) == 0) {
+
+/*                        new_score += scoring_opts->no_splice_signal; */
+                        /* FIXME: temporarely, do not create chains if splice
+                           signals are not found */
+                        new_score = 0;
+                    }
+
+                    chain = HSPChainFree(chain);
+                }
+                else if (newhsp->query.offset - hsp->query.end == 1) {
+                    /* FIXME: this is a temporary hack, we need to increase
+                       the score of combining two HSP into one with a
+                       mismatch so that it is scored the same as the one with
+                       splice signal */
+                    new_score++;
+                }
+                else {
+                    new_score = 0;
+                }
+
+                if (new_score > nodes[i].best_score) {
+                    nodes[i].best_score = new_score;
+                    nodes[i].path_next = &(nodes[k]);
+                }
+            }
+        }
+
+        /* we want to return all top scoring hits, so we save all paths with
+           top score */
+        if (nodes[i].best_score == best_score) {
+            if (path->num_paths < MAX_NUM_HSP_PATHS) {
+                path->start[path->num_paths++] = &(nodes[i]);
+            }
+        }
+        else if (nodes[i].best_score > best_score) {
+            best_score = nodes[i].best_score;
+            path->start[0] = &(nodes[i]);
+            path->num_paths = 1;
+        }
+    }
+    ASSERT(path->num_paths);
+    path->score = path->start[0]->best_score;
+
+    /* Find if any paths share an HSP and remove the one with the larger index.
+       Doing this at the end ensures that we find optimal path in terms of
+       score and/or HSP positions. */
+    for (i = 0;i < path->num_paths - 1;i++) {
+        if (!path->start[i]) {
+            continue;
+        }
+        for (k = i + 1;k < path->num_paths;k++) {
+            HSPNode* node_i = path->start[i];
+            if (!path->start[k]) {
+                continue;
+            }
+
+            while (node_i) {
+                HSPNode* node_k = path->start[k];
+                while (node_k) {
+                    if (node_i->hsp[0] == node_k->hsp[0]) {
+                        path->start[k] = NULL;
+                        break;
+                    }
+                    node_k = node_k->path_next;
+                }
+                node_i = node_i->path_next;
+            }
+
+        }
+    }
+
+    ASSERT(path->num_paths > 0);
+    ASSERT(path->start[0]);
+
+    /* conver from HSPPath to HSPChain structure */
+    if (path->num_paths > 0) {
+        HSPChain* ch = NULL;
+        HSPContainer* hc = NULL;
+        HSPNode* node = path->start[0];
+
+        retval = HSPChainNew((*node->hsp)->context);
+        if (!retval) {
+            return NULL;
+        }
+        retval->oid = oid;
+        retval->score = path->score;
+        retval->hsps = hc = HSPContainerNew(node->hsp);
+        node = node->path_next;
+        while (node) {
+            hc->next = HSPContainerNew(node->hsp);
+            if (!hc->next) {
+                HSPChainFree(retval);
+                return NULL;
+            }
+            hc = hc->next;
+            node = node->path_next;
+        }
+        ASSERT(retval->hsps);
+
+        ch = retval;
+        for (i = 1;i < path->num_paths;i++) {
+            node = path->start[i];
+            if (!node) {
+                continue;
+            }
+            ch->next = HSPChainNew((*node->hsp)->context);
+            ASSERT(ch->next);
+            if (!ch->next) {
+                HSPChainFree(retval);
+                return NULL;
+            }
+            ch->next->oid = oid;
+            ch->next->score = path->score;
+            ch->next->hsps = hc = HSPContainerNew(node->hsp);
+            node = node->path_next;
+            while (node) {
+                hc->next = HSPContainerNew(node->hsp);
+                ASSERT(hc->next);
+                if (!hc->next) {
+                    HSPChainFree(retval);
+                    return NULL;
+                }
+                hc = hc->next;
+                node = node->path_next;
+            }
+            ch = ch->next;
+            ASSERT(ch->hsps);
+        }
+    }
+
+    ASSERT(path->num_paths == 0 || s_TestChains(retval));
+    
+    return retval;
+}
+
+/* Compare HSPs by context (accending), and score (descending). */
+static int
+s_CompareHSPsByContextScore(const void* v1, const void* v2)
+{
+   BlastHSP* h1,* h2;
+   BlastHSP** hp1,** hp2;
+
+   hp1 = (BlastHSP**) v1;
+   hp2 = (BlastHSP**) v2;
+   h1 = *hp1;
+   h2 = *hp2;
+
+   if (!h1 && !h2)
+      return 0;
+   else if (!h1) 
+      return -1;
+   else if (!h2)
+      return 1;
+
+   if (h1->context < h2->context) 
+      return -1;
+   if (h1->context > h2->context)
+      return 1;
+
+   if (h1->score < h2->score)
+      return 1;
+   if (h1->score > h2->score)
+      return -1;
+
+   return 0;
+}
+
+static int
+s_CompareHSPsByContextSubjectOffset(const void* v1, const void* v2)
+{
+   BlastHSP* h1,* h2;
+   BlastHSP** hp1,** hp2;
+
+   hp1 = (BlastHSP**) v1;
+   hp2 = (BlastHSP**) v2;
+   h1 = *hp1;
+   h2 = *hp2;
+
+   if (!h1 && !h2)
+      return 0;
+   else if (!h1) 
+      return 1;
+   else if (!h2)
+      return -1;
+
+   /* If these are from different contexts, don't compare offsets */
+   if (h1->context < h2->context) 
+      return -1;
+   if (h1->context > h2->context)
+      return 1;
+
+   if (h1->subject.offset < h2->subject.offset)
+      return -1;
+   if (h1->subject.offset > h2->subject.offset)
+      return 1;
+
+   if (h1->query.offset < h2->query.offset)
+      return -1;
+   if (h1->query.offset > h2->query.offset)
+      return 1;
+
+   /* tie breakers: sort by decreasing score, then 
+      by increasing size of query range, then by
+      increasing subject range. */
+
+   if (h1->score < h2->score)
+      return 1;
+   if (h1->score > h2->score)
+      return -1;
+
+   if (h1->query.end < h2->query.end)
+      return 1;
+   if (h1->query.end > h2->query.end)
+      return -1;
+
+   if (h1->subject.end < h2->subject.end)
+      return 1;
+   if (h1->subject.end > h2->subject.end)
+      return -1;
+
+   return 0;
+}
+
+
+/* Pair data, used for selecting optimal pairs of aligned chains */
+typedef struct Pairinfo
+{
+    HSPChain* first;
+    HSPChain* second;
+    Int4 distance;
+    Int4 conf;
+    Int4 score;
+    Int4 trim_first;    // when a chain overextends past beginning of the pair
+    Int4 trim_second;   // it needs to be trimmed
+    Boolean valid_pair;
+} Pairinfo;
+
+
+static void s_BlastHSPMapperSplicedRunCleanUp(HSPPath* path,
+                                              HSPNode* nodes,
+                                              Pairinfo* pair_data)
+{
+    HSPPathFree(path);
+
+    if (nodes) {
+        sfree(nodes);
+    }
+
+    if (pair_data) {
+        sfree(pair_data);
+    }
+}
+
+
+/* Compare two HSP chain pairs aligned for the same query and subject
+   by score and distance */
+static int
+s_ComparePairs(const void* v1, const void* v2)
+{
+    Pairinfo* a = (Pairinfo*)v1;
+    Pairinfo* b = (Pairinfo*)v2;
+
+    if (a->score > b->score) {
+        return -1;
+    }
+    if (a->score < b->score) {
+        return 1;
+    }
+
+    if (a->conf < b->conf) {
+        return -1;
+    }
+    if (a->conf > b->conf) {
+        return 1;
+    }
+
+    if (a->distance < b->distance) {
+        return -1;
+    }
+    if (a->distance > b->distance) {
+        return 1;
+    }
+
+    return 0;
+}
+
+
+/* Trim beginning of a chain alignment up to the given subject position */
+static Int4 s_TrimChainStartToSubjPos(HSPChain* chain, Int4 subj_pos,
+                                      Int4 mismatch_score,
+                                      Int4 gap_open_score,
+                                      Int4 gap_extend_score)
+{
+    HSPContainer* h = NULL;
+    BlastHSP* hsp = NULL;
+    BlastHSP* next_hsp = NULL;
+    Int4 num_left;
+    Int4 old_score;
+
+    ASSERT(chain);
+    ASSERT(subj_pos >= 0);
+    if (!chain || subj_pos < 0) {
+        return 0;
+    }
+
+    /* first remove HSPs that are fully below the subject position */
+    h = chain->hsps;
+    while (h && h->hsp->subject.end < subj_pos) {
+        HSPContainer* tmp = h;
+        ASSERT(tmp);
+        h = h->next;
+        tmp->next = NULL;
+        chain->score -= tmp->hsp->score;
+        HSPContainerFree(tmp);
+    }
+    ASSERT(h);
+    chain->hsps = h;
+    if (!h) {
+        return -1;
+    }
+
+    /* if all remaning HSPs are above the subject position, then exit */
+    if (h->hsp->subject.offset >= subj_pos) {
+        return 0;
+    }
+
+    /* otherwise move HSP start positions */
+    hsp = h->hsp;
+    num_left = subj_pos - hsp->subject.offset;
+    ASSERT(num_left > 0 && num_left <= hsp->subject.end - hsp->subject.offset);
+
+    old_score = hsp->score;
+    s_TrimHSP(hsp, num_left, FALSE, TRUE, mismatch_score, gap_open_score,
+              gap_extend_score);
+
+    /* update chain score */
+    chain->score -= old_score - hsp->score;
+
+    /* remove splice signals and exon flags */
+    hsp->map_info->left_edge &= 0xff ^ MAPPER_SPLICE_SIGNAL;
+    hsp->map_info->left_edge &= 0xff ^ MAPPER_EXON;
+
+    /* check whether the HSP is contained within the next one and remove it
+       if it is */
+    next_hsp = NULL;
+    if (chain->hsps->next) {
+        next_hsp = chain->hsps->next->hsp;
+    }
+    if (next_hsp && hsp->query.offset >= next_hsp->query.offset) {
+        chain->hsps = h->next;
+        h->next = NULL;
+        HSPContainerFree(h);
+    }
+
+    return 0;
+}
+
+/* Trim chain alignment end up the the given subject position */
+static Int4 s_TrimChainEndToSubjPos(HSPChain* chain, Int4 subj_pos,
+                                    Int4 mismatch_score,
+                                    Int4 gap_open_score, Int4 gap_extend_score)
+{
+    HSPContainer* h = NULL;
+    BlastHSP* hsp = NULL;
+    Int4 num_left;
+    Int4 old_score;
+
+    ASSERT(chain);
+    ASSERT(subj_pos >= 0);
+    if (!chain || subj_pos <= 0) {
+        return -1;
+    }
+
+    /* first remove HSPs that are full above the subject position */
+    h = chain->hsps;
+    while (h->next && h->next->hsp->subject.end < subj_pos) {
+        h = h->next;
+    }
+
+    if (h->next) {
+        HSPContainer* hc = NULL;
+        if (h->next->hsp->subject.offset < subj_pos) {
+            h = h->next;
+        }
+
+        /* update chain score */
+        for (hc = h->next;hc != NULL;hc = hc->next) {
+            chain->score -= hc->hsp->score;
+        }
+
+        HSPContainerFree(h->next);
+        h->next = NULL;
+    }
+
+    /* if all remaning HSPs are below the subject position, exit */
+    if (h->hsp->subject.end <= subj_pos) {
+        return 0;
+    }
+
+    /* otheriwse move HSP end positions */
+    hsp = h->hsp;
+    num_left = hsp->subject.end - subj_pos;
+    ASSERT(num_left > 0 && num_left <= hsp->subject.end - hsp->subject.offset);
+
+    old_score = hsp->score;
+    s_TrimHSP(hsp, num_left, FALSE, FALSE, mismatch_score, gap_open_score,
+              gap_extend_score);
+
+    /* update chain score */
+    chain->score -= old_score - hsp->score;
+
+    /* remove splice signals and exon flags */
+    hsp->map_info->right_edge &= 0xff ^ MAPPER_SPLICE_SIGNAL;
+    hsp->map_info->right_edge &= 0xff ^ MAPPER_EXON;
+
+    /* check whether the HSP is contained within the next one and remove it
+       if it is */
+    if (chain->hsps != h) {
+        HSPContainer* hc = chain->hsps;
+        while (hc && hc->next != h) {
+            hc = hc->next;
+        }
+        ASSERT(hc && hc->next == h);
+        if (hc->hsp->query.end >= h->hsp->query.end) {
+            chain->score -= h->hsp->score;
+            HSPContainerFree(h);
+            hc->next = NULL;
+        }
+    }
+
+    return 0;
+}
+
+
+/* Find optimal pairs */
+static Boolean s_FindBestPairs(HSPChain** first_list,
+                               HSPChain** second_list,
+                               Int4 min_score,
+                               Pairinfo** pair_info_ptr,
+                               Int4* max_num_pairs,
+                               const ScoringOptions* scoring_options)
+{
+    HSPChain* first;
+    HSPChain* second;
+    Pairinfo* pair_info = *pair_info_ptr;
+    Int4 conv_bonus = 0;
+    Int4 num_pairs = 0;
+    Boolean found = FALSE;
+
+    /* iterate over all pairs of HSP chains for the first and second read of
+       the pair and collect pair information */
+    for (first = *first_list; first; first = first->next) {
+        for (second = *second_list; second; second = second->next) {
+            Int2 first_frame = first->hsps->hsp->query.frame;
+            Int2 second_frame = second->hsps->hsp->query.frame;
+
+            /* reallocate pair info array if necessary */
+            if (num_pairs >= *max_num_pairs) {
+                *max_num_pairs *= 2;
+                Pairinfo* new_pair_info =
+                    realloc(pair_info, *max_num_pairs * sizeof(Pairinfo));
+                if (!new_pair_info) {
+                    return -1;
+                }
+                pair_info = new_pair_info;
+                *pair_info_ptr = new_pair_info;
+            }
+
+            /* collect pair information */
+            pair_info[num_pairs].first = first;
+            pair_info[num_pairs].second = second;
+            pair_info[num_pairs].score = first->score + second->score;
+            pair_info[num_pairs].trim_first = 0;
+            pair_info[num_pairs].trim_second = 0;
+            pair_info[num_pairs].valid_pair = 0;
+
+            /* if the chains align on the opposite strands */
+            ASSERT(first_frame != 0 && second_frame != 0);
+            if (SIGN(first_frame) != SIGN(second_frame)) {
+                HSPChain* plus = NULL, *minus = NULL;
+                Int4 plus_start, minus_start;
+                HSPContainer* hsp = NULL;
+                Int4 distance = 0;
+
+                /* find which query aligns to plus and which to minus strand
+                   on the subject */
+                if (first_frame > 0) {
+                    plus = first;
+                }
+                else {
+                    minus = first;
+                }
+                if (second_frame > 0) {
+                    plus = second;
+                }
+                else {
+                    minus = second;
+                }
+                ASSERT(plus && minus);
+                
+                /* find start positions on the subject, for the minus strand we
+                   are interested subject start position on the minus strand,
+                   but the HSP has subject on plus and query on the minus
+                   strand, so we need to flip the query */
+                plus_start = plus->hsps->hsp->subject.offset;
+                hsp = minus->hsps;
+                while (hsp->next) {
+                    hsp = hsp->next;
+                }
+                ASSERT(hsp);
+                minus_start = hsp->hsp->subject.end;
+
+                /* this is also fragment length */
+                distance = minus_start - plus_start;
+                pair_info[num_pairs].distance = distance;
+
+                /* distance > 0 indicates a convergent pair (typical) */
+                if (distance > 0) {
+                    Int4 plus_end, minus_end;
+                    hsp = plus->hsps;
+                    while (hsp->next) {
+                        hsp = hsp->next;
+                    }
+                    ASSERT(hsp);
+                    plus_end = hsp->hsp->subject.end;
+                    minus_end = minus->hsps->hsp->subject.offset;
+
+                    /* HSP chain end going past the beginning of the chain
+                       for the pair, indicates that the this end of the
+                       query may be aligned to an adapater instead of a real
+                       sequence and needs to be trimmed */
+                    if (plus_end > minus_start || minus_end < plus_start) {
+                        ASSERT(plus && minus);
+
+                        /* check the 3' (right) side of the fragment */
+                        if (plus_end > minus_start) {
+                            ASSERT(plus_end - minus_start > 0);
+
+                            /* decrease the score by the trimmed portion; we
+                               assume here that the trimmed part aligns
+                               perfectly, which may not be the case, but this
+                               score is only used for comparison with different
+                               pairs */
+                            pair_info[num_pairs].score -=
+                                plus_end - minus_start;
+
+                            /* Mark which chain and up to what subject location
+                               needs to be trimmed. We cannot trim here,
+                               because pair_info holds poiners to chains that
+                               may be part of better pairs */
+                            if (plus == pair_info[num_pairs].first) {
+                                pair_info[num_pairs].trim_first = minus_start;
+                            }
+                            else {
+                                pair_info[num_pairs].trim_second = minus_start;
+                            }
+                        }
+
+                        /* check the 5' (left) side doe the fragment */
+                        if (minus_end < plus_start) {
+                            ASSERT(plus_start - minus_end > 0);
+
+                            pair_info[num_pairs].score -=
+                                plus_start - minus_end;
+
+                            if (minus == pair_info[num_pairs].first) {
+                                pair_info[num_pairs].trim_first = plus_start;
+                            }
+                            else {
+                                pair_info[num_pairs].trim_second = plus_start;
+                            }
+                        }
+                    }
+
+                    pair_info[num_pairs].conf = PAIR_CONVERGENT;
+
+                    /* add a bonus for convergent pairs; because they are more
+                       common we prefer them over different configurations
+                       with a sligntly better score */
+                    pair_info[num_pairs].score += conv_bonus;
+                }
+                else {
+                    pair_info[num_pairs].conf = PAIR_DIVERGENT;
+                }
+
+                /* skip pairs with a score smaller than one found for a
+                   different subject */
+                if (pair_info[num_pairs].score < min_score) {
+                    continue;
+                }
+
+                num_pairs++;
+            }
+            else {
+                /* for read pairs aligned in the same direction */
+                pair_info[num_pairs].conf = PAIR_PARALLEL;
+                pair_info[num_pairs].score -= 1;
+                num_pairs++;
+            }
+        }
+    }
+
+    if (num_pairs > 0) {
+        Int4 i;
+        Int4 best_score = pair_info[0].score;
+        Int4 margin = 5;
+        HSPChain* ch = NULL;
+
+        /* sort pair information by score, configuration distance */
+        qsort(pair_info, num_pairs, sizeof(Pairinfo), s_ComparePairs);
+    
+        /* iterate over pair information and collect pairs */
+        for (i=0;i < num_pairs;i++) {
+            HSPChain* f = pair_info[i].first;
+            HSPChain* s = pair_info[i].second;
+
+            /* skip pairs with chains already used in other pairs */
+            if (pair_info[i].first->pair || pair_info[i].second->pair) {
+                continue;
+            }
+            
+            /* skip pairs with scores significantly smaller than the best one
+               found */
+            if (best_score - pair_info[i].score > margin) {
+                break;
+            }
+
+            /* link chains as a pair */
+            f->pair = s;
+            s->pair = f;
+            f->pair_conf = s->pair_conf = pair_info[i].conf;
+            pair_info[i].valid_pair = TRUE;
+            found = TRUE;
+        }
+
+        /* for chains that pair with already paired chains, clone the paired
+           chain */
+        for (ch = *first_list; ch; ch = ch->next) {
+            HSPChain* pair = NULL;
+
+            if (ch->pair) {
+                continue;
+            }
+
+            i = 0;
+            while (i < num_pairs &&
+                   (pair_info[i].first != ch || !pair_info[i].second->pair ||
+                    pair_info[i].conf != PAIR_CONVERGENT ||
+                    best_score - pair_info[i].score > margin)) {
+                i++;
+            }
+            if (i >= num_pairs) {
+                continue;
+            }
+            ASSERT(pair_info[i].second->pair);
+
+            pair = s_CloneChain(pair_info[i].second);
+            ASSERT(pair);
+            ASSERT(s_TestChains(pair));
+            pair_info[i].second = pair;
+            ch->pair = pair;
+            pair->pair = ch;
+            ch->pair_conf = pair->pair_conf = pair_info[i].conf;
+            pair_info[i].valid_pair = TRUE;
+            HSPChainListInsert(second_list, pair, FALSE);
+        }
+
+        for (ch = *second_list; ch; ch = ch->next) {
+            HSPChain* pair = NULL;
+
+            if (ch->pair) {
+                continue;
+            }
+
+            i = 0;
+            while (i < num_pairs &&
+                   (pair_info[i].second != ch || !pair_info[i].first->pair ||
+                    pair_info[i].conf != PAIR_CONVERGENT ||
+                    best_score - pair_info[i].score > margin)) {
+                i++;
+            }
+            if (i >= num_pairs) {
+                continue;
+            }
+            ASSERT(pair_info[i].first->pair);
+
+            pair = s_CloneChain(pair_info[i].first);
+            ASSERT(pair);
+            ASSERT(s_TestChains(pair));
+            pair_info[i].first = pair;
+            ch->pair = pair;
+            pair->pair = ch;
+            ch->pair_conf = pair->pair_conf = pair_info[i].conf;
+            pair_info[i].valid_pair = TRUE;
+            HSPChainListInsert(first_list, pair, FALSE);
+        }
+
+        /* trim the alignments that overextend beyond the pair */
+        for (i = 0;i < num_pairs;i++) {
+            if (!pair_info[i].valid_pair ||
+                !pair_info[i].first->pair || !pair_info[i].second->pair) {
+                continue;
+            }
+
+            /* trim the first chain if its end goes beyond the start of
+               second on the subject */
+            if (pair_info[i].trim_first > 0) {
+                if (pair_info[i].first->hsps->hsp->query.frame > 0) {
+                    s_TrimChainEndToSubjPos(pair_info[i].first,
+                                            pair_info[i].trim_first,
+                                            scoring_options->penalty,
+                                            scoring_options->gap_open,
+                                            scoring_options->gap_extend);
+                }
+                else {
+                    /* minus strand of the qurey is represented by another
+                       (reverse complemented) sequence aligned like the plus
+                       strand, so the end of the chain is really the beginnig
+                       by query coordinates */
+                    s_TrimChainStartToSubjPos(pair_info[i].first,
+                                              pair_info[i].trim_first,
+                                              scoring_options->penalty,
+                                              scoring_options->gap_open,
+                                              scoring_options->gap_extend);
+                }
+            }
+
+            /* trim the second chain if its end goes beyond the start of the
+               first on the subject */
+            if (pair_info[i].trim_second > 0) {
+                if (pair_info[i].second->hsps->hsp->query.frame > 0) {
+                    s_TrimChainEndToSubjPos(pair_info[i].second,
+                                            pair_info[i].trim_second,
+                                            scoring_options->penalty,
+                                            scoring_options->gap_open,
+                                            scoring_options->gap_extend);
+                }
+                else {
+                    s_TrimChainStartToSubjPos(pair_info[i].second,
+                                              pair_info[i].trim_second,
+                                              scoring_options->penalty,
+                                              scoring_options->gap_open,
+                                              scoring_options->gap_extend);
+                }
+            }
+
+        }
+    }
+
+    return found;
+}
+
+
+/** Perform writing task for paired reads
+ * ownership of the HSP list and sets the dereferenced pointer to NULL.
+ * @param data To store results to [in][out]
+ * @param hsp_list Pointer to the HSP list to save in the collector. [in]
+ */
+static int 
+s_BlastHSPMapperSplicedPairedRun(void* data, BlastHSPList* hsp_list)
+{
+    BlastHSPMapperData* spl_data = data;
+    BlastHSPMapperParams* params = spl_data->params;
+    const ScoringOptions* scoring_opts = &params->scoring_options;
+    Boolean is_spliced  = params->splice;
+    BLAST_SequenceBlk* query_blk = spl_data->query;
+    BlastQueryInfo* query_info = spl_data->query_info;
+    const Int4 kDefaultMaxHsps = 1000;
+    Int4 max_hsps = kDefaultMaxHsps;
+    HSPNode* nodes = calloc(max_hsps, sizeof(HSPNode));
+    HSPPath* path = NULL;
+    BlastHSP** hsp_array;
+    Int4 num_hsps = 0;
+    Int4 i;
+
+    HSPChain** saved_chains = spl_data->saved_chains;
+    HSPChain* chain_array[2];
+    HSPChain* first = NULL, *second = NULL;
+    Int4 workspace_size = 40;
+    Pairinfo* pair_workspace = calloc(workspace_size, sizeof(Pairinfo));
+    /* the score bonus needs to include exon pars that were to short to be
+       aligned (at either end of the chain) */
+    const Int4 kPairBonus = is_spliced ? 21 : 5;
+
+    if (!hsp_list) {
+        s_BlastHSPMapperSplicedRunCleanUp(path, nodes, pair_workspace);
+        return 0;
+    }
+
+    if (!params || !nodes) {
+        s_BlastHSPMapperSplicedRunCleanUp(path, nodes, pair_workspace);
+        return -1;
+    }
+
+    hsp_array = hsp_list->hsp_array;
+
+    path = HSPPathNew();
+
+    /* sort HSPs by query context and subject position for spliced aligments */
+    if (is_spliced) {
+        qsort(hsp_array, hsp_list->hspcnt, sizeof(BlastHSP*),
+              s_CompareHSPsByContextSubjectOffset);
+    }
+    else {
+        /* for non spliced alignments, sort HSPs by query context and score */
+        qsort(hsp_array, hsp_list->hspcnt, sizeof(BlastHSP*),
+              s_CompareHSPsByContextScore);
+    }
+
+    i = 0;
+    chain_array[0] = NULL;
+    chain_array[1] = NULL;
+    while (i < hsp_list->hspcnt) {
+
+        Int4 context = hsp_array[i]->context;
+        /* is this query the first segment of a pair */
+        Boolean has_pair = (query_info->contexts[context].segment_flags ==
+                            eFirstSegment);
+        Int4 query_idx  = context / NUM_STRANDS;
+        Int4 first_context = query_idx * NUM_STRANDS;
+        Int4 context_next_fragment = has_pair ? (query_idx + 2) * NUM_STRANDS :
+            (query_idx + 1) * NUM_STRANDS;
+
+        HSPChain* new_chains = NULL;
+
+        /* iterate over contexts that belong to a read pair */
+        while (i < hsp_list->hspcnt &&
+               hsp_array[i]->context < context_next_fragment) {
+       
+            memset(nodes, 0, num_hsps * sizeof(HSPNode));
+            num_hsps = 0;
+            context = hsp_array[i]->context;
+
+            /* collect HSPs for the current context */
+            while (i < hsp_list->hspcnt && hsp_array[i]->context == context) {
+
+                /* Overlapping portions of two consecutive subject chunks
+                   may produce two HSPs representing the same alignment. We
+                   drop one of them here (assuming the HSPs for the same
+                   context are sorted by score or subject position). */
+                BlastHSP* h = (num_hsps == 0 ? NULL : *nodes[num_hsps - 1].hsp);
+                if (!h || hsp_array[i]->context != h->context ||
+                    hsp_array[i]->subject.offset != h->subject.offset ||
+                    hsp_array[i]->score != h->score) {
+
+                    /* reallocate node array if necessary */
+                    if (num_hsps >= max_hsps) {
+                        HSPNode* new_nodes = NULL;
+
+                        /* For non-spliced mapping we are only interested in
+                           the best scoring whole HSPs. HSPs are sorted by
+                           score and those that map to many places are not good
+                           so the node array does not need to be extended. */
+                        if (!is_spliced) {
+                            break;
+                        }
+
+                        max_hsps *= 2;
+                        new_nodes = calloc(max_hsps, sizeof(HSPNode));
+                        if (!nodes) {
+                            s_BlastHSPMapperSplicedRunCleanUp(path, nodes,
+                                                              pair_workspace);
+                            return -1;
+                        }
+                        s_HSPNodeArrayCopy(new_nodes, nodes, num_hsps);
+                        free(nodes);
+                        nodes = new_nodes;
+                    }
+
+                    nodes[num_hsps].hsp = &(hsp_array[i]);
+                    nodes[num_hsps].best_score = hsp_array[i]->score;
+
+                    num_hsps++;
+                }
+                i++;
+            }
+
+            /* find the best scoring chain of HSPs that align to exons
+               parts of the query and the subject */
+            new_chains = s_FindBestPath(nodes, num_hsps, path,
+                                        hsp_list->oid, is_spliced,
+                                        query_blk, query_info, scoring_opts);
+
+            ASSERT(new_chains);
+            HSPChainListInsert(&chain_array[(context - first_context) /
+                                            NUM_STRANDS],
+                               new_chains, FALSE);
+
+            /* skip HSPs for the same context if there are more then max
+               allowed per context */
+            while (i < hsp_list->hspcnt && hsp_array[i]->context == context) {
+                i++;
+            }
+        }
+
+#if _DEBUG
+        ASSERT(!chain_array[0] || s_TestChainsSorted(chain_array[0]));
+        ASSERT(!chain_array[1] || s_TestChainsSorted(chain_array[1]));
+#endif
+
+        if (is_spliced && chain_array[0]) {
+            s_FindSpliceJunctions(chain_array[0], query_blk, query_info,
+                                  scoring_opts);
+        }
+
+        if (is_spliced && chain_array[1]) {
+            s_FindSpliceJunctions(chain_array[1], query_blk, query_info,
+                                  scoring_opts);
+        }
+
+        first = chain_array[0];
+        second = chain_array[1];
+
+        /* If the chains provide sufficient score check for pairs.
+           The score bonus is added to prefer a pair with a slightly smaller
+           score to single chains with a better one. */
+        if (first && second) {
+
+            s_FindBestPairs(&first, &second, 0, &pair_workspace,
+                            &workspace_size, scoring_opts);
+
+            ASSERT(s_TestChains(first));
+            ASSERT(s_TestChains(second));
+        }
+
+        /* save all chains and remove ones with scores lower than 
+           best score - kPairBonus */
+        if (first) {
+            HSPChainListInsert(&saved_chains[query_idx], first, TRUE);
+            HSPChainListTrim(saved_chains[query_idx], kPairBonus);
+        }
+        if (second) {
+            HSPChainListInsert(&saved_chains[query_idx + 1], second, TRUE);
+            HSPChainListTrim(saved_chains[query_idx + 1], kPairBonus);
+        }
+
+#if _DEBUG
+        ASSERT(!chain_array[0] || s_TestChainsSorted(saved_chains[query_idx]));
+        ASSERT(!chain_array[1] || s_TestChainsSorted(saved_chains[query_idx + 1]));
+#endif
+
+        /* make temporary lists empty */
+        chain_array[0] = chain_array[1] = NULL;
+    }
+   
+    /* delete HSPs that were not saved in results */
+    hsp_list = Blast_HSPListFree(hsp_list);
+
+    s_BlastHSPMapperSplicedRunCleanUp(path, nodes, pair_workspace);
+
+    return 0; 
+}
+
+
+/** Free the writer 
+ * @param writer The writer to free [in]
+ * @return NULL.
+ */
+static
+BlastHSPWriter*
+s_BlastHSPMapperFree(BlastHSPWriter* writer) 
+{
+   BlastHSPMapperData *data = writer->data;
+   sfree(data->params); 
+   sfree(writer->data);
+   sfree(writer);
+   return NULL;
+}
+
+/** create the writer
+ * @param params Pointer to the hit paramters [in]
+ * @param query_info BlastQueryInfo (not used) [in]
+ * @return writer
+ */
+static
+BlastHSPWriter* 
+s_BlastHSPMapperPairedNew(void* params, BlastQueryInfo* query_info,
+                          BLAST_SequenceBlk* query)
+{
+   BlastHSPWriter* writer = NULL;
+   BlastHSPMapperData* data = NULL;
+/*   BlastHSPMapperParams * spl_param = params; */
+
+   /* allocate space for writer */
+   writer = malloc(sizeof(BlastHSPWriter));
+
+   /* fill up the function pointers */
+   writer->InitFnPtr   = &s_BlastHSPMapperPairedInit;
+   writer->FinalFnPtr  = &s_BlastHSPMapperFinal;
+   writer->FreeFnPtr   = &s_BlastHSPMapperFree;
+   writer->RunFnPtr    = &s_BlastHSPMapperSplicedPairedRun;
+
+   /* allocate for data structure */
+   writer->data = calloc(1, sizeof(BlastHSPMapperData));
+   data = writer->data;
+   data->params = params;
+   data->query_info = query_info;
+   data->query = query;
+    
+   return writer;
+}
+
+
+/*************************************************************/
+/** The following are exported functions to be used by APP   */
+
+BlastHSPMapperParams*
+BlastHSPMapperParamsNew(const BlastHitSavingOptions* hit_options,
+                        const BlastScoringOptions* scoring_options)
+{
+       BlastHSPMapperParams* retval = NULL;
+
+       if (hit_options == NULL)
+           return NULL;
+
+       retval = (BlastHSPMapperParams*)malloc(sizeof(BlastHSPMapperParams));
+       retval->hitlist_size = MAX(hit_options->hitlist_size, 10);
+       retval->paired = hit_options->paired;
+       retval->splice = hit_options->splice;
+       retval->program = hit_options->program_number;
+       retval->scoring_options.reward = scoring_options->reward;
+       retval->scoring_options.penalty = scoring_options->penalty;
+       retval->scoring_options.gap_open = -scoring_options->gap_open;
+       retval->scoring_options.gap_extend = -scoring_options->gap_extend;
+       retval->scoring_options.no_splice_signal = -2;
+       return retval;
+}
+
+BlastHSPMapperParams*
+BlastHSPMapperParamsFree(BlastHSPMapperParams* opts)
+{
+    if ( !opts )
+        return NULL;
+    sfree(opts);
+    return NULL;
+}
+
+BlastHSPWriterInfo*
+BlastHSPMapperInfoNew(BlastHSPMapperParams* params) {
+   BlastHSPWriterInfo * writer_info =
+                        malloc(sizeof(BlastHSPWriterInfo)); 
+
+   writer_info->NewFnPtr = &s_BlastHSPMapperPairedNew;
+
+   writer_info->params = params;
+   return writer_info;
+}
diff --git a/c++/src/algo/blast/core/jumper.c b/c++/src/algo/blast/core/jumper.c
new file mode 100644
index 0000000..7c47e74
--- /dev/null
+++ b/c++/src/algo/blast/core/jumper.c
@@ -0,0 +1,4025 @@
+/* $Id $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  Greg Boratyn
+ *
+ * Implementaion of Jumper alignment
+ *
+ */
+
+#include "blast_gapalign_priv.h"
+
+#include <algo/blast/core/blast_nalookup.h>
+#include <algo/blast/core/blast_hits.h>
+
+#include "jumper.h"
+
+
+JUMP jumper_default [] = {
+ {1, 1, 9, 0},  /* this was added for illumina */
+ {2, 2, 10, 0}, /* try double mismatch before indels */
+ {1, 0, 10, 0},    /* insert in 1 */ 
+ {0, 1, 10, 0},    /* deletion in 1 */
+ {1, 1, 6, 0},
+ {1, 0, 7, 0},
+ {0, 1, 7, 0},
+ {1, 0, 10, 2},
+ {0, 1, 10, 2},
+ {2, 0, 10, 2}, 
+ {0, 2, 10, 2}, 
+ {3, 0, 13, 2},
+ {0, 3, 13, 2},
+/* removed for illumina
+ {4, 0, 15, 3},
+ {0, 4, 15, 3},
+ {5, 0, 15, 3},
+ {0, 5, 15, 3},
+ {6, 0, 15, 3},
+ {0, 6, 15, 3},
+ {7, 0, 15, 3},
+ {0, 7, 15, 3},
+ {8, 0, 15, 3},
+ {0, 8, 15, 3},
+ {9, 0, 15, 3},
+ {0, 9, 15, 3},
+ {10, 0, 15, 3},
+ {0, 10, 15, 3},
+*/
+ {1, 1, 0, 0}    /* default is punctual */
+} ;
+
+JUMP jumper_edge [] = {
+    {1, 0, 6, 0},
+    {0, 1, 6, 0},
+    {1, 0, 2, 0},
+    {0, 1, 2, 0},
+    {1, 1, 0, 0}
+};
+
+
+JUMP jumper_ungapped [] = {
+ {1, 1, 0, 0}    /* default is punctual */
+};
+
+
+#define GET_BASE(seq, pos, compressed) (compressed ? NCBI2NA_UNPACK_BASE(seq[pos >> 2], 3 - (pos & 3)) : seq[pos])
+
+
+#define UNPACK_BASE_OLD(seq, pos) ((((seq)[(pos) >> 2] << (2 * ((pos) & 3))) & 0xC0) >> 6)
+
+
+#define UNPACK_BASE(seq, pos) (NCBI2NA_UNPACK_BASE((seq)[(pos) / 4], 3 - ((pos) & 3)))
+
+
+#define JUMPER_EDIT_BLOCK_ADD(block, op) ((block)->edit_ops[(block)->num_ops++] = op)
+
+
+/* convert jumper edit op type to BLAST op type */
+#define JOP_TO_OP(op) (op >= 0 ? eGapAlignSub : (op == JUMPER_INSERTION ? eGapAlignIns : eGapAlignDel))
+
+/* get number of ops */
+#define JOP_TO_NUM(op) (op > 0 ? op : 1)
+
+
+static JumperPrelimEditBlock* JumperPrelimEditBlockNew(Int4 size)
+{
+    JumperPrelimEditBlock* retval = calloc(1, sizeof(JumperPrelimEditBlock));
+    if (!retval) {
+        return NULL;
+    }
+
+    retval->edit_ops = calloc(size, sizeof(JumperOpType));
+    if (!retval->edit_ops) {
+        free(retval);
+        return NULL;
+    }
+
+    retval->num_allocated = size;
+    return retval;
+}
+
+static JumperPrelimEditBlock* JumperPrelimEditBlockFree(
+                                                JumperPrelimEditBlock* block)
+{
+    if (block) {
+        if (block->edit_ops) {
+            free(block->edit_ops);
+        }
+
+        free(block);
+    }
+
+    return NULL;
+}
+
+Int4 JumperPrelimEditBlockAdd(JumperPrelimEditBlock* block, JumperOpType op)
+{
+    if (block->num_ops >= block->num_allocated) {
+        block->edit_ops = realloc(block->edit_ops,
+                              block->num_allocated * sizeof(JumperOpType) * 2);
+
+        if (!block->edit_ops) {
+            return -1;
+        }
+        block->num_allocated *= 2;
+    }
+
+    if (block->num_ops > 0 && block->edit_ops[block->num_ops - 1] > 0 &&
+        op > 0) {
+
+        block->edit_ops[block->num_ops - 1] += op;
+    }
+    else {
+        block->edit_ops[block->num_ops++] = op;
+    }
+
+    return 0;
+}
+
+
+static void s_CreateTable(Uint4* table)
+{
+    int i, k;
+    for (i = 0; i < 256; i++) {
+        table[i] = 0;
+        for (k = 0;k < 4; k++) {
+            Uint4 cell = ((i >> (2 * k)) & 3);
+            switch (k) {
+            case 0: table[i] += cell << 3 * 8; break;
+            case 1: table[i] += cell << 2 * 8; break;
+            case 2: table[i] += cell << 1 * 8; break;
+            case 3: table[i] += cell; break;
+            default: ASSERT(0);
+            }
+        }
+    }
+}
+
+
+JumperGapAlign* JumperGapAlignFree(JumperGapAlign* jgap_align)
+{
+    if (!jgap_align) {
+        return NULL;
+    }
+
+    JumperPrelimEditBlockFree(jgap_align->left_prelim_block);
+    JumperPrelimEditBlockFree(jgap_align->right_prelim_block);
+    if (jgap_align->table) {
+        free(jgap_align->table);
+    }
+    sfree(jgap_align);
+    return NULL;
+}
+
+
+JumperGapAlign* JumperGapAlignNew(Int4 size)
+{
+    JumperGapAlign* retval = (JumperGapAlign*)calloc(1, sizeof(JumperGapAlign));
+    if (!retval) {
+        return NULL;
+    }
+
+    retval->left_prelim_block = JumperPrelimEditBlockNew(size);
+    if (!retval->left_prelim_block) {
+        JumperGapAlignFree(retval);
+        return NULL;
+    }
+
+    retval->right_prelim_block = JumperPrelimEditBlockNew(size);
+    if (!retval->right_prelim_block) {
+        JumperGapAlignFree(retval);
+        return NULL;
+    }
+
+    retval->table = calloc(256, sizeof(Uint4));
+    if (!retval->table) {
+        JumperGapAlignFree(retval);
+        return NULL;
+    }
+    s_CreateTable(retval->table);
+
+    return retval;
+}
+
+/* Reset prelim edit blocks so that they can be used for a new alignment */
+static void s_ResetJumperPrelimEditBlocks(JumperPrelimEditBlock* left,
+                                          JumperPrelimEditBlock* right)
+{
+    if (!left || !right) {
+        return;
+    }
+
+    left->num_ops = 0;
+    right->num_ops = 0;
+}
+
+
+/* Get query and subject position at the edit_index element of the edit script.
+   The jumper edit script must be going forwadr (from right extension) and
+   *query_pos and *subject_pos must be initialized to start positions of
+   the HSP. The resulting positions will be in *query_pos and *subject_pos. */
+static int s_GetSeqPositions(JumperPrelimEditBlock* edit_script, 
+                             Int4 edit_index,
+                             Int4* query_pos, Int4* subject_pos)
+{
+    Int4 j;
+
+    ASSERT(edit_script);
+    ASSERT(query_pos);
+    ASSERT(subject_pos);
+    ASSERT(edit_index < edit_script->num_ops);
+
+    if (!edit_script || !query_pos || !subject_pos) {
+        return -1;
+    }
+
+    for (j = 0;j < edit_index;j++) {
+        ASSERT(j < edit_script->num_ops);
+        
+        if (edit_script->edit_ops[j] == JUMPER_MISMATCH) {
+            (*query_pos)++;
+            (*subject_pos)++;
+        }
+        else if (edit_script->edit_ops[j] == JUMPER_INSERTION) {
+            (*query_pos)++;
+        }
+        else if (edit_script->edit_ops[j] == JUMPER_DELETION) {
+            (*subject_pos)++;
+        }
+        else {
+            *query_pos += edit_script->edit_ops[j];
+            *subject_pos += edit_script->edit_ops[j];
+        }
+    }
+
+    return 0;
+}
+
+
+/* Shift gaps to the right using the forward edit script (right extension).
+   Alignment score and number of matches may improve if input the alignment
+   is not optimal */
+static int s_ShiftGapsRight(JumperPrelimEditBlock* edit_script,
+                            const Uint1* query, const Uint1* subject,
+                            Int4 query_offset, Int4 subject_offset,
+                            Int4 query_length, Int4 subject_length,
+                            Int4* score, Int4 err_score, Int4* num_identical)
+{
+    Int4 i;
+    Int4 q_pos;
+    Int4 s_pos;
+
+    ASSERT(score && num_identical);
+
+    /* iterate over edit script elements */
+    for (i = 0;i < edit_script->num_ops;i++) {
+
+        /* if insertion or deltion */
+        if (edit_script->edit_ops[i] < 0) {
+
+            /* find the end of the gap; gap start will be marked with i and
+               k will be right after gap end */
+            Int4 k = i + 1;
+            while (k < edit_script->num_ops &&
+                   edit_script->edit_ops[k] == edit_script->edit_ops[i]) {
+                k++;
+            }
+
+            /* iterate over the next script elements and see if any can switch
+               sides with the indel */
+            for (;k < edit_script->num_ops;k++) {
+                ASSERT(edit_script->edit_ops[i] < 0);
+
+                /* if a deletion follows insertion (or the other way around),
+                   change it into a mismatch, it is one error instead of two */
+                if (edit_script->edit_ops[k] < 0 &&
+                    edit_script->edit_ops[k] != edit_script->edit_ops[i]) {
+                    Int4 j;
+
+                    /* remove one indel */
+                    for (j = k;j < edit_script->num_ops - 1;j++) {
+                        edit_script->edit_ops[j] =
+                            edit_script->edit_ops[j + 1];
+                    }
+                    edit_script->num_ops--;
+                    /* change the leftmost indel to a mismatch */
+                    edit_script->edit_ops[i] = JUMPER_MISMATCH;
+                    /* update poiner to the beginning of the gap */
+                    i++;
+
+                    /* update score */
+                    (*score) -= err_score;
+
+                    /* if there a no indels left, search for a new gap */
+                    if (i >= 0) {
+                        break;
+                    }
+                }
+
+                /* if a mismatch follows an indel, move the mismatch to the
+                   left; it will result in a different mismatch or a macth,
+                   so alignment score will not decrease */
+                if (edit_script->edit_ops[k] == JUMPER_MISMATCH) {
+                    /* shift the mismatch to the left by swapping ops */
+                    JumperOpType tmp = edit_script->edit_ops[i];
+                    edit_script->edit_ops[i] = edit_script->edit_ops[k];
+                    edit_script->edit_ops[k] = tmp;
+                    i++;
+
+                    /* check if mismatch did not change to a match and update 
+                       scores and identity if it did */
+                    q_pos = query_offset;
+                    s_pos = subject_offset;
+                    s_GetSeqPositions(edit_script, i - 1, &q_pos, &s_pos);
+                    if (query[q_pos] == UNPACK_BASE(subject, s_pos)) {
+                        edit_script->edit_ops[i - 1] = 1;
+                        (*score) -= err_score;
+                        (*score)++;
+                        (*num_identical)++;
+                    }
+                }
+
+                /* if matches follow an indel, check if bases to the right
+                   of the indel match bases to the left and move the matches
+                   if they do */
+                if (edit_script->edit_ops[k] > 0) {
+
+                    Int4 num_matches = (Int4)edit_script->edit_ops[k];
+                    Int4 /*j, */ b = 0;
+
+                    q_pos = query_offset;
+                    s_pos = subject_offset;
+                    s_GetSeqPositions(edit_script, i, &q_pos, &s_pos);
+
+                    /* find how many bases match */
+                    while (b < edit_script->edit_ops[k] &&
+                           query[q_pos] == UNPACK_BASE(subject, s_pos)) {
+
+                        b++;
+                        q_pos++;
+                        s_pos++;
+                        ASSERT(q_pos <= query_length);
+                        ASSERT(s_pos <= subject_length);
+                    }
+
+                    /* if none, look for a new indel */
+                    if (b == 0) {
+                        break;
+                    }
+
+                    /* otherwise shift the gap to the right */
+                    ASSERT(i > 0);
+                    /* if there are no matches preceding the indel, add a new
+                       script element */
+                    if (edit_script->edit_ops[i - 1] <= 0) {
+                        Int4 j;
+                        /* make space */
+                        JumperPrelimEditBlockAdd(edit_script, JUMPER_MISMATCH);
+                        for (j = edit_script->num_ops - 1;j > i;j--) {
+                            edit_script->edit_ops[j] =
+                                edit_script->edit_ops[j - 1];
+                        }
+                        k++;
+                        i++;
+                        /* new matches will be here */
+                        edit_script->edit_ops[i - 1] = 0;
+                    }
+                    /* move matching bases to the left */
+                    edit_script->edit_ops[i - 1] += b;
+                    edit_script->edit_ops[k] -= b;
+
+                    /* if not all matches were moved, search for a new indel */
+                    if (b < num_matches) {
+                        break;
+                    }
+                    else {
+                        /* otherwise remove the script element that held the
+                           moved matches */
+                        Int4 j;
+                        ASSERT(edit_script->edit_ops[k] == 0);
+                        for (j = k;j < edit_script->num_ops - 1;j++) {
+                            edit_script->edit_ops[j] =
+                                edit_script->edit_ops[j + 1];
+                        }
+                        edit_script->num_ops--;
+                        ASSERT(edit_script->num_ops > 0);
+                        k--;
+                    }
+                }
+            }
+
+            /* move indel pointer to the end of the indel, to find a new one */
+            i = k - 1;
+        } 
+    }
+    
+
+    return 0;
+}
+
+
+/* Shift gaps to the right and update scores and identities */
+static int s_ShiftGaps(BlastGapAlignStruct* gap_align,
+                       const Uint1* query, const Uint1* subject,
+                       Int4 query_length, Int4 subject_length,
+                       Int4 err_score, Int4* num_identical)
+{
+    Int4 i;
+    JumperPrelimEditBlock* left = gap_align->jumper->left_prelim_block;
+    JumperPrelimEditBlock* right = gap_align->jumper->right_prelim_block;
+    JumperPrelimEditBlock* combined = JumperPrelimEditBlockNew(
+                                                        right->num_allocated);
+    /* create a single forward edit script from the scripts for the left
+       and right extensions */
+    for (i = left->num_ops - 1;i >=0;i--) {
+        JUMPER_EDIT_BLOCK_ADD(combined, left->edit_ops[i]);
+    }
+
+    for (i = 0;i < right->num_ops;i++) {
+        JUMPER_EDIT_BLOCK_ADD(combined, right->edit_ops[i]);
+    }
+
+    for (i = 1;i < combined->num_ops;i++) {
+        if (combined->edit_ops[i - 1] > 0 && combined->edit_ops[i] > 0) {
+            Int4 k;
+            combined->edit_ops[i - 1] += combined->edit_ops[i];
+            for (k = i + 1;k < combined->num_ops;k++) {
+                combined->edit_ops[k - 1] = combined->edit_ops[k];
+            }
+            combined->num_ops--;
+        }
+    }
+
+    /* shift gaps */
+    s_ShiftGapsRight(combined, query, subject, gap_align->query_start,
+                     gap_align->subject_start, query_length,
+                     subject_length, &gap_align->score,
+                     err_score, num_identical);
+
+    /* trim flanking gaps */
+    while (combined->num_ops > 0 &&
+           combined->edit_ops[combined->num_ops - 1] < 0) {
+
+        if (combined->edit_ops[combined->num_ops - 1] == JUMPER_DELETION) {
+            gap_align->subject_stop--;
+        }
+        else {
+            gap_align->query_stop--;
+        }
+        combined->num_ops--;
+        gap_align->score -= err_score;
+    }
+
+    /* replace edit scripts with the new ones in gap_align */
+    left->num_ops = 0;
+    JumperPrelimEditBlockFree(right);
+    gap_align->jumper->right_prelim_block = combined;
+
+    return 0;
+}
+
+
+/* trimm the extension so that there is at least -mismatch penalty matches
+   after the last mismatch */
+static void s_TrimExtension(JumperPrelimEditBlock* jops, int margin,
+                            const Uint1** cp, Int4* cq, Int4* num_identical,
+                            Boolean is_right_ext)
+{
+
+    Int4 num_matches = 0;
+    Int4 index = jops->num_ops - 1;
+
+    if (jops->num_ops == 0 || margin == 0) {
+        return;
+    }
+
+    /* no trimming if mismatches do not cost anything */
+    if (margin == 0) {
+        return;
+    }
+
+    /* find number of local matches
+       Consequitive match operations are not guaranteed to be combined in the
+       preliminary block. This is to facilitate faster extensions */
+
+    while (index >= 1 && jops->edit_ops[index] > 0) {
+        num_matches += jops->edit_ops[index];
+        index--;
+    }
+
+    /* we do not remove the last op; thanks to word hit there will be enough
+       matches, but extension starting at word hit edge may not have enugh
+       matches */
+    while (jops->num_ops > 1 && num_matches < margin) {
+
+        JumperOpType op = jops->edit_ops[jops->num_ops - 1];
+        switch (JOP_TO_OP(op)) {
+        case eGapAlignSub:
+            if (op > 0) {
+                (*cp) += (is_right_ext ? -op : op);
+                (*cq) += (is_right_ext ? -op : op);
+                *num_identical -= op;
+            }
+            else if (is_right_ext) {
+                (*cp)--;
+                (*cq)--;
+            }
+            else {
+                (*cp)++;
+                (*cq)++;
+            }
+            break;
+
+        case eGapAlignIns:
+            if (is_right_ext) {
+                (*cp)--;
+            }
+            else {
+                (*cp)++;
+            }
+            break;
+
+        case eGapAlignDel:
+            if (is_right_ext) {
+                (*cq)--;
+            }
+            else {
+                (*cq)++;
+            }
+            break;
+
+        default:
+            ASSERT(0);
+        }
+        jops->num_ops--;
+
+        if (index >= jops->num_ops) {
+            num_matches = 0;
+            index = jops->num_ops - 1;
+            while (index >= 1 && jops->edit_ops[index] > 0) {
+                num_matches += jops->edit_ops[index];
+                index--;
+            }
+        }
+    }
+    ASSERT(jops->num_ops > 0);
+    /* remove the last op (closest to the word match) only if it is different
+       than match */
+    if (jops->num_ops == 1 && jops->edit_ops[0] <= 0) {
+        jops->num_ops--;
+    }
+    ASSERT(jops->num_ops == 0 || jops->edit_ops[jops->num_ops - 1] > 0);
+}
+
+/* Create BLAST edit script from jumper scripts for left and right extensions */
+GapEditScript* JumperPrelimEditBlockToGapEditScript(
+                                      JumperPrelimEditBlock* rev_prelim_block,
+                                      JumperPrelimEditBlock* fwd_prelim_block)
+{
+    Int4 size = 0;
+    Int4 i;
+    Int4 index;
+    GapEditScript* retval;
+    EGapAlignOpType last_op;
+
+    if (rev_prelim_block->num_ops == 0 && fwd_prelim_block->num_ops == 0) {
+        return NULL;
+    }
+
+    /* find the size of the resulting edit scrtipt */
+    size = 1;
+    last_op = rev_prelim_block->num_ops > 0 ? 
+        JOP_TO_OP(rev_prelim_block->edit_ops[rev_prelim_block->num_ops - 1])
+        : JOP_TO_OP(fwd_prelim_block->edit_ops[0]);
+
+    for (i = rev_prelim_block->num_ops - 2;i >= 0;i--) {
+        if (last_op != JOP_TO_OP(rev_prelim_block->edit_ops[i])) {
+            size++;
+            last_op = JOP_TO_OP(rev_prelim_block->edit_ops[i]);
+        }
+    }
+    for (i = 0;i < fwd_prelim_block->num_ops;i++) {
+        if (last_op != JOP_TO_OP(fwd_prelim_block->edit_ops[i])) {
+            size++;
+            last_op = JOP_TO_OP(fwd_prelim_block->edit_ops[i]);
+        }
+    }
+
+    retval = GapEditScriptNew(size);
+
+    /* rev_prelim_block needs to be reveresed, because left extension edit
+       operations are collected backwards */
+    index = 0;
+    if (rev_prelim_block->num_ops > 0) {
+        i = rev_prelim_block->num_ops - 1;
+        retval->op_type[index] = JOP_TO_OP(rev_prelim_block->edit_ops[i]);
+        retval->num[index] = JOP_TO_NUM(rev_prelim_block->edit_ops[i]);
+        last_op = retval->op_type[index];
+        i--;
+        for (;i >= 0;i--) {
+            EGapAlignOpType current_op = JOP_TO_OP(rev_prelim_block->edit_ops[i]);
+            if (current_op == last_op) {
+                retval->num[index] += JOP_TO_NUM(rev_prelim_block->edit_ops[i]);
+            }
+            else {
+                index++;
+                retval->op_type[index] = JOP_TO_OP(rev_prelim_block->edit_ops[i]);
+                retval->num[index] = JOP_TO_NUM(rev_prelim_block->edit_ops[i]);
+                last_op = current_op;
+            }
+        }
+    }
+
+    i = 0;
+    if (index == 0 && retval->num[index] == 0) {
+        retval->op_type[index] = JOP_TO_OP(fwd_prelim_block->edit_ops[i]);
+        retval->num[index] = JOP_TO_NUM(fwd_prelim_block->edit_ops[i]);
+        last_op = retval->op_type[index];
+        i++;
+    }
+    for (;i < fwd_prelim_block->num_ops;i++) {
+        EGapAlignOpType current_op = JOP_TO_OP(fwd_prelim_block->edit_ops[i]);
+        if (current_op == last_op) {
+            retval->num[index] += JOP_TO_NUM(fwd_prelim_block->edit_ops[i]);
+        }
+        else {
+            index++;
+            retval->op_type[index] = JOP_TO_OP(fwd_prelim_block->edit_ops[i]);
+            retval->num[index] = JOP_TO_NUM(fwd_prelim_block->edit_ops[i]);
+            last_op = current_op;
+        }
+    }
+
+    return retval;
+}
+
+
+/* Compute a score for an extension */
+static Int4 s_ComputeExtensionScore(JumperPrelimEditBlock* edit_script,
+                                    Int4 match_score, Int4 mismatch_score,
+                                    Int4 gap_open_score, Int4 gap_extend_score)
+{
+    Int4 score = 0;
+    Int4 i;
+
+    for (i = 0;i < edit_script->num_ops;i++) {
+        Int4 op = edit_script->edit_ops[i];
+
+/* indel penalty is the same as mismatch penalty
+        if (op < 0) {
+            continue;
+        }
+*/
+
+        if (op > 0) {
+            score += op * match_score;
+        }
+        else if (op == 0) {
+            score += mismatch_score;
+        }
+        else {
+            score += gap_open_score;
+            while (i < edit_script->num_ops && edit_script->edit_ops[i] == op) {
+                score += gap_extend_score;
+                i++;
+            }
+            i--;
+        }
+    }
+
+    return score;
+}
+
+
+
+/* query is one base per byte, subject is 2NA, we assume that initial seed is 
+   at byte edge */
+
+
+Int4 JumperExtendRightCompressed(const Uint1* query, const Uint1* subject, 
+                                 int query_length, int subject_length,
+                                 Int4 match_score, Int4 mismatch_score,
+                                 Int4 gap_open_score, Int4 gap_extend_score,
+                                 int max_mismatches, int window, Uint4* table,
+                                 Int4* query_ext_len, Int4* subject_ext_len,
+                                 Int4* num_identical,
+                                 Int4* ungapped_ext_len)
+{ 
+    const Uint1 *cp, *cp1, *cpmax, *cpmax4, *cpstop = NULL;
+    Int4 cq, cq1, cqmax, cqmax4, cqstop = 0;
+    int i, n;
+    JUMP *jp;
+    int num_mismatches = 0;
+    int new_matches = 0;
+    Uint4 trace = 0;
+    Uint4 trace_mask = (1 << max_mismatches) - 1;
+    Int4 score = 0, best_score = 0;
+    Boolean is_ungapped = TRUE;
+    JUMP* jumper = jumper_default;
+
+    if (!query || ! subject) {
+        return -1;
+    }
+
+    cp = query;
+    cpmax = cp + query_length;
+
+    /* or assume matches up to byte edge */
+    cq = 0;
+    cqmax = subject_length;
+
+    cpmax4 = cpmax - 4;
+    cqmax4 = cqmax - 4;
+
+    /* skip the first pair as it is compared by the left extension */
+    cp++;
+    cq++;
+
+    while (cp < cpmax && cq < cqmax && num_mismatches < max_mismatches) {
+
+        if (!(cq & 3) && cp < cpmax4 && cq < cqmax4) {
+            if (table[subject[cq / 4]] == *(Uint4*)(cp)) {
+                cp += 4;
+                cq += 4;
+                new_matches += 4;
+                continue;
+            }
+        }
+
+        if (*cp == UNPACK_BASE(subject, cq)) {
+            cp++;
+            cq++;
+            new_matches++;
+            continue;
+        }
+
+        jp = jumper; 
+        jp-- ;
+        while (jp++) { /* 1, 1, 0, 0 = last always accepted */
+         
+            if (!jp->lng) {
+                break;
+            }
+
+            n = 0;
+            i = jp->ok;
+            cp1 = cp + jp->dcp;
+            cq1 = cq + jp->dcq;
+            while (i--) {
+                if (cp1 >= cpmax || cq1 >= cqmax
+                    || *cp1++ != UNPACK_BASE(subject, cq1)) {
+
+                    goto next_jp;
+                }
+                cq1++;
+            }
+
+            n = 0;
+            i = jp->lng;
+            cp1 = cp + jp->dcp;
+            cq1 = cq + jp->dcq;
+            if (i + cp1 >= cpmax || i + cq1 >= cqmax) {
+                continue;
+            }
+            while (i--) {
+                if (cp1 >= cpmax || cq1 >= cqmax) {
+                    goto next_jp;
+                }
+                if (*cp1++ != UNPACK_BASE(subject, cq1)) {
+                    if (++n > jp->ok) {
+                        goto next_jp;
+                    }
+                }
+                cq1++;
+            }
+            /* current jumper row works */
+            break;
+
+next_jp:
+            continue;
+        }
+
+        if (new_matches) {
+            if (trace) {
+                if (new_matches < window) {
+                    trace <<= new_matches;
+                }
+                else {
+                    trace = 0;
+                }
+            }
+            *num_identical += new_matches;
+            score += new_matches * match_score;
+            new_matches = 0;
+        }
+
+        /* update recent errors and score */
+        if (jp->dcp == jp->dcq) {
+            score += mismatch_score * jp->dcp;
+            if (trace & trace_mask) {
+                num_mismatches += jp->dcp;
+                trace <<= jp->dcp;
+                trace |= (1 << jp->dcp) - 1;
+            }
+            else {
+                num_mismatches = jp->dcp;
+                trace = (1 << jp->dcp) - 1;
+            }
+        }
+        /* note that we are not penalizing gaps */
+        
+        /* save the length of the ungapped extension */
+        if (is_ungapped && jp->dcp != jp->dcq) {
+            *ungapped_ext_len = cp - query - 1;
+            is_ungapped = FALSE;
+        }
+
+        /* update cp and cq */
+        cp += jp->dcp;
+        cq += jp->dcq;
+        
+        /* we have already checked that these are matches */
+        if (jp->ok == 0 && jp->lng) {
+            cp += jp->lng;
+            cq += jp->lng;
+            trace <<= jp->lng;
+            *num_identical += jp->lng;
+            score += jp->lng * match_score;
+        }
+
+        /* update optimal alignment extent */
+        if (score >= best_score) {
+            cpstop = cp;
+            cqstop = cq;
+            best_score = score;
+        }
+    }
+
+    /* if matches all the way to the end of a sequence */
+    if (new_matches) {
+        *num_identical += new_matches;
+        score += new_matches * match_score;
+        if (score >= best_score) {
+            cpstop = cp;
+            cqstop = cq;
+        }        
+    }
+
+    *query_ext_len = cpstop - query;
+    *subject_ext_len = cqstop;
+
+    if (is_ungapped) {
+        *ungapped_ext_len = *query_ext_len;
+    }
+
+    return best_score;
+} /* JumperExtendRightCompressed */
+
+
+
+Int4 JumperExtendRightCompressedWithTraceback(
+                                 const Uint1* query, const Uint1* subject, 
+                                 int query_length, int subject_length,
+                                 Int4 match_score, Int4 mismatch_score,
+                                 Int4 gap_open_score, Int4 gap_extend_score,
+                                 int max_mismatches, int window, Uint4* table,
+                                 Int4* query_ext_len, Int4* subject_ext_len,
+                                 JumperPrelimEditBlock* edit_script,
+                                 Int4* num_identical,
+                                 Boolean left_extension,
+                                 Int4* ungapped_ext_len,
+                                 JUMP* jumper)
+{ 
+    const Uint1 *cp, *cp1, *cpmax, *cpmax4;
+    Int4 cq, cq1, cqmax, cqmax4;
+    int i, n;
+    JUMP *jp;
+    int num_mismatches = 0;
+    int new_matches = 0;
+    Uint4 trace = 0;
+    Uint4 trace_mask = (1 << max_mismatches) - 1;
+    Boolean is_ungapped = TRUE;
+
+    if (!query || ! subject) {
+        return -1;
+    }
+
+    cp = query;
+    cpmax = cp + query_length;
+
+    /* or assume matches up to byte edge */
+    cq = 0;
+    cqmax = subject_length;
+
+    cpmax4 = cpmax - 4;
+    cqmax4 = cqmax - 4;
+
+    /* skip the first pair as it is compared by the left extension */
+    cp++;
+    cq++;
+    if (!left_extension) {
+        new_matches++;
+    }
+
+    while (cp < cpmax && cq < cqmax && num_mismatches < max_mismatches) {
+
+        if (!(cq & 3) && cp < cpmax4 && cq < cqmax4) {
+            if (table[subject[cq / 4]] == *(Uint4*)(cp)) {
+                cp += 4;
+                cq += 4;
+                new_matches += 4;
+                continue;
+            }
+        }
+
+        if (*cp == UNPACK_BASE(subject, cq)) {
+            cp++;
+            cq++;
+            new_matches++;
+            continue;
+        }
+
+        jp = jumper; 
+        jp-- ;
+        while (jp++) { /* 1, 1, 0, 0 = last always accepted */
+         
+            if (!jp->lng) {
+                break;
+            }
+
+            n = 0;
+            i = jp->ok;
+            cp1 = cp + jp->dcp;
+            cq1 = cq + jp->dcq;
+            while (i--) {
+                if (cp1 >= cpmax || cq1 >= cqmax
+                    || *cp1++ != UNPACK_BASE(subject, cq1)) {
+
+                    goto next_jp;
+                }
+                cq1++;
+            }
+
+            n = 0;
+            i = jp->lng;
+            cp1 = cp + jp->dcp;
+            cq1 = cq + jp->dcq;
+            if (i + cp1 >= cpmax || i + cq1 >= cqmax) {
+                continue;
+            }
+            while (i--) {
+                if (cp1 >= cpmax || cq1 >= cqmax) {
+                    goto next_jp;
+                }
+                if (*cp1++ != UNPACK_BASE(subject, cq1)) {
+                    if (++n > jp->ok) {
+                        goto next_jp;
+                    }
+                }
+                cq1++;
+            }
+            /* current jumper row works */
+            break;
+
+next_jp:
+            continue;
+        }
+
+        if (new_matches) {
+            ASSERT(edit_script->num_ops < edit_script->num_allocated);
+            JUMPER_EDIT_BLOCK_ADD(edit_script, new_matches);
+            if (trace) {
+                if (new_matches < window) {
+                    trace <<= new_matches;
+                }
+                else {
+                    trace = 0;
+                }
+            }
+            *num_identical += new_matches;
+            new_matches = 0;
+        }
+
+        /* update recent errors */
+        if (jp->dcp == jp->dcq) {
+            if (trace & trace_mask) {
+                num_mismatches += jp->dcp;
+                trace <<= jp->dcp;
+                trace |= (1 << jp->dcp) - 1;
+            }
+            else {
+                num_mismatches = jp->dcp;
+                trace = (1 << jp->dcp) - 1;
+            }
+            for (i = 0;i < jp->dcp;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_MISMATCH);
+            }
+        } else if (jp->dcp > jp->dcq) {
+            for (i = 0;i < jp->dcp - jp->dcq;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_INSERTION);
+            }
+            if (jp->dcq) {
+                /* either jp->dcp r jp->dcq must be zero or jp->dcp == jp->dcq
+                   otherwise number of mismatches must be updated here */
+                ASSERT(0);
+            }
+        }
+        else {
+            for (i = 0;i < jp->dcq - jp->dcp;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_DELETION);
+            }
+            if (jp->dcp) {
+                /* either jp->dcp r jp->dcq must be zero or jp->dcp == jp->dcq
+                   otherwise number of mismatches must be updated here */
+                ASSERT(0);
+            }
+        }
+        
+        /* save the length of the ungapped extension */
+        if (is_ungapped && jp->dcp != jp->dcq) {
+            *ungapped_ext_len = cp - query - 1;
+            is_ungapped = FALSE;
+        }
+
+        /* update cp and cq */
+        cp += jp->dcp;
+        cq += jp->dcq;
+        
+        /* we have already checked that these are matches */
+        if (jp->ok == 0 && jp->lng) {
+            cp += jp->lng;
+            cq += jp->lng;
+            ASSERT(edit_script->num_ops < edit_script->num_allocated);
+            JUMPER_EDIT_BLOCK_ADD(edit_script, jp->lng);
+            trace <<= jp->lng;
+            *num_identical += jp->lng;
+            /* reset number of mismatches (we assume that error window is
+               smaller than jp->lng) */
+            num_mismatches = 0;
+        }
+    }
+
+    /* if matches all the way to the end of a sequence */
+    if (new_matches) {
+        ASSERT(edit_script->num_ops < edit_script->num_allocated);
+        JUMPER_EDIT_BLOCK_ADD(edit_script, new_matches);
+        *num_identical += new_matches;
+    }
+
+    /* find optimal length of the extension */
+    s_TrimExtension(edit_script, -mismatch_score, &cp, &cq, num_identical,
+                    TRUE);
+
+    *query_ext_len = cp - query;
+    *subject_ext_len = cq;
+
+    if (is_ungapped) {
+        *ungapped_ext_len = *query_ext_len;
+    }
+
+    /* return extension score */
+    return s_ComputeExtensionScore(edit_script, match_score, mismatch_score,
+                                   gap_open_score, gap_extend_score);
+} /* JumperExtendRightCompressedWithTraceback */
+
+
+Int4 JumperExtendRightCompressedWithTracebackOptimal(
+                                 const Uint1* query, const Uint1* subject, 
+                                 int query_length, int subject_length,
+                                 Int4 match_score, Int4 mismatch_score,
+                                 Int4 gap_open_score, Int4 gap_extend_score,
+                                 int max_mismatches, int window, Uint4* table,
+                                 Int4* query_ext_len, Int4* subject_ext_len,
+                                 JumperPrelimEditBlock* edit_script,
+                                 Int4* best_num_identical,
+                                 Boolean left_extension,
+                                 Int4* ungapped_ext_len)
+{ 
+    const Uint1 *cp, *cp1, *cpmax, *cpmax4, *cpstop = NULL;
+    Int4 cq, cq1, cqmax, cqmax4, cqstop = 0;
+    int i, n;
+    JUMP *jp;
+    int num_mismatches = 0;
+    int new_matches = 0;
+    Uint4 trace = 0;
+    Uint4 trace_mask = (1 << max_mismatches) - 1;
+    Boolean is_ungapped = TRUE;
+    Int4 score = 0, best_score = 0;
+    Int4 num_ops = 0, num_identical = *best_num_identical;
+    /* 0 - no gap, JUMPER_INSERTION, JUMPER_DELETION for open insertion  or
+       deletion */
+    Int4 last_gap_open = 0;
+    JUMP* jumper = jumper_default;
+
+    if (!query || ! subject) {
+        return -1;
+    }
+
+    cp = query;
+    cpmax = cp + query_length;
+
+    /* or assume matches up to byte edge */
+    cq = 0;
+    cqmax = subject_length;
+
+    cpmax4 = cpmax - 4;
+    cqmax4 = cqmax - 4;
+
+    /* skip the first pair as it is compared by the left extension */
+    cp++;
+    cq++;
+    if (!left_extension) {
+        new_matches++;
+    }
+
+    while (cp < cpmax && cq < cqmax && num_mismatches < max_mismatches) {
+
+        if (!(cq & 3) && cp < cpmax4 && cq < cqmax4) {
+            if (table[subject[cq / 4]] == *(Uint4*)(cp)) {
+                cp += 4;
+                cq += 4;
+                new_matches += 4;
+                continue;
+            }
+        }
+
+        if (*cp == UNPACK_BASE(subject, cq)) {
+            cp++;
+            cq++;
+            new_matches++;
+            continue;
+        }
+
+        jp = jumper; 
+        jp-- ;
+        while (jp++) { /* 1, 1, 0, 0 = last always accepted */
+         
+            if (!jp->lng) {
+                break;
+            }
+
+            n = 0;
+            i = jp->ok;
+            cp1 = cp + jp->dcp;
+            cq1 = cq + jp->dcq;
+            while (i--) {
+                if (cp1 >= cpmax || cq1 >= cqmax
+                    || *cp1++ != UNPACK_BASE(subject, cq1)) {
+
+                    goto next_jp;
+                }
+                cq1++;
+            }
+
+            n = 0;
+            i = jp->lng;
+            cp1 = cp + jp->dcp;
+            cq1 = cq + jp->dcq;
+            if (i + cp1 >= cpmax || i + cq1 >= cqmax) {
+                continue;
+            }
+            while (i--) {
+                if (cp1 >= cpmax || cq1 >= cqmax) {
+                    goto next_jp;
+                }
+                if (*cp1++ != UNPACK_BASE(subject, cq1)) {
+                    if (++n > jp->ok) {
+                        goto next_jp;
+                    }
+                }
+                cq1++;
+            }
+            /* current jumper row works */
+            break;
+
+next_jp:
+            continue;
+        }
+
+        if (new_matches) {
+            ASSERT(edit_script->num_ops < edit_script->num_allocated);
+            JUMPER_EDIT_BLOCK_ADD(edit_script, new_matches);
+            if (trace) {
+                if (new_matches < window) {
+                    trace <<= new_matches;
+                }
+                else {
+                    trace = 0;
+                }
+            }
+            num_identical += new_matches;
+            score += new_matches * match_score;
+            new_matches = 0;
+            last_gap_open = 0;
+        }
+
+        /* update optimal alignment extent */
+        if (score >= best_score) {
+            cpstop = cp;
+            cqstop = cq;
+            num_ops = edit_script->num_ops;
+            best_score = score;
+            *best_num_identical = num_identical;
+        }
+
+        /* update recent errors */
+        if (jp->dcp == jp->dcq) {
+            score += jp->dcp * mismatch_score;
+            if (trace & trace_mask) {
+                num_mismatches += jp->dcp;
+                trace <<= jp->dcp;
+                trace |= (1 << jp->dcp) - 1;
+            }
+            else {
+                num_mismatches = jp->dcp;
+                trace = (1 << jp->dcp) - 1;
+            }
+            for (i = 0;i < jp->dcp;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_MISMATCH);
+            }
+        } else if (jp->dcp > jp->dcq) {
+            for (i = 0;i < jp->dcp - jp->dcq;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_INSERTION);
+                score += gap_extend_score;
+            }
+            if (last_gap_open != JUMPER_INSERTION) {
+                score += gap_open_score;
+            }
+            last_gap_open = JUMPER_INSERTION;
+            if (jp->dcq) {
+                /* either jp->dcp r jp->dcq must be zero or jp->dcp == jp->dcq
+                   otherwise number of mismatches must be updated here */
+                ASSERT(0);
+            }
+        }
+        else {
+            for (i = 0;i < jp->dcq - jp->dcp;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_DELETION);
+                score += gap_extend_score;
+            }
+            if (last_gap_open != JUMPER_DELETION) {
+                score += gap_open_score;
+            }
+            last_gap_open = JUMPER_DELETION;
+            if (jp->dcp) {
+                /* either jp->dcp r jp->dcq must be zero or jp->dcp == jp->dcq
+                   otherwise number of mismatches must be updated here */
+                ASSERT(0);
+            }
+        }
+        
+        /* save the length of the ungapped extension */
+        if (is_ungapped && jp->dcp != jp->dcq) {
+            *ungapped_ext_len = cp - query - 1;
+            is_ungapped = FALSE;
+        }
+
+        /* update cp and cq */
+        cp += jp->dcp;
+        cq += jp->dcq;
+        
+        /* we have already checked that these are matches */
+        if (jp->ok == 0 && jp->lng) {
+            cp += jp->lng;
+            cq += jp->lng;
+            ASSERT(edit_script->num_ops < edit_script->num_allocated);
+            JUMPER_EDIT_BLOCK_ADD(edit_script, jp->lng);
+            trace <<= jp->lng;
+            num_identical += jp->lng;
+            score += jp->lng * match_score;
+            last_gap_open = 0;
+        }
+
+        /* update optimal alignment extent */
+        if (score >= best_score) {
+            cpstop = cp;
+            cqstop = cq;
+            num_ops = edit_script->num_ops;
+            best_score = score;
+            *best_num_identical = num_identical;
+        }
+    }
+
+    /* if matches all the way to the end of a sequence */
+    if (new_matches) {
+        ASSERT(edit_script->num_ops < edit_script->num_allocated);
+        JUMPER_EDIT_BLOCK_ADD(edit_script, new_matches);
+        num_identical += new_matches;
+        score += new_matches;
+    }
+
+    /* update optimal alignment extent */
+    if (score >= best_score) {
+        cpstop = cp;
+        cqstop = cq;
+        num_ops = edit_script->num_ops;
+        best_score = score;
+        *best_num_identical = num_identical;
+    }
+
+    *query_ext_len = cpstop - query;
+    *subject_ext_len = cqstop;
+    edit_script->num_ops = num_ops;
+
+    if (is_ungapped) {
+        *ungapped_ext_len = *query_ext_len;
+    }
+
+    return best_score;
+} /* JumperExtendRightCompressedWithTracebackOptimal */
+
+
+
+Int4 JumperExtendRight(const Uint1* query, const Uint1* subject, 
+                       int query_length, int subject_length,
+                       Int4 match_score, Int4 mismatch_score,
+                       Int4 gap_open_score, Int4 gap_extend_score,
+                       int max_mismatches, int window,
+                       int* query_ext_len, int* subject_ext_len,
+                       GapPrelimEditBlock* edit_script,
+                       Boolean left_extension)
+{ 
+    const Uint1 *cp, *cp1, *cpmax;
+    Int4 cq, cq1, cqmax;
+    int i, n;
+    JUMP *jp;
+    int score = 0, num_mismatches = 0;
+    int new_matches = 0;
+    Uint4 trace = 0;
+    Uint4 trace_mask = (1 << max_mismatches) - 1;
+    JUMP* jumper = jumper_default;
+
+    if (!query || ! subject || !edit_script) {
+        return -1;
+    }
+
+    cp = query;
+    cpmax = cp + query_length;
+
+    /* or assume matches up to byte edge */
+    cq = 0;
+    cqmax = subject_length;
+
+    /* skip the first pair as it is compared by the left extension */
+    cp++;
+    cq++;
+    if (!left_extension) {
+        new_matches++;
+    }
+
+    while (cp < cpmax && cq < cqmax && num_mismatches < max_mismatches) {
+
+        if (*cp == subject[cq]) {
+            score += match_score;
+            cp++;
+            cq++;
+            new_matches++;
+            continue;
+        }
+
+        /* handle ambiguous bases */
+
+/* this is only for 454
+        jp = (cqmax - cq > 80) ? jumper : jumper_edge;
+*/
+        jp = jumper;
+        jp-- ;
+        while (jp++) { /* 1, 1, 0, 0 = last always accepted */
+         
+            if (!jp->lng) {
+                break;
+            }
+
+            n = 0;
+            i = jp->ok;
+            cp1 = cp + jp->dcp;
+            cq1 = cq + jp->dcq;
+            while (i--) {
+                if (cp1 >= cpmax || cq1 >= cqmax
+                    || *cp1++ != subject[cq1]) {
+
+                    goto next_jp;
+                }
+                cq1++;
+            }
+
+            n = 0;
+            i = jp->lng;
+            cp1 = cp + jp->dcp;
+            cq1 = cq + jp->dcq;
+            if (i + cp1 >= cpmax || i + cq1 >= cqmax) {
+                continue;
+            }
+            while (i--) {
+                if (cp1 >= cpmax || cq1 >= cqmax) {
+                    goto next_jp;
+                }
+                if (*cp1++ != subject[cq1]) {
+                    if (++n > jp->ok) {
+                        goto next_jp;
+                    }
+                }
+                cq1++;
+            }
+            /* current jumper row works */
+            break;
+
+next_jp:
+            continue;
+        }
+
+        if (new_matches) {
+            GapPrelimEditBlockAdd(edit_script, eGapAlignSub, new_matches);
+            if (trace) {
+                if (new_matches < window) {
+                    trace <<= new_matches;
+                }
+                else {
+                    trace = 0;
+                }
+            }
+            new_matches = 0;
+        }
+
+/* another stop condition, ensures a positive score *--/
+        if (!jp->lng && num_mismatches >= score + mismatch_score) {
+            break;
+        }
+*/
+
+        /* update score */
+        if (jp->dcp == jp->dcq) {
+            score += mismatch_score * jp->dcp;
+            if (trace & trace_mask) {
+                num_mismatches += jp->dcp;
+                trace <<= jp->dcp;
+                trace |= (1 << jp->dcp) - 1;
+            }
+            else {
+                num_mismatches = jp->dcp;
+                trace = (1 << jp->dcp) - 1;
+            }
+            GapPrelimEditBlockAdd(edit_script, eGapAlignSub, jp->dcp);
+        } else if (jp->dcp > jp->dcq) {
+            score += gap_open_score + gap_extend_score * (jp->dcp - jp->dcq);
+            GapPrelimEditBlockAdd(edit_script, eGapAlignIns, jp->dcp - jp->dcq);
+            ASSERT(!jp->dcq);
+        }
+        else {
+            score += gap_open_score + gap_extend_score * (jp->dcq - jp->dcp);
+            GapPrelimEditBlockAdd(edit_script, eGapAlignDel, jp->dcq - jp->dcp);
+            ASSERT(!jp->dcp);
+        }
+
+        /* update cp and cq */
+        cp += jp->dcp;
+        cq += jp->dcq;
+        
+        /* we have already checked that these are matches */
+        if (jp->ok == 0 && jp->lng) {
+            score += match_score * jp->lng;
+            cp += jp->lng;
+            cq += jp->lng;
+
+            GapPrelimEditBlockAdd(edit_script, eGapAlignSub, jp->lng);
+            trace <<= jp->lng;
+        }
+    }
+
+    /* if matches all the way to the end of a sequence */
+    if (new_matches) {
+        GapPrelimEditBlockAdd(edit_script, eGapAlignSub, new_matches);
+    }
+
+    *query_ext_len = cp - query;
+    *subject_ext_len = cq;
+
+    return score;
+} /* JumperExtendRight */
+
+
+Int4 JumperExtendRightWithTraceback(
+                                 const Uint1* query, const Uint1* subject, 
+                                 int query_length, int subject_length,
+                                 Int4 match_score, Int4 mismatch_score,
+                                 Int4 gap_open_score, Int4 gap_extend_score,
+                                 int max_mismatches, int window,
+                                 Int4* query_ext_len, Int4* subject_ext_len,
+                                 JumperPrelimEditBlock* edit_script,
+                                 Int4* num_identical,
+                                 Boolean left_extension,
+                                 Int4* ungapped_ext_len,
+                                 JUMP* jumper)
+{ 
+    const Uint1 *cp, *cp1, *cpmax;
+    Int4 cq, cq1, cqmax;
+    int i, n;
+    JUMP *jp;
+    int num_mismatches = 0;
+    int new_matches = 0;
+    Uint4 trace = 0;
+    Uint4 trace_mask = (1 << max_mismatches) - 1;
+    Boolean is_ungapped = TRUE;
+
+    if (!query || ! subject) {
+        return -1;
+    }
+
+    cp = query;
+    cpmax = cp + query_length;
+
+    /* or assume matches up to byte edge */
+    cq = 0;
+    cqmax = subject_length;
+
+    /* skip the first pair as it is compared by the left extension */
+    if (left_extension) {
+        cp++;
+        cq++;
+    }
+
+    while (cp < cpmax && cq < cqmax && num_mismatches < max_mismatches) {
+
+        if (*cp == subject[cq]) {
+            cp++;
+            cq++;
+            new_matches++;
+            continue;
+        }
+
+        jp = jumper; 
+        jp-- ;
+        while (jp++) { /* 1, 1, 0, 0 = last always accepted */
+         
+            if (!jp->lng) {
+                break;
+            }
+
+            n = 0;
+            i = jp->ok;
+            cp1 = cp + jp->dcp;
+            cq1 = cq + jp->dcq;
+            while (i--) {
+                if (cp1 >= cpmax || cq1 >= cqmax
+                    || *cp1++ != subject[cq1]) {
+
+                    goto next_jp;
+                }
+                cq1++;
+            }
+
+            n = 0;
+            i = jp->lng;
+            cp1 = cp + jp->dcp;
+            cq1 = cq + jp->dcq;
+            if (i + cp1 >= cpmax || i + cq1 >= cqmax) {
+                continue;
+            }
+            while (i--) {
+                if (cp1 >= cpmax || cq1 >= cqmax) {
+                    goto next_jp;
+                }
+                if (*cp1++ != subject[cq1]) {
+                    if (++n > jp->ok) {
+                        goto next_jp;
+                    }
+                }
+                cq1++;
+            }
+            /* current jumper row works */
+            break;
+
+next_jp:
+            continue;
+        }
+
+        if (new_matches) {
+            ASSERT(edit_script->num_ops < edit_script->num_allocated);
+            JUMPER_EDIT_BLOCK_ADD(edit_script, new_matches);
+            if (trace) {
+                if (new_matches < window) {
+                    trace <<= new_matches;
+                }
+                else {
+                    trace = 0;
+                }
+            }
+            *num_identical += new_matches;
+            new_matches = 0;
+        }
+
+        /* update recent errors */
+        if (jp->dcp == jp->dcq) {
+            if (trace & trace_mask) {
+                num_mismatches += jp->dcp;
+                trace <<= jp->dcp;
+                trace |= (1 << jp->dcp) - 1;
+            }
+            else {
+                num_mismatches = jp->dcp;
+                trace = (1 << jp->dcp) - 1;
+            }
+            for (i = 0;i < jp->dcp;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_MISMATCH);
+            }
+        } else if (jp->dcp > jp->dcq) {
+            for (i = 0;i < jp->dcp - jp->dcq;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_INSERTION);
+            }
+            if (jp->dcq) {
+                /* either jp->dcp r jp->dcq must be zero or jp->dcp == jp->dcq
+                   otherwise number of mismatches must be updated here */
+                ASSERT(0);
+            }
+        }
+        else {
+            for (i = 0;i < jp->dcq - jp->dcp;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_DELETION);
+            }
+            if (jp->dcp) {
+                /* either jp->dcp r jp->dcq must be zero or jp->dcp == jp->dcq
+                   otherwise number of mismatches must be updated here */
+                ASSERT(0);
+            }
+        }
+        
+        /* save the length of the ungapped extension */
+        if (is_ungapped && jp->dcp != jp->dcq) {
+            *ungapped_ext_len = cp - query - 1;
+            is_ungapped = FALSE;
+        }
+
+        /* update cp and cq */
+        cp += jp->dcp;
+        cq += jp->dcq;
+        
+        /* we have already checked that these are matches */
+        if (jp->ok == 0 && jp->lng) {
+            cp += jp->lng;
+            cq += jp->lng;
+            ASSERT(edit_script->num_ops < edit_script->num_allocated);
+            JUMPER_EDIT_BLOCK_ADD(edit_script, jp->lng);
+            trace <<= jp->lng;
+            *num_identical += jp->lng;
+            /* reset number of mismatches (we assume that error window is
+               smaller than jp->lng) */
+            num_mismatches = 0;
+        }
+    }
+
+    /* if matches all the way to the end of a sequence */
+    if (new_matches) {
+        ASSERT(edit_script->num_ops < edit_script->num_allocated);
+        JUMPER_EDIT_BLOCK_ADD(edit_script, new_matches);
+        *num_identical += new_matches;
+    }
+
+    /* find optimal length of the extension */
+    s_TrimExtension(edit_script, -mismatch_score, &cp, &cq, num_identical,
+                    TRUE);
+
+    *query_ext_len = cp - query;
+    *subject_ext_len = cq;
+
+    if (is_ungapped) {
+        *ungapped_ext_len = *query_ext_len;
+    }
+
+    /* return extension score */
+    return s_ComputeExtensionScore(edit_script, match_score, mismatch_score,
+                                   gap_open_score, gap_extend_score);
+} /* JumperExtendRightWithTraceback */
+
+
+
+Int4 JumperExtendLeftCompressed(const Uint1* query, const Uint1* subject,
+                                Int4 query_offset, Int4 subject_offset,
+                                Int4 match_score, Int4 mismatch_score,
+                                Int4 gap_open_score, Int4 gap_extend_score,
+                                int max_mismatches, int window, Uint4* table,
+                                Int4* query_ext_len, Int4* subject_ext_len,
+                                Int4* num_identical)
+{ 
+    const Uint1 *cp, *cp1, *cpmin, *cpmin4, *cpstop = NULL;
+    Int4 cq, cq1, cqmin, cqmin4, cqstop = 0;
+    int i, n;
+    JUMP *jp;
+    int num_mismatches = 0;
+    int new_matches = 0;
+    Uint4 trace = 0;
+    Uint4 trace_mask = (1 << max_mismatches) - 1;
+    Int4 score = 0, best_score = 0;
+    JUMP* jumper = jumper_default;
+
+    if (!query || ! subject) {
+        return -1;
+    }
+
+    cp = query + query_offset;
+    cpmin = query;
+
+    /* or assume matches up to byte edge */
+    cq = subject_offset;
+    cqmin = 0;
+
+    cpmin4 = query + 4;
+    cqmin4 = 4;
+
+
+    while (cp >= cpmin && cq >= cqmin && num_mismatches < max_mismatches) {
+
+        if ((cq & 3) == 3 && cp >= cpmin4 && cq >= cqmin4) {
+            if (table[subject[cq / 4]] == *(Uint4*)(cp - 3)) {
+                cp -= 4;
+                cq -= 4;
+                new_matches += 4;
+                continue;
+            }
+        }
+
+        if (*cp == UNPACK_BASE(subject, cq)) {
+            cp--;
+            cq--;
+            new_matches++;
+            continue;
+        }
+
+        /* handle ambiguous bases */
+
+
+        jp = jumper; 
+        jp-- ;
+        while (jp++) { /* 1, 1, 0, 0 = last always accepted */
+         
+            if (!jp->lng) {
+                break;
+            }
+
+            n = 0;
+            i = jp->ok;
+            cp1 = cp - jp->dcp;
+            cq1 = cq - jp->dcq;
+            while (i--) {
+                if (cp1 < cpmin || cq1 < cqmin
+                    || *cp1-- != UNPACK_BASE(subject, cq1)) {
+
+                    goto next_jp;
+                }
+                cq1--;
+            }
+
+            n = 0;
+            i = jp->lng;
+            cp1 = cp - jp->dcp;
+            cq1 = cq - jp->dcq;
+            if (cp1 - i < cpmin || cq1 - i < cqmin) {
+                continue;
+            }
+            while (i--) {
+                if (cp1 < cpmin || cq1 < cqmin) {
+                    goto next_jp;
+                }
+                if (*cp1-- != UNPACK_BASE(subject, cq1)) {
+                    if (++n > jp->ok) {
+                        goto next_jp;
+                    }
+                }
+                cq1--;
+            }
+            /* current jumper row works */
+            break;
+
+next_jp:
+            continue;
+        }
+
+        if (new_matches) {
+            if (trace) {
+                if (new_matches < window) {
+                    trace <<= new_matches;
+                }
+                else {
+                    trace = 0;
+                }
+            }
+            *num_identical += new_matches;
+            score = new_matches * match_score;
+            new_matches = 0;
+        }
+
+        /* update recent errors and score */
+        if (jp->dcp == jp->dcq) {
+            score += mismatch_score * jp->dcp;
+            if (trace & trace_mask) {
+                num_mismatches += jp->dcp;
+                trace <<= jp->dcp;
+                trace |= (1 << jp->dcp) - 1;
+            }
+            else {
+                num_mismatches = jp->dcp;
+                trace = (1 << jp->dcp) - 1;
+            }
+        }
+        /* note that we are not penalizing gaps */
+
+        /* update cp and cq */
+        cp -= jp->dcp;
+        cq -= jp->dcq;
+        
+        /* we have already checked that these are matches */
+        if (!jp->ok && jp->lng) {
+            cp -= jp->lng;
+            cq -= jp->lng;
+            trace <<= jp->lng;
+            *num_identical += jp->lng;
+            score += jp->lng * match_score;
+        }
+
+        /* update optimal alignment extent */
+        if (score >= best_score) {
+            cpstop = cp;
+            cqstop = cq;
+            best_score = score;
+        }
+    }
+
+    /* if matches all the way to the end of a sequence */
+    if (new_matches) {
+        *num_identical += new_matches;
+        score += new_matches * match_score;
+        if (score >= best_score) {
+            cpstop = cp;
+            cqstop = cq;
+        }
+    }
+
+    *query_ext_len = query + query_offset - cpstop;
+    *subject_ext_len = subject_offset - cqstop;
+
+    return best_score;
+} /* JumperExtendLeftCompressed */
+
+
+Int4 JumperExtendLeftCompressedWithTraceback(
+                                const Uint1* query, const Uint1* subject,
+                                Int4 query_offset, Int4 subject_offset,
+                                Int4 match_score, Int4 mismatch_score,
+                                Int4 gap_open_score, Int4 gap_extend_score,
+                                int max_mismatches, int window, Uint4* table,
+                                Int4* query_ext_len, Int4* subject_ext_len,
+                                JumperPrelimEditBlock* edit_script,
+                                Int4* num_identical,
+                                JUMP* jumper)
+{ 
+    const Uint1 *cp, *cp1, *cpmin, *cpmin4;
+    Int4 cq, cq1, cqmin, cqmin4;
+    int i, n;
+    JUMP *jp;
+    int num_mismatches = 0;
+    int new_matches = 0;
+    Uint4 trace = 0;
+    Uint4 trace_mask = (1 << max_mismatches) - 1;
+
+    if (!query || ! subject) {
+        return -1;
+    }
+
+    cp = query + query_offset;
+    cpmin = query;
+
+    /* or assume matches up to byte edge */
+    cq = subject_offset;
+    cqmin = 0;
+
+    cpmin4 = query + 4;
+    cqmin4 = 4;
+
+
+    while (cp >= cpmin && cq >= cqmin && num_mismatches < max_mismatches) {
+
+        if ((cq & 3) == 3 && cp >= cpmin4 && cq >= cqmin4) {
+            if (table[subject[cq / 4]] == *(Uint4*)(cp - 3)) {
+                cp -= 4;
+                cq -= 4;
+                new_matches += 4;
+                continue;
+            }
+        }
+
+        if (*cp == UNPACK_BASE(subject, cq)) {
+            cp--;
+            cq--;
+            new_matches++;
+            continue;
+        }
+
+        /* handle ambiguous bases */
+
+
+        jp = jumper; 
+        jp-- ;
+        while (jp++) { /* 1, 1, 0, 0 = last always accepted */
+         
+            if (!jp->lng) {
+                break;
+            }
+
+            n = 0;
+            i = jp->ok;
+            cp1 = cp - jp->dcp;
+            cq1 = cq - jp->dcq;
+            while (i--) {
+                if (cp1 < cpmin || cq1 < cqmin
+                    || *cp1-- != UNPACK_BASE(subject, cq1)) {
+
+                    goto next_jp;
+                }
+                cq1--;
+            }
+
+            n = 0;
+            i = jp->lng;
+            cp1 = cp - jp->dcp;
+            cq1 = cq - jp->dcq;
+            if (cp1 - i < cpmin || cq1 - i < cqmin) {
+                continue;
+            }
+            while (i--) {
+                if (cp1 < cpmin || cq1 < cqmin) {
+                    goto next_jp;
+                }
+                if (*cp1-- != UNPACK_BASE(subject, cq1)) {
+                    if (++n > jp->ok) {
+                        goto next_jp;
+                    }
+                }
+                cq1--;
+            }
+            /* current jumper row works */
+            break;
+
+next_jp:
+            continue;
+        }
+
+        if (new_matches) {
+            ASSERT(edit_script->num_ops < edit_script->num_allocated);
+            JUMPER_EDIT_BLOCK_ADD(edit_script, new_matches);
+            if (trace) {
+                if (new_matches < window) {
+                    trace <<= new_matches;
+                }
+                else {
+                    trace = 0;
+                }
+            }
+            *num_identical += new_matches;
+            new_matches = 0;
+        }
+
+        /* update recent errors */
+        if (jp->dcp == jp->dcq) {
+            if (trace & trace_mask) {
+                num_mismatches += jp->dcp;
+                trace <<= jp->dcp;
+                trace |= (1 << jp->dcp) - 1;
+            }
+            else {
+                num_mismatches = jp->dcp;
+                trace = (1 << jp->dcp) - 1;
+            }
+            for (i = 0;i < jp->dcp;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_MISMATCH);
+            }
+        } else if (jp->dcp > jp->dcq) {
+            for (i = 0;i < jp->dcp - jp->dcq;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_INSERTION);
+            }
+            if (jp->dcq) {
+                /* either jp->dcp r jp->dcq must be zero or jp->dcp == jp->dcq
+                   otherwise number of mismatches must be updated here */
+                ASSERT(0);
+            }
+        }
+        else {
+            for (i = 0;i < jp->dcq - jp->dcp;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_DELETION);
+            }
+            if (jp->dcp) {
+                /* either jp->dcp r jp->dcq must be zero or jp->dcp == jp->dcq
+                   otherwise number of mismatches must be updated here */
+                ASSERT(0);
+            }
+        }
+
+        /* update cp and cq */
+        cp -= jp->dcp;
+        cq -= jp->dcq;
+        
+        /* we have already checked that these are matches */
+        if (!jp->ok && jp->lng) {
+            cp -= jp->lng;
+            cq -= jp->lng;
+            ASSERT(edit_script->num_ops < edit_script->num_allocated);
+            JUMPER_EDIT_BLOCK_ADD(edit_script, jp->lng);
+            trace <<= jp->lng;
+            *num_identical += jp->lng;
+            /* reset number of mismatches (we assume that error window is
+               smaller than jp->lng) */
+            num_mismatches = 0;
+        }
+    }
+
+    /* if matches all the way to the end of a sequence */
+    if (new_matches) {
+        ASSERT(edit_script->num_ops < edit_script->num_allocated);
+        JUMPER_EDIT_BLOCK_ADD(edit_script, new_matches);
+        *num_identical += new_matches;
+    }
+
+    /* find optimal extension length */
+    s_TrimExtension(edit_script, -mismatch_score, &cp, &cq, num_identical,
+                    FALSE); 
+
+    *query_ext_len = query + query_offset - cp;
+    *subject_ext_len = subject_offset - cq;
+
+    /* return extension score */
+    return s_ComputeExtensionScore(edit_script, match_score, mismatch_score,
+                                   gap_open_score, gap_extend_score);
+} /* JumperExtendLeftCompressedWithTraceback */
+
+
+Int4 JumperExtendLeftCompressedWithTracebackOptimal(
+                                const Uint1* query, const Uint1* subject,
+                                Int4 query_offset, Int4 subject_offset,
+                                Int4 match_score, Int4 mismatch_score,
+                                Int4 gap_open_score, Int4 gap_extend_score,
+                                int max_mismatches, int window, Uint4* table,
+                                Int4* query_ext_len, Int4* subject_ext_len,
+                                JumperPrelimEditBlock* edit_script,
+                                Int4* best_num_identical)
+{ 
+    const Uint1 *cp, *cp1, *cpmin, *cpmin4, *cpstop = NULL;
+    Int4 cq, cq1, cqmin, cqmin4, cqstop = 0;
+    int i, n;
+    JUMP *jp;
+    int num_mismatches = 0;
+    int new_matches = 0;
+    Uint4 trace = 0;
+    Uint4 trace_mask = (1 << max_mismatches) - 1;
+    Int4 score = 0, best_score = 0;
+    Int4 num_ops = 0, num_identical = *best_num_identical;
+    /* 0 - no gap, JUMPER_INSERTION, JUMPER_DELETION for open insertion  or
+       deletion */
+    Int4 last_gap_open = 0;
+    JUMP* jumper = jumper_default;
+
+    if (!query || ! subject) {
+        return -1;
+    }
+
+    cp = query + query_offset;
+    cpmin = query;
+
+    /* or assume matches up to byte edge */
+    cq = subject_offset;
+    cqmin = 0;
+
+    cpmin4 = query + 4;
+    cqmin4 = 4;
+
+
+    while (cp >= cpmin && cq >= cqmin && num_mismatches < max_mismatches) {
+
+        if ((cq & 3) == 3 && cp >= cpmin4 && cq >= cqmin4) {
+            if (table[subject[cq / 4]] == *(Uint4*)(cp - 3)) {
+                cp -= 4;
+                cq -= 4;
+                new_matches += 4;
+                continue;
+            }
+        }
+
+        if (*cp == UNPACK_BASE(subject, cq)) {
+            cp--;
+            cq--;
+            new_matches++;
+            continue;
+        }
+
+        /* handle ambiguous bases */
+
+
+        jp = jumper; 
+        jp-- ;
+        while (jp++) { /* 1, 1, 0, 0 = last always accepted */
+         
+            if (!jp->lng) {
+                break;
+            }
+
+            n = 0;
+            i = jp->ok;
+            cp1 = cp - jp->dcp;
+            cq1 = cq - jp->dcq;
+            while (i--) {
+                if (cp1 < cpmin || cq1 < cqmin
+                    || *cp1-- != UNPACK_BASE(subject, cq1)) {
+
+                    goto next_jp;
+                }
+                cq1--;
+            }
+
+            n = 0;
+            i = jp->lng;
+            cp1 = cp - jp->dcp;
+            cq1 = cq - jp->dcq;
+            if (cp1 - i < cpmin || cq1 - i < cqmin) {
+                continue;
+            }
+            while (i--) {
+                if (cp1 < cpmin || cq1 < cqmin) {
+                    goto next_jp;
+                }
+                if (*cp1-- != UNPACK_BASE(subject, cq1)) {
+                    if (++n > jp->ok) {
+                        goto next_jp;
+                    }
+                }
+                cq1--;
+            }
+            /* current jumper row works */
+            break;
+
+next_jp:
+            continue;
+        }
+
+        if (new_matches) {
+            ASSERT(edit_script->num_ops < edit_script->num_allocated);
+            JUMPER_EDIT_BLOCK_ADD(edit_script, new_matches);
+            if (trace) {
+                if (new_matches < window) {
+                    trace <<= new_matches;
+                }
+                else {
+                    trace = 0;
+                }
+            }
+            num_identical += new_matches;
+            score += new_matches * match_score;
+            new_matches = 0;
+            last_gap_open = 0;
+        }
+
+        /* update optimal alignment extent */
+        if (score >= best_score) {
+            cpstop = cp;
+            cqstop = cq;
+            best_score = score;
+            num_ops = edit_script->num_ops;
+            *best_num_identical = num_identical;
+        }
+
+        /* update recent errors */
+        if (jp->dcp == jp->dcq) {
+            score += jp->dcp * mismatch_score;
+            if (trace & trace_mask) {
+                num_mismatches += jp->dcp;
+                trace <<= jp->dcp;
+                trace |= (1 << jp->dcp) - 1;
+            }
+            else {
+                num_mismatches = jp->dcp;
+                trace = (1 << jp->dcp) - 1;
+            }
+            for (i = 0;i < jp->dcp;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_MISMATCH);
+            }
+        } else if (jp->dcp > jp->dcq) {
+            for (i = 0;i < jp->dcp - jp->dcq;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_INSERTION);
+                score += gap_extend_score;
+            }
+            if (last_gap_open != JUMPER_INSERTION) {
+                score += gap_open_score;
+            }
+            last_gap_open = JUMPER_INSERTION;
+            if (jp->dcq) {
+                /* either jp->dcp r jp->dcq must be zero or jp->dcp == jp->dcq
+                   otherwise number of mismatches must be updated here */
+                ASSERT(0);
+            }
+        }
+        else {
+            for (i = 0;i < jp->dcq - jp->dcp;i++) {
+                ASSERT(edit_script->num_ops < edit_script->num_allocated);
+                JUMPER_EDIT_BLOCK_ADD(edit_script, JUMPER_DELETION);
+                score += gap_extend_score;
+            }
+            if (last_gap_open != JUMPER_DELETION) {
+                score += gap_open_score;
+            }
+            last_gap_open  = JUMPER_DELETION;
+            if (jp->dcp) {
+                /* either jp->dcp r jp->dcq must be zero or jp->dcp == jp->dcq
+                   otherwise number of mismatches must be updated here */
+                ASSERT(0);
+            }
+        }
+
+        /* update cp and cq */
+        cp -= jp->dcp;
+        cq -= jp->dcq;
+        
+        /* we have already checked that these are matches */
+        if (!jp->ok && jp->lng) {
+            cp -= jp->lng;
+            cq -= jp->lng;
+            ASSERT(edit_script->num_ops < edit_script->num_allocated);
+            JUMPER_EDIT_BLOCK_ADD(edit_script, jp->lng);
+            trace <<= jp->lng;
+            num_identical += jp->lng;
+            score += jp->lng * match_score;
+            last_gap_open = 0;
+        }
+
+        /* update optimal alignment extent */
+        if (score >= best_score) {
+            cpstop = cp;
+            cqstop = cq;
+            best_score = score;
+            num_ops = edit_script->num_ops;
+            *best_num_identical = num_identical;
+        }
+    }
+
+    /* if matches all the way to the end of a sequence */
+    if (new_matches) {
+        ASSERT(edit_script->num_ops < edit_script->num_allocated);
+        JUMPER_EDIT_BLOCK_ADD(edit_script, new_matches);
+        num_identical += new_matches;
+        score += new_matches * match_score;
+    }
+    
+    /* update optimal alignment extent */
+    if (score >= best_score) {
+        cpstop = cp;
+        cqstop = cq;
+        best_score = score;
+        num_ops = edit_script->num_ops;
+        *best_num_identical = num_identical;
+    }
+
+    *query_ext_len = query + query_offset - cpstop;
+    *subject_ext_len = subject_offset - cqstop;
+    edit_script->num_ops = num_ops;
+
+    /* return extension score */
+    return best_score;
+} /* JumperExtendLeftCompressedWithTracebackOptimal */
+
+
+Int4 JumperExtendLeft(const Uint1* query, const Uint1* subject,
+                      Int4 query_offset, Int4 subject_offset,
+                      Int4 match_score, Int4 mismatch_score,
+                      Int4 gap_open_score, Int4 gap_extend_score,
+                      int max_mismatches, int window,
+                      int* query_ext_len, int* subject_ext_len,
+                      GapPrelimEditBlock* edit_script)
+{ 
+    const Uint1 *cp, *cp1, *cpmin;
+    Int4 cq, cq1, cqmin;
+    int i, n;
+    JUMP *jp;
+    int score = 0, num_mismatches = 0;
+    int new_matches = 0;
+    Uint4 trace = 0;
+    Uint4 trace_mask = (1 << max_mismatches) - 1;
+    JUMP* jumper = jumper_default;
+
+    if (!query || ! subject || !edit_script) {
+        return -1;
+    }
+
+    cp = query + query_offset;
+    cpmin = query;
+
+    /* or assume matches up to byte edge */
+    cq = subject_offset;
+    cqmin = 0;
+
+    while (cp >= cpmin && cq >= cqmin && num_mismatches < max_mismatches) {
+
+        if (*cp == subject[cq]) {
+            score += match_score;
+            cp--;
+            cq--;
+            new_matches++;
+            continue;
+        }
+
+        /* handle ambiguous bases */
+
+
+        jp = jumper; 
+        jp-- ;
+        while (jp++) { /* 1, 1, 0, 0 = last always accepted */
+         
+            if (!jp->lng) {
+                break;
+            }
+
+            n = 0;
+            i = jp->ok;
+            cp1 = cp - jp->dcp;
+            cq1 = cq - jp->dcq;
+            while (i--) {
+                if (cp1 < cpmin || cq1 < cqmin
+                    || *cp1-- != subject[cq1]) {
+
+                    goto next_jp;
+                }
+                cq1--;
+            }
+
+            n = 0;
+            i = jp->lng;
+            cp1 = cp - jp->dcp;
+            cq1 = cq - jp->dcq;
+            if (cp1 - i < cpmin || cq1 - i < cqmin) {
+                continue;
+            }
+            while (i--) {
+                if (cp1 < cpmin || cq1 < cqmin) {
+                    goto next_jp;
+                }
+                if (*cp1-- != subject[cq1]) {
+                    if (++n > jp->ok) {
+                        goto next_jp;
+                    }
+                }
+                cq1--;
+            }
+            /* current jumper row works */
+            break;
+
+next_jp:
+            continue;
+        }
+
+        if (new_matches) {
+            GapPrelimEditBlockAdd(edit_script, eGapAlignSub, new_matches);
+            if (trace) {
+                if (new_matches < window) {
+                    trace <<= new_matches;
+                }
+                else {
+                    trace = 0;
+                }
+            }
+            new_matches = 0;
+        }
+
+/* another stop condition, ensures a positive score *--/
+        if (!jp->lng && num_mismatches >= score + mismatch_score) {
+            break;
+        }
+*/
+
+        /* update score */
+        if (jp->dcp == jp->dcq) {
+            score += mismatch_score * jp->dcp;
+            if  (trace & trace_mask) {
+                num_mismatches += jp->dcp;
+                trace <<= jp->dcp;
+                trace |= (1 << jp->dcp) - 1;
+            }
+            else {
+                num_mismatches = jp->dcp;
+                trace = (1 << jp->dcp) - 1;
+            }
+            GapPrelimEditBlockAdd(edit_script, eGapAlignSub, jp->dcp);
+        } else if (jp->dcp > jp->dcq) {
+            score += gap_open_score + gap_extend_score * (jp->dcp - jp->dcq);
+            GapPrelimEditBlockAdd(edit_script, eGapAlignIns, jp->dcp - jp->dcq);
+            ASSERT(!jp->dcq);
+        }
+        else {
+            score += gap_open_score + gap_extend_score * (jp->dcq - jp->dcp);
+            GapPrelimEditBlockAdd(edit_script, eGapAlignDel, jp->dcq - jp->dcp);
+            ASSERT(!jp->dcp);
+        }
+
+        /* update cp and cq */
+        cp -= jp->dcp;
+        cq -= jp->dcq;
+        
+        /* we have already checked that these are matches */
+        if (!jp->ok && jp->lng) {
+            score += match_score * jp->lng;
+            cp -= jp->lng;
+            cq -= jp->lng;
+
+            GapPrelimEditBlockAdd(edit_script, eGapAlignSub, jp->lng);
+            trace <<= jp->lng;
+        }
+    }
+
+    /* if matches all the way to the end of a sequence */
+    if (new_matches) {
+        GapPrelimEditBlockAdd(edit_script, eGapAlignSub, new_matches);
+    }
+
+    *query_ext_len = query + query_offset - cp;
+    *subject_ext_len = subject_offset - cq;
+
+    return score;
+} /* JumperExtendLeft */
+
+
+int JumperGappedAlignmentCompressedWithTraceback(const Uint1* query,
+                               const Uint1* subject,
+                               Int4 query_length, Int4 subject_length,
+                               Int4 query_start, Int4 subject_start,
+                               BlastGapAlignStruct* gap_align,
+                               const BlastScoringParameters* score_params,
+                               Int4* num_identical,
+                               Int4* right_ungapped_ext_len)
+{
+    Int4 score_left = 0, score_right = 0;
+    Int4 q_ext_len, s_ext_len;
+    Int4 q_length, s_length;
+    Int4 offset_adjustment;
+    Boolean left_ext_done = FALSE;
+    const Uint1 kBaseN = 14;
+    Int4 i;
+
+
+    ASSERT(gap_align->jumper);
+
+    *num_identical = 0;
+
+    JumperPrelimEditBlock** rev_prelim_block =
+        &gap_align->jumper->left_prelim_block;
+
+    JumperPrelimEditBlock** fwd_prelim_block =
+        &gap_align->jumper->right_prelim_block;
+
+    /* reallocate gapped preliminary edit blocks if necessary;
+       edit scripts should not be longer than 2 times the length of the shorter
+       sequence, so memory reallocation will not be necessary */
+    if (!*rev_prelim_block || !*fwd_prelim_block ||
+        (*rev_prelim_block)->num_allocated <
+        2 * MIN(query_length, subject_length)) {
+
+        JumperPrelimEditBlockFree(*rev_prelim_block);
+        *rev_prelim_block =
+            JumperPrelimEditBlockNew(2 * MIN(query_length, subject_length));
+
+        JumperPrelimEditBlockFree(*fwd_prelim_block);
+        *fwd_prelim_block =
+            JumperPrelimEditBlockNew(2 * MIN(query_length, subject_length));
+    }
+    s_ResetJumperPrelimEditBlocks(*rev_prelim_block, *fwd_prelim_block);
+
+    /* this is currently needed for right extension */
+    offset_adjustment = COMPRESSION_RATIO - (subject_start % COMPRESSION_RATIO);
+
+    q_length = query_start + offset_adjustment;
+    s_length = subject_start + offset_adjustment;
+
+
+    if (query_start > 0 && subject_start > 0) {
+
+        score_left = JumperExtendLeftCompressedWithTracebackOptimal(
+                                      query, subject,
+                                      q_length, s_length,
+                                      score_params->reward,
+                                      score_params->penalty,
+                                      -score_params->gap_open,
+                                      -score_params->gap_extend,
+                                      gap_align->max_mismatches,
+                                      gap_align->mismatch_window,
+                                      gap_align->jumper->table,
+                                      &q_ext_len, &s_ext_len,
+                                      *rev_prelim_block,
+                                      num_identical);
+
+
+        gap_align->query_start = q_length - q_ext_len + 1;
+        gap_align->subject_start = s_length - s_ext_len + 1;
+        left_ext_done = TRUE;
+        ASSERT(gap_align->query_start >= 0);
+        ASSERT(gap_align->subject_start >= 0);
+    }
+    else {
+        gap_align->query_start = query_start;
+        gap_align->subject_start = subject_start;
+    }
+                                  
+    if (query_start < query_length - 1 && subject_start < subject_length - 1) {
+
+        score_right = JumperExtendRightCompressedWithTracebackOptimal(
+                                        query + q_length,
+                                        subject + (s_length + 3) / 4,
+                                        query_length - q_length,
+                                        subject_length - s_length,
+                                        score_params->reward,
+                                        score_params->penalty,
+                                        -score_params->gap_open,
+                                        -score_params->gap_extend,
+                                        gap_align->max_mismatches,
+                                        gap_align->mismatch_window,
+                                        gap_align->jumper->table,
+                                        &q_ext_len, &s_ext_len,
+                                        *fwd_prelim_block,
+                                        num_identical,
+                                        left_ext_done,
+                                        right_ungapped_ext_len);
+
+        gap_align->query_stop = q_length + q_ext_len;
+        gap_align->subject_stop = s_length + s_ext_len;
+    }
+    else {
+        gap_align->query_stop = query_start;
+        gap_align->subject_stop = subject_start;
+    }
+
+    gap_align->score = score_left + score_right;
+
+    if (offset_adjustment && !left_ext_done) {
+        ASSERT((*rev_prelim_block)->num_ops < 
+               (*rev_prelim_block)->num_allocated);
+        JUMPER_EDIT_BLOCK_ADD(*rev_prelim_block, offset_adjustment);
+
+        *num_identical += offset_adjustment;
+        gap_align->score += offset_adjustment * score_params->reward;
+    }
+    if (offset_adjustment && *right_ungapped_ext_len) {
+        *right_ungapped_ext_len += offset_adjustment;
+    }
+
+    /* Remove mismatch penalty for Ns. We assume that there are no gaps
+       corresponfding to Ns (gaps may happen, but are unlikely). This to
+       ensure that an alignment spanning the whole read containing a few Ns
+       has a larger score than one covering a part. */
+    for (i = gap_align->query_start;i < gap_align->query_stop;i++) {
+        if (query[i] == kBaseN) {
+            gap_align->score -= score_params->penalty;
+        }
+    }
+
+    return 0;
+}
+
+
+Boolean JumperGoodAlign(const BlastGapAlignStruct* gap_align,
+                        const BlastHitSavingParameters* hit_params,
+                        Int4 num_identical,
+                        BlastContextInfo* context_info)
+{
+    Int4 score = gap_align->score;
+
+    /* first check general score and coverage thresholds */
+    if (score < hit_params->options->cutoff_score) {
+        return FALSE;
+    }
+
+    Int4 align_len = MAX(gap_align->query_stop - gap_align->query_start,
+                         gap_align->subject_stop - gap_align->subject_start);
+
+    if (100.0 * (double)num_identical / (double)align_len
+        < hit_params->options->percent_identity) {
+
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+
+
+JumperEditsBlock* JumperEditsBlockFree(JumperEditsBlock* block)
+{
+    if (!block) {
+        return NULL;
+    }
+
+    if (block->edits) {
+        sfree(block->edits);
+    }
+    sfree(block);
+
+    return NULL;
+}
+
+JumperEditsBlock* JumperEditsBlockNew(Int4 num)
+{
+    JumperEditsBlock* retval =
+        (JumperEditsBlock*)calloc(1, sizeof(JumperEditsBlock));
+
+    if (!retval) {
+        return NULL;
+    }
+
+    retval->edits = (JumperEdit*)calloc(num, sizeof(JumperEdit));
+    if (!retval->edits) {
+        JumperEditsBlockFree(retval);
+        return NULL;
+    }
+
+    retval->num_edits = 0;
+    return retval;
+}
+
+JumperEditsBlock* JumperEditsBlockDup(const JumperEditsBlock* block)
+{
+    JumperEditsBlock* retval = NULL;
+
+    if (!block) {
+        return NULL;
+    }
+
+    retval = JumperEditsBlockNew(block->num_edits);
+    if (retval) {
+        memcpy(retval->edits, block->edits,
+               block->num_edits * sizeof(JumperEdit));
+        retval->num_edits = block->num_edits;
+    }
+
+    return retval;
+}
+
+JumperEditsBlock* JumperFindEdits(const Uint1* query, const Uint1* subject,
+                                  BlastGapAlignStruct* gap_align)
+{
+    const Uint1 kGap = 15;
+    Int4 q_pos = gap_align->query_start;
+    Int4 s_pos = gap_align->subject_start;
+
+    JumperPrelimEditBlock* left_ext = gap_align->jumper->left_prelim_block;
+    JumperPrelimEditBlock* right_ext = gap_align->jumper->right_prelim_block;
+    
+    JumperEditsBlock* retval = NULL;
+    int len = left_ext->num_ops + right_ext->num_ops;
+    int i, k;
+
+    retval = JumperEditsBlockNew(len);
+    if (!retval) {
+        return NULL;
+    }
+    k = 0;
+    for (i=left_ext->num_ops - 1;i >= 0;i--) {
+
+        ASSERT(k < len);
+
+        JumperEdit* edit = &retval->edits[k];
+        JumperOpType* edit_op = &left_ext->edit_ops[i];
+        switch(*edit_op) {
+        case JUMPER_MISMATCH:
+            edit->query_pos = q_pos;
+            edit->query_base = query[q_pos];
+            edit->subject_base = UNPACK_BASE(subject, s_pos);
+            q_pos++;
+            s_pos++;
+            k++;
+            break;
+
+        case JUMPER_DELETION:
+            edit->query_pos = q_pos;
+            edit->query_base = kGap;
+            edit->subject_base = UNPACK_BASE(subject, s_pos);
+            s_pos++;
+            k++;
+            break;
+
+        case JUMPER_INSERTION:
+            edit->query_pos = q_pos;
+            edit->query_base = query[q_pos];
+            edit->subject_base = kGap;
+            q_pos++;
+            k++;
+            break;
+
+        default:
+            q_pos += *edit_op;
+            s_pos += *edit_op;
+        }
+    }
+
+    for (i=0;i < right_ext->num_ops;i++) {
+
+        ASSERT(k < len);
+
+        JumperEdit* edit = &retval->edits[k];
+        JumperOpType* edit_op = &right_ext->edit_ops[i];
+        switch(*edit_op) {
+        case JUMPER_MISMATCH:
+            edit->query_pos = q_pos;
+            edit->query_base = query[q_pos];
+            edit->subject_base = UNPACK_BASE(subject, s_pos);
+            q_pos++;
+            s_pos++;
+            k++;
+            break;
+
+        case JUMPER_DELETION:
+            edit->query_pos = q_pos;
+            edit->query_base = kGap;
+            edit->subject_base = UNPACK_BASE(subject, s_pos);
+            s_pos++;
+            k++;
+            break;
+
+        case JUMPER_INSERTION:
+            edit->query_pos = q_pos;
+            edit->query_base = query[q_pos];
+            edit->subject_base = kGap;
+            q_pos++;
+            k++;
+            break;
+
+        default:
+            q_pos += *edit_op;
+            s_pos += *edit_op;
+        }
+    }
+
+    retval->num_edits = k;
+
+    ASSERT(k <= len);
+    ASSERT(q_pos == gap_align->query_stop);
+    ASSERT(s_pos == gap_align->subject_stop);
+
+    return retval;
+}
+
+
+JumperEditsBlock* JumperEditsBlockCombine(JumperEditsBlock** block_ptr,
+                                          JumperEditsBlock** append_ptr)
+{
+    Int4 i;
+    JumperEditsBlock* block = NULL;
+    JumperEditsBlock* append = NULL;
+
+    if (!block_ptr || !*block_ptr || !append_ptr) {
+        return NULL;
+    }
+
+    block = *block_ptr;
+    append = *append_ptr;
+
+    if (!append || append->num_edits == 0) {
+        *append_ptr = JumperEditsBlockFree(*append_ptr);
+        return block;
+    }
+
+    block->edits = realloc(block->edits,
+                           (block->num_edits + append->num_edits) *
+                           sizeof(JumperEdit));
+
+    if (!block->edits) {
+        return NULL;
+    }
+    for (i = 0;i < append->num_edits;i++) {
+        block->edits[block->num_edits++] = append->edits[i];
+    }
+
+    *append_ptr = JumperEditsBlockFree(*append_ptr);
+
+    return block;
+}
+
+GapEditScript* GapEditScriptCombine(GapEditScript** edit_script_ptr,
+                                    GapEditScript** append_ptr)
+{
+    Int4 i = 0;
+    GapEditScript* edit_script = NULL;
+    GapEditScript* append = NULL;
+
+    if (!edit_script_ptr || !*edit_script_ptr || !append_ptr) {
+        return NULL;
+    }
+
+    edit_script = *edit_script_ptr;
+    append = *append_ptr;
+
+    if (!append || append->size == 0) {
+        *append_ptr = GapEditScriptDelete(*append_ptr);
+        return edit_script;
+    }
+
+    edit_script->op_type = realloc(edit_script->op_type,
+                                   (edit_script->size + append->size) *
+                                   sizeof(EGapAlignOpType));
+    if (!edit_script->op_type) {
+        return NULL;
+    }
+    edit_script->num = realloc(edit_script->num,
+                               (edit_script->size + append->size) *
+                               sizeof(Int4));
+    if (!edit_script->num) {
+        return NULL;
+    }
+
+    if (edit_script->op_type[edit_script->size - 1] == append->op_type[0]) {
+        edit_script->num[edit_script->size - 1] += append->num[0];
+        i = 1;
+    }
+    for (;i < append->size;i++) {
+        edit_script->op_type[edit_script->size] = append->op_type[i];
+        edit_script->num[edit_script->size] = append->num[i];
+        edit_script->size++;
+    }
+
+    *append_ptr = GapEditScriptDelete(*append_ptr);
+
+    return edit_script;
+}
+
+
+#define NUM_SIGNALS 8
+
+/* Record subject bases pre and post alignment in HSP as possible splice
+   signals and set a flag for recognized signals */
+int JumperFindSpliceSignals(BlastHSP* hsp, Int4 query_len,
+                            const Uint1* subject, Int4 subject_len)
+{
+    Uint1 signals[NUM_SIGNALS] = {1, /* AC */
+                                  2, /* AG */
+                                  4, /* CA */
+                                  7, /* CT */
+                                  8, /* GA */
+                                  11, /* GT */
+                                  13, /* TC */
+                                  14 /* TG */ };
+
+
+    if (!hsp || !subject) {
+        return -1;
+    }
+
+    if (hsp->query.offset == 0 || hsp->subject.offset < 2) {
+        hsp->map_info->left_edge = MAPPER_EXON;
+    }
+    else {
+        int k;
+        hsp->map_info->left_edge =
+            (UNPACK_BASE(subject, hsp->subject.offset - 2) << 2) |
+            UNPACK_BASE(subject, hsp->subject.offset - 1);
+
+        for (k = 0;k < NUM_SIGNALS;k++) {
+            if (hsp->map_info->left_edge == signals[k]) {
+                hsp->map_info->left_edge |= MAPPER_SPLICE_SIGNAL;
+                break;
+            }
+        }
+    }
+
+    if (hsp->query.end == query_len || hsp->subject.end == subject_len) {
+        hsp->map_info->right_edge = MAPPER_EXON;
+    }
+    else {
+        int k;
+        hsp->map_info->right_edge =
+            (UNPACK_BASE(subject, hsp->subject.end) << 2) |
+            UNPACK_BASE(subject, hsp->subject.end + 1);
+
+        for (k = 0;k < NUM_SIGNALS;k++) {
+            if (hsp->map_info->right_edge == signals[k]) {
+                hsp->map_info->right_edge |= MAPPER_SPLICE_SIGNAL;
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+
+#define MAX_SUBJECT_OVERHANG 20
+
+SequenceOverhangs* SequenceOverhangsFree(SequenceOverhangs* overhangs)
+{
+    if (!overhangs) {
+        return NULL;
+    }
+
+    if (overhangs->left) {
+        sfree(overhangs->left);
+    }
+
+    if (overhangs->right) {
+        sfree(overhangs->right);
+    }
+
+    sfree(overhangs);
+    return NULL;
+}
+
+
+static Int4 s_SaveSubjectOverhangs(BlastHSP* hsp, Uint1* subject,
+                                   Int4 query_len)
+{
+    SequenceOverhangs* overhangs = NULL;
+    const Int4 kMinOverhangLength = 0;
+
+    if (hsp->query.offset < kMinOverhangLength &&
+        query_len - hsp->query.end < kMinOverhangLength) {
+
+        return 0;
+    }
+
+    overhangs = calloc(1, sizeof(SequenceOverhangs));
+    if (!overhangs) {
+        return -1;
+    }
+
+    if (hsp->query.offset >= kMinOverhangLength) {
+        Int4 i;
+        /* at least two subject bases are needed for the search for splice
+           signals */
+        Int4 len = MIN(MAX(hsp->query.offset, 2), MAX_SUBJECT_OVERHANG);
+        Uint1* overhang = calloc(len, sizeof(Uint1));
+        if (!overhang) {
+            SequenceOverhangsFree(overhangs);
+            return -1;
+        }
+        if (hsp->subject.offset < len) {
+            len = hsp->subject.offset;
+        }
+        for (i = 0;i < len; i++) {
+            overhang[i] = UNPACK_BASE(subject, hsp->subject.offset - len + i);
+        }
+        overhangs->left = overhang;
+        overhangs->left_len = len;
+    }
+
+    if (hsp->query.end <= query_len - kMinOverhangLength) {
+        Int4 i;
+        Int4 len =
+            MIN(MAX(query_len - hsp->query.end + 1, 2), MAX_SUBJECT_OVERHANG);
+        Uint1* overhang = calloc(len, sizeof(Uint1));
+        if (!overhang) {
+            SequenceOverhangsFree(overhangs);
+            return -1;
+        }
+        for (i = 0;i < len;i++) {
+            /* hsp->subject.end is an open limit */
+            overhang[i] = UNPACK_BASE(subject, hsp->subject.end + i);
+        }
+        overhangs->right = overhang;
+        overhangs->right_len = len;
+    }
+
+    hsp->map_info->subject_overhangs = overhangs;
+
+    return 0;
+}
+
+
+static int s_CompareOffsetPairsByDiagQuery(const void* a, const void* b)
+{
+    BlastOffsetPair* first = (BlastOffsetPair*)a;
+    BlastOffsetPair* second = (BlastOffsetPair*)b;
+
+    Int4 first_diag = first->qs_offsets.s_off - first->qs_offsets.q_off;
+    Int4 second_diag = second->qs_offsets.s_off - second->qs_offsets.q_off;
+
+    if (first_diag < second_diag) {
+        return -1;
+    }
+    if (first_diag > second_diag) {
+        return 1;
+    }
+
+    if (first->qs_offsets.q_off < second->qs_offsets.q_off) {
+        return -1;
+    }
+    if (first->qs_offsets.q_off > second->qs_offsets.q_off) {
+        return 1;
+    }
+
+    if (first->qs_offsets.s_off < second->qs_offsets.s_off) {
+        return -1;
+    }
+    if (first->qs_offsets.s_off > second->qs_offsets.s_off) {
+        return 1;
+    }
+
+    return 0;
+}
+
+
+/* Create an HSP from a word hit */
+static BlastHSP* s_CreateHSPForWordHit(Int4 q_offset, Int4 s_offset,
+                                       Int4 length, Int4 context,
+                                       const Uint1* query,
+                                       const BlastQueryInfo* query_info,
+                                       const BLAST_SequenceBlk* subject,
+                                       Int4 query_len)
+{
+    BlastHSP* retval = NULL;
+    GapEditScript* edit_script = NULL;
+    Int2 status;
+    Int4 i;
+    Int4 num_Ns = 0;
+
+    edit_script = GapEditScriptNew(1);
+    if (!edit_script) {
+        return NULL;
+    }
+
+    edit_script->num[0] = length;
+    edit_script->op_type[0] = eGapAlignSub;
+    
+
+    status = Blast_HSPInit(q_offset,
+                           q_offset + length,
+                           s_offset,
+                           s_offset + length,
+                           q_offset, s_offset,
+                           context,
+                           query_info->contexts[context].frame,
+                           subject->frame,
+                           length,
+                           &edit_script,
+                           &retval);
+    if (status) {
+        if (retval) {
+            Blast_HSPFree(retval);
+        }
+        else {
+            GapEditScriptDelete(edit_script);
+        }
+        return NULL;
+    }
+    
+    retval->map_info = BlastHSPMappingInfoNew();
+    if (!retval->map_info) {
+        Blast_HSPFree(retval);
+        return NULL;
+    }
+
+    /* ambiguous bases in query are allowed for extending small word matches,
+       so there can be Ns within the word hit */
+    for (i = 0;i < length;i++) {
+        if ((query[q_offset + i] & 0xfc) != 0) {
+            num_Ns++;
+        }
+    }
+
+    retval->num_ident = length - num_Ns;
+    retval->evalue = 0.0;
+    retval->map_info->edits = JumperEditsBlockNew(num_Ns);
+    if (!retval->map_info->edits) {
+        Blast_HSPFree(retval);
+        return NULL;
+    }
+
+    /* add edits for ambiguous bases */
+    for (i = 0;i < length;i++) {
+        if ((query[q_offset + i] & 0xfc) != 0) {
+            JumperEdit* edit = retval->map_info->edits->edits +
+                retval->map_info->edits->num_edits;
+
+            ASSERT(retval->map_info->edits->num_edits < num_Ns);
+            edit->query_pos = q_offset + i;
+            edit->query_base = query[q_offset + i];
+            edit->subject_base = UNPACK_BASE(subject->sequence, s_offset + i);
+            retval->map_info->edits->num_edits++;
+        }
+    }
+
+    /* FIXME: This is currently needed because these splice sites are used
+       in finding splice signals for overlapping HSPs */
+    JumperFindSpliceSignals(retval, query_len, subject->sequence,
+                            subject->length);
+
+    s_SaveSubjectOverhangs(retval, subject->sequence, query_len);
+
+    return retval;
+}
+
+/* for mapping this may only work if we hash genome and scan reads */
+Int4
+BlastNaExtendJumper(BlastOffsetPair* offset_pairs, Int4 num_hits,
+                    const BlastInitialWordParameters* word_params,
+                    const BlastScoringParameters* score_params,
+                    const BlastHitSavingParameters* hit_params,
+                    LookupTableWrap* lookup_wrap,
+                    BLAST_SequenceBlk* query,
+                    BLAST_SequenceBlk* subject,
+                    BlastQueryInfo* query_info,
+                    BlastGapAlignStruct* gap_align,
+                    BlastHSPList* hsp_list,
+                    Uint4 s_range,
+                    SubjectIndex* s_index)
+{
+    Int4 index = 0;
+    Int4 hits_extended = 0;
+    Int4 word_length, lut_word_length, ext_to;
+    Int4 context;
+    int status;
+    Int4 num_identical = 0;
+    /* word matches until this query position will be skipped */
+    Int4 skip_until = 0;
+    Int4 last_diag = 0;
+
+    if (lookup_wrap->lut_type == eMBLookupTable) {
+        BlastMBLookupTable *lut = (BlastMBLookupTable *) lookup_wrap->lut;
+        word_length = lut->word_length;
+        lut_word_length = lut->lut_word_length;
+    } 
+    else {
+        BlastNaLookupTable *lut = (BlastNaLookupTable *) lookup_wrap->lut;
+        word_length = lut->word_length;
+        lut_word_length = lut->lut_word_length;
+    }
+    ext_to = word_length - lut_word_length;
+
+    /* We trust that the bases of the hit itself are exact matches, 
+       and look only for exact matches before and after the hit.
+
+       Most of the time, the lookup table width is close to the word size 
+       so only a few bases need examining. Also, most of the time (for
+       random sequences) extensions will fail almost immediately (the
+       first base examined will not match about 3/4 of the time). Thus it 
+       is critical to reduce as much as possible all work that is not the 
+       actual examination of sequence data */
+
+    /* Sort word hits by diagnal, query, and subject position */
+    qsort(offset_pairs, num_hits, sizeof(BlastOffsetPair),
+          s_CompareOffsetPairsByDiagQuery);
+
+    for (; index < num_hits; ++index) {
+        Int4 s_offset = offset_pairs[index].qs_offsets.s_off;
+        Int4 q_offset = offset_pairs[index].qs_offsets.q_off;
+        Int4 query_start;
+        /* FIXME: this may need to be Int8 for 10M queries or long reads */
+        Int4 diag = s_offset - q_offset;
+
+        /* skip word hits from already explored part of the diagonal (word
+           hits must be sorted by diagonal and query position) */
+        if (diag == last_diag && q_offset < skip_until) {
+            continue;
+        }
+
+        /* begin with the left extension; the initialization is slightly
+           faster. Point to the first base of the lookup table hit and
+           work backwards */
+
+        Int4 ext_left = 0;
+        Int4 s_off = s_offset;
+        Uint1 *q = query->sequence + q_offset;
+        Uint1 *s = subject->sequence + s_off / COMPRESSION_RATIO;
+
+        for (; ext_left < MIN(ext_to, s_offset); ++ext_left) {
+            s_off--;
+            q--;
+            if (s_off % COMPRESSION_RATIO == 3)
+                s--;
+            if (((Uint1) (*s << (2 * (s_off % COMPRESSION_RATIO))) >> 6)
+                != *q)
+                break;
+        }
+
+        /* do the right extension if the left extension did not find all
+           the bases required. Begin at the first base beyond the lookup
+           table hit and move forwards */
+
+        if (ext_left < ext_to) {
+            Int4 ext_right = 0;
+            s_off = s_offset + lut_word_length;
+            if (s_off + ext_to - ext_left > s_range) 
+                continue;
+            q = query->sequence + q_offset + lut_word_length;
+            s = subject->sequence + s_off / COMPRESSION_RATIO;
+
+            for (; ext_right < ext_to - ext_left; ++ext_right) {
+                if (((Uint1) (*s << (2 * (s_off % COMPRESSION_RATIO))) >>
+                     6) != *q)
+                    break;
+                s_off++;
+                q++;
+                if (s_off % COMPRESSION_RATIO == 0)
+                    s++;
+            }
+
+            /* check if enough extra matches were found */
+            if (ext_left + ext_right < ext_to)
+                continue;
+        }
+        
+        q_offset -= ext_left;
+        s_offset -= ext_left;
+
+        /* adjust query offset */
+        context = BSearchContextInfo(q_offset, query_info);
+        query_start = query_info->contexts[context].query_offset;
+        q_offset -= query_start;
+        ASSERT(q_offset >= 0);
+
+        Int4 query_len = query_info->contexts[context].query_length;
+        Uint1* query_seq = query->sequence + query_start;
+        Int4 right_ungapped_ext_len = 0;
+
+        JumperGappedAlignmentCompressedWithTraceback(query_seq,
+                                                     subject->sequence,
+                                                     query_len,
+                                                     subject->length,
+                                                     q_offset,
+                                                     s_offset,
+                                                     gap_align,
+                                                     score_params, 
+                                                     &num_identical,
+                                                     &right_ungapped_ext_len);
+
+        hits_extended++;
+        /* Word hits on the same diagonal up to this query position will be
+           skipped. right_ungapped_ext_len gives the length of the first
+           ungapped segment of the right extension, hence word hits on this
+           part of the diagonal will not generate better alignment than the
+           one just found. This is assuming that word hits are sorted by
+           diagonal and query position. */
+        skip_until = q_offset + query_start + right_ungapped_ext_len;
+        last_diag = diag;
+
+        if (JumperGoodAlign(gap_align, hit_params, num_identical,
+                            &query_info->contexts[context])) {
+
+            BlastHSP* new_hsp;
+            Uint1* query_seq = query->sequence + query_start;
+            /* minimum length of the unaligned part of the subject to search
+               for matching small words */
+            const Int4 kMinSubjectOverhang = 100;
+            /* maximum intron length, i.e. gap between two hsps that can be
+               combined */
+            const Int4 kMaxIntronLength = hit_params->options->longest_intron;
+
+            /* shift gaps the right */
+            /* When several gap positions give the same alignment score,
+               gap positions in the alignment are arbitrary. Here we ensure
+               that gaps will be at the same postitions for all reads
+               that map to the same place in the genome. */
+            if (!getenv("MAPPER_NO_GAP_SHIFT")) {
+                s_ShiftGaps(gap_align, query_seq, subject->sequence,
+                            query_len, subject->length,
+                            score_params->penalty, &num_identical);
+            }
+
+            gap_align->edit_script = JumperPrelimEditBlockToGapEditScript(
+                                        gap_align->jumper->left_prelim_block,
+                                        gap_align->jumper->right_prelim_block);
+
+
+            status = Blast_HSPInit(gap_align->query_start,
+                                   gap_align->query_stop,
+                                   gap_align->subject_start,
+                                   gap_align->subject_stop,
+                                   q_offset, s_offset,
+                                   context,
+                                   query_info->contexts[context].frame,
+                                   subject->frame,
+                                   gap_align->score,
+                                   &(gap_align->edit_script),
+                                   &new_hsp);
+            if (!new_hsp) {
+                return -1;
+            }
+            new_hsp->map_info = BlastHSPMappingInfoNew();
+            if (!new_hsp->map_info) {
+                return -1;
+            }
+            new_hsp->num_ident = num_identical;
+            new_hsp->evalue = 0.0;
+            new_hsp->map_info->edits =
+                    JumperFindEdits(query_seq, subject->sequence, gap_align);
+
+            if (hit_params->options->splice) {
+                /* FIXME: This is currently needed because these splice 
+                   sites are used in finding splice signals for overlapping
+                   HSPs */
+                JumperFindSpliceSignals(new_hsp, query_len, subject->sequence,
+                                        subject->length);
+
+                s_SaveSubjectOverhangs(new_hsp, subject->sequence, query_len);
+            }
+                
+            ASSERT(new_hsp);
+            status = Blast_HSPListSaveHSP(hsp_list, new_hsp);
+            if (status) {
+                break;
+            }
+
+
+            /* If left of right query overhang is shorter than word size, then
+               if overhang length is smaller than mismatch penalty,
+               first assume the alignment ended with a mismatch and try to
+               extend it with perfect matches to the end of the query. If this
+               does not succeed, then look for 4-base word matches from
+               query overhangs. */
+
+            /* first for the right end of the query */
+            if (getenv("MAPPER_USE_SMALL_WORDS") &&
+                query_len - new_hsp->query.end < 16 &&
+                query_len - new_hsp->query.end >= SUBJECT_INDEX_WORD_LENGTH &&
+                subject->length - new_hsp->subject.end >= kMinSubjectOverhang) {
+
+                Int4 q = new_hsp->query.end;
+                Int4 round = 0;
+                Boolean found = FALSE;
+                ASSERT(s_index);
+
+                /* if number of unaligned query bases is smaller than
+                   mismatch penalty, then try extending the alignment past the
+                   mismatch to the end of the query */
+                if (query_len - new_hsp->query.end < -score_params->penalty) {
+                    Int4 i;
+                    for (i = 1;i < query_len - new_hsp->query.end;i++) {
+                        if (query_seq[new_hsp->query.end + i] !=
+                            UNPACK_BASE(subject->sequence,
+                                        new_hsp->subject.end + i)) {
+                            break;
+                        }
+                    }
+
+                    /* if extension succeeded through 4 bases or till the end
+                       of thequery, create and save an HSP */
+                    if (i > 4 || i == query_len - new_hsp->query.end) {
+
+                        BlastHSP* w_hsp = s_CreateHSPForWordHit(
+                                               new_hsp->query.end + 1,
+                                               new_hsp->subject.end + 1,
+                                               i - 1,
+                                               context, query_seq,
+                                               query_info, subject,
+                                               query_len);
+
+                        ASSERT(w_hsp->query.offset >= 0 &&
+                               w_hsp->query.end <= query_len);
+                        status = Blast_HSPListSaveHSP(hsp_list, w_hsp);
+                        if (status) {
+                            return -1;
+                        }
+                    }
+                }
+
+                for (; !found && q + SUBJECT_INDEX_WORD_LENGTH <= query_len &&
+                         round < 2;q++, round++) {
+                    Int4 word;
+                    Int4 from;
+                    Int4 s_pos;
+                    SubjectIndexIterator* it = NULL;
+                    Int4 i;
+
+                    /* skip over ambiguous bases */
+                    while (q + SUBJECT_INDEX_WORD_LENGTH <= query_len) {
+                        for (i = 0;i < SUBJECT_INDEX_WORD_LENGTH;i++) {
+                            if ((query_seq[q + i] & 0xfc) != 0) {
+                                q = q + i + 1;
+                                break;
+                            }
+                        }
+
+                        if (i == SUBJECT_INDEX_WORD_LENGTH) {
+                            break;
+                        }
+                    }
+
+                    if (q + SUBJECT_INDEX_WORD_LENGTH - 1 >= query_len) {
+                        break;
+                    }
+
+                    /* this is query word */
+                    word = (query_seq[q] << 6) | (query_seq[q + 1] << 4) |
+                        (query_seq[q + 2] << 2) | query_seq[q + 3];
+                    for (i = 4; i < SUBJECT_INDEX_WORD_LENGTH; i++) {
+                        word = (word << 2) | query_seq[q + i];
+                    }
+
+                    /* search subject for matching words from this position */
+                    from = new_hsp->subject.end;
+
+                    /* create subject word iterator and iterate from the end
+                       of current HSP through the max intron length or up to
+                       the end of subject less query overhang bases (so that
+                       we can extend to the end of the query) */
+                    it = SubjectIndexIteratorNew(s_index, word, from,
+                                MIN((from + kMaxIntronLength),
+                                    (subject->length - (query_len - q + 1))));
+
+                    /* for each word match position in the subject */
+                    for (s_pos = SubjectIndexIteratorNext(it); s_pos >= 0;
+                         s_pos = SubjectIndexIteratorNext(it)) {
+                        Int4 qt;
+                        Int4 st;
+
+                        /* try to extend the hit right to the end of the
+                           query accepting only matches */
+                        qt = q;
+                        st = s_pos;
+                        while (qt < query_len && st < subject->length &&
+                               (query_seq[qt] ==
+                                UNPACK_BASE(subject->sequence, st) ||
+                                /* skip over ambiguous bases */
+                                (query_seq[qt] & 0xfc) != 0)) {
+                            qt++;
+                            st++;
+                        }
+
+                        /* proceed only if query matches to the end and try
+                           extending left as much as possible */
+                        if (qt == query_len) {
+                            Int4 qf = q;
+                            Int4 sf = s_pos;
+                            BlastHSP* w_hsp = NULL;
+
+                            while (qf >= 0 && sf >= 0 &&
+                                   (query_seq[qf] ==
+                                    UNPACK_BASE(subject->sequence, sf) ||
+                                    (query_seq[qf] & 0xfc) != 0)) {
+
+                                qf--;
+                                sf--;
+                            }
+                            qf++;
+                            sf++;
+                            ASSERT(qt - qf == st - sf);
+
+                            if (qt - qf < 5 ||
+                                qf > new_hsp->query.end + 1 ||
+                                qf <= new_hsp->query.offset) {
+
+                                continue;
+                            }
+
+
+                            /* trim ambiguous bases at the ends of the word
+                               match */
+                            while (qf < qt && (query_seq[qf] & 0xfc) != 0) {
+                                qf++;
+                                sf++;
+                            }
+
+                            while (qt > qf && (query_seq[qt - 1] & 0xfc) != 0) {
+                                qt--;
+                                st--;
+                            }
+
+                            if (qf >= qt) {
+                                continue;
+                            }
+
+                            /* create HSP */
+                            w_hsp = s_CreateHSPForWordHit(qf, sf, qt - qf,
+                                                          context, query_seq,
+                                                          query_info, subject,
+                                                          query_len);
+
+                            ASSERT(w_hsp->query.offset >= 0 &&
+                                   w_hsp->query.end <= query_len);
+
+                            ASSERT(w_hsp);
+                            if (!w_hsp) {
+                                return -1;
+                            }
+
+                            /* add HSP to the list */
+                            status = Blast_HSPListSaveHSP(hsp_list, w_hsp);
+                            if (status) {
+                                return -1;
+                            }
+                        }
+                    }
+                    it = SubjectIndexIteratorFree(it);
+                }
+            }
+
+
+            if (getenv("MAPPER_USE_SMALL_WORDS") &&
+                new_hsp->query.offset < 16 &&
+                new_hsp->query.offset >= SUBJECT_INDEX_WORD_LENGTH &&
+                new_hsp->subject.offset >= kMinSubjectOverhang) {
+
+                Int4 q = MAX(new_hsp->query.offset - SUBJECT_INDEX_WORD_LENGTH,
+                             0);
+                Int4 round = 0;
+                Boolean found = FALSE;
+                ASSERT(s_index);
+
+                /* if number of unaligned query bases is smaller than
+                   mismatch penalty, then try extending the alignment past the
+                   mismatch to beginning of the query */
+                if (new_hsp->query.offset < -score_params->penalty) {
+                    Int4 i;
+                    for (i = 2;i < new_hsp->query.offset - 1;i++) {
+                        if (query_seq[new_hsp->query.offset - i] !=
+                            UNPACK_BASE(subject->sequence,
+                                        new_hsp->subject.offset - i)) {
+                            break;
+                        }
+                    }
+
+                    /* if the extension suceeded thrught at least 4 bases or
+                       to the beginning of the query, create and save the HSP */
+                    if (i > 4 || i == new_hsp->query.offset - 1) {
+
+                        BlastHSP* w_hsp = s_CreateHSPForWordHit(
+                                               new_hsp->query.offset - 1 - i,
+                                               new_hsp->subject.offset - 1- i,
+                                               i,
+                                               context, query_seq,
+                                               query_info, subject,
+                                               query_len);
+
+                        ASSERT(w_hsp->query.offset >= 0 &&
+                               w_hsp->query.end <= query_len);
+                        status = Blast_HSPListSaveHSP(hsp_list, w_hsp);
+                        if (status) {
+                            return -1;
+                        }
+                    }
+                }
+
+
+                for (; !found && q >= 0 && round < 2;q--, round++) {
+
+                    Int4 word;
+                    Int4 from;
+                    Int4 s_pos;
+                    SubjectIndexIterator* it = NULL;
+                    Int4 i;
+
+                    /* skip over ambiguous bases */
+                    while (q >= 0) {
+                        for (i = 0;i < SUBJECT_INDEX_WORD_LENGTH;i++) {
+                            if ((query_seq[q + i] & 0xfc) != 0) {
+                                q = q + i - SUBJECT_INDEX_WORD_LENGTH;
+                                break;
+                            }
+                        }
+
+                        if (i == SUBJECT_INDEX_WORD_LENGTH) {
+                            break;
+                        }
+                    }
+
+                    if (q < 0) {
+                        break;
+                    }
+
+
+                    /* this is query word */
+                    word = (query_seq[q] << 6) | (query_seq[q + 1] << 4) |
+                        (query_seq[q + 2] << 2) | query_seq[q + 3];
+                    for (i = 4; i < SUBJECT_INDEX_WORD_LENGTH; i++) {
+                        word = (word << 2) | query_seq[q + i];
+                    }
+
+
+                    /* search subject for matching words from this position */
+                    from = new_hsp->subject.offset - SUBJECT_INDEX_WORD_LENGTH;
+
+                    it = SubjectIndexIteratorNew(s_index, word, from,
+                                        MAX(from - kMaxIntronLength, q + 1));
+
+                    /* for each word match position in the subject */
+                    for (s_pos = SubjectIndexIteratorPrev(it); s_pos >= 0;
+                         s_pos = SubjectIndexIteratorPrev(it)) {
+
+                        /* try extending left */
+                        Int4 k = q;
+                        Int4 s = s_pos;
+                        while (k >= 0 && 
+                               (query_seq[k] ==
+                                UNPACK_BASE(subject->sequence, s) ||
+                                (query_seq[k] & 0xfc) != 0)) {
+                            k--;
+                            s--;
+                        }
+                        /* if query matches all the way, then extend right as
+                           far as there are matches */
+                        if (k == -1) {
+                            Int4 qt = q;
+                            Int4 st = s_pos;
+                            BlastHSP* w_hsp = NULL;
+
+                            k++;
+                            s++;
+                            while (qt < query_len && st < subject->length && 
+                                   (query_seq[qt] ==
+                                    UNPACK_BASE(subject->sequence, st) ||
+                                    /* skip over ambiguous bases */
+                                    (query_seq[qt] & 0xfc) != 0)) {
+                                qt++;
+                                st++;
+                            }
+                            ASSERT(k - qt == s - st);
+
+
+                            if (qt - k < 5 || 
+                                s >= new_hsp->subject.offset ||
+                                new_hsp->query.offset > qt + 1) {
+                                continue;
+                            }
+
+
+                            /* trim ambiguous bases at the ends of the word
+                               match */
+                            while (k < qt && (query_seq[k] & 0xfc) != 0) {
+                                k++;
+                                s++;
+                            }
+
+                            while (qt > k && (query_seq[qt] & 0xfc) != 0) {
+                                qt--;
+                                st--;
+                            }
+
+                            if (k >= qt) {
+                                continue;
+                            }
+
+                            /* create HSP */
+                            w_hsp = s_CreateHSPForWordHit(k, s, qt - k,
+                                                          context, query_seq,
+                                                          query_info, subject,
+                                                          query_len);
+
+                            ASSERT(w_hsp->query.offset >= 0 &&
+                                   w_hsp->query.end <= query_len);
+
+                            ASSERT(w_hsp);
+                            if (!w_hsp) {
+                                return -1;
+                            }
+
+                            status = Blast_HSPListSaveHSP(hsp_list, w_hsp);
+                            if (status) {
+                                return -1;
+                            }
+                        }
+                    }
+                    it = SubjectIndexIteratorFree(it);
+                }
+            }
+
+        }
+    }
+
+    return hits_extended;
+}
+
+
+SubjectIndex* SubjectIndexFree(SubjectIndex* sindex)
+{
+    if (!sindex) {
+        return NULL;
+    }
+
+    if (sindex->lookups) {
+        Int4 i;
+        for (i = 0;i < sindex->num_lookups;i++) {
+            if (sindex->lookups[i]) {
+                BlastNaLookupTableDestruct(sindex->lookups[i]);
+            }
+        }
+        free(sindex->lookups);
+    }
+
+    free(sindex);
+    return NULL;
+}
+
+static void 
+s_SubjectIndexNewCleanup(BLAST_SequenceBlk* sequence, BlastSeqLoc* seqloc,
+                         LookupTableOptions* opt, QuerySetUpOptions* query_opt,
+                         SubjectIndex* sindex)
+{
+    if (sequence) {
+        if (sequence->sequence) {
+            free(sequence->sequence);
+        }
+        free(sequence);
+    }
+
+    while (seqloc) {
+        BlastSeqLoc* s = seqloc->next;
+        if (seqloc->ssr) {
+            free(seqloc->ssr);
+        }
+        free(seqloc);
+        seqloc = s;
+    }
+
+    if (opt) {
+        free(opt);
+    }
+
+    if (query_opt) {
+        free(query_opt);
+    }
+
+    SubjectIndexFree(sindex);
+}
+
+SubjectIndex* SubjectIndexNew(BLAST_SequenceBlk* subject, Int4 width,
+                              Int4 word_size)
+{
+    Int4 i;
+    BLAST_SequenceBlk* sequence = NULL;
+    BlastSeqLoc* seqloc = NULL;
+    SSeqRange* ssr = NULL;
+    LookupTableOptions* opt = NULL;
+    QuerySetUpOptions* query_opt = NULL;
+    SubjectIndex* retval = NULL;
+    Int4 num_lookups = subject->length / width + 1;
+    
+    sequence = calloc(1, sizeof(BLAST_SequenceBlk));
+    if (!sequence) {
+        return NULL;
+    }
+
+    /* convert subject sequence to blastna */
+    sequence->sequence = calloc(subject->length, sizeof(Uint1));
+    if (!sequence->sequence) {
+        free(sequence);
+        return NULL;
+    }
+
+    for (i = 0;i < subject->length / 4;i++) {
+        Int4 k;
+        for (k = 0;k < 4;k++) {
+            sequence->sequence[4 * i + k] =
+                (subject->sequence[i] >> (2 * (3 - k))) & 3;
+        }
+    }
+
+    retval = calloc(1, sizeof(SubjectIndex));
+    if (!retval) {
+        s_SubjectIndexNewCleanup(sequence, seqloc, opt, query_opt, retval);
+    }
+
+    retval->lookups = calloc(num_lookups, sizeof(BlastNaLookupTable*));
+    if (!retval->lookups) {
+        s_SubjectIndexNewCleanup(sequence, seqloc, opt, query_opt, retval);
+    }
+
+    ssr = malloc(sizeof(SSeqRange));
+    if (!ssr) {
+        s_SubjectIndexNewCleanup(sequence, seqloc, opt, query_opt, retval);
+    }
+
+    seqloc = calloc(1, sizeof(BlastSeqLoc));
+    if (!seqloc) {
+        if (ssr) {
+            free(ssr);
+        }
+        s_SubjectIndexNewCleanup(sequence, seqloc, opt, query_opt, retval);
+        return NULL;
+    }
+
+    opt = calloc(1, sizeof(LookupTableOptions));
+    if (!opt) {
+        s_SubjectIndexNewCleanup(sequence, seqloc, opt, query_opt, retval);
+        return NULL;
+    }
+    opt->word_size = 4;
+
+    query_opt = calloc(1, sizeof(QuerySetUpOptions));
+    if (!query_opt) {
+        s_SubjectIndexNewCleanup(sequence, seqloc, opt, query_opt, retval);
+        return NULL;
+    }
+
+
+    for (i = 0;i < num_lookups;i++) {
+
+        ssr->left = width * i;
+        ssr->right = MIN(ssr->left + width, subject->length - 1);
+
+        seqloc->ssr = ssr;
+
+        BlastNaLookupTableNew(sequence, seqloc, &(retval->lookups[i]), opt,
+                              query_opt, word_size);
+
+        if (!retval->lookups[i]) {
+            s_SubjectIndexNewCleanup(sequence, seqloc, opt, query_opt, retval);
+        }
+
+        ASSERT(i < num_lookups);
+    }
+    retval->num_lookups = i;
+    retval->width = width;
+
+    s_SubjectIndexNewCleanup(sequence, seqloc, opt, query_opt, NULL);
+
+    return retval;
+}
+
+
+SubjectIndexIterator* SubjectIndexIteratorFree(SubjectIndexIterator* it)
+{
+    if (it) {
+        free(it);
+    }
+
+    return NULL;
+}
+
+/* Create an iterator for positions of a given word in subject sequence between
+   positions from and to */
+SubjectIndexIterator* SubjectIndexIteratorNew(SubjectIndex* s_index, Int4 word,
+                                              Int4 from, Int4 to)
+{
+    SubjectIndexIterator* retval = NULL;
+
+    if (!s_index || !s_index->lookups[0]) {
+        return NULL;
+    }
+
+    retval = calloc(1, sizeof(SubjectIndexIterator));
+    if (!retval) {
+        return NULL;
+    }
+
+    retval->subject_index = s_index;
+    retval->to = to;
+    retval->lookup_index = from / s_index->width;
+    ASSERT(retval->lookup_index < s_index->num_lookups);
+    if (retval->lookup_index >= s_index->num_lookups) {
+        SubjectIndexIteratorFree(retval);
+        return NULL;
+    }
+
+    /* find the first word with position at least from */
+    while (retval->lookup_index < retval->subject_index->num_lookups) {
+        BlastNaLookupTable* lookup = s_index->lookups[retval->lookup_index];
+        if (!lookup) {
+            SubjectIndexIteratorFree(retval);
+            return NULL;
+        }
+
+        word = word & lookup->mask;
+        retval->num_words = lookup->thick_backbone[word].num_used;
+        if (retval->num_words <= NA_HITS_PER_CELL) {
+            retval->lookup_pos = lookup->thick_backbone[word].payload.entries;
+        }
+        else {
+            retval->lookup_pos = lookup->overflow +
+                lookup->thick_backbone[word].payload.overflow_cursor;
+        }
+
+        retval->word = word;
+        retval->word_index = 0;
+
+        while (retval->word_index < retval->num_words &&
+               retval->lookup_pos[retval->word_index] < from) {
+        
+            retval->word_index++;
+        }
+
+        if (retval->word_index >= retval->num_words) {
+            retval->lookup_index++;
+        }
+        else {
+            break;
+        }
+    }
+
+    return retval;
+}
+
+/* Return current position of a word and move iterator to the next position */
+Int4 SubjectIndexIteratorNext(SubjectIndexIterator* it)
+{
+    Int4 pos;
+
+    if (!it) {
+        return -1;
+    }
+
+    /* if all words in the current lookup table were processed, move to the
+       next lookup table */
+    if (it->word_index >= it->num_words) {
+        BlastNaLookupTable* lookup = NULL;
+        it->lookup_index++;
+
+        /* if no more lookup table return no positon found */
+        if (it->lookup_index >= it->subject_index->num_lookups) {
+            return -1;
+        }
+        lookup = it->subject_index->lookups[it->lookup_index];
+        ASSERT(lookup);
+        it->num_words = lookup->thick_backbone[it->word].num_used;
+        if (it->num_words <= NA_HITS_PER_CELL) {
+            it->lookup_pos = lookup->thick_backbone[it->word].payload.entries;
+        }
+        else {
+            it->lookup_pos = lookup->overflow +
+                lookup->thick_backbone[it->word].payload.overflow_cursor;
+        }
+        ASSERT(it->lookup_pos);
+        it->word_index = 0;
+    }
+
+    if (!it->lookup_pos) {
+        return -1;
+    }
+
+    pos = it->lookup_pos[it->word_index];
+    if (pos > it->to) {
+        return -1;
+    }
+
+    /* move iterator to the next position */
+    it->word_index++;
+
+    return pos;
+}
+
+/* Return current position of a word and move iterator to the previous
+   position */
+Int4 SubjectIndexIteratorPrev(SubjectIndexIterator* it)
+{
+    Int4 pos;
+
+    if (!it) {
+        return -1;
+    }
+
+    if (it->word_index < 0) {
+        BlastNaLookupTable* lookup = NULL;
+        it->lookup_index--;
+        if (it->lookup_index < 0) {
+            return -1;
+        }
+        lookup = it->subject_index->lookups[it->lookup_index];
+        ASSERT(lookup);
+        it->num_words = lookup->thick_backbone[it->word].num_used;
+        if (it->num_words <= NA_HITS_PER_CELL) {
+            it->lookup_pos = lookup->thick_backbone[it->word].payload.entries;
+        }
+        else {
+            it->lookup_pos = lookup->overflow +
+                lookup->thick_backbone[it->word].payload.overflow_cursor;
+        }
+        ASSERT(it->lookup_pos);
+        it->word_index = it->num_words - 1;
+    }
+
+    if (!it->lookup_pos) {
+        return -1;
+    }
+
+    pos = it->lookup_pos[it->word_index];
+    if (pos < it->to) {
+        return -1;
+    }
+
+    it->word_index--;
+
+    return pos;
+}
+
+
diff --git a/c++/src/algo/blast/core/jumper.h b/c++/src/algo/blast/core/jumper.h
new file mode 100644
index 0000000..9895ddb
--- /dev/null
+++ b/c++/src/algo/blast/core/jumper.h
@@ -0,0 +1,279 @@
+/*  $Id: jumper.h 504946 2016-06-21 13:53:04Z madden $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  Greg Boratyn
+ *
+ * Jumper alignment
+ *
+ */
+
+#include <algo/blast/core/ncbi_std.h>
+#include <algo/blast/core/blast_util.h>
+#include <algo/blast/core/blast_def.h>
+#include <algo/blast/core/blast_gapalign.h>
+#include <algo/blast/core/blast_parameters.h>
+#include <algo/blast/core/blast_extend.h>
+#include <algo/blast/core/gapinfo.h>
+#include <algo/blast/core/blast_nalookup.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct { int dcp, dcq, lng, ok; } JUMP;
+
+/* Simple edit script for jumper: represented as integer n:
+   n > 0: n matches
+   n == 0: a single mismatch
+   n < 0: a single insertion or deletion */
+#define JUMPER_MISMATCH (0)
+#define JUMPER_INSERTION (-1)
+#define JUMPER_DELETION (-2)
+
+/** Jumper edit script operation */
+typedef Int2 JumperOpType;
+
+/** Internal alignment edit script */
+typedef struct JumperPrelimEditBlock
+{
+    JumperOpType* edit_ops;
+    Int4 num_ops;
+    Int4 num_allocated;
+} JumperPrelimEditBlock;
+
+
+/** Gapped alignment data needed for jumper */
+typedef struct JumperGapAlign
+{
+    JumperPrelimEditBlock* left_prelim_block;
+    JumperPrelimEditBlock* right_prelim_block;
+    Uint4* table; /**< Table used for matching 4 bases in compressed subject
+                       to 4 bases in uncompressed query */
+} JumperGapAlign;
+
+
+JumperGapAlign* JumperGapAlignFree(JumperGapAlign* jumper_align);
+JumperGapAlign* JumperGapAlignNew(Int4 size);
+Int4 JumperPrelimEditBlockAdd(JumperPrelimEditBlock* block, JumperOpType op);
+
+
+/** Single alignment error */
+typedef struct JumperEdit
+{
+    Int4 query_pos;      /**< Query position*/
+    Uint1 query_base;    /**< Query base at this position */
+    Uint1 subject_base;  /**< Subject base at this position */
+} JumperEdit;
+
+
+/** Alignment edit script for gapped alignment */
+typedef struct JumperEditsBlock
+{
+    JumperEdit* edits;
+    Int4 num_edits;
+} JumperEditsBlock;
+
+
+JumperEditsBlock* JumperEditsBlockFree(JumperEditsBlock* block);
+JumperEditsBlock* JumperEditsBlockDup(const JumperEditsBlock* block);
+JumperEditsBlock* JumperFindEdits(const Uint1* query, const Uint1* subject,
+                                  BlastGapAlignStruct* gap_align);
+
+/** Convert Jumper's preliminary edit script to GapEditScript */
+GapEditScript* JumperPrelimEditBlockToGapEditScript(
+                                      JumperPrelimEditBlock* rev_prelim_block,
+                                      JumperPrelimEditBlock* fwd_prelim_block);
+
+
+/** Test whether an HSP should be saved */
+Boolean JumperGoodAlign(const BlastGapAlignStruct* gap_align,
+                        const BlastHitSavingParameters* hit_params,
+                        Int4 num_identical,
+                        BlastContextInfo* range_info);
+
+
+/** Right extension with traceback */
+Int4 JumperExtendRightWithTraceback(
+                                 const Uint1* query, const Uint1* subject, 
+                                 int query_length, int subject_length,
+                                 Int4 match_score, Int4 mismatch_score,
+                                 Int4 gap_open, Int4 gap_extend,
+                                 int max_mismatches, int window,
+                                 Int4* query_ext_len, Int4* subject_ext_len,
+                                 JumperPrelimEditBlock* edit_script,
+                                 Int4* num_identical,
+                                 Boolean left_extension,
+                                 Int4* ungapped_ext_len,
+                                 JUMP* jumper);
+
+
+
+/** Jumper gapped alignment with traceback; 1 base per byte in query, 4 bases
+    per byte in subject */
+int JumperGappedAlignmentCompressedWithTraceback(const Uint1* query,
+                               const Uint1* subject,
+                               Int4 query_length, Int4 subject_length,
+                               Int4 query_start, Int4 subject_start,
+                               BlastGapAlignStruct* gap_align,
+                               const BlastScoringParameters* score_params,
+                               Int4* num_identical,
+                               Int4* right_ungapped_ext_len);
+
+
+#define SUBJECT_INDEX_WORD_LENGTH (4)
+
+/** Index for a chunk of a subject sequence */
+typedef struct SubjectIndex
+{
+    /** Array of lookup tables */
+    BlastNaLookupTable** lookups;
+    /** Number of bases covered by each lookup table */
+    Int4 width;  
+    /** Number of lookup tables used */
+    Int4 num_lookups;
+} SubjectIndex;
+
+/** Free subject index structure */
+SubjectIndex* SubjectIndexFree(SubjectIndex* sindex);
+
+/** Index a sequence, used for indexing compressed nucleotide subject
+ *  sequence. The index consists of a list of lookup tables, each covering
+ *  width number of bases.
+ *    
+ * @param subject Sequence to be indexed [in]
+ * @param width Number of bases covered by a single lookup table [in]
+ * @param word_size Word size to be used in the lookup table [in]
+ * @return Pointer to the created index
+ */
+SubjectIndex* SubjectIndexNew(BLAST_SequenceBlk* subject, Int4 width,
+                              Int4 word_size);
+
+
+/** Iterator over word locations in subject index */
+typedef struct SubjectIndexIterator
+{
+    SubjectIndex* subject_index;
+    Int4 word;
+    Int4 from;
+    Int4 to;
+    Int4 lookup_index;
+    Int4* lookup_pos;
+    Int4 num_words;
+    Int4 word_index;
+} SubjectIndexIterator;
+
+
+/** Free memory reserved for subject index word iterator */
+SubjectIndexIterator* SubjectIndexIteratorFree(SubjectIndexIterator* it);
+
+/** Create an iterator for locations of a given word
+ * @param s_index Sequence index [in]
+ * @param word Nucleotide word to be searched [in]
+ * @param from Sequence location to begin search [in]
+ * @param to Sequence location to end search [in]
+ * @return Word location iterator
+ */
+SubjectIndexIterator* SubjectIndexIteratorNew(SubjectIndex* s_index, Int4 word,
+                                              Int4 from, Int4 to);
+
+/** Return the next location of a word in an indexed sequence
+ * @param it Iterator [in|out]
+ * @return Word location or value less than zero if no more words are found
+ */
+Int4 SubjectIndexIteratorNext(SubjectIndexIterator* it);
+
+/** Return the previous location of a word in an indexed sequence
+ * @param it Iterator [in|out]
+ * @return Word location or value less than zero if no more words are found
+ */
+Int4 SubjectIndexIteratorPrev(SubjectIndexIterator* it);
+
+
+
+/** Extend a list of word hits */
+Int4 BlastNaExtendJumper(BlastOffsetPair* offset_pairs, Int4 num_hits,
+                         const BlastInitialWordParameters* word_params,
+                         const BlastScoringParameters* score_params,
+                         const BlastHitSavingParameters* hit_params,
+                         LookupTableWrap* lookup_wrap,
+                         BLAST_SequenceBlk* query,
+                         BLAST_SequenceBlk* subject,
+                         BlastQueryInfo* query_info,
+                         BlastGapAlignStruct* gap_align,
+                         BlastHSPList* hsp_list,
+                         Uint4 s_range,
+                         SubjectIndex* s_index);
+
+
+#define MAPPER_SPLICE_SIGNAL (0x80)
+#define MAPPER_EXON (0x40)
+#define MAPPER_POLY_A (0x20)
+#define MAPPER_ADAPTER (0x10)
+
+/** Find splice signals at the edges of an HSP and save them in the HSP
+ * @param hsp HSP [in|out]
+ * @param query_len Length of the query/read [in]
+ * @param subject Subject sequence [in]
+ * @param subject_len Subject length [in]
+ * @return Zero on success
+ */
+int JumperFindSpliceSignals(BlastHSP* hsp, Int4 query_len,
+                            const Uint1* subject, Int4 subject_len);
+
+
+#define MAPPER_FLAGS_PAIR_CONVERGENT (1)
+#define MAPPER_FLAGS_PAIR_DIVERGENT  (1 << 1)
+#define MAPPER_FLAGS_PAIR_REARRANGED (1 << 2)
+
+#define MAPPER_FLAGS_PAIR (MAPPER_FLAGS_PAIR_CONVERGENT | MAPPER_FLAGS_PAIR_DIVERGENT | MAPPER_FLAGS_PAIR_REARRANGED)
+
+
+/* Combine edit scripts into one. Returns the combined edit script, deletes
+   input scripts. */
+GapEditScript* GapEditScriptCombine(GapEditScript** edit_script,
+                                    GapEditScript** append);
+
+/* Combine two edits blocks into one. Returns the combined block, deletes input
+   blocks */
+JumperEditsBlock* JumperEditsBlockCombine(JumperEditsBlock** block,
+                                          JumperEditsBlock** append);
+
+/** Structure to save short unaligned subsequences outside an HSP */
+typedef struct SequenceOverhangs
+{
+    Int4 left_len;    /**< Length of the left subsequence */
+    Int4 right_len;   /**< Length of the right subsequence */
+    Uint1* left;      /**< Left subsequence */
+    Uint1* right;     /**< Rught subsequence */
+} SequenceOverhangs;
+
+SequenceOverhangs* SequenceOverhangsFree(SequenceOverhangs* overhangs);
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/c++/src/algo/blast/core/link_hsps.c b/c++/src/algo/blast/core/link_hsps.c
index 41d543f..4ba0cec 100644
--- a/c++/src/algo/blast/core/link_hsps.c
+++ b/c++/src/algo/blast/core/link_hsps.c
@@ -1,5 +1,5 @@
 
-/* $Id: link_hsps.c 371542 2012-08-09 14:41:30Z boratyng $
+/* $Id: link_hsps.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  * Functions to link with use of sum statistics
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: link_hsps.c 371542 2012-08-09 14:41:30Z boratyng $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/link_hsps.h>
 #include <algo/blast/core/blast_util.h>
 #include "blast_hits_priv.h"
diff --git a/c++/src/algo/blast/core/lookup_util.c b/c++/src/algo/blast/core/lookup_util.c
index dd38202..a9f426d 100644
--- a/c++/src/algo/blast/core/lookup_util.c
+++ b/c++/src/algo/blast/core/lookup_util.c
@@ -1,4 +1,4 @@
-/* $Id: lookup_util.c 94537 2006-12-01 16:52:58Z papadopo $
+/* $Id: lookup_util.c 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -28,11 +28,6 @@
  *  Utility functions for lookup table generation.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: lookup_util.c 94537 2006-12-01 16:52:58Z papadopo $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/lookup_util.h>
 
 static void fkm_output(Int4 * a,
@@ -73,7 +68,7 @@ iexp(Int4 x,
 }
 
 Int4
-ilog2(Int4 x)
+ilog2(Int8 x)
 {
     Int4 lg = 0;
 
diff --git a/c++/src/algo/blast/core/lookup_wrap.c b/c++/src/algo/blast/core/lookup_wrap.c
index 94884a4..a289778 100644
--- a/c++/src/algo/blast/core/lookup_wrap.c
+++ b/c++/src/algo/blast/core/lookup_wrap.c
@@ -1,4 +1,4 @@
-/* $Id: lookup_wrap.c 363884 2012-05-21 15:54:30Z morgulis $
+/* $Id: lookup_wrap.c 506102 2016-07-01 15:48:06Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -35,11 +35,6 @@
  * megablast lookup table, etc.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: lookup_wrap.c 363884 2012-05-21 15:54:30Z morgulis $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/lookup_wrap.h>
 #include <algo/blast/core/blast_aalookup.h>
 #include <algo/blast/core/blast_nalookup.h>
@@ -54,7 +49,8 @@ Int2 LookupTableWrapInit(BLAST_SequenceBlk* query,
         const QuerySetUpOptions* query_options,
         BlastSeqLoc* lookup_segments, BlastScoreBlk* sbp, 
         LookupTableWrap** lookup_wrap_ptr, const BlastRPSInfo *rps_info,
-        Blast_Message* *error_msg)
+        Blast_Message* *error_msg,
+        BlastSeqSrc* seqsrc)
 {
    Int2 status = 0;
    LookupTableWrap* lookup_wrap;
@@ -121,7 +117,8 @@ Int2 LookupTableWrapInit(BLAST_SequenceBlk* query,
              BlastMBLookupTableNew(query, lookup_segments, 
                                (BlastMBLookupTable* *) &(lookup_wrap->lut), 
                                lookup_options, query_options,
-                               num_table_entries, lut_width);
+                               num_table_entries, lut_width,
+                               seqsrc);
           }
           else if (lookup_wrap->lut_type == eSmallNaLookupTable) {
              status = BlastSmallNaLookupTableNew(query, lookup_segments,
@@ -143,6 +140,13 @@ Int2 LookupTableWrapInit(BLAST_SequenceBlk* query,
       ASSERT( lookup_wrap->lut_type != eMixedMBLookupTable );
       break;
 
+   case eNaHashLookupTable:
+           status = BlastNaHashLookupTableNew(query, lookup_segments,
+                             (BlastNaHashLookupTable**) &(lookup_wrap->lut), 
+                             lookup_options, query_options, seqsrc);
+       break;
+
+
    case ePhiLookupTable: case ePhiNaLookupTable:
        {
            const Boolean kIsDna = 
@@ -210,6 +214,11 @@ LookupTableWrap* LookupTableWrapFree(LookupTableWrap* lookup)
          BlastNaLookupTableDestruct((BlastNaLookupTable*)lookup->lut);
       break;
 
+   case eNaHashLookupTable:
+      lookup->lut = (void*) 
+         BlastNaHashLookupTableDestruct((BlastNaHashLookupTable*)lookup->lut);
+      break;
+
    case eAaLookupTable:
       lookup->lut = (void*) 
          BlastAaLookupTableDestruct((BlastAaLookupTable*)lookup->lut);
@@ -251,6 +260,10 @@ Int4 GetOffsetArraySize(LookupTableWrap* lookup)
       offset_array_size = OFFSET_ARRAY_SIZE + 
          ((BlastNaLookupTable*)lookup->lut)->longest_chain;
       break;
+   case eNaHashLookupTable:
+      offset_array_size = OFFSET_ARRAY_SIZE + 
+         ((BlastNaHashLookupTable*)lookup->lut)->longest_chain;
+      break;
    default:
       offset_array_size = OFFSET_ARRAY_SIZE;
       break;
diff --git a/c++/src/algo/blast/core/matrix_freq_ratios.c b/c++/src/algo/blast/core/matrix_freq_ratios.c
index 8a47a7a..7bd6c58 100644
--- a/c++/src/algo/blast/core/matrix_freq_ratios.c
+++ b/c++/src/algo/blast/core/matrix_freq_ratios.c
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: matrix_freq_ratios.c 439568 2014-07-01 16:13:36Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/core/na_ungapped.c b/c++/src/algo/blast/core/na_ungapped.c
index ed200a4..1c3d5b3 100644
--- a/c++/src/algo/blast/core/na_ungapped.c
+++ b/c++/src/algo/blast/core/na_ungapped.c
@@ -1,4 +1,4 @@
-/* $Id: na_ungapped.c 449473 2014-10-16 19:52:47Z fongah2 $
+/* $Id: na_ungapped.c 505619 2016-06-27 18:51:47Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -28,11 +28,6 @@
  * Nucleotide ungapped extension routines
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: na_ungapped.c 449473 2014-10-16 19:52:47Z fongah2 $";
-#endif                          /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/na_ungapped.h>
 #include <algo/blast/core/blast_nalookup.h>
 #include <algo/blast/core/blast_nascan.h>
@@ -41,6 +36,7 @@ static char const rcsid[] =
 
 #include "index_ungapped.h"
 #include "masksubj.inl"
+#include "jumper.h"
 
 /** Check to see if an index->q_pos pair exists in MB lookup table 
  * @param lookup_wrap The lookup table wrap structure [in]
@@ -640,7 +636,8 @@ s_BlastnDiagTableExtendInitialHit(BLAST_SequenceBlk * query,
                              const BlastInitialWordParameters * word_params,
                              Int4 ** matrix, 
                              BLAST_DiagTable * diag_table,
-                             BlastInitHitList * init_hitlist)
+                             BlastInitHitList * init_hitlist,
+                             Boolean check_masks)
 {
     Int4 diag, real_diag;
     Int4 s_end, s_off_pos, s_end_pos;
@@ -715,7 +712,7 @@ s_BlastnDiagTableExtendInitialHit(BLAST_SequenceBlk * query,
                 hit_ready = 0;
             }
         }
-    } else {
+    } else if (check_masks) {
         /* check the masks for the word */
         if(!s_TypeOfWord(query, subject, &q_off, &s_off,
                         query_mask, query_info, s_range, 
@@ -807,7 +804,8 @@ s_BlastnDiagHashExtendInitialHit(BLAST_SequenceBlk * query,
                                const BlastInitialWordParameters * word_params,
                                Int4 ** matrix,
                                BLAST_DiagHash * hash_table,
-                               BlastInitHitList * init_hitlist)
+			       BlastInitHitList * init_hitlist,
+			       Boolean check_masks)
 {
     Int4 diag;
     Int4 s_end, s_off_pos, s_end_pos, s_l;
@@ -883,8 +881,8 @@ s_BlastnDiagHashExtendInitialHit(BLAST_SequenceBlk * query,
                 hit_ready = 0;
             }
         }
-    } else {
-        /* check the masks for the word */
+    }  else if (check_masks) {
+	 /* check the masks for the word */
         if (!s_TypeOfWord(query, subject, &q_off, &s_off,
                           query_mask, query_info, s_range,
                           word_length, lut_word_length, lut, FALSE, &extended)) return 0;
@@ -973,11 +971,13 @@ s_BlastNaExtendDirect(const BlastOffsetPair * offset_pairs, Int4 num_hits,
     Int4 index = 0;
     Int4 hits_extended = 0;
     Int4 word_length;
+    Boolean check_masks = TRUE;
 
     if (lookup_wrap->lut_type == eMBLookupTable) {
         BlastMBLookupTable *lut = (BlastMBLookupTable *) lookup_wrap->lut;
         word_length = (lut->discontiguous) ? lut->template_length : lut->word_length;
         ASSERT(word_length == lut->lut_word_length || lut->discontiguous);
+        check_masks = !lut->stride;
     } 
     else if (lookup_wrap->lut_type == eSmallNaLookupTable) {
         BlastSmallNaLookupTable *lut = 
@@ -1002,7 +1002,8 @@ s_BlastNaExtendDirect(const BlastOffsetPair * offset_pairs, Int4 num_hits,
                                                 lookup_wrap,
                                                 word_params, matrix,
                                                 ewp->hash_table,
-                                                init_hitlist);
+                                                init_hitlist,
+                                                check_masks);
         }
     } 
     else {
@@ -1018,7 +1019,8 @@ s_BlastNaExtendDirect(const BlastOffsetPair * offset_pairs, Int4 num_hits,
                                                 lookup_wrap,
                                                 word_params, matrix,
                                                 ewp->diag_table,
-                                                init_hitlist);
+                                                init_hitlist,
+                                                check_masks);
         }
     }
     return hits_extended;
@@ -1058,12 +1060,14 @@ s_BlastNaExtend(const BlastOffsetPair * offset_pairs, Int4 num_hits,
     Int4 hits_extended = 0;
     Int4 word_length, lut_word_length, ext_to;
     BlastSeqLoc* masked_locations = NULL;
+    Boolean check_masks = TRUE;
 
     if (lookup_wrap->lut_type == eMBLookupTable) {
         BlastMBLookupTable *lut = (BlastMBLookupTable *) lookup_wrap->lut;
         word_length = lut->word_length;
         lut_word_length = lut->lut_word_length;
         masked_locations = lut->masked_locations;
+        check_masks = !lut->stride;
     } 
     else {
         BlastNaLookupTable *lut = (BlastNaLookupTable *) lookup_wrap->lut;
@@ -1148,7 +1152,8 @@ s_BlastNaExtend(const BlastOffsetPair * offset_pairs, Int4 num_hits,
                                                 lookup_wrap,
                                                 word_params, matrix,
                                                 ewp->hash_table,
-                                                init_hitlist);
+                                                init_hitlist,
+                                                check_masks);
         } else {
             hits_extended += s_BlastnDiagTableExtendInitialHit(query, subject, 
                                                 q_offset, s_offset,  
@@ -1158,7 +1163,8 @@ s_BlastNaExtend(const BlastOffsetPair * offset_pairs, Int4 num_hits,
                                                 lookup_wrap,
                                                 word_params, matrix,
                                                 ewp->diag_table,
-                                                init_hitlist);
+                                                init_hitlist,
+                                                check_masks);
         }
     }
     return hits_extended;
@@ -1197,12 +1203,14 @@ s_BlastNaExtendAligned(const BlastOffsetPair * offset_pairs, Int4 num_hits,
     Int4 hits_extended = 0;
     Int4 word_length, lut_word_length, ext_to;
     BlastSeqLoc* masked_locations = NULL;
+    Boolean check_masks = TRUE;
 
     if (lookup_wrap->lut_type == eMBLookupTable) {
         BlastMBLookupTable *lut = (BlastMBLookupTable *) lookup_wrap->lut;
         word_length = lut->word_length;
         lut_word_length = lut->lut_word_length;
         masked_locations = lut->masked_locations;
+        check_masks = !lut->stride;
     } 
     else {
         BlastNaLookupTable *lut = (BlastNaLookupTable *) lookup_wrap->lut;
@@ -1294,7 +1302,8 @@ s_BlastNaExtendAligned(const BlastOffsetPair * offset_pairs, Int4 num_hits,
                                                 lookup_wrap,
                                                 word_params, matrix,
                                                 ewp->hash_table,
-                                                init_hitlist);
+                                                init_hitlist,
+                                                check_masks);
         } else {
             hits_extended += s_BlastnDiagTableExtendInitialHit(query, subject, 
                                                 q_offset, s_offset,  
@@ -1304,7 +1313,8 @@ s_BlastNaExtendAligned(const BlastOffsetPair * offset_pairs, Int4 num_hits,
                                                 lookup_wrap,
                                                 word_params, matrix,
                                                 ewp->diag_table,
-                                                init_hitlist);
+                                                init_hitlist,
+                                                check_masks);
         }
     }
     return hits_extended;
@@ -1430,7 +1440,8 @@ s_BlastSmallNaExtendAlignedOneByte(const BlastOffsetPair * offset_pairs,
                                                 lookup_wrap,
                                                 word_params, matrix,
                                                 ewp->hash_table,
-                                                init_hitlist);
+                    					        init_hitlist,
+					                        	TRUE);
         }
         else {
             hits_extended += s_BlastnDiagTableExtendInitialHit(query, subject, 
@@ -1441,7 +1452,8 @@ s_BlastSmallNaExtendAlignedOneByte(const BlastOffsetPair * offset_pairs,
                                                 lookup_wrap,
                                                 word_params, matrix,
                                                 ewp->diag_table,
-                                                init_hitlist);
+                                                init_hitlist,
+                                                TRUE);
         }
     }
     return hits_extended;
@@ -1559,7 +1571,8 @@ s_BlastSmallNaExtend(const BlastOffsetPair * offset_pairs, Int4 num_hits,
                                                 lookup_wrap,
                                                 word_params, matrix,
                                                 ewp->hash_table,
-                                                init_hitlist);
+                                                init_hitlist,
+                                                TRUE);
         } else {
             hits_extended += s_BlastnDiagTableExtendInitialHit(query, subject, 
                                                 q_offset, s_offset,  
@@ -1569,7 +1582,8 @@ s_BlastSmallNaExtend(const BlastOffsetPair * offset_pairs, Int4 num_hits,
                                                 lookup_wrap,
                                                 word_params, matrix,
                                                 ewp->diag_table,
-                                                init_hitlist);
+                                                init_hitlist,
+                                                TRUE);
         }
     }
     return hits_extended;
@@ -1800,6 +1814,9 @@ void BlastChooseNaExtend(LookupTableWrap * lookup_wrap)
         else
             lut->extend_callback = (void *)s_BlastSmallNaExtend;
     }
+    else if (lookup_wrap->lut_type == eNaHashLookupTable) {
+        lookup_wrap->lookup_callback = NULL;
+    }
     else {
         BlastNaLookupTable *lut;
         lookup_wrap->lookup_callback = (void *)s_NaLookup;
@@ -1814,3 +1831,489 @@ void BlastChooseNaExtend(LookupTableWrap * lookup_wrap)
             lut->extend_callback = (void *)s_BlastNaExtend;
     }
 }
+
+
+MapperWordHits* MapperWordHitsFree(MapperWordHits* wh)
+{
+    if (wh) {
+        if (wh->pair_arrays) {
+            if (wh->pair_arrays[0]) {
+                sfree(wh->pair_arrays[0]);
+            }
+            sfree(wh->pair_arrays);
+        }
+
+        if (wh->num) {
+            sfree(wh->num);
+        }
+
+        if (wh->last_diag) {
+            sfree(wh->last_diag);
+        }
+
+        if (wh->last_pos) {
+            sfree(wh->last_pos);
+        }
+
+        sfree(wh);
+    }
+
+    return NULL;
+}
+
+MapperWordHits* MapperWordHitsNew(const BLAST_SequenceBlk* query,
+                                  const BlastQueryInfo* query_info)
+{
+    MapperWordHits* wh = NULL;
+    Int4 num_arrays;
+    Int4 array_size;
+    Int4 i;
+
+    num_arrays = MAX(query_info->num_queries / 100, 1);
+    array_size = 1000;
+
+    wh = calloc(1, sizeof(MapperWordHits));
+    if (!wh) {
+        return NULL;
+    }
+
+    wh->pair_arrays = calloc(num_arrays, sizeof(BlastOffsetPair*));
+    if (!wh->pair_arrays) {
+        MapperWordHitsFree(wh);
+        return NULL;
+    }
+
+    wh->pair_arrays[0] =
+        malloc(num_arrays * array_size * sizeof(BlastOffsetPair));
+    if (!wh->pair_arrays[0]) {
+        MapperWordHitsFree(wh);
+        return NULL;
+    }
+
+    for (i = 1;i < num_arrays;i++) {
+        wh->pair_arrays[i] = wh->pair_arrays[0] + (i * array_size);
+    }
+
+    wh->num = calloc(num_arrays, sizeof(Int4));
+    if (!wh->num) {
+        MapperWordHitsFree(wh);
+        return NULL;
+    }
+
+    wh->num_arrays = num_arrays;
+    wh->array_size = array_size;
+    wh->divisor = query->length / wh->num_arrays + 1;
+
+    wh->last_diag = calloc(query_info->last_context + 1, sizeof(Int4));
+    if (!wh) {
+        MapperWordHitsFree(wh);
+        return NULL;
+    }
+
+    wh->last_pos = malloc((query_info->last_context + 1) * sizeof(Int4));
+    if (!wh) {
+        MapperWordHitsFree(wh);
+        return NULL;
+    }
+    for (i = 0;i < query_info->num_queries;i++) {
+        wh->last_pos[i] = INT4_MIN;
+    }
+
+    return wh;
+}
+
+
+Int2
+JumperNaWordFinder(BLAST_SequenceBlk * subject,
+                   BLAST_SequenceBlk * query,
+                   BlastQueryInfo * query_info,
+                   LookupTableWrap * lookup_wrap,
+                   const BlastInitialWordParameters * word_params,
+                   const BlastScoringParameters* score_params,
+                   const BlastHitSavingParameters* hit_params,
+                   BlastOffsetPair * offset_pairs,
+                   MapperWordHits* word_hits,
+                   Int4 max_hits,
+                   BlastGapAlignStruct* gap_align,
+                   BlastInitHitList* init_hitlist,
+                   BlastHSPList** hsp_list_ptr,
+                   BlastUngappedStats * ungapped_stats,
+                   BlastGappedStats* gapped_stats)
+{
+    Int4 hitsfound, total_hits = 0;
+    Int4 hits_extended = 0;
+    TNaScanSubjectFunction scansub = NULL;
+    Int4 scan_range[3];
+    Int4 word_length;
+    Int4 lut_word_length;
+    BlastHSPList* hsp_list = NULL;
+    Boolean read_is_query = query_info->max_length < subject->length;
+    SubjectIndex* s_index = NULL;
+    Int4 i;
+
+    if (*hsp_list_ptr == NULL) {
+        *hsp_list_ptr = hsp_list = Blast_HSPListNew(BlastHspNumMax(TRUE,
+                                                         hit_params->options));
+    }
+    else {
+        hsp_list = *hsp_list_ptr;
+    }
+
+    if (word_hits) {
+        memset(word_hits->num, 0, word_hits->num_arrays * sizeof(Int4));
+    }
+
+    if (lookup_wrap->lut_type == eSmallNaLookupTable) {
+        BlastSmallNaLookupTable *lookup = 
+                                (BlastSmallNaLookupTable *) lookup_wrap->lut;
+        word_length = lookup->word_length;
+        lut_word_length = lookup->lut_word_length;
+        scansub = (TNaScanSubjectFunction)lookup->scansub_callback;
+    }
+    else if (lookup_wrap->lut_type == eMBLookupTable) {
+        BlastMBLookupTable *lookup = 
+                                (BlastMBLookupTable *) lookup_wrap->lut;
+        if (lookup->discontiguous) {
+            word_length = lookup->template_length;
+            lut_word_length = lookup->template_length;
+        } else {
+            word_length = lookup->word_length;
+            lut_word_length = lookup->lut_word_length;
+        }
+        scansub = (TNaScanSubjectFunction)lookup->scansub_callback;
+    }
+    else if (lookup_wrap->lut_type == eNaHashLookupTable) {
+        BlastNaHashLookupTable *lookup = 
+                                (BlastNaHashLookupTable *) lookup_wrap->lut;
+
+        word_length = lookup->word_length;
+        lut_word_length = lookup->lut_word_length;
+        scansub = (TNaScanSubjectFunction)lookup->scansub_callback;
+    }
+    else {
+        BlastNaLookupTable *lookup = 
+                                (BlastNaLookupTable *) lookup_wrap->lut;
+        word_length = lookup->word_length;
+        lut_word_length = lookup->lut_word_length;
+        scansub = (TNaScanSubjectFunction)lookup->scansub_callback;
+    }
+
+    scan_range[0] = 0;  /* subject seq mask index */
+    scan_range[1] = 0;	/* start pos of scan */
+    scan_range[2] = subject->length - lut_word_length; /*end pos (inclusive) of scan*/
+
+    /* if sequence is masked, fall back to generic scanner and extender */
+    if (subject->mask_type != eNoSubjMasking) {
+        if (lookup_wrap->lut_type == eMBLookupTable &&
+            ((BlastMBLookupTable *) lookup_wrap->lut)->discontiguous) {
+            /* discontiguous scan subs assumes any (non-aligned starting offset */
+        } else {
+            scansub = (TNaScanSubjectFunction) 
+                  BlastChooseNucleotideScanSubjectAny(lookup_wrap);
+        }
+        /* generic scanner permits any (non-aligned) starting offset */
+        scan_range[1] = subject->seq_ranges[0].left + word_length - lut_word_length;
+        scan_range[2] = subject->seq_ranges[0].right - lut_word_length;
+    }
+
+    ASSERT(scansub);
+
+    if (getenv("MAPPER_USE_SMALL_WORDS")) {
+        s_index = SubjectIndexNew(subject, 10000, SUBJECT_INDEX_WORD_LENGTH);
+    }
+    while(s_DetermineScanningOffsets(subject, word_length, lut_word_length, scan_range)) {
+
+
+        hitsfound = scansub(lookup_wrap, subject, offset_pairs, max_hits, &scan_range[1]);
+
+        if (hitsfound >= 0) {
+
+            /* if the extended word hits structure is allocated */
+            if (word_hits) {
+
+                /* Distribute each word hit into lists that correspond to
+                   a group of queries, ensuring that most word hits for each
+                   query are extended in the same batch. */
+                for (i = 0; i < hitsfound;i++) {
+                    Int4 q_off = offset_pairs[i].qs_offsets.q_off;
+                    Int4 s_off = offset_pairs[i].qs_offsets.s_off;
+                    Int4 index = q_off / word_hits->divisor;
+
+                    Int4 context = BSearchContextInfo(q_off, query_info);
+                    Int4 diag = s_off - q_off;
+                    Int4 last_d = word_hits->last_diag[context];
+                    Int4 last_p = word_hits->last_pos[context];
+
+                    word_hits->last_diag[context] = diag;
+                    word_hits->last_pos[context] = s_off;
+
+                    /* Discard word hits on the same diagnol and with adjacent
+                       positions, allowing up to 2 mismatches, as the last one
+                       saved. All these word hits will produce the same
+                       alignment. There is another check for this situation
+                       before extension, but doing it here helps keeping
+                       numer of word hits managable. The other check is still
+                       necessary, because depending on extension more
+                       word hits can be discarded. */
+                    if (last_d == diag && s_off - last_p < lut_word_length + 3) {
+                        continue;
+                    }
+                    ASSERT(index < word_hits->num_arrays);
+
+
+                    /* if the word hit list for the current word hit is full,
+                       then extend hits from this list */
+                    if (word_hits->num[index] >= word_hits->array_size) {
+                        Int4 range = word_hits->pair_arrays[index][
+                              word_hits->num[index] - 1].qs_offsets.s_off +
+                            lut_word_length;
+                        hits_extended += BlastNaExtendJumper(
+                                                word_hits->pair_arrays[index],
+                                                word_hits->num[index],
+                                                word_params, score_params,
+                                                hit_params,
+                                                lookup_wrap,
+                                                query, subject, 
+                                                query_info,
+                                                gap_align,
+                                                hsp_list,
+                                                range,
+                                                s_index);
+
+                        word_hits->num[index] = 0;
+
+                    }
+
+                    /* add new word hit */
+                    word_hits->pair_arrays[index][word_hits->num[index]++] =
+                        offset_pairs[i];
+                }
+            }
+            else {
+                /* otherwise extend collected word hits */
+
+                total_hits += hitsfound;
+                hits_extended += BlastNaExtendJumper(offset_pairs, hitsfound,
+                                             word_params, score_params,
+                                             hit_params,
+                                             lookup_wrap,
+                                             query, subject, 
+                                             query_info,
+                                             gap_align,
+                                             hsp_list,
+                                             scan_range[2] + lut_word_length,
+                                             s_index);
+
+            }
+        }
+
+        if (!read_is_query) {
+            break;
+        }
+    }
+
+    if (word_hits) {
+
+        /* extend word hits from all lists */
+        for (i = 0;i < word_hits->num_arrays;i++) {
+            if (word_hits->num[i] > 0) {
+                Int4 range = word_hits->pair_arrays[i][
+                                word_hits->num[i] - 1].qs_offsets.s_off +
+                    lut_word_length;
+                hits_extended += BlastNaExtendJumper(word_hits->pair_arrays[i],
+                                                 word_hits->num[i],
+                                                 word_params, score_params,
+                                                 hit_params,
+                                                 lookup_wrap,
+                                                 query, subject, 
+                                                 query_info,
+                                                 gap_align,
+                                                 hsp_list,
+                                                 range,
+                                                 s_index);
+                
+            }
+            word_hits->num[i] = 0;
+        }
+    }
+
+    Blast_UngappedStatsUpdate(ungapped_stats, total_hits, 0, 0);
+    
+    if (gapped_stats) {
+        gapped_stats->extensions = hits_extended;
+        /* this is needed for adaptive batch size */
+        ungapped_stats->good_init_extends = hits_extended;
+    }
+
+    if (s_index) {
+        s_index = SubjectIndexFree(s_index);
+    }
+
+    return 0;
+
+}
+
+
+/* read is a qurey, reference is a subject */
+Int2 ShortRead_IndexedWordFinder( 
+        BLAST_SequenceBlk * subject,
+        BLAST_SequenceBlk * query,
+        BlastQueryInfo * query_info,
+        LookupTableWrap * lookup_wrap,
+        const BlastInitialWordParameters * word_params,
+        const BlastScoringParameters* score_params,
+        const BlastHitSavingParameters* hit_params,
+        BlastOffsetPair * offset_pairs,
+        MapperWordHits* word_hits,
+        Int4 max_hits,
+        BlastGapAlignStruct* gap_align,
+        BlastInitHitList* init_hitlist,
+        BlastHSPList** hsp_list,
+        BlastUngappedStats* ungapped_stats,
+        BlastGappedStats* gapped_stats)
+{ 
+    BlastInitHSP * hsp, /* *new_hsp,*/ * hsp_end;
+    ir_diag_hash * hash = 0;
+    ir_hash_entry * e = 0;
+    Uint4 word_size;
+    Uint4 q_off, s_off;
+    Uint4 diag, key;
+    Int4 oid = subject->oid;
+    Int4 chunk = subject->chunk;
+    T_MB_IdbCheckOid check_oid = 
+        (T_MB_IdbCheckOid)lookup_wrap->check_index_oid;
+    T_MB_IdbGetResults get_results = 
+                        (T_MB_IdbGetResults)lookup_wrap->read_indexed_db;
+    Int4 last_vol_idx = LAST_VOL_IDX_NULL;
+
+    /* In the case oid belongs to the non-indexed part of the
+       database, route the call to the original word finder.
+    */
+    if( check_oid( oid, &last_vol_idx ) == eNotIndexed ) {
+        return JumperNaWordFinder(
+                subject, query, query_info, lookup_wrap, word_params,
+                score_params, hit_params, offset_pairs, word_hits, max_hits,
+                gap_align, init_hitlist, hsp_list, ungapped_stats,
+                gapped_stats);
+    }
+
+    ASSERT(get_results);
+    word_size = get_results(oid, chunk, init_hitlist);
+
+    if (*hsp_list == NULL) {
+        *hsp_list = Blast_HSPListNew(BlastHspNumMax(TRUE,
+                                                    hit_params->options));
+    }
+
+    if( word_size > 0) {
+
+        hash = ir_hash_create();
+        hsp = init_hitlist->init_hsp_array;
+        hsp_end = hsp + init_hitlist->total;
+
+        for( ; hsp < hsp_end; ++hsp ) {
+            q_off = hsp->offsets.qs_offsets.q_off;
+            s_off = hsp->offsets.qs_offsets.s_off;
+
+
+            diag = IR_DIAG( q_off, s_off );
+            key  = IR_KEY( diag );
+            e = IR_LOCATE( hash, diag, key );
+
+            if( e != 0 ) {
+
+
+                Int4 context = BSearchContextInfo(q_off, query_info);
+                Int4 query_start = query_info->contexts[context].query_offset;
+                Int4 query_len = query_info->contexts[context].query_length;
+                Uint1* query_seq = query->sequence + query_start;
+
+                if( q_off + word_size - 1 > e->diag_data.qend ) {
+
+                    Int4 num_identical = 0;
+                    Int4 right_ungapped_ext_len = 0;
+                    gapped_stats->extensions++;
+
+                    JumperGappedAlignmentCompressedWithTraceback(query_seq,
+                                                         subject->sequence,
+                                                         query_len,
+                                                         subject->length,
+                                                         q_off - query_start,
+                                                         s_off,
+                                                         gap_align,
+                                                         score_params, 
+                                                         &num_identical,
+                                                         &right_ungapped_ext_len);
+
+
+                    if (JumperGoodAlign(gap_align, hit_params, num_identical,
+                                        &query_info->contexts[context])) {
+
+                        BlastHSP* new_hsp;
+                        int status;
+
+                        gap_align->edit_script =
+                            JumperPrelimEditBlockToGapEditScript(
+                                        gap_align->jumper->left_prelim_block,
+                                        gap_align->jumper->right_prelim_block);
+
+                        status = Blast_HSPInit(gap_align->query_start,
+                                       gap_align->query_stop,
+                                       gap_align->subject_start,
+                                       gap_align->subject_stop,
+                                       q_off - query_start, s_off,
+                                       context,
+                                       query_info->contexts[context].frame,
+                                       subject->frame,
+                                       gap_align->score,
+                                       &(gap_align->edit_script),
+                                       &new_hsp);
+                        if (!new_hsp) {
+                            return -1;
+                        }
+                        new_hsp->map_info = BlastHSPMappingInfoNew();
+                        if (!new_hsp->map_info) {
+                            return -1;
+                        }
+                        new_hsp->num_ident = num_identical;
+                        new_hsp->evalue = 0.0;
+                        new_hsp->map_info->edits = JumperFindEdits(query_seq,
+                                                         subject->sequence,
+                                                         gap_align);
+
+                        if (hit_params->options->splice) {
+                            JumperFindSpliceSignals(new_hsp, query_len,
+                                                    subject->sequence,
+                                                    subject->length);
+                        }
+
+                        status = Blast_HSPListSaveHSP(*hsp_list, new_hsp);
+                        if (status) {
+                            break;
+                        }
+                    }
+
+                    if (e->diag_data.diag != diag) {
+                        e->diag_data.diag = diag;
+                    }
+                    e->diag_data.qend = q_off + right_ungapped_ext_len - 1;
+
+                }
+
+
+            }
+/*
+            else {
+                if( new_hsp != hsp ) *new_hsp = *hsp;
+                ++new_hsp;
+            }
+*/
+        }
+
+        hash = ir_hash_destroy( hash );
+    }
+
+    return 0;
+}
+
+
diff --git a/c++/src/algo/blast/core/ncbi_math.c b/c++/src/algo/blast/core/ncbi_math.c
index 157bef4..74592fd 100644
--- a/c++/src/algo/blast/core/ncbi_math.c
+++ b/c++/src/algo/blast/core/ncbi_math.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_math.c 351814 2012-02-01 17:14:10Z ucko $
+/* $Id: ncbi_math.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -28,11 +28,6 @@
  * Definitions for portable math library
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: ncbi_math.c 351814 2012-02-01 17:14:10Z ucko $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/ncbi_math.h>
 
 double BLAST_Expm1(double	x)
diff --git a/c++/src/algo/blast/core/ncbi_std.c b/c++/src/algo/blast/core/ncbi_std.c
index 3f39bd3..acfc1b2 100644
--- a/c++/src/algo/blast/core/ncbi_std.c
+++ b/c++/src/algo/blast/core/ncbi_std.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_std.c 72729 2005-11-16 14:31:37Z madden $
+/* $Id: ncbi_std.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  * A few utilities needed by code in algo/blast/core but not provided elsewhere.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: ncbi_std.c 72729 2005-11-16 14:31:37Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/blast_def.h> /* for sfree() macro */
 #include <algo/blast/core/ncbi_std.h>
 
diff --git a/c++/src/algo/blast/core/pattern.c b/c++/src/algo/blast/core/pattern.c
index 8e57971..4d4b2ac 100644
--- a/c++/src/algo/blast/core/pattern.c
+++ b/c++/src/algo/blast/core/pattern.c
@@ -1,4 +1,4 @@
-/* $Id: pattern.c 134303 2008-07-17 17:42:49Z camacho $
+/* $Id: pattern.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -54,11 +54,6 @@
  *
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: pattern.c 134303 2008-07-17 17:42:49Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/pattern.h>
 #include "pattern_priv.h"
 
diff --git a/c++/src/algo/blast/core/phi_extend.c b/c++/src/algo/blast/core/phi_extend.c
index 9436a2a..4b63363 100644
--- a/c++/src/algo/blast/core/phi_extend.c
+++ b/c++/src/algo/blast/core/phi_extend.c
@@ -1,4 +1,4 @@
-/* $Id: phi_extend.c 94064 2006-11-21 17:19:42Z papadopo $
+/* $Id: phi_extend.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Word finder functions for PHI-BLAST
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: phi_extend.c 94064 2006-11-21 17:19:42Z papadopo $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/phi_lookup.h>
 #include <algo/blast/core/phi_extend.h>
 
diff --git a/c++/src/algo/blast/core/phi_gapalign.c b/c++/src/algo/blast/core/phi_gapalign.c
index cc6a2f4..81a5df5 100644
--- a/c++/src/algo/blast/core/phi_gapalign.c
+++ b/c++/src/algo/blast/core/phi_gapalign.c
@@ -1,4 +1,4 @@
-/* $Id: phi_gapalign.c 134303 2008-07-17 17:42:49Z camacho $
+/* $Id: phi_gapalign.c 505944 2016-06-30 12:29:20Z madden $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -53,11 +53,6 @@
  * </pre>
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: phi_gapalign.c 134303 2008-07-17 17:42:49Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/phi_gapalign.h>
 #include <algo/blast/core/blast_encoding.h>
 #include <algo/blast/core/blast_gapalign.h>
@@ -861,7 +856,6 @@ Int2 PHIGappedAlignmentWithTraceback(Uint1* query, Uint1* subject,
     GapPrelimEditBlockReset(rev_prelim_tback);
 
     found_end = FALSE;
-    score_left = 0;
         
     score_left = 
        Blast_SemiGappedAlign(query, subject, q_start, s_start, 
diff --git a/c++/src/algo/blast/core/phi_lookup.c b/c++/src/algo/blast/core/phi_lookup.c
index ae38069..500f1bb 100644
--- a/c++/src/algo/blast/core/phi_lookup.c
+++ b/c++/src/algo/blast/core/phi_lookup.c
@@ -1,4 +1,4 @@
-/* $Id: phi_lookup.c 94060 2006-11-21 17:14:28Z papadopo $
+/* $Id: phi_lookup.c 505944 2016-06-30 12:29:20Z madden $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  * @todo FIXME needs doxygen comments and lines shorter than 80 characters
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: phi_lookup.c 94060 2006-11-21 17:14:28Z papadopo $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/phi_lookup.h>
 #include <algo/blast/core/blast_encoding.h>
 #include <algo/blast/core/blast_util.h> /* for NCBI2NA_UNPACK_BASE */
@@ -439,7 +434,6 @@ SPHIPatternSearchBlkNew(char* pattern_in, Boolean is_dna, BlastScoreBlk* sbp,
 
     wildcardProduct = 1;
     currentWildcardProduct = 1;
-    prevSetMask = 0;
     currentSetMask = 0;
 
     pattern_length = strlen(pattern_in);
diff --git a/c++/src/algo/blast/core/split_query.c b/c++/src/algo/blast/core/split_query.c
index 1593392..b702251 100644
--- a/c++/src/algo/blast/core/split_query.c
+++ b/c++/src/algo/blast/core/split_query.c
@@ -1,4 +1,4 @@
-/*  $Id: split_query.c 195768 2010-06-25 17:12:38Z maning $
+/*  $Id: split_query.c 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /** @file split_query.c
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: split_query.c 195768 2010-06-25 17:12:38Z maning $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <algo/blast/core/split_query.h>
 #include <algo/blast/core/blast_def.h>      /* needed for sfree */
 #include "blast_dynarray.h"
diff --git a/c++/src/algo/blast/dbindex/dbindex_factory.cpp b/c++/src/algo/blast/dbindex/dbindex_factory.cpp
index a616bb5..8810174 100644
--- a/c++/src/algo/blast/dbindex/dbindex_factory.cpp
+++ b/c++/src/algo/blast/dbindex/dbindex_factory.cpp
@@ -1,4 +1,4 @@
-/*  $Id: dbindex_factory.cpp 412159 2013-09-04 21:12:36Z ucko $
+/*  $Id: dbindex_factory.cpp 506382 2016-07-07 13:47:26Z morgulis $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -997,7 +997,6 @@ class COffsetList
         class CDataPool
         {
                 static const Uint4 BLOCK_SIZE     = 1024*1024ULL;
-                static const Uint4 BLOCKS_RESERVE = 10*1024ULL;
 
                 typedef vector< SDataUnit > TBlock;
                 typedef vector< TBlock > TBlocks;
@@ -1006,7 +1005,6 @@ class COffsetList
 
                 CDataPool() : free_( 0 )
                 {
-                    pool_.reserve( BLOCKS_RESERVE );
                     new_block();
                 }
 
@@ -1053,6 +1051,8 @@ class COffsetList
                 TBlocks pool_;
         };
 
+        void SetDataPool( CDataPool * pool ) { data_.SetDataPool( pool ); }
+
     private:
 
         class CData
@@ -1140,9 +1140,12 @@ class COffsetList
                 typedef CDataIterator const_iterator;
                 typedef Uint4 size_type;
 
-                CData() : start_( 0 ), curr_( 0 ), last_( 0 ), size_( 0 )
+                CData() : pool_( 0 ), 
+                          start_( 0 ), curr_( 0 ), last_( 0 ), size_( 0 )
                 {}
 
+                void SetDataPool( CDataPool * pool ) { pool_ = pool; }
+
                 const_iterator begin() const
                 { return const_iterator( start_, 1, size_ ); }
 
@@ -1155,14 +1158,14 @@ class COffsetList
                 void push_back( const TWord & d )
                 {
                     if( start_ == 0 ) {
-                        start_ = curr_ = Pool_.alloc();
+                        start_ = curr_ = pool_->alloc();
                         start_->next = 0;
                     }
                     
                     curr_->data[last_++] = d;
 
                     if( last_ >= DATA_UNIT_SIZE ) {
-                        SDataUnit * t = Pool_.alloc();
+                        SDataUnit * t = pool_->alloc();
                         t->next = 0;
                         curr_->next = t;
                         curr_ = t;
@@ -1175,7 +1178,7 @@ class COffsetList
                 void resize( Uint4 newsize )
                 {
                     if( newsize == 0 ) {
-                        Pool_.free( start_ );
+                        pool_->free( start_ );
                         start_ = curr_ = 0;
                         size_ = last_ = 0;
                         return;
@@ -1191,17 +1194,15 @@ class COffsetList
                         tn = tp->next;
                     }
 
-                    Pool_.free( tn );
+                    pool_->free( tn );
                     curr_ = tp;
                     last_ = DATA_UNIT_SIZE - (t - newsize) - 1;
                     size_ = newsize;
                 }
 
-                static void Clear() { Pool_.clear(); }
-
             private:
 
-                static CDataPool Pool_;
+                CDataPool * pool_;
 
                 SDataUnit * start_;
                 SDataUnit * curr_;
@@ -1215,14 +1216,8 @@ class COffsetList
         TData data_;               /**< Offset list data storage. */
         unsigned long min_offset_; /**< Minimum offset used by the index. */
         unsigned long mult_;       /**< Max multiple to use in list pre-ordering. */
-
-    public:
-
-        static void ClearAll() { TData::Clear(); }
 };
 
-COffsetList::CDataPool COffsetList::CData::Pool_;
-
 //-------------------------------------------------------------------------
 inline void COffsetList::Save( CNcbiOstream & os) const
 {
@@ -1307,7 +1302,8 @@ class COffsetData_Factory
         */
         COffsetData_Factory( 
                 TSubjectMap & subject_map, 
-                const CDbIndex::SOptions & options )
+                const CDbIndex::SOptions & options,
+                COffsetList::CDataPool * pool )
             : subject_map_( subject_map ),
               hash_table_( 1<<(2*options.hkey_width) ),
               report_level_( options.report_level ),
@@ -1320,11 +1316,10 @@ class COffsetData_Factory
             for( THashTable::iterator i = hash_table_.begin();
                     i != hash_table_.end(); ++i ) {
                 i->SetIndexParams( options_ );
+                i->SetDataPool( pool );
             }
         }
 
-        ~COffsetData_Factory() { COffsetList::ClearAll(); }
-
         /** Get the total memory usage by offset lists in bytes.
             @return memory usage by this instance
         */
@@ -1669,8 +1664,11 @@ void CDbIndex_Factory::do_create_1_2(
     typedef CSubjectMap_Factory TSubjectMap;
     typedef COffsetData_Factory TOffsetData;
 
+    std::auto_ptr< COffsetList::CDataPool > pool( 
+            new COffsetList::CDataPool );
+
     TSubjectMap subject_map( options );
-    TOffsetData offset_data( subject_map, options );
+    TOffsetData offset_data( subject_map, options, pool.get() );
 
     TSeqNum i = start;
 
diff --git a/c++/src/algo/blast/dbindex/makeindex/main.cpp b/c++/src/algo/blast/dbindex/makeindex/main.cpp
index ecf1a54..7e53228 100644
--- a/c++/src/algo/blast/dbindex/makeindex/main.cpp
+++ b/c++/src/algo/blast/dbindex/makeindex/main.cpp
@@ -1,4 +1,4 @@
-/*  $Id: main.cpp 473030 2015-07-15 19:29:59Z camacho $
+/*  $Id: main.cpp 492284 2016-02-16 16:55:37Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -50,5 +50,5 @@ USING_NCBI_SCOPE;
 
 int main( int argc, char * argv[] )
 { 
-    return CMkIndexApplication().AppMain(argc, argv, 0, eDS_Default, "");
+    return CMkIndexApplication().AppMain(argc, argv);
 }
diff --git a/c++/src/algo/blast/format/blast_format.cpp b/c++/src/algo/blast/format/blast_format.cpp
index 1721377..774c14b 100644
--- a/c++/src/algo/blast/format/blast_format.cpp
+++ b/c++/src/algo/blast/format/blast_format.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: blast_format.cpp 495288 2016-03-16 14:51:11Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 /*
 * ===========================================================================
 *
@@ -43,6 +39,7 @@ Author: Jason Papadopoulos
 #include <objects/seq/Seq_descr.hpp>
 #include <objmgr/seq_loc_mapper.hpp>
 #include <objmgr/util/sequence.hpp>
+#include <objmgr/util/create_defline.hpp>
 #include <algo/blast/core/blast_stat.h>
 #include <corelib/ncbiutil.hpp>                 // for FindBestChoice
 #include <algo/blast/api/sseqloc.hpp>
@@ -62,6 +59,7 @@ USING_NCBI_SCOPE;
 USING_SCOPE(blast);
 USING_SCOPE(objects);
 USING_SCOPE(align_format);
+USING_SCOPE(sequence);
 #endif
 
 
@@ -183,6 +181,12 @@ CBlastFormat::CBlastFormat(const blast::CBlastOptions& options,
     if (m_FormatType == CFormattingArgs::eSAM) {
     	x_InitSAMFormatter();
     }
+
+    CNcbiApplication* app = CNcbiApplication::Instance();
+    if (app) {
+        const CNcbiRegistry& registry = app->GetConfig();
+        m_LongSeqId = (registry.Get("BLAST", "LONG_SEQID") == "1");
+    }
 }
 
 CBlastFormat::CBlastFormat(const blast::CBlastOptions& opts, 
@@ -284,6 +288,12 @@ CBlastFormat::CBlastFormat(const blast::CBlastOptions& opts,
     if (m_FormatType == CFormattingArgs::eSAM) {
     	x_InitSAMFormatter();
     }
+
+    CNcbiApplication* app = CNcbiApplication::Instance();
+    if (app) {
+        const CNcbiRegistry& registry = app->GetConfig();
+        m_LongSeqId = (registry.Get("BLAST", "LONG_SEQID") == "1");
+    }
 }
 
 CBlastFormat::~CBlastFormat()
@@ -473,6 +483,9 @@ CBlastFormat::x_ConfigCShowBlastDefline(CShowBlastDefline& showdef,
         flags |= CShowBlastDefline::eShowGi;
     if (num_descriptions_to_show == 0)
         flags |= CShowBlastDefline::eNoShowHeader;
+    if (m_LongSeqId) {
+        flags |= CShowBlastDefline::eLongSeqId;
+    }
 
     showdef.SetOption(flags);
     showdef.SetDbName(m_DbName);
@@ -783,8 +796,74 @@ CBlastFormat::x_PrintTabularReport(const blast::CSearchResults& results,
     }
 }
 
+static void s_SetCloneInfo(const CIgBlastTabularInfo& tabinfo,
+                           const CBioseq_Handle& handle,
+                           CBlastFormat::SClone& clone_info) {
+   
+    if (handle.GetSeqId()->Which() == CSeq_id::e_Local){
+        CDeflineGenerator defline (handle.GetSeq_entry_Handle());
+        clone_info.seqid = defline.GenerateDefline(handle).substr(0, 45);
+        
+    //    clone_info.seqid = CDeflineGenerator.substr(0, 45);
+    } else {
+        string seqid;
+        CRef<CSeq_id> wid = FindBestChoice(handle.GetBioseqCore()->GetId(), CSeq_id::WorstRank);
+        wid->GetLabel(&seqid, CSeq_id::eContent);
+        clone_info.seqid = seqid.substr(0, 45);
+    }
+    tabinfo.GetIgInfo (clone_info.v_gene, clone_info.d_gene, clone_info.j_gene,
+                       clone_info.chain_type, clone_info.na, clone_info.aa, clone_info.productive);
+    clone_info.identity = 0;
+    const vector<CIgBlastTabularInfo::SIgDomain*>& domains = tabinfo.GetIgDomains();
+    int length = 0;
+    int num_match = 0;
+    for (unsigned int i=0; i<domains.size(); ++i) {
+        if (domains[i]->length > 0) {
+            length += domains[i]->length;
+            num_match += domains[i]->num_match;
+        }
+    }
+    if (length > 0){
+        clone_info.identity = ((double)num_match)/length;
+        
+    }
+   
+}
+
 void
-CBlastFormat::x_PrintIgTabularReport(const blast::CIgBlastResults& results)
+CBlastFormat::x_PrintTaxReport(const blast::CSearchResults& results)
+{    
+    CBioseq_Handle bhandle = m_Scope->GetBioseqHandle(*results.GetSeqId(),
+                                                      CScope::eGetBioseq_All);
+    CConstRef<CBioseq> bioseq = bhandle.GetBioseqCore();
+    if(m_IsHTML) {
+        m_Outfile <<  "<pre>";
+    }
+    else {
+        m_Outfile <<  "\n";
+    }
+    CBlastFormatUtil::AcknowledgeBlastQuery(*bioseq, kFormatLineLength,
+                                            m_Outfile, m_BelieveQuery,
+                                            m_IsHTML, false,
+                                            results.GetRID());
+
+    if(m_IsHTML) {
+        m_Outfile <<  "</pre>";
+    }
+    CConstRef<CSeq_align_set> aln_set = results.GetSeqAlign();
+    if (m_IsUngappedSearch && results.HasAlignments()) {
+        aln_set.Reset(CDisplaySeqalign::PrepareBlastUngappedSeqalign(*aln_set));
+    }
+    
+    CRef<CSeq_align_set> new_aln_set(const_cast<CSeq_align_set*>(aln_set.GetPointer()));
+    CTaxFormat *taxFormatRes = new CTaxFormat (*new_aln_set,*m_Scope,m_IsHTML ? CTaxFormat::eHtml:CTaxFormat::eText, false,max(kMinTaxFormatLineLength,kFormatLineLength)); 
+    taxFormatRes->DisplayOrgReport(m_Outfile);    
+}
+
+void
+CBlastFormat::x_PrintIgTabularReport(const blast::CIgBlastResults& results,
+                                     SClone& clone_info,
+                                     bool fill_clone_info)
 {
     CConstRef<CSeq_align_set> aln_set = results.GetSeqAlign();
     /* TODO do we support ungapped Igblast search?
@@ -823,7 +902,9 @@ CBlastFormat::x_PrintIgTabularReport(const blast::CIgBlastResults& results)
                                 annots->m_ChainTypeToShow, 
                                 &m_ScoringMatrix);
         tabinfo.SetIgAnnotation(annots, m_IgOptions);
-
+        if (fill_clone_info) {
+            s_SetCloneInfo(tabinfo, bhandle, clone_info);
+        }
         tabinfo.PrintHeader(strProgVersion, *(bhandle.GetBioseqCore()),
                                 m_DbName, 
                                 m_IgOptions->m_DomainSystem,
@@ -999,6 +1080,13 @@ CBlastFormat::PrintOneResultSet(const blast::CSearchResults& results,
         x_PrintTabularReport(results, itr_num);
         return;
     }
+    if (m_FormatType == CFormattingArgs::eTaxFormat) {
+        string reportCaption = "Tax BLAST report";
+        reportCaption = m_IsHTML ? "<h1>" + reportCaption + "</h1>" : CAlignFormatUtil::AddSpaces(reportCaption,max(kMinTaxFormatLineLength,kFormatLineLength),CAlignFormatUtil::eSpacePosToCenter | CAlignFormatUtil::eAddEOLAtLineStart | CAlignFormatUtil::eAddEOLAtLineEnd);
+        m_Outfile << reportCaption;
+        x_PrintTaxReport(results);
+        return;
+    }
     const bool kIsTabularOutput = false;
 
     if (is_deltablast_domain_result) {
@@ -1027,6 +1115,7 @@ CBlastFormat::PrintOneResultSet(const blast::CSearchResults& results,
                                             m_Outfile, m_BelieveQuery,
                                             m_IsHTML, kIsTabularOutput,
                                             results.GetRID());
+
     if (m_IsBl2Seq && !m_IsDbScan) {
         m_Outfile << "\n";
         // FIXME: this might be configurable in the future
@@ -1081,10 +1170,16 @@ CBlastFormat::PrintOneResultSet(const blast::CSearchResults& results,
     display.SetDbName(m_DbName);
     display.SetDbType(!m_DbIsAA);
     display.SetLineLen(m_LineLength);
+    int kAlignToShow=2000000000;  // Nice large number per SB-1817
+    display.SetNumAlignToShow(kAlignToShow);
 
     // set the alignment flags
     display.SetAlignOption(flags);
 
+    if (m_LongSeqId) {
+        display.UseLongSequenceIds();
+    }
+
     if (m_Program == "blastn" || m_Program == "megablast") {
             display.SetMiddleLineStyle(CDisplaySeqalign::eBar);
             display.SetAlignType(CDisplaySeqalign::eNuc);
@@ -1110,8 +1205,12 @@ CBlastFormat::PrintOneResultSet(const blast::CSearchResults& results,
 void
 CBlastFormat::PrintOneResultSet(blast::CIgBlastResults& results,
                                 CConstRef<blast::CBlastQueryVector> queries, 
+                                SClone& clone_info,
+                                bool fill_clone_info,
                                 int index)
 {
+    clone_info.na = NcbiEmptyString;
+    clone_info.aa = NcbiEmptyString;
 
     // For remote searches, we don't retrieve the sequence data for the query
     // sequence when initially sending the request to the BLAST server (if it's
@@ -1161,10 +1260,17 @@ CBlastFormat::PrintOneResultSet(blast::CIgBlastResults& results,
         m_FormatType == CFormattingArgs::eTabularWithComments ||
         m_FormatType == CFormattingArgs::eCommaSeparatedValues) {
         m_FormatType = CFormattingArgs::eTabularWithComments;
-        x_PrintIgTabularReport(results);
+        x_PrintIgTabularReport(results, clone_info, fill_clone_info);
         return;
     }
 
+    if (m_FormatType == CFormattingArgs::eTaxFormat) {
+        string reportCaption = "Tax BLAST report";
+        reportCaption = m_IsHTML ? "<h1>" + reportCaption + "</h1>" : CAlignFormatUtil::AddSpaces(reportCaption,max(kMinTaxFormatLineLength,kFormatLineLength),CAlignFormatUtil::eSpacePosToCenter | CAlignFormatUtil::eAddEOLAtLineStart | CAlignFormatUtil::eAddEOLAtLineEnd);
+        m_Outfile << reportCaption;
+        x_PrintTaxReport(results);
+        return;
+    }
 
     const bool kIsTabularOutput = false;
 
@@ -1228,6 +1334,9 @@ CBlastFormat::PrintOneResultSet(blast::CIgBlastResults& results,
                                 annots->m_ChainTypeToShow, 
                                 &m_ScoringMatrix);
         tabinfo.SetIgAnnotation(annots, m_IgOptions);
+        if (fill_clone_info) {
+            s_SetCloneInfo(tabinfo, bhandle, clone_info);
+        }
         m_Outfile << "Domain classification requested: " << m_IgOptions->m_DomainSystem << endl << endl;
         if (m_IsHTML) {
             tabinfo.PrintHtmlSummary();
@@ -1328,6 +1437,10 @@ CBlastFormat::PrintOneResultSet(blast::CIgBlastResults& results,
     display.SetDbType(!m_DbIsAA);
     display.SetLineLen(90);
 
+    if (m_LongSeqId) {
+        display.UseLongSequenceIds();
+    }
+
     if (annots->m_FrameInfo[0] >= 0 && m_IgOptions->m_Translate) {
         display.SetTranslatedFrameForLocalSeq((CDisplaySeqalign::TranslatedFrameForLocalSeq) (annots->m_FrameInfo[0]%3)); 
         flags += CDisplaySeqalign::eShowTranslationForLocalSeq;
@@ -1379,6 +1492,9 @@ CBlastFormat::PrintOneResultSet(blast::CIgBlastResults& results,
 void 
 CBlastFormat::x_ReverseQuery(blast::CIgBlastResults& results)
 {
+    if (!results.HasAlignments()){
+        return;
+    }
     // create a temporary seq_id
     CConstRef<CSeq_id> qid = results.GetSeqId();
     string new_id = qid->AsFastaString() + "_reversed";
@@ -1486,6 +1602,15 @@ CBlastFormat::PrintPhiResult(const blast::CSearchResultSet& result_set,
         }
         return;
     }
+    if (m_FormatType == CFormattingArgs::eTaxFormat) {
+        string reportCaption = "Tax BLAST report";
+        reportCaption = m_IsHTML ? "<h1>" + reportCaption + "</h1>" : CAlignFormatUtil::AddSpaces(reportCaption,max(kMinTaxFormatLineLength,kFormatLineLength),CAlignFormatUtil::eSpacePosToCenter | CAlignFormatUtil::eAddEOLAtLineStart | CAlignFormatUtil::eAddEOLAtLineEnd);
+        m_Outfile << reportCaption;
+        ITERATE(CSearchResultSet, result, result_set) {
+            x_PrintTaxReport(**result);
+        }
+        return;
+    }
 
     const CSearchResults& first_results = result_set[0];
 
@@ -1505,6 +1630,16 @@ CBlastFormat::PrintPhiResult(const blast::CSearchResultSet& result_set,
                                             m_IsHTML, false,
                                             first_results.GetRID());
 
+    if (m_FormatType == CFormattingArgs::eTaxFormat) {
+        string reportCaption = "Tax BLAST report";
+        reportCaption = m_IsHTML ? "<h1>" + reportCaption + "</h1>" : CAlignFormatUtil::AddSpaces(reportCaption,max(kMinTaxFormatLineLength,kFormatLineLength),CAlignFormatUtil::eSpacePosToCenter | CAlignFormatUtil::eAddEOLAtLineStart | CAlignFormatUtil::eAddEOLAtLineEnd);
+        m_Outfile << reportCaption;
+        ITERATE(CSearchResultSet, result, result_set) {
+           x_PrintTaxReport(**result);
+        }        
+        return;
+    }
+
     const SPHIQueryInfo *phi_query_info = first_results.GetPhiQueryInfo();
 
     if (phi_query_info)
@@ -1580,6 +1715,10 @@ CBlastFormat::PrintPhiResult(const blast::CSearchResultSet& result_set,
            // set the alignment flags
            display.SetAlignOption(flags);
 
+           if (m_LongSeqId) {
+               display.UseLongSequenceIds();
+           }
+
            if (m_Program == "blastn" || m_Program == "megablast") {
                display.SetMiddleLineStyle(CDisplaySeqalign::eBar);
                display.SetAlignType(CDisplaySeqalign::eNuc);
diff --git a/c++/src/algo/blast/format/blastfmtutil.cpp b/c++/src/algo/blast/format/blastfmtutil.cpp
index 9064084..c8abe65 100644
--- a/c++/src/algo/blast/format/blastfmtutil.cpp
+++ b/c++/src/algo/blast/format/blastfmtutil.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastfmtutil.cpp 479455 2015-09-21 14:39:54Z fongah2 $
+/*  $Id: blastfmtutil.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  *   blast formatter utilities
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: blastfmtutil.cpp 479455 2015-09-21 14:39:54Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 
 #include <algo/blast/format/blastfmtutil.hpp>
@@ -100,7 +95,16 @@ CBlastFormatUtil::BlastPrintReference(bool html, size_t line_len,
     ostringstream str;
     if(html)
     {
+        CNcbiIfstream  config_file(".ncbirc");
+        CNcbiRegistry config_reg(config_file);
+        string httpProt = "https:";
+        if(!config_reg.Empty()) {
+            if(config_reg.HasEntry("BLASTFMTUTIL","PROTOCOL")) {
+                httpProt = config_reg.Get("BLASTFMTUTIL","PROTOCOL");
+            }
+        }        
         str << "<b><a href=\""
+            << httpProt
             << blast::CReference::GetPubmedUrl(pub)
             << "\">" << reference << "</a>:</b>"
             << "\n";
diff --git a/c++/src/algo/blast/format/blastxml_format.cpp b/c++/src/algo/blast/format/blastxml_format.cpp
index b1a1ea4..50363ed 100644
--- a/c++/src/algo/blast/format/blastxml_format.cpp
+++ b/c++/src/algo/blast/format/blastxml_format.cpp
@@ -1,4 +1,4 @@
-/* $Id: blastxml_format.cpp 401131 2013-05-28 18:34:25Z grichenk $
+/* $Id: blastxml_format.cpp 504861 2016-06-20 15:45:40Z boratyng $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 
 /// @file blastxml_format.cpp
 /// Formatting of BLAST results in XML form, using the BLAST XML specification.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: blastxml_format.cpp 401131 2013-05-28 18:34:25Z grichenk $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objmgr/object_manager.hpp>
 #include <objects/seqloc/Seq_interval.hpp>
@@ -661,6 +656,7 @@ s_GetBlastPublication(EProgram program)
 
     switch (program) {
     case eMegablast:
+    case eMapper:
         publication = CReference::eMegaBlast; break;
     case ePHIBlastp: case ePHIBlastn:
         publication = CReference::ePhiBlast; break;
diff --git a/c++/src/algo/blast/format/data4xmlformat.cpp b/c++/src/algo/blast/format/data4xmlformat.cpp
index 4bc291f..92b6e43 100644
--- a/c++/src/algo/blast/format/data4xmlformat.cpp
+++ b/c++/src/algo/blast/format/data4xmlformat.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: data4xmlformat.cpp 393164 2013-03-22 13:39:25Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 /*
 * ===========================================================================
 *
diff --git a/c++/src/algo/blast/format/sam.cpp b/c++/src/algo/blast/format/sam.cpp
index 14f03bd..45e46ca 100644
--- a/c++/src/algo/blast/format/sam.cpp
+++ b/c++/src/algo/blast/format/sam.cpp
@@ -85,10 +85,13 @@ void CBlast_SAM_Formatter::x_ProcessCustomSpec(const string & custom_spec,
 		                                       const CSAM_Formatter::SProgramInfo & info)
 {
 	vector<string> format_tokens;
-	NStr::Tokenize(custom_spec, " ", format_tokens);
+	NStr::Split(custom_spec, " ", format_tokens);
 	CSAM_Formatter::SetProgram(info);
 	m_refRow = 1;
 	ITERATE (vector<string>, iter, format_tokens) {
+		 if("SR" == *iter) {
+			m_refRow = 0;
+		 }
 		 if ("SQ" == *iter) {
 			CSAM_Formatter::SetFlag(CSAM_Formatter::fSAM_SeqData);
 		}
diff --git a/c++/src/algo/blast/format/vecscreen_run.cpp b/c++/src/algo/blast/format/vecscreen_run.cpp
index cd5e58e..2221dd0 100644
--- a/c++/src/algo/blast/format/vecscreen_run.cpp
+++ b/c++/src/algo/blast/format/vecscreen_run.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: vecscreen_run.cpp 384567 2012-12-28 04:20:22Z ucko $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 /*
 * ===========================================================================
 *
diff --git a/c++/src/algo/blast/igblast/igblast.cpp b/c++/src/algo/blast/igblast/igblast.cpp
index d0e1ddd..8d9d1ba 100644
--- a/c++/src/algo/blast/igblast/igblast.cpp
+++ b/c++/src/algo/blast/igblast/igblast.cpp
@@ -1,7 +1,3 @@
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: igblast.cpp 499246 2016-04-25 11:32:24Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
 /* ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -133,13 +129,13 @@ CIgAnnotationInfo::CIgAnnotationInfo(CConstRef<CIgBlastOptions> &ig_opt)
     }
 };
 
-void CIgBlast::x_ScreenV(CRef<CSearchResultSet> & results){
+void CIgBlast::x_ScreenByAlignLength(CRef<CSearchResultSet> & results, int length){
     NON_CONST_ITERATE(CSearchResultSet, result, *results) {
         if ((*result)->HasAlignments()) {
             CSeq_align_set::Tdata & align_list = (*result)->SetSeqAlign()->Set();
             CSeq_align_set::Tdata::iterator it = align_list.begin();
             while (it != align_list.end()) {
-                if((*it)->GetAlignLength() - (*it)->GetTotalGapCount(0) < m_IgOptions->m_MinVLength){
+                if((*it)->GetAlignLength() - (*it)->GetTotalGapCount(0) < length){
                     it = align_list.erase(it);
                 } else {
                     ++it;
@@ -249,11 +245,12 @@ CIgBlast::Run()
     {
         x_SetupVSearch(qf, opts_hndl);
         CLocalBlast blast(qf, opts_hndl, m_IgOptions->m_Db[0]);
+         blast.SetNumberOfThreads(m_NumThreads);
         results[0] = blast.Run();
         if (m_IgOptions->m_ExtendAlign){
             x_ExtendAlign(results[0]);
         }
-        x_ScreenV(results[0]);
+        x_ScreenByAlignLength(results[0], m_IgOptions->m_MinVLength);
         x_ConvertResultType(results[0]);
         s_SortResultsByEvalue(results[0]);
         x_AnnotateV(results[0], annots);
@@ -263,15 +260,19 @@ CIgBlast::Run()
     {
         opts_hndl->SetHitlistSize(20);  // use a larger number to ensure annotation
         CLocalBlast blast(qf, opts_hndl, m_IgOptions->m_Db[3]);
+        blast.SetNumberOfThreads(m_NumThreads);
         results[3] = blast.Run();
         if (m_IgOptions->m_ExtendAlign){
             x_ExtendAlign(results[3]);
         }
-        x_ScreenV(results[3]);
+        x_ScreenByAlignLength(results[3], m_IgOptions->m_MinVLength);
         s_SortResultsByEvalue(results[3]);
         x_AnnotateDomain(results[0], results[3], annots);
     }
 
+    opts_hndl.Reset(CBlastOptionsFactory
+                     ::Create((m_IgOptions->m_IsProtein)? eBlastp: eBlastn));
+
     /*** search DJ germline */
     int num_genes =  (m_IgOptions->m_IsProtein) ? 1 : 3;
     if (num_genes > 1) {
@@ -280,7 +281,11 @@ CIgBlast::Run()
             x_SetupDJSearch(annots, qf, opts_hndl, gene);
             CLocalBlast blast(qf, opts_hndl, m_IgOptions->m_Db[gene]);
             try {
+                blast.SetNumberOfThreads(m_NumThreads);
                 results[gene] = blast.Run();
+                if (gene == 2){
+                    x_ScreenByAlignLength(results[gene], m_IgOptions->m_MinJLength);
+                }
                 x_ConvertResultType(results[gene]);
             } catch(...) {
                 num_genes = 1;
@@ -332,7 +337,7 @@ CIgBlast::Run()
     x_SetChainType(final_results, annots);
 
     /*** attach annotation info back to the results */
-    s_SetAnnotation(annots, final_results);
+    x_SetAnnotation(annots, final_results);
 
     return final_results;
 };
@@ -347,13 +352,13 @@ void CIgBlast::x_SetupVSearch(CRef<IQueryFactory>       &qf,
         int penalty = m_Options->GetOptions().GetMismatchPenalty();
         opts.SetMatchReward(1);
         opts.SetMismatchPenalty(penalty);
-        opts.SetWordSize(9);
+        opts.SetWordSize(m_Options->GetOptions().GetWordSize());
         if (penalty == -1) {
             opts.SetGapOpeningCost(4);
             opts.SetGapExtensionCost(1);
         }
     }
-    opts_hndl->SetEvalueThreshold(20.0);
+    opts_hndl->SetEvalueThreshold(m_Options->GetOptions().GetEvalueThreshold());
     opts_hndl->SetFilterString("F");
     opts_hndl->SetHitlistSize(15+ m_IgOptions->m_NumAlign[0]);
     qf.Reset(new CObjMgr_QueryFactory(*m_Query));
@@ -541,7 +546,14 @@ static bool s_CompareSeqAlignByEvalue(const CRef<CSeq_align> &x,
     int dx, dy;
     dx = x->GetAlignLength();
     dy = y->GetAlignLength();
-    return (ix*dy >= iy*dx);
+    if (ix*dy != iy*dx) {
+        return (ix*dy >= iy*dx);
+    }
+    string x_id = NcbiEmptyString;
+    string y_id = NcbiEmptyString;
+    x->GetSeq_id(1).GetLabel(&x_id, CSeq_id::eContent);
+    y->GetSeq_id(1).GetLabel(&y_id, CSeq_id::eContent);
+    return (x_id < y_id);
 };
 
 // Compare two seqaligns according to their evalue and coverage
@@ -556,6 +568,29 @@ static bool s_CompareSeqAlignByScore(const CRef<CSeq_align> &x, const CRef<CSeq_
     return (sx <= sy);
 };
 
+// Compare two seqaligns according to their evalue and coverage and name 
+//compare name since blast does not guarantee order of same score hits
+static bool s_CompareSeqAlignByScoreAndName(const CRef<CSeq_align> &x, const CRef<CSeq_align> &y)
+{
+    int sx, sy;
+    x->GetNamedScore(CSeq_align::eScore_Score, sx);
+    y->GetNamedScore(CSeq_align::eScore_Score, sy);
+    if (sx != sy) return (sx > sy);
+    x->GetNamedScore(CSeq_align::eScore_IdentityCount, sx);
+    y->GetNamedScore(CSeq_align::eScore_IdentityCount, sy);
+    if (sx != sy) {
+        return (sx <= sy);
+    }
+    
+    string x_id = NcbiEmptyString;
+    string y_id = NcbiEmptyString;
+    x->GetSeq_id(1).GetLabel(&x_id, CSeq_id::eContent);
+    y->GetSeq_id(1).GetLabel(&y_id, CSeq_id::eContent);
+    return (x_id < y_id);
+    
+};
+
+
 // Test if D and J annotation not compatible
 static bool s_DJNotCompatible(const CSeq_align &d, const CSeq_align &j, bool ms, int margin)
 {
@@ -710,7 +745,7 @@ void CIgBlast::x_FindDJAln(CRef<CSeq_align_set>& align_D,
                 else ++it;
             }
             /* sort according to score */
-            align_list.sort(s_CompareSeqAlignByScore);
+            align_list.sort(s_CompareSeqAlignByScoreAndName);
         }
 
         /* preprocess J */
@@ -759,7 +794,7 @@ void CIgBlast::x_FindDJAln(CRef<CSeq_align_set>& align_D,
                 else ++it;
             }
             /* sort according to score */
-            align_list.sort(s_CompareSeqAlignByScore);
+            align_list.sort(s_CompareSeqAlignByScoreAndName);
         }
 
         /* which one to keep, D or J? */
@@ -1336,15 +1371,20 @@ void CIgBlast::s_AppendResults(CRef<CSearchResultSet> &results,
     }
 };
 
-void CIgBlast::s_SetAnnotation(vector<CRef <CIgAnnotation> > &annots,
+void CIgBlast::x_SetAnnotation(vector<CRef <CIgAnnotation> > &annots,
                                CRef<CSearchResultSet> &final_results)
 {
     int iq = 0;
-    ITERATE(CSearchResultSet, result, *final_results) {
+    NON_CONST_ITERATE(CSearchResultSet, result, *final_results) {
         CIgBlastResults *ig_result = dynamic_cast<CIgBlastResults *>
-                                     (const_cast<CSearchResults *>(&**result));
+            (const_cast<CSearchResults *>(&**result));
         CIgAnnotation *annot = &*(annots[iq++]);
         ig_result->SetIgAnnotation().Reset(annot);
+        if (annot->m_GeneInfo[4] < 0 && m_IgOptions->m_MinJLength > 0) { //no J
+            if ((*result)->HasAlignments()){
+                (*result)->SetSeqAlign()->Set().clear();
+            }
+        } 
     }
 };
 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.aalookup_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.aalookup_unit_test.app
index 8f74aee..0e07045 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.aalookup_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.aalookup_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.aalookup_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.aalookup_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = aalookup_unit_test
 SRC = aalookup_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.aascan_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.aascan_unit_test.app
index 6842eae..b792c4f 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.aascan_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.aascan_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.aascan_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.aascan_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = aascan_unit_test
 SRC = aascan_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.bl2seq_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.bl2seq_unit_test.app
index b754de4..258b96c 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.bl2seq_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.bl2seq_unit_test.app
@@ -1,10 +1,10 @@
-# $Id: Makefile.bl2seq_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.bl2seq_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = bl2seq_unit_test
 SRC = bl2seq_unit_test
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
-LIB = blast_unit_test_util test_boost $(BLAST_INPUT_LIBS) ncbi_xloader_blastdb_rmt \
+LIB = blast_unit_test_util test_boost $(BLAST_INPUT_LIBS) \
     $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
 LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.blast_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.blast_unit_test.app
index da21ad2..045ae44 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.blast_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.blast_unit_test.app
@@ -1,10 +1,10 @@
-# $Id: Makefile.blast_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.blast_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = blast_unit_test
 SRC = blast_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
-LIB = blast_unit_test_util test_boost $(BLAST_INPUT_LIBS) ncbi_xloader_blastdb_rmt \
+LIB = blast_unit_test_util test_boost $(BLAST_INPUT_LIBS) \
     $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
 LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.blast_unit_test_util.lib b/c++/src/algo/blast/unit_tests/api/Makefile.blast_unit_test_util.lib
index 2392dd6..37d4d83 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.blast_unit_test_util.lib
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.blast_unit_test_util.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.blast_unit_test_util.lib 454210 2014-12-11 18:20:43Z camacho $
+# $Id: Makefile.blast_unit_test_util.lib 505858 2016-06-29 16:55:21Z elisovdn $
 
 WATCHERS = camacho madden fongah2
 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.blastdiag_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.blastdiag_unit_test.app
index dc622a3..ca94660 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.blastdiag_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.blastdiag_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.blastdiag_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.blastdiag_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = blastdiag_unit_test
 SRC = blastdiag_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.blastengine_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.blastengine_unit_test.app
index 2d7280e..309aa85 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.blastengine_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.blastengine_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.blastengine_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.blastengine_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = blastengine_unit_test
 SRC = blastengine_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.blastextend_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.blastextend_unit_test.app
index 9a147be..b597893 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.blastextend_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.blastextend_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.blastextend_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.blastextend_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = blastextend_unit_test
 SRC = blastextend_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.blastfilter_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.blastfilter_unit_test.app
index f175ec0..c2025de 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.blastfilter_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.blastfilter_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.blastfilter_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.blastfilter_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = blastfilter_unit_test
 SRC = blastfilter_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.blasthits_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.blasthits_unit_test.app
index fdfd972..9fdcea6 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.blasthits_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.blasthits_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.blasthits_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.blasthits_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = blasthits_unit_test
 SRC = blasthits_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.blastoptions_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.blastoptions_unit_test.app
index 7bc6576..6833743 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.blastoptions_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.blastoptions_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.blastoptions_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.blastoptions_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = blastoptions_unit_test
 SRC = blastoptions_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.blastsetup_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.blastsetup_unit_test.app
index 242fd23..52c4680 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.blastsetup_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.blastsetup_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.blastsetup_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.blastsetup_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = blastsetup_unit_test
 SRC = blastsetup_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.delta_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.delta_unit_test.app
index 7d9234c..4c801d5 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.delta_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.delta_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.delta_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.delta_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = delta_unit_test
 SRC = delta_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.gapinfo_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.gapinfo_unit_test.app
index 21ee6bf..d8af43d 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.gapinfo_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.gapinfo_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.gapinfo_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.gapinfo_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = gapinfo_unit_test
 SRC = gapinfo_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.gencode_singleton_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.gencode_singleton_unit_test.app
index 83ee07b..d782c5a 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.gencode_singleton_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.gencode_singleton_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.gencode_singleton_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.gencode_singleton_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = gencode_singleton_unit_test
 SRC = gencode_singleton_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.hspfilter_besthit_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.hspfilter_besthit_unit_test.app
index 247b268..15971fe 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.hspfilter_besthit_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.hspfilter_besthit_unit_test.app
@@ -1,11 +1,11 @@
-# $Id: Makefile.hspfilter_besthit_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.hspfilter_besthit_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = hspfilter_besthit_unit_test
 SRC = hspfilter_besthit_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
 LIB = test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = hspfilter_besthit_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.hspfilter_culling_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.hspfilter_culling_unit_test.app
index 817a5ef..1e58bc5 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.hspfilter_culling_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.hspfilter_culling_unit_test.app
@@ -1,11 +1,11 @@
-# $Id: Makefile.hspfilter_culling_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.hspfilter_culling_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = hspfilter_culling_unit_test
 SRC = hspfilter_culling_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
 LIB = test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = hspfilter_culling_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.hspstream_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.hspstream_unit_test.app
index c3e314d..3cd0537 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.hspstream_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.hspstream_unit_test.app
@@ -1,11 +1,11 @@
-# $Id: Makefile.hspstream_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.hspstream_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = hspstream_unit_test
 SRC = hspstream_unit_test hspstream_test_util
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
 LIB = test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = hspstream_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.in b/c++/src/algo/blast/unit_tests/api/Makefile.in
index 5b7ae8a..9be6ba8 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.in
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in 498724 2016-04-19 13:36:57Z ivanov $
+# $Id: Makefile.in 505606 2016-06-27 18:14:44Z boratyng $
 
 LIB_PROJ = blast_unit_test_util seqalign_util
 
@@ -47,7 +47,8 @@ blastfilter_unit_test \
 blastoptions_unit_test \
 gencode_singleton_unit_test \
 bl2seq_unit_test \
-stat_unit_test
+stat_unit_test \
+magicblast_unit_test
 
 REQUIRES = Boost.Test.Included
 
@@ -151,3 +152,5 @@ bl2seq_unit_test: lib
 	${MAKE} ${MFLAGS} -f Makefile.bl2seq_unit_test_app
 stat_unit_test: lib
 	${MAKE} ${MFLAGS} -f Makefile.stat_unit_test_app
+magicblast_unit_test:
+	${MAKE} ${MFLAGS} -f Makefile.magicblast_unit_test_app
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.linkhsp_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.linkhsp_unit_test.app
index 92f3c0e..5dbe3a1 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.linkhsp_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.linkhsp_unit_test.app
@@ -1,11 +1,11 @@
-# $Id: Makefile.linkhsp_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.linkhsp_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = linkhsp_unit_test
 SRC = linkhsp_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE) -I$(srcdir)/../../api
 LIB = blast_unit_test_util test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = linkhsp_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.magicblast_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.magicblast_unit_test.app
new file mode 100644
index 0000000..7a8dd07
--- /dev/null
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.magicblast_unit_test.app
@@ -0,0 +1,16 @@
+# $Id: Makefile.magicblast_unit_test.app 507273 2016-07-18 13:56:27Z boratyng $
+
+APP = magicblast_unit_test
+SRC = magicblast_unit_test 
+
+CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
+LIB = test_boost $(BLAST_INPUT_LIBS) \
+    $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
+
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(ORIG_LIBS)
+
+CHECK_REQUIRES = MT in-house-resources
+CHECK_CMD = magicblast_unit_test
+CHECK_COPY = data magicblast_unit_test.ini
+
+WATCHERS = boratyng
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.msa2pssm_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.msa2pssm_unit_test.app
index 95d5a5b..4d9a68c 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.msa2pssm_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.msa2pssm_unit_test.app
@@ -1,11 +1,11 @@
-# $Id: Makefile.msa2pssm_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.msa2pssm_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = msa2pssm_unit_test
 SRC = msa2pssm_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
 LIB = test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = msa2pssm_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.ntlookup_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.ntlookup_unit_test.app
index f36b5bc..e13d2f4 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.ntlookup_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.ntlookup_unit_test.app
@@ -1,14 +1,14 @@
-# $Id: Makefile.ntlookup_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.ntlookup_unit_test.app 507273 2016-07-18 13:56:27Z boratyng $
 
 APP = ntlookup_unit_test
 SRC = ntlookup_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE) -I$(srcdir)/../../api
 LIB = blast_unit_test_util test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = ntlookup_unit_test
-CHECK_COPY = ntlookup_unit_test.ini
+CHECK_COPY = data ntlookup_unit_test.ini
 
 WATCHERS = boratyng morgulis madden camacho fongah2
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.ntscan_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.ntscan_unit_test.app
index d7a1ef1..6e61f35 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.ntscan_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.ntscan_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.ntscan_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.ntscan_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = ntscan_unit_test
 SRC = ntscan_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.optionshandle_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.optionshandle_unit_test.app
index d7ac7b8..629348c 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.optionshandle_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.optionshandle_unit_test.app
@@ -1,11 +1,11 @@
-# $Id: Makefile.optionshandle_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.optionshandle_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = optionshandle_unit_test
 SRC = optionshandle_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
 LIB = test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = optionshandle_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.phiblast_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.phiblast_unit_test.app
index 3d55f56..39d995b 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.phiblast_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.phiblast_unit_test.app
@@ -1,11 +1,11 @@
-# $Id: Makefile.phiblast_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.phiblast_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = phiblast_unit_test
 SRC = phiblast_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE) -I$(srcdir)/../../api
 LIB = test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = phiblast_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.prelimsearch_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.prelimsearch_unit_test.app
index 84bb066..65b1bd3 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.prelimsearch_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.prelimsearch_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.prelimsearch_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.prelimsearch_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = prelimsearch_unit_test
 SRC = prelimsearch_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.psibl2seq_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.psibl2seq_unit_test.app
index 4d20824..7773a8f 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.psibl2seq_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.psibl2seq_unit_test.app
@@ -1,11 +1,11 @@
-# $Id: Makefile.psibl2seq_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.psibl2seq_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = psibl2seq_unit_test
 SRC = psibl2seq_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE) -I$(srcdir)/../../api
 LIB = test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = psibl2seq_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.psiblast_iteration_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.psiblast_iteration_unit_test.app
index 01106e4..73e456a 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.psiblast_iteration_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.psiblast_iteration_unit_test.app
@@ -1,11 +1,11 @@
-# $Id: Makefile.psiblast_iteration_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.psiblast_iteration_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = psiblast_iteration_unit_test
 SRC = psiblast_iteration_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE) -I$(srcdir)/../../api
 LIB = test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = psiblast_iteration_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.psiblast_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.psiblast_unit_test.app
index d94e8f0..47fea7f 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.psiblast_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.psiblast_unit_test.app
@@ -1,10 +1,10 @@
-# $Id: Makefile.psiblast_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.psiblast_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = psiblast_unit_test
 SRC = psiblast_unit_test
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE) -I$(srcdir)/../../api
-LIB = seqalign_util test_boost $(BLAST_INPUT_LIBS) ncbi_xloader_blastdb_rmt \
+LIB = seqalign_util test_boost $(BLAST_INPUT_LIBS) \
     $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
 LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.pssmcreate_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.pssmcreate_unit_test.app
index b85eb30..bec0c9c 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.pssmcreate_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.pssmcreate_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.pssmcreate_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.pssmcreate_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = pssmcreate_unit_test
 SRC = pssmcreate_unit_test pssm_test_util pssmcreate_cdd_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.pssmenginefreqratios_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.pssmenginefreqratios_unit_test.app
index 6852a51..2df1eab 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.pssmenginefreqratios_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.pssmenginefreqratios_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.pssmenginefreqratios_unit_test.app 464229 2015-04-07 14:51:55Z fongah2 $
+# $Id: Makefile.pssmenginefreqratios_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = pssmenginefreqratios_unit_test
 SRC = pssmenginefreqratios_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.querydata_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.querydata_unit_test.app
index e4610be..234d68c 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.querydata_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.querydata_unit_test.app
@@ -1,11 +1,11 @@
-# $Id: Makefile.querydata_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.querydata_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = querydata_unit_test
 SRC = querydata_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
 LIB = blast_unit_test_util test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = querydata_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.queryinfo_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.queryinfo_unit_test.app
index a5ff542..0b1ada5 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.queryinfo_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.queryinfo_unit_test.app
@@ -1,11 +1,11 @@
-# $Id: Makefile.queryinfo_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.queryinfo_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = queryinfo_unit_test
 SRC = queryinfo_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE) -I$(srcdir)/../../api
 LIB = blast_unit_test_util test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = queryinfo_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.redoalignment_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.redoalignment_unit_test.app
index 75431f4..1e2c197 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.redoalignment_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.redoalignment_unit_test.app
@@ -1,15 +1,15 @@
-# $Id: Makefile.redoalignment_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.redoalignment_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = redoalignment_unit_test
 SRC = redoalignment_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE) -I$(srcdir)/../../api -I$(srcdir)/../../core
-LIB = blast_unit_test_util test_boost $(BLAST_INPUT_LIBS) ncbi_xloader_blastdb_rmt \
+LIB = blast_unit_test_util test_boost $(BLAST_INPUT_LIBS) \
     $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = redoalignment_unit_test
 CHECK_COPY = redoalignment_unit_test.ini data
 
-WATCHERS = boratyng madden 
+WATCHERS = boratyng madden
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.remote_blast_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.remote_blast_unit_test.app
index 9aa515c..a675b49 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.remote_blast_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.remote_blast_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.remote_blast_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.remote_blast_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = remote_blast_unit_test
 SRC = remote_blast_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.rps_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.rps_unit_test.app
index 3b3193e..d0f88a4 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.rps_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.rps_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.rps_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.rps_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = rps_unit_test
 SRC = rps_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.scoreblk_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.scoreblk_unit_test.app
index a10ceb4..939a7e4 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.scoreblk_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.scoreblk_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.scoreblk_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.scoreblk_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = scoreblk_unit_test
 SRC = scoreblk_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.search_strategy_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.search_strategy_unit_test.app
index 2a68bc7..47fb260 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.search_strategy_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.search_strategy_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.search_strategy_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.search_strategy_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = search_strategy_unit_test
 SRC = search_strategy_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.seqalign_util.lib b/c++/src/algo/blast/unit_tests/api/Makefile.seqalign_util.lib
index 25b5574..d61a2a3 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.seqalign_util.lib
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.seqalign_util.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.seqalign_util.lib 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.seqalign_util.lib 505858 2016-06-29 16:55:21Z elisovdn $
 
 WATCHERS = camacho madden fongah2
 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.seqinfosrc_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.seqinfosrc_unit_test.app
index 523060c..8728d6f 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.seqinfosrc_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.seqinfosrc_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.seqinfosrc_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.seqinfosrc_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = seqinfosrc_unit_test
 SRC = seqinfosrc_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.seqsrc_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.seqsrc_unit_test.app
index f89fb76..d95bbfa 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.seqsrc_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.seqsrc_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.seqsrc_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.seqsrc_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = seqsrc_unit_test
 SRC = seqsrc_unit_test seqsrc_mock mockseqsrc1_unit_test mockseqsrc2_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.setupfactory_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.setupfactory_unit_test.app
index dad179e..7c2f710 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.setupfactory_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.setupfactory_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.setupfactory_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.setupfactory_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = setupfactory_unit_test
 SRC = setupfactory_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.split_query_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.split_query_unit_test.app
index c6fcc12..49bba31 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.split_query_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.split_query_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.split_query_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.split_query_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = split_query_unit_test
 SRC = split_query_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.stat_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.stat_unit_test.app
index 72de2e7..1eac3cb 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.stat_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.stat_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.stat_unit_test.app 498724 2016-04-19 13:36:57Z ivanov $
+# $Id: Makefile.stat_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = stat_unit_test
 SRC = stat_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.subj_ranges_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.subj_ranges_unit_test.app
index c98812c..02d53db 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.subj_ranges_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.subj_ranges_unit_test.app
@@ -1,11 +1,11 @@
-# $Id: Makefile.subj_ranges_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.subj_ranges_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = subj_ranges_unit_test
 SRC = subj_ranges_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
 LIB = test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = subj_ranges_unit_test
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.traceback_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.traceback_unit_test.app
index ce666f7..b4a415e 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.traceback_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.traceback_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.traceback_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.traceback_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = traceback_unit_test
 SRC = traceback_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.tracebacksearch_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.tracebacksearch_unit_test.app
index 190142f..5eb2d98 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.tracebacksearch_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.tracebacksearch_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.tracebacksearch_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.tracebacksearch_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = tracebacksearch_unit_test
 SRC = tracebacksearch_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.uniform_search_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.uniform_search_unit_test.app
index f14e404..5cbaa04 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.uniform_search_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.uniform_search_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.uniform_search_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.uniform_search_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = uniform_search_unit_test
 SRC = uniform_search_unit_test 
diff --git a/c++/src/algo/blast/unit_tests/api/Makefile.version_reference_unit_test.app b/c++/src/algo/blast/unit_tests/api/Makefile.version_reference_unit_test.app
index c2df777..780eb5e 100644
--- a/c++/src/algo/blast/unit_tests/api/Makefile.version_reference_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/api/Makefile.version_reference_unit_test.app
@@ -1,14 +1,14 @@
-# $Id: Makefile.version_reference_unit_test.app 454176 2014-12-11 16:00:59Z camacho $
+# $Id: Makefile.version_reference_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = version_reference_unit_test
 SRC = version_reference_unit_test 
 
 CPPFLAGS = -DNCBI_MODULE=BLAST $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
 LIB = test_boost $(BLAST_LIBS) xobjsimple $(OBJMGR_LIBS:ncbi_x%=ncbi_x%$(DLL))
-LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
 CHECK_REQUIRES = MT in-house-resources
 CHECK_CMD = version_reference_unit_test
 CHECK_COPY = version_reference_unit_test.ini
 
-WATCHERS = madden camacho 
+WATCHERS = madden camacho
diff --git a/c++/src/algo/blast/unit_tests/api/aalookup_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/aalookup_unit_test.cpp
index 1fd2460..d030ea8 100644
--- a/c++/src/algo/blast/unit_tests/api/aalookup_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/aalookup_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: aalookup_unit_test.cpp 347537 2011-12-19 16:45:43Z maning $
+/*  $Id: aalookup_unit_test.cpp 504861 2016-06-20 15:45:40Z boratyng $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -193,6 +193,7 @@ struct AalookupTestFixture {
 			sbp,
 			&lookup_wrap_ptr,
                       NULL /* RPS info */,
+                      NULL,
                       NULL);
     lookup = (BlastAaLookupTable*) lookup_wrap_ptr->lut;
   }
diff --git a/c++/src/algo/blast/unit_tests/api/aascan_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/aascan_unit_test.cpp
index 7bb3a02..c627420 100644
--- a/c++/src/algo/blast/unit_tests/api/aascan_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/aascan_unit_test.cpp
@@ -1,4 +1,4 @@
-/* $Id: aascan_unit_test.cpp 272713 2011-04-11 14:49:23Z camacho $
+/* $Id: aascan_unit_test.cpp 504861 2016-06-20 15:45:40Z boratyng $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -215,6 +215,7 @@ struct AascanTestFixture {
                             sbp,
                             &lookup_wrap_ptr,
                             NULL /* RPS Info */,
+                            NULL,
                             NULL);
         BOOST_REQUIRE_EQUAL(0, status);
 
diff --git a/c++/src/algo/blast/unit_tests/api/bl2seq_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/bl2seq_unit_test.cpp
index 427223d..df702dd 100644
--- a/c++/src/algo/blast/unit_tests/api/bl2seq_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/bl2seq_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: bl2seq_unit_test.cpp 495292 2016-03-16 14:52:49Z ivanov $
+/*  $Id: bl2seq_unit_test.cpp 507726 2016-07-21 14:42:04Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1986,7 +1986,7 @@ BOOST_AUTO_TEST_CASE(ProteinBlast2Seqs) {
     CSeq_id id("gi|129295");
     auto_ptr<SSeqLoc> query(CTestObjMgr::Instance().CreateSSeqLoc(id));
 
-    id.SetGi(GI_FROM(TIntId, 7662354));
+    id.SetGi(GI_CONST(7662354));
     auto_ptr<SSeqLoc> subj(CTestObjMgr::Instance().CreateSSeqLoc(id));
 
     CBl2Seq blaster(*query, *subj, eBlastp);
@@ -2197,7 +2197,7 @@ BOOST_AUTO_TEST_CASE(ProteinBlastChangeQuery) {
     CSeq_id id("gi|129295");
     auto_ptr<SSeqLoc> query(CTestObjMgr::Instance().CreateSSeqLoc(id));
 
-    id.SetGi(GI_FROM(TIntId, 7662354));
+    id.SetGi(GI_CONST(7662354));
     auto_ptr<SSeqLoc> subj(CTestObjMgr::Instance().CreateSSeqLoc(id));
 
     // Run self hit first
@@ -3313,7 +3313,7 @@ BOOST_AUTO_TEST_CASE(testOneSubjectResults2CSeqAlign)
     int index;
     for (index = 0; index < num_subjects; ++index) {
         id.Reset(new CSeq_id(CSeq_id::e_Gi, (query_gi + gi_diff + index)));
-cerr << query_gi + gi_diff + index << endl;
+        //cerr << query_gi + gi_diff + index << endl;
         sl.reset(CTestObjMgr::Instance().CreateSSeqLoc(*id, 
                                                        eNa_strand_both));
         subjects.push_back(*sl);
@@ -3325,7 +3325,7 @@ cerr << query_gi + gi_diff + index << endl;
     index = 0;
     ITERATE(TSeqAlignVector, itr, seqalign_v)
     {
-cerr << index << endl;
+        //cerr << index << endl;
         BOOST_REQUIRE_EQUAL(results_size[index], (int) (*itr)->Get().size());
         index++;
     }
@@ -3593,7 +3593,7 @@ BOOST_AUTO_TEST_CASE(MultiIntervalLoc) {
 
 BOOST_AUTO_TEST_CASE(QueryMaskIgnoredInMiniExtension) {
     CRef<CSeq_loc> qloc(new CSeq_loc());
-    qloc->SetWhole().SetGi(GI_FROM(TIntId, 4505696));
+    qloc->SetWhole().SetGi(GI_CONST(4505696));
     CSeq_id sid("gi|29809252");
     pair<TSeqPos, TSeqPos> range(662070, 662129);
 
diff --git a/c++/src/algo/blast/unit_tests/api/blastdiag_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/blastdiag_unit_test.cpp
index 576fdbf..b3bc061 100644
--- a/c++/src/algo/blast/unit_tests/api/blastdiag_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/blastdiag_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastdiag_unit_test.cpp 462040 2015-03-16 13:14:29Z vasilche $
+/*  $Id: blastdiag_unit_test.cpp 506072 2016-07-01 13:01:25Z dicuccio $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -35,10 +35,8 @@
 
 #include <algo/blast/core/blast_extend.h>
 
-#include "test_objmgr.hpp"
 
 using namespace ncbi;
-using namespace ncbi::blast;
 
 BOOST_AUTO_TEST_SUITE(BlastDiag)
 
diff --git a/c++/src/algo/blast/unit_tests/api/blastengine_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/blastengine_unit_test.cpp
index 077301a..e8bc6d8 100644
--- a/c++/src/algo/blast/unit_tests/api/blastengine_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/blastengine_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastengine_unit_test.cpp 498724 2016-04-19 13:36:57Z ivanov $
+/*  $Id: blastengine_unit_test.cpp 507726 2016-07-21 14:42:04Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -148,8 +148,8 @@ void testShortMatchDiagnostics(BlastDiagnostics* diagnostics)
 BOOST_AUTO_TEST_CASE(testTBLASTNLongMatchBlastEngine) {
     const Int4 kNumHspsEnd=23;
     const Int8 kEffectiveSearchSpace = 1050668186940LL;
-    const TGi kQueryGi = GI_FROM(TIntId, 9790067);
-    const TGi kSubjectGi = GI_FROM(TIntId, 30698605);
+    const TGi kQueryGi = GI_CONST(9790067);
+    const TGi kSubjectGi = GI_CONST(30698605);
     const EBlastProgramType kProgramType = eBlastTypeTblastn;
     const EProgram kProgram = eTblastn;
 
@@ -220,8 +220,8 @@ BOOST_AUTO_TEST_CASE(testTBLASTNLongMatchBlastEngine) {
 BOOST_AUTO_TEST_CASE(testTBLASTNShortMatchBlastEngine) {
     const Int4 kNumHspsEnd=8;
     const Int8 kEffectiveSearchSpace = 1050668186940LL;
-    const TGi kQueryGi = GI_FROM(TIntId, 9790067);
-    const TGi kSubjectGi = GI_FROM(TIntId, 38547463);
+    const TGi kQueryGi = GI_CONST(9790067);
+    const TGi kSubjectGi = GI_CONST(38547463);
     const EBlastProgramType kProgramType = eBlastTypeTblastn;
     const EProgram kProgram = eTblastn;
     
@@ -282,8 +282,8 @@ BOOST_AUTO_TEST_CASE(testTBLASTNShortMatchBlastEngine) {
 // and hence has a large number of hits, even with an increased word size.
 BOOST_AUTO_TEST_CASE(testBlastnWithLargeWordSize)
 {
-    const TGi kQueryGi = GI_FROM(TIntId, 186279); // Short human sequence with repeats
-    const TGi kSubjectGi = GI_FROM(TIntId, 29791382); // Contig from human chromosome 1
+    const TGi kQueryGi = GI_CONST(186279); // Short human sequence with repeats
+    const TGi kSubjectGi = GI_CONST(29791382); // Contig from human chromosome 1
     const int kNumHsps = 330;
     const EBlastProgramType kProgramType = eBlastTypeBlastn;
 
@@ -316,8 +316,8 @@ BOOST_AUTO_TEST_CASE(testBlastnWithLargeWordSize)
 // only 1 HSP is left. 
 BOOST_AUTO_TEST_CASE(testBlastnWithRepeatsFiltering)
 {
-    const TGi kQueryGi = GI_FROM(TIntId, 186279); // Short human sequence with repeats
-    const TGi kSubjectGi = GI_FROM(TIntId, 29791382); // Contig from human chromosome 1
+    const TGi kQueryGi = GI_CONST(186279); // Short human sequence with repeats
+    const TGi kSubjectGi = GI_CONST(29791382); // Contig from human chromosome 1
     const int kNumHsps = 3;
     const int kMaskedLength = 389;
     const EBlastProgramType kProgramType = eBlastTypeBlastn;
@@ -355,7 +355,7 @@ BOOST_AUTO_TEST_CASE(testBlastnWithRepeatsFiltering)
 
 BOOST_AUTO_TEST_CASE(testDiscMegaBlastPartialRun) 
 {
-    const TGi kQueryGi = GI_FROM(TIntId, 14702146); 
+    const TGi kQueryGi = GI_CONST(14702146); 
     const string kDbName("data/seqn");
     const size_t kNumHits = 2;
     const TIntId kGis[kNumHits] = { 46071158, 46072400 };
@@ -412,8 +412,8 @@ BOOST_AUTO_TEST_CASE(testDiscMegaBlastPartialRun)
 BOOST_AUTO_TEST_CASE(testBlastpPrelimSearch) 
 {
     const string kDbName("data/seqp");
-    const TGi kQueryGi1 = GI_FROM(TIntId, 21282798);
-    const TGi kQueryGi2 = GI_FROM(TIntId, 129295);
+    const TGi kQueryGi1 = GI_CONST(21282798);
+    const TGi kQueryGi2 = GI_CONST(129295);
     const int kNumHits = 31;
     const int kNumHitsToCheck = 3;
     const int kIndices[kNumHitsToCheck] = { 1, 4, 8 };
diff --git a/c++/src/algo/blast/unit_tests/api/blastfilter_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/blastfilter_unit_test.cpp
index ee5c005..702d565 100644
--- a/c++/src/algo/blast/unit_tests/api/blastfilter_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/blastfilter_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastfilter_unit_test.cpp 496425 2016-03-28 15:16:22Z ivanov $
+/*  $Id: blastfilter_unit_test.cpp 507726 2016-07-21 14:42:04Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -413,9 +413,9 @@ BOOST_AUTO_TEST_CASE(TSeqLocVector2Packed_seqint_TestIntervals) {
 BOOST_AUTO_TEST_CASE(TSeqLocVector2Packed_seqint_TestNoIntervals) {
     typedef pair<TGi, TSeqPos> TGiLength;
     vector<TGiLength> gis;
-    gis.push_back(make_pair(GI_FROM(TIntId, 6), 342U));
-    gis.push_back(make_pair(GI_FROM(TIntId, 129295), 232U));
-    gis.push_back(make_pair(GI_FROM(TIntId, 15606659), 443U));
+    gis.push_back(make_pair(GI_CONST(6), 342U));
+    gis.push_back(make_pair(GI_CONST(129295), 232U));
+    gis.push_back(make_pair(GI_CONST(15606659), 443U));
 
     TSeqLocVector input;
     input.reserve(gis.size());
@@ -545,14 +545,14 @@ BOOST_AUTO_TEST_CASE(WindowMasker)
         { 0, 79,
           100, 122,
           146, 169,
-          225, 248,
+          225, 247,
           286, 329,
           348, 366,
           373, 688,
           701, 1303,
           1450, 1485,
           2858, 2887,
-          3086, 3212,
+          3103, 3212,
           3217, 3735,
           4142, 4162,
           5423, 5443,
@@ -564,7 +564,8 @@ BOOST_AUTO_TEST_CASE(WindowMasker)
           7170, 7189,
           7604, 7623,
           8454, 8476,
-          8829, 8889 
+          8829, 8851,
+          8860, 8889
         };
     
     size_t num_locs = sizeof(intervals) / pair_size;
diff --git a/c++/src/algo/blast/unit_tests/api/blasthits_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/blasthits_unit_test.cpp
index 1611e4a..1e11c09 100644
--- a/c++/src/algo/blast/unit_tests/api/blasthits_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/blasthits_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blasthits_unit_test.cpp 500125 2016-05-02 16:14:49Z ivanov $
+/*  $Id: blasthits_unit_test.cpp 514847 2016-09-26 17:22:13Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -70,38 +70,38 @@ BOOST_AUTO_TEST_SUITE(blasthits)
         const int kNumLists = 3;
         const int kMaxHspCount = 6;
         const int kHspCounts[kNumLists] = { 6, 6, 4 };
-        const int kSubjectOffsets[kNumLists][kMaxHspCount] = 
-            { { 100, 9950, 5000, 9850, 3000, 9970 }, 
-              { 9950, 9902, 9970, 10400, 19750, 19820 }, 
+        const int kSubjectOffsets[kNumLists][kMaxHspCount] =
+            { { 100, 9950, 5000, 9850, 3000, 9970 },
+              { 9950, 9902, 9970, 10400, 19750, 19820 },
               { 19805, 25000, 19820, 22000 } };
-        const int kQueryOffsets[kNumLists][kMaxHspCount] = 
-            { { 100, 200, 300, 400, 500, 600 }, 
-              { 200, 452, 600, 100, 200, 300 }, 
+        const int kQueryOffsets[kNumLists][kMaxHspCount] =
+            { { 100, 200, 300, 400, 500, 600 },
+              { 200, 452, 600, 100, 200, 300 },
               { 255, 100, 300, 200 } };
-        const int kLengths[kNumLists][kMaxHspCount] = 
-            { { 100, 45, 100, 100, 100, 28 }, 
-              { 100, 48, 100, 100, 100, 60 }, 
+        const int kLengths[kNumLists][kMaxHspCount] =
+            { { 100, 45, 100, 100, 100, 28 },
+              { 100, 48, 100, 100, 100, 60 },
               { 45, 200, 60, 200} };
-        const int kScores[kNumLists][kMaxHspCount] = 
-            { { 60, 30, 70, 75, 65, 28 }, 
-              { 80, 40, 62, 77, 72, 44 }, 
+        const int kScores[kNumLists][kMaxHspCount] =
+            { { 60, 30, 70, 75, 65, 28 },
+              { 80, 40, 62, 77, 72, 44 },
               { 32, 120, 44, 111 } };
-        const int contexts[kNumLists][kMaxHspCount] = 
-            { { 0, 1, 2, 1, 3, 1 }, 
-              { 1, 4, 1, 0, 1, 1 }, 
+        const int contexts[kNumLists][kMaxHspCount] =
+            { { 0, 1, 2, 1, 3, 1 },
+              { 1, 4, 1, 0, 1, 1 },
               { 1, 0, 1, 4 } };
 
         int index;
         BlastHSPList* hsp_list = *hsp_list_ptr;
         hsp_list->hspcnt = kHspCounts[chunk];
         for (index = 0; index < kHspCounts[chunk]; ++index) {
-            hsp_list->hsp_array[index] = 
+            hsp_list->hsp_array[index] =
                 (BlastHSP*) calloc(1, sizeof(BlastHSP));
             hsp_list->hsp_array[index]->query.offset = kQueryOffsets[chunk][index];
             hsp_list->hsp_array[index]->subject.offset = kSubjectOffsets[chunk][index];
-            hsp_list->hsp_array[index]->query.end = 
+            hsp_list->hsp_array[index]->query.end =
                 kQueryOffsets[chunk][index] + kLengths[chunk][index];
-            hsp_list->hsp_array[index]->subject.end = 
+            hsp_list->hsp_array[index]->subject.end =
                 kSubjectOffsets[chunk][index] + kLengths[chunk][index];
             hsp_list->hsp_array[index]->score = kScores[chunk][index];
             hsp_list->hsp_array[index]->context = contexts[chunk][index];
@@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
 {
     CAutomaticGenCodeSingleton instance;
     CSeq_id sid("CU856286");  // DNA sequence
-    auto_ptr<SSeqLoc> subj(CTestObjMgr::Instance().CreateSSeqLoc(sid)); 
+    auto_ptr<SSeqLoc> subj(CTestObjMgr::Instance().CreateSSeqLoc(sid));
 
     Int2 status = 0;
     SBlastSequence subj_sequence(
@@ -126,8 +126,8 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
     BLAST_SequenceBlk* subject_blk;
     BlastSeqBlkNew(&subject_blk);
     status = BlastSeqBlkSetSequence(subject_blk,
-                            subj_sequence.data.release(), 
-                            sequence::GetLength(*subj->seqloc, subj->scope)); 
+                            subj_sequence.data.release(),
+                            sequence::GetLength(*subj->seqloc, subj->scope));
 
     SBlastTargetTranslation* target_t = NULL;
 
@@ -138,16 +138,19 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
     BOOST_REQUIRE_EQUAL(0, status);
     BOOST_REQUIRE(target_t);
 
-    // HSP is NULL so nothing returned. 
+    // HSP is NULL so nothing returned.
     const Uint1* null_sequence = Blast_HSPGetTargetTranslation(target_t, NULL, NULL);
     BOOST_REQUIRE(null_sequence == NULL);
 
     const int kNumTests = 6;
     BlastHSP* hsp;
     Blast_HSPInit(1, 2000, 2000, 3000, 1, 2000, 0, 0, -3, 2000, NULL, &hsp);
-    // These are values that come out for this case.  kLength could change if 
-    // heuristic for allocating buffers in Blast_HSPGetTargetTranslation changes. 
-    const int kLength[kNumTests] = {3899, 4099, 4300, 4500, 4699, 4899 }; 
+    // The following line must match the value in blast_hits.c
+    const int kMaxTranslation = 99;
+    const int kMaxDiv3 = kMaxTranslation / 3;
+    // These are values that come out for this case.  kLength could change if
+    // heuristic for allocating buffers in Blast_HSPGetTargetTranslation changes.
+    const int kLength[kNumTests] = {3199, 3399, 3600, 3800, 3999, 4199};
     const int kValues[2*kNumTests] = {6, 16, 18, 10, 10, 6, 8, 4, 18, 17, 1, 6};
     int index = 0;
     for (index=0; index<kNumTests; index++)
@@ -159,40 +162,40 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         BOOST_REQUIRE_EQUAL(kValues[2*index], (int) sequence[hsp->subject.offset+5]);
 
         Int4 i, n = 0;
-        for (i = hsp->subject.offset-701; i < hsp->subject.offset - 693; ++i) {
-            if (sequence[i] == 201) ++n; 
+        for (i = hsp->subject.offset-(kMaxDiv3 + 1); i < hsp->subject.offset - (kMaxDiv3 - 7); ++i) {
+            if (sequence[i] == 201) ++n;
         }
         BOOST_REQUIRE(n!=0);
         n = 0;
-        for (; i < hsp->subject.end + 693; ++i) {
-            if (sequence[i] == 201) ++n; 
+        for (; i < hsp->subject.end + (kMaxDiv3 - 7); ++i) {
+            if (sequence[i] == 201) ++n;
         }
         BOOST_REQUIRE(n==0);
         n = 0;
-        for (; i < hsp->subject.end + 701 && n == 0; ++i) {
-            if (sequence[i] == 201) ++n; 
+        for (; i < hsp->subject.end + (kMaxDiv3 + 1) && n == 0; ++i) {
+            if (sequence[i] == 201) ++n;
         }
         BOOST_REQUIRE(n!=0);
 
         hsp->subject.offset += 200;
         hsp->subject.end += 200;
         sequence = Blast_HSPGetTargetTranslation(target_t, hsp, &length);
-        BOOST_REQUIRE_EQUAL(kLength[index], length);
+        BOOST_REQUIRE_EQUAL(kLength[index] + kMaxDiv3, length);
         BOOST_REQUIRE_EQUAL(kValues[2*index+1], (int) sequence[hsp->subject.offset+5]);
 
         n = 0;
-        for (i = hsp->subject.offset-701; i < hsp->subject.offset - 693; ++i) {
-            if (sequence[i] == 201) ++n; 
+        for (i = hsp->subject.offset-(kMaxDiv3 + 1); i < hsp->subject.offset - (kMaxDiv3 - 7); ++i) {
+            if (sequence[i] == 201) ++n;
         }
         BOOST_REQUIRE(n!=0);
         n = 0;
-        for (; i < hsp->subject.end + 693; ++i) {
-            if (sequence[i] == 201) ++n; 
+        for (; i < hsp->subject.end + (kMaxDiv3 - 7); ++i) {
+            if (sequence[i] == 201) ++n;
         }
         BOOST_REQUIRE(n==0);
         n = 0;
-        for (; i < hsp->subject.end + 701 && n == 0; ++i) {
-            if (sequence[i] == 201) ++n; 
+        for (; i < hsp->subject.end + (kMaxDiv3 + 1) && n == 0; ++i) {
+            if (sequence[i] == 201) ++n;
         }
         BOOST_REQUIRE(n!=0);
 
@@ -222,12 +225,12 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         const int kNumChunks = 3;
         const int kOffsetIncrement = 9900;
         const int kTotalNumHsps = 12;
-        const int kFinalScores[kTotalNumHsps] = 
+        const int kFinalScores[kTotalNumHsps] =
             { 120, 111, 80, 77, 75, 72, 70, 70, 65, 60, 44, 40 };
-        const int kFinalOffsets[kTotalNumHsps] = 
-            { 25000, 22000, 9950, 10400, 9850, 19750, 5000, 9970, 3000, 100, 
+        const int kFinalOffsets[kTotalNumHsps] =
+            { 25000, 22000, 9950, 10400, 9850, 19750, 5000, 9970, 3000, 100,
               19820, 9902 };
-        const int kFinalLengths[kTotalNumHsps] = 
+        const int kFinalLengths[kTotalNumHsps] =
             { 200, 200, 100, 100, 100, 100, 100, 100, 100, 100, 60, 48 };
         Int4 offset = 0, hsp_num_max = INT4_MAX;
         int chunk;
@@ -236,9 +239,9 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         for (chunk = 0; chunk < kNumChunks; ++chunk) {
             BlastHSPList* hsp_list = Blast_HSPListNew(0);
             setupHSPList(&hsp_list, chunk);
-            Blast_HSPListsMerge(&hsp_list, &combined_hsp_list, 
+            Blast_HSPListsMerge(&hsp_list, &combined_hsp_list,
                                 hsp_num_max, &offset, INT4_MIN,
-                                DBSEQ_CHUNK_OVERLAP, TRUE);
+                                DBSEQ_CHUNK_OVERLAP, TRUE, FALSE);
             offset += kOffsetIncrement;
         }
 
@@ -250,7 +253,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
             BlastHSP* hsp = combined_hsp_list->hsp_array[index];
             BOOST_REQUIRE_EQUAL(kFinalScores[index], hsp->score);
             BOOST_REQUIRE_EQUAL(kFinalOffsets[index], hsp->subject.offset);
-            BOOST_REQUIRE_EQUAL(kFinalLengths[index], 
+            BOOST_REQUIRE_EQUAL(kFinalLengths[index],
                                  hsp->subject.end - hsp->subject.offset);
         }
 
@@ -272,7 +275,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
        Check that the hspcnt is reset to zero at the end. */
     BOOST_AUTO_TEST_CASE(testPurgeOfEmptyHSPList) {
        BlastHSPList* hsp_list = Blast_HSPListNew(0);
-       const int kNumNullHsps=5; 
+       const int kNumNullHsps=5;
        hsp_list->hspcnt = kNumNullHsps;
        Blast_HSPListPurgeNullHSPs(hsp_list);
        /* Nothing was put on list, nothing should be purged off. */
@@ -345,7 +348,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
        hsp_list->hsp_array[7] = Blast_HSPFree(hsp_list->hsp_array[7]);
        hsp_list->hsp_array[17] = Blast_HSPFree(hsp_list->hsp_array[17]);
        hsp_list->hsp_array[24] = Blast_HSPFree(hsp_list->hsp_array[kNumHsps-1]); // last
-       
+
        /* Purge, this should remove the "holes" in the array. */
        Blast_HSPListPurgeNullHSPs(hsp_list);
 
@@ -360,7 +363,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
        {
            BOOST_REQUIRE_EQUAL((BlastHSP*)0, hsp_list->hsp_array[index]);
        }
-       
+
        hsp_list = Blast_HSPListFree(hsp_list);
        BOOST_REQUIRE(hsp_list == NULL);
     }
@@ -373,14 +376,14 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
 
        GapEditScript * kPtrValue = edit_script;
 
-       Int2 rv = Blast_HSPInit(kOffset, 2*kOffset, 3*kOffset, 4*kOffset, 
-                               5*kOffset, 6*kOffset, 0, 0, 0, 10*kOffset, 
+       Int2 rv = Blast_HSPInit(kOffset, 2*kOffset, 3*kOffset, 4*kOffset,
+                               5*kOffset, 6*kOffset, 0, 0, 0, 10*kOffset,
                                &edit_script, &new_hsp);
        BOOST_REQUIRE_EQUAL((Int2)0, rv);
 
        BOOST_REQUIRE_EQUAL((GapEditScript *) 0, edit_script); // this was NULL'ed out
        // HSP got the pointer to edit_script
-       BOOST_REQUIRE_EQUAL(kPtrValue, new_hsp->gap_info); 
+       BOOST_REQUIRE_EQUAL(kPtrValue, new_hsp->gap_info);
        BOOST_REQUIRE_EQUAL(kOffset, new_hsp->query.offset);
        BOOST_REQUIRE_EQUAL(2*kOffset, new_hsp->query.end);
        BOOST_REQUIRE_EQUAL(3*kOffset, new_hsp->subject.offset);
@@ -403,30 +406,30 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
        BOOST_REQUIRE(new_hsp == NULL);
     }
 
-    static void 
+    static void
     s_SetupQueryInfoForReevaluateTest(EBlastProgramType program_number,
                                       BLAST_SequenceBlk* query_blk,
                                       Uint4 subj_length,
                                       BlastQueryInfo* * query_info_ptr)
     {
         BlastQueryInfo* query_info = BlastQueryInfoNew(program_number, 1);
-        
+
         query_info->contexts[0].eff_searchsp =
             (Int8) query_blk->length*subj_length;
         query_info->contexts[0].query_length = query_blk->length;
-        
+
         /* mark the other contexts as invalid so they are not used. */
         for (int i=1; i<=query_info->last_context; i++)
             query_info->contexts[i].is_valid = false;
-        
+
         *query_info_ptr = query_info;
     }
 
-    static void 
+    static void
     s_SetupScoringOptionsForReevaluateHSP(BlastScoringOptions* * options_ptr,
                                           bool gapped, bool is_prot)
     {
-        BlastScoringOptions* options = 
+        BlastScoringOptions* options =
             (BlastScoringOptions*) calloc(1, sizeof(BlastScoringOptions));
         if (gapped) {
            options->gapped_calculation = TRUE;
@@ -442,42 +445,42 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         *options_ptr = options;
     }
 
-    static void 
+    static void
     s_SetupHSPForUngappedReevaluateNucl(BlastHSP* * hsp_ptr)
     {
         BlastHSP* hsp;
-        
+
         if (*hsp_ptr != NULL) {
             hsp = *hsp_ptr;
         } else {
             *hsp_ptr = hsp = Blast_HSPNew();
         }
 
-        hsp->query.offset = 0; 
+        hsp->query.offset = 0;
         hsp->query.end = 20;
         hsp->subject.offset = 0;
         hsp->subject.end = 20;
         hsp->score = 20;
     }
 
-    static void 
-    s_SetupSequencesForUngappedReevaluateNucl(BLAST_SequenceBlk* * query_blk, 
+    static void
+    s_SetupSequencesForUngappedReevaluateNucl(BLAST_SequenceBlk* * query_blk,
                                             Uint1* * subject_seq_ptr)
     {
         const int kLength = 22;
         const Uint1 kQuerySeq[kLength+2] = { 15, 0, 1, 2, 3, 0, 0, 1, 1, 2, 2, 3,
                                             3, 3, 3, 0, 1, 2, 2, 1, 1, 0, 0, 15 };
-        const Uint1 kSubjectSeq[kLength] = { 0, 1, 2, 2, 14, 14, 1, 1, 2, 2, 3, 
+        const Uint1 kSubjectSeq[kLength] = { 0, 1, 2, 2, 14, 14, 1, 1, 2, 2, 3,
                                             3, 3, 3, 0, 1, 8, 2, 1, 1, 14, 0 };
 
         BlastSeqBlkNew(query_blk);
-        BlastSeqBlkSetSequence(*query_blk, 
-                               (Uint1*) BlastMemDup(kQuerySeq, kLength+2), 
+        BlastSeqBlkSetSequence(*query_blk,
+                               (Uint1*) BlastMemDup(kQuerySeq, kLength+2),
                                kLength);
         *subject_seq_ptr = (Uint1*) BlastMemDup(kSubjectSeq, kLength);;
     }
 
-    static void 
+    static void
     checkReevaluateResultsUngappedNucl(BlastHSP* hsp)
     {
         const int kScore = 11;
@@ -501,7 +504,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         const Uint4 kSubjLength = 100000;
         const Uint4 kDbLength = 100000000;
         BlastHSP* hsp = NULL;
-        BLAST_SequenceBlk* query_blk = NULL; 
+        BLAST_SequenceBlk* query_blk = NULL;
         Uint1* subject_seq = NULL;
         BlastQueryInfo* query_info = NULL;
         EBlastProgramType program_number = eBlastTypeBlastn;
@@ -518,19 +521,19 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
 
         s_SetupScoringOptionsForReevaluateHSP(&scoring_options, false, false);
         Blast_Message* blast_msg = NULL;
-        BOOST_REQUIRE_EQUAL(0, 
-            (int) BlastSetup_ScoreBlkInit(query_blk, query_info, 
-                                           scoring_options, program_number, 
+        BOOST_REQUIRE_EQUAL(0,
+            (int) BlastSetup_ScoreBlkInit(query_blk, query_info,
+                                           scoring_options, program_number,
                                            &sbp, 1.0, &blast_msg,
                                            &BlastFindMatrixPath));
 
         BOOST_REQUIRE(blast_msg == NULL);
         BlastExtensionOptions* ext_options = NULL;
-        BlastExtensionOptionsNew(program_number, &ext_options, 
+        BlastExtensionOptionsNew(program_number, &ext_options,
                                  scoring_options->gapped_calculation);
         BlastHitSavingOptionsNew(program_number, &hit_options,
                                  scoring_options->gapped_calculation);
-        hit_options->expect_value = kEvalue; 
+        hit_options->expect_value = kEvalue;
 
         BlastHitSavingParametersNew(program_number, hit_options, sbp, query_info,
                                     kDbLength, 0, &hit_params);
@@ -540,15 +543,15 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         QuerySetUpOptions* query_options = NULL;
         BlastQuerySetUpOptionsNew(&query_options);
         LookupTableWrap* lookup_wrap = NULL;
-        LookupTableOptions* lookup_options = NULL; 
+        LookupTableOptions* lookup_options = NULL;
         BlastSeqLoc* blast_seq_loc = BlastSeqLocNew(NULL, 0, query_info->contexts[0].query_length-1);
 
         LookupTableOptionsNew(program_number, &lookup_options);
-        LookupTableWrapInit(query_blk, lookup_options, query_options, blast_seq_loc, sbp, &lookup_wrap, NULL, NULL);
+        LookupTableWrapInit(query_blk, lookup_options, query_options, blast_seq_loc, sbp, &lookup_wrap, NULL, NULL, NULL);
         query_options = BlastQuerySetUpOptionsFree(query_options);
         BOOST_REQUIRE(query_options == NULL);
         BlastInitialWordOptionsNew(program_number, &word_options);
-        BlastInitialWordParametersNew(program_number, word_options, hit_params, 
+        BlastInitialWordParametersNew(program_number, word_options, hit_params,
               lookup_wrap, sbp, query_info, kSubjLength, &word_params);
 
         blast_seq_loc = BlastSeqLocFree(blast_seq_loc);
@@ -562,8 +565,8 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
 
         s_SetupHSPForUngappedReevaluateNucl(&hsp);
 
-        BOOST_REQUIRE(Blast_HSPReevaluateWithAmbiguitiesUngapped(hsp, 
-                           query_blk->sequence, subject_seq, word_params, 
+        BOOST_REQUIRE(Blast_HSPReevaluateWithAmbiguitiesUngapped(hsp,
+                           query_blk->sequence, subject_seq, word_params,
                            sbp, FALSE) == FALSE);
 
         checkReevaluateResultsUngappedNucl(hsp);
@@ -581,47 +584,47 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         BlastScoreBlkFree(sbp);
     }
 
-     static void 
+     static void
     s_SetupHSPListForUngappedReevaluateTransl(BlastHSPList* * hsplist_ptr)
     {
         BlastHSP* hsp = Blast_HSPNew();
 
-        hsp->query.offset = 0; 
+        hsp->query.offset = 0;
         hsp->query.end = 12;
         hsp->subject.offset = 0;
         hsp->subject.frame = 1;
         hsp->subject.end = 12;
         hsp->score = 45;
-        
+
         *hsplist_ptr = Blast_HSPListNew(1);
         (*hsplist_ptr)->hsp_array[0] = hsp;
         (*hsplist_ptr)->hspcnt = 1;
     }
 
 
-    static void 
-    s_SetupSequencesForUngappedReevaluateTransl(BLAST_SequenceBlk* * query_blk, 
+    static void
+    s_SetupSequencesForUngappedReevaluateTransl(BLAST_SequenceBlk* * query_blk,
                                                 BLAST_SequenceBlk* * subject_blk)
     {
         const int kLength = 12;
         const Uint1 kQuerySeq[kLength + 2] =
            { 0, 11, 19, 13, 1, 9, 22, 6, 10, 7, 12, 20, 10, 0 };
-        const Uint1 kSubjectSeq[3*kLength] = 
+        const Uint1 kSubjectSeq[3*kLength] =
            { 2, 8, 4, 4, 8, 4, 1, 1, 10, 8, 15, 2, 1, 8, 1, 8, 8, 15, 8, 8, 8,
              1, 5, 1, 4, 4, 2, 1, 1, 1, 8, 4, 4, 4, 1, 4 };
 
         BlastSeqBlkNew(query_blk);
-        BlastSeqBlkSetSequence(*query_blk, 
+        BlastSeqBlkSetSequence(*query_blk,
                                (Uint1*) BlastMemDup(kQuerySeq, kLength+2),
                                kLength);
         BlastSeqBlkNew(subject_blk);
-        BlastSeqBlkSetSequence(*subject_blk, 
-                               (Uint1*) BlastMemDup(kSubjectSeq, 3*kLength), 
+        BlastSeqBlkSetSequence(*subject_blk,
+                               (Uint1*) BlastMemDup(kSubjectSeq, 3*kLength),
                                3*kLength);
         (*subject_blk)->sequence = (*subject_blk)->sequence_start;
     }
 
-    static void 
+    static void
     checkReevaluateResultsUngappedTransl(BlastHSPList* hsp_list)
     {
         const int kScore = 38;
@@ -648,8 +651,8 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         const Uint4 kSubjLength = 50000;
         const Uint4 kDbLength = 100000000;
         BlastHSPList* hsp_list = NULL;
-        BLAST_SequenceBlk* query_blk = NULL; 
-        BLAST_SequenceBlk* subject_blk = NULL; 
+        BLAST_SequenceBlk* query_blk = NULL;
+        BLAST_SequenceBlk* subject_blk = NULL;
         BlastQueryInfo* query_info = NULL;
         EBlastProgramType program_number = eBlastTypeTblastn;
         BlastScoringOptions* scoring_options = NULL;
@@ -664,19 +667,19 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
                                           query_blk, kDbLength, &query_info);
 
         s_SetupScoringOptionsForReevaluateHSP(&scoring_options, false, true);
-        BlastScoringParameters* score_params = 
+        BlastScoringParameters* score_params =
            (BlastScoringParameters*) calloc(1, sizeof(BlastScoringParameters));
         score_params->options = scoring_options;
         Blast_Message* blast_msg = NULL;
 
-        BOOST_REQUIRE_EQUAL(0, 
-            (int) BlastSetup_ScoreBlkInit(query_blk, query_info, 
-                                           scoring_options, program_number, 
+        BOOST_REQUIRE_EQUAL(0,
+            (int) BlastSetup_ScoreBlkInit(query_blk, query_info,
+                                           scoring_options, program_number,
                                            &sbp, 1.0, &blast_msg,
                                            &BlastFindMatrixPath));
 
         BlastExtensionOptions* ext_options = NULL;
-        BlastExtensionOptionsNew(program_number, &ext_options, 
+        BlastExtensionOptionsNew(program_number, &ext_options,
                                  scoring_options->gapped_calculation);
         BlastHitSavingOptionsNew(program_number, &hit_options,
                                  scoring_options->gapped_calculation);
@@ -689,15 +692,15 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         QuerySetUpOptions* query_options = NULL;
         BlastQuerySetUpOptionsNew(&query_options);
         LookupTableWrap* lookup_wrap = NULL;
-        LookupTableOptions* lookup_options = NULL; 
+        LookupTableOptions* lookup_options = NULL;
         BlastSeqLoc* blast_seq_loc = BlastSeqLocNew(NULL, 0, query_info->contexts[0].query_length-1);
 
         LookupTableOptionsNew(program_number, &lookup_options);
-        LookupTableWrapInit(query_blk, lookup_options, query_options, blast_seq_loc, sbp, &lookup_wrap, NULL, NULL);
+        LookupTableWrapInit(query_blk, lookup_options, query_options, blast_seq_loc, sbp, &lookup_wrap, NULL, NULL, NULL);
         query_options = BlastQuerySetUpOptionsFree(query_options);
         BOOST_REQUIRE(query_options == NULL);
         BlastInitialWordOptionsNew(program_number, &word_options);
-        BlastInitialWordParametersNew(program_number, word_options, hit_params, 
+        BlastInitialWordParametersNew(program_number, word_options, hit_params,
               lookup_wrap, sbp, query_info, kSubjLength, &word_params);
 
         blast_seq_loc = BlastSeqLocFree(blast_seq_loc);
@@ -714,19 +717,19 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         Uint1* gen_code_string = (Uint1*)
            BlastMemDup(FindGeneticCode(1).get(), 64);
 
-        Blast_HSPListReevaluateUngapped(program_number, 
-                                 hsp_list, query_blk, subject_blk, 
-                                 word_params, hit_params, query_info, sbp, 
+        Blast_HSPListReevaluateUngapped(program_number,
+                                 hsp_list, query_blk, subject_blk,
+                                 word_params, hit_params, query_info, sbp,
                                  score_params, NULL, gen_code_string);
 
         checkReevaluateResultsUngappedTransl(hsp_list);
 
-        // Now check identity and length test: the percent identity for the 
+        // Now check identity and length test: the percent identity for the
         // first HSP is below 80%.
         hit_params->options->percent_identity = 80;
-        BOOST_REQUIRE(Blast_HSPTestIdentityAndLength(program_number, 
-                           hsp_list->hsp_array[0], query_blk->sequence, 
-                           subject_blk->sequence, score_params->options, 
+        BOOST_REQUIRE(Blast_HSPTestIdentityAndLength(program_number,
+                           hsp_list->hsp_array[0], query_blk->sequence,
+                           subject_blk->sequence, score_params->options,
                            hit_params->options));
 
         sfree(gen_code_string);
@@ -744,25 +747,25 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         BlastScoreBlkFree(sbp);
     }
 
-   static void 
+   static void
     s_SetupHSPForGappedReevaluateTest(BlastHSP* * hsp_ptr)
     {
         const int kNumSegs = 5;
-        const EGapAlignOpType kEditScriptOpType[kNumSegs] = 
-            { eGapAlignSub, eGapAlignDel, eGapAlignSub, eGapAlignDel, 
+        const EGapAlignOpType kEditScriptOpType[kNumSegs] =
+            { eGapAlignSub, eGapAlignDel, eGapAlignSub, eGapAlignDel,
               eGapAlignSub };
         const Int4 kEditScriptNum[kNumSegs] = { 4, 1, 11, 1, 5 };
         int index;
         GapEditScript* esp = NULL;
         BlastHSP* hsp;
-        
+
         if (*hsp_ptr != NULL) {
             hsp = *hsp_ptr;
         } else {
             *hsp_ptr = hsp = Blast_HSPNew();
         }
 
-        hsp->query.offset = 0; 
+        hsp->query.offset = 0;
         hsp->query.end = 20;
         hsp->subject.offset = 2;
         hsp->subject.end = 24;
@@ -779,29 +782,29 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         }
     }
 
-    static void 
-    s_SetupSequencesForGappedReevaluateTest(BLAST_SequenceBlk* * query_blk, 
-                                          Uint1* * subject_seq_ptr, 
+    static void
+    s_SetupSequencesForGappedReevaluateTest(BLAST_SequenceBlk* * query_blk,
+                                          Uint1* * subject_seq_ptr,
                                           Uint4* subj_length)
     {
         const int kQueryLength = 20;
         const int kSubjectLength = 25;
-        const Uint1 kQuerySeq[kQueryLength+2] = { 15, 0, 1, 2, 3, 0, 0, 1, 1, 
-                                                  2, 2, 3, 3, 3, 3, 2, 2, 1, 1, 
+        const Uint1 kQuerySeq[kQueryLength+2] = { 15, 0, 1, 2, 3, 0, 0, 1, 1,
+                                                  2, 2, 3, 3, 3, 3, 2, 2, 1, 1,
                                                   0, 0, 15 };
-        const Uint1 kSubjectSeq[kSubjectLength] = { 1, 2, 0, 1, 2, 3, 3, 2, 
-                                                    14, 1, 1, 2, 2, 3, 3, 3, 3, 
+        const Uint1 kSubjectSeq[kSubjectLength] = { 1, 2, 0, 1, 2, 3, 3, 2,
+                                                    14, 1, 1, 2, 2, 3, 3, 3, 3,
                                                     2, 0, 2, 1, 14, 0, 0, 3 };
 
         BlastSeqBlkNew(query_blk);
-        BlastSeqBlkSetSequence(*query_blk, 
-                               (Uint1*) BlastMemDup(kQuerySeq, kQueryLength+2), 
+        BlastSeqBlkSetSequence(*query_blk,
+                               (Uint1*) BlastMemDup(kQuerySeq, kQueryLength+2),
                                kQueryLength);
         *subj_length = kSubjectLength;
         *subject_seq_ptr = (Uint1*) BlastMemDup(kSubjectSeq, kSubjectLength);;
     }
 
-    static void 
+    static void
     checkReevaluateResultsGapped(BlastHSP* hsp)
     {
         const int kScore = 10;
@@ -810,7 +813,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         const int kSubjectStart = 9;
         const int kSubjectEnd = 24;
         const int kNumSegs = 3;
-        const Uint1 kEditScriptOpType[kNumSegs] = 
+        const Uint1 kEditScriptOpType[kNumSegs] =
             { eGapAlignSub, eGapAlignDel, eGapAlignSub };
         const Uint1 kEditScriptNum[kNumSegs] = { 9, 1, 5 };
 
@@ -834,7 +837,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
     BOOST_AUTO_TEST_CASE(testReevaluateWithAmbiguitiesGapped)
     {
         BlastHSP* hsp = NULL;
-        BLAST_SequenceBlk* query_blk = NULL; 
+        BLAST_SequenceBlk* query_blk = NULL;
         Uint1* subject_seq = NULL;
         BlastQueryInfo* query_info = NULL;
         BlastHitSavingOptions* hit_options = NULL;
@@ -845,35 +848,35 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         EBlastProgramType program_number = eBlastTypeBlastn;
         Uint4 subj_length = 0;
 
-        s_SetupSequencesForGappedReevaluateTest(&query_blk, &subject_seq, 
+        s_SetupSequencesForGappedReevaluateTest(&query_blk, &subject_seq,
                                               &subj_length);
         s_SetupQueryInfoForReevaluateTest(program_number,
                                           query_blk, subj_length, &query_info);
         s_SetupScoringOptionsForReevaluateHSP(&scoring_options, true, false);
 
         BlastExtensionOptions* ext_options = NULL;
-        BlastExtensionOptionsNew(program_number, &ext_options, 
+        BlastExtensionOptionsNew(program_number, &ext_options,
                                  scoring_options->gapped_calculation);
         BlastHitSavingOptionsNew(program_number, &hit_options,
                                  scoring_options->gapped_calculation);
-        hit_options->expect_value = 1; 
-        BOOST_REQUIRE_EQUAL(0, 
-            (int) BlastSetup_ScoreBlkInit(query_blk, query_info, 
-                                           scoring_options, program_number, 
+        hit_options->expect_value = 1;
+        BOOST_REQUIRE_EQUAL(0,
+            (int) BlastSetup_ScoreBlkInit(query_blk, query_info,
+                                           scoring_options, program_number,
                                            &sbp, 1.0, &blast_message,
                                            &BlastFindMatrixPath));
-        BOOST_REQUIRE_EQUAL(0, 
+        BOOST_REQUIRE_EQUAL(0,
             (int) BlastScoringParametersNew(scoring_options, sbp,
                                             &scoring_params));
 
-        BlastHitSavingParameters* hit_params = (BlastHitSavingParameters*) 
+        BlastHitSavingParameters* hit_params = (BlastHitSavingParameters*)
             calloc(1, sizeof(BlastHitSavingParameters));
 
         BOOST_REQUIRE(query_blk);
         BOOST_REQUIRE(sbp->kbp_gap[0]);
 
-        BLAST_Cutoffs(&hit_params->cutoff_score_min, 
-                      &hit_options->expect_value, 
+        BLAST_Cutoffs(&hit_params->cutoff_score_min,
+                      &hit_options->expect_value,
                       sbp->kbp_gap[0], subj_length*query_blk->length, FALSE, 0);
         hit_params->options = hit_options;
         hit_params->cutoffs = (BlastGappedCutoffs *)calloc(1,
@@ -884,35 +887,35 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         Blast_HSPReevaluateWithAmbiguitiesGapped(hsp, query_blk->sequence, query_blk->length,
             subject_seq, subj_length, hit_params, scoring_params, sbp);
 
-        // With e-value 1, the low-scoring front piece of the alignment is 
+        // With e-value 1, the low-scoring front piece of the alignment is
         // cut off.
         checkReevaluateResultsGapped(hsp);
-        
+
         hit_options->expect_value = 10;
         hit_params->cutoff_score_min = 1;
-        BLAST_Cutoffs(&hit_params->cutoff_score_min, 
-                      &hit_options->expect_value, 
+        BLAST_Cutoffs(&hit_params->cutoff_score_min,
+                      &hit_options->expect_value,
                       sbp->kbp_gap[0], subj_length*query_blk->length, FALSE, 0);
         hit_params->cutoffs[0].cutoff_score = hit_params->cutoff_score_min;
-        
+
         s_SetupHSPForGappedReevaluateTest(&hsp);
         Blast_HSPReevaluateWithAmbiguitiesGapped(hsp, query_blk->sequence, query_blk->length,
             subject_seq, subj_length, hit_params, scoring_params, sbp);
-        // With e-value 10, the front piece of the alignment is left, and the 
+        // With e-value 10, the front piece of the alignment is left, and the
         // remainder is cut off.
         checkReevaluateResultsGapped(hsp);
 
-        // Now check identity and length test: the percent identity for the 
+        // Now check identity and length test: the percent identity for the
         // First HSP identity is above 80%.
         hit_params->options->percent_identity = 80;
-        BOOST_REQUIRE_EQUAL(0, 
-            (int) Blast_HSPTestIdentityAndLength(program_number, 
+        BOOST_REQUIRE_EQUAL(0,
+            (int) Blast_HSPTestIdentityAndLength(program_number,
                       hsp, query_blk->sequence, subject_seq,
                       scoring_params->options, hit_params->options));
         // But its length is less than 20.
         hit_params->options->min_hit_length = 20;
-        BOOST_REQUIRE_EQUAL(1, 
-            (int) Blast_HSPTestIdentityAndLength(program_number, 
+        BOOST_REQUIRE_EQUAL(1,
+            (int) Blast_HSPTestIdentityAndLength(program_number,
                       hsp, query_blk->sequence, subject_seq,
                       scoring_params->options, hit_params->options));
 
@@ -935,9 +938,9 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         const int kLength = 22;
         const int kGappedStart = 1;
         const int kCutoff = 4;
-        Uint1 query[kLength] = { 2, 0, 1, 3, 2, 0, 2, 1, 2, 0, 1, 3, 3, 1, 0, 1, 
+        Uint1 query[kLength] = { 2, 0, 1, 3, 2, 0, 2, 1, 2, 0, 1, 3, 3, 1, 0, 1,
                                  3, 3, 3, 1, 0, 1 };
-        Uint1 subject[kLength] = { 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+        Uint1 subject[kLength] = { 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
                                    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 };
         BlastHSP* hsp = (BlastHSP*) calloc(1, sizeof(BlastHSP));
         hsp->query.end = hsp->subject.end = kLength;
@@ -945,7 +948,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         hsp->gap_info = GapEditScriptNew(1);
         hsp->gap_info->op_type[0] = eGapAlignSub;
         hsp->gap_info->num[0] = kLength;
-     
+
         BlastScoringOptions* score_opts = NULL;
         BlastScoringOptionsNew(kProgram, &score_opts);
         BlastScoreBlk* sbp = BlastScoreBlkNew(BLASTNA_SEQ_CODE, 1);
@@ -954,7 +957,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         BlastScoringParametersNew(score_opts, sbp, &score_params);
         BlastHitSavingOptions* hit_opts = NULL;
         BlastExtensionOptions* ext_options = NULL;
-        BlastExtensionOptionsNew(kProgram, &ext_options, 
+        BlastExtensionOptionsNew(kProgram, &ext_options,
                                  score_opts->gapped_calculation);
         BlastHitSavingOptionsNew(kProgram, &hit_opts,
                                  score_opts->gapped_calculation);
@@ -966,7 +969,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
                                                   sizeof(BlastGappedCutoffs));
         hit_params->cutoffs[0].cutoff_score = hit_params->cutoff_score_min;
 
-        Boolean delete_hsp = 
+        Boolean delete_hsp =
             Blast_HSPReevaluateWithAmbiguitiesGapped(hsp, query, kLength, subject, kLength,
                                                      hit_params, score_params,
                                                      sbp);
@@ -991,13 +994,13 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
     BOOST_AUTO_TEST_CASE(testGetOOFNumIdentities)
     {
         const char* query = "ADADADADADBADADADADADADADAADADAD";
-        const char* subject = 
+        const char* subject =
             "ABCDBCABCDBCEABCDBCABCDBCABCDBCABCDBCABCDBABCDBCABCDABCDBCABCDBCFFABCDBCABCDBCABCDBCABCDBCGBCDBC";
         const int kNumSegs = 13;
-        const EGapAlignOpType kEditScriptOp[kNumSegs] = 
-            { eGapAlignSub, eGapAlignIns1, eGapAlignSub, eGapAlignDel, 
+        const EGapAlignOpType kEditScriptOp[kNumSegs] =
+            { eGapAlignSub, eGapAlignIns1, eGapAlignSub, eGapAlignDel,
               eGapAlignSub, eGapAlignDel1, eGapAlignSub, eGapAlignDel2,
-              eGapAlignSub, eGapAlignIns2, eGapAlignSub, eGapAlignIns, 
+              eGapAlignSub, eGapAlignIns2, eGapAlignSub, eGapAlignIns,
               eGapAlignSub };
         const int kEditScriptNum[kNumSegs] = { 4, 1, 6, 1, 4, 1, 4, 1, 4, 1, 4, 1, 6 };
         const int kGoodNumIdent = 30;
@@ -1006,7 +1009,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         Int4 num_ident = 0, align_length = 0;
 
         BlastHSP* hsp = Blast_HSPNew();
-        hsp->query.offset = 0; 
+        hsp->query.offset = 0;
         hsp->query.end = 32;
         hsp->subject.offset = 0;
         hsp->subject.end = 96;
@@ -1022,7 +1025,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         BlastScoringOptionsNew(eBlastTypeTblastn, &scoring_opts);
         scoring_opts->is_ooframe = TRUE;
 
-        Blast_HSPGetNumIdentities((Uint1*)query, (Uint1*)subject, hsp, 
+        Blast_HSPGetNumIdentities((Uint1*)query, (Uint1*)subject, hsp,
                                   scoring_opts, &align_length);
         num_ident = hsp->num_ident;
         Blast_HSPFree(hsp);
@@ -1031,56 +1034,77 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         BOOST_REQUIRE_EQUAL(kGoodAlignLength, align_length);
     }
 
-   BOOST_AUTO_TEST_CASE(testHSPListSort) 
-   {
-      const int kHspCount = 10;
-      const int kScores[kHspCount] = 
-	 { 10, 20, 15, 100, 21, 40, 55, 30, 90, 40 };
-      const double kEvalues[kHspCount] = 
-	 { 1, 0.1, 0.5, 0, 0.11, 0.01, 0.001, 0.05, 0, 0.01 };
-
-      const int kScoresSorted[kHspCount] = 
-	 { 100, 90, 55, 40, 40, 30, 21, 20, 15, 10 };
-      const double kEvaluesSorted[kHspCount] = 
-	 { 0, 0, 0.001, 0.01, 0.01, 0.05, 0.1, 0.11, 0.5, 1 };
-
-      BlastHSPList* hsp_list = Blast_HSPListNew(kHspCount);
-      int index;
-
-      hsp_list->hspcnt = kHspCount;
-
-      for (index = 0; index < kHspCount; ++index) {
-	 hsp_list->hsp_array[index] = Blast_HSPNew();
-	 hsp_list->hsp_array[index]->query.offset = index;
-	 hsp_list->hsp_array[index]->query.end = index + kScores[index];
-	 hsp_list->hsp_array[index]->subject.offset = 10 - index;
-	 hsp_list->hsp_array[index]->subject.end = 
-	    10 - index + kScores[index];
-	 hsp_list->hsp_array[index]->score = kScores[index];
-	 hsp_list->hsp_array[index]->evalue = kEvalues[index];
-      }
-
-      Blast_HSPListSortByScore(hsp_list);
-      for (index = 0; index < kHspCount; ++index) {
-	 BOOST_REQUIRE_EQUAL(kScoresSorted[index], 
-			      hsp_list->hsp_array[index]->score);
-      }
-      Blast_HSPListSortByEvalue(hsp_list);
-      for (index = 0; index < kHspCount; ++index) {
-	 BOOST_REQUIRE_EQUAL(kEvaluesSorted[index], 
-			      hsp_list->hsp_array[index]->evalue);
-      }
-      /* Check that subject offset tie breaker was correctly applied
-	 between HSP's #5 and #9. */
-      BOOST_REQUIRE_EQUAL(5, hsp_list->hsp_array[4]->subject.offset); 
-
-      Blast_HSPListFree(hsp_list);
-   }
+    BOOST_AUTO_TEST_CASE(testHSPListSort)
+    {
+        /*
+         * Evalues < 1.0e-180 are considered "equal" to zero.
+         * (see blast_hits.c:s_EvalueComp)
+         */
+        const int kHspCount = 16;
+        const int kScores[kHspCount] = {
+                10, 20, 15, 100, 21, 40, 55, 30, 90, 40,
+                150, 40, 100, 200, 250,
+                45
+        };
+        const double kEvalues[kHspCount] = {
+                1, 0.1, 0.5, 0, 0.11, 0.01, 0.001, 0.05, 0, 0.01,
+                1.0e-181, 1.0e-140, 1.0e-250, 2.0e-180, 5.0e-181,
+                1.000000001e-140
+        };
+
+        const int kScoresSorted[kHspCount] = {
+                250, 200, 150, 100,
+                100, 90, 55, 45, 40, 40, 40, 30, 21, 20, 15, 10
+        };
+        const double kEvaluesSorted[kHspCount] = {
+                5.0e-181, 1.0e-181, 1.0e-250,   /* these two rows... */
+                0, 0,                           /* ... are "zeroes"  */
+                2.0e-180, 1.0e-140,
+                1.000000001e-140,
+                0.001, 0.01, 0.01, 0.05, 0.1, 0.11, 0.5, 1
+        };
+
+        BlastHSPList* hsp_list = Blast_HSPListNew(kHspCount);
+        int index;
+
+        hsp_list->hspcnt = kHspCount;
+
+        for (index = 0; index < kHspCount; ++index) {
+            hsp_list->hsp_array[index] = Blast_HSPNew();
+            hsp_list->hsp_array[index]->query.offset = index;
+            hsp_list->hsp_array[index]->query.end = index + kScores[index];
+            hsp_list->hsp_array[index]->subject.offset = kHspCount - index;
+            hsp_list->hsp_array[index]->subject.end =
+                    kHspCount - index + kScores[index];
+            hsp_list->hsp_array[index]->score = kScores[index];
+            hsp_list->hsp_array[index]->evalue = kEvalues[index];
+        }
+
+        Blast_HSPListSortByScore(hsp_list);
+        for (index = 0; index < kHspCount; ++index) {
+            BOOST_REQUIRE_EQUAL(kScoresSorted[index],
+                    hsp_list->hsp_array[index]->score);
+        }
+        Blast_HSPListSortByEvalue(hsp_list);
+        for (index = 0; index < kHspCount; ++index) {
+            BOOST_REQUIRE_EQUAL(kEvaluesSorted[index],
+                    hsp_list->hsp_array[index]->evalue);
+        }
+        /*
+         * Check that subject offset tie breaker was correctly applied
+         * between HSP's #5 and #9 in the unsorted arrays.  They should now be
+         * in array offsets 10 and 9 respectively.
+         */
+        BOOST_REQUIRE_EQUAL((kHspCount - 5), hsp_list->hsp_array[10]->subject.offset);
+        BOOST_REQUIRE_EQUAL((kHspCount - 9), hsp_list->hsp_array[9]->subject.offset);
+
+        Blast_HSPListFree(hsp_list);
+    }
 
     static void s_AddNextHSP(BlastHSPList* hsp_list, int& score)
     {
         BlastHSP* hsp = Blast_HSPNew();
-        if (score == 0) 
+        if (score == 0)
             score = 19;
         hsp->score = score = (31 * score) % 100;
         Blast_HSPListSaveHSP(hsp_list, hsp);
@@ -1093,7 +1117,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         const int kMaxScore = 99;
         int index;
         int score = 0;
-        
+
 
         BlastHSPList* hsp_list = Blast_HSPListNew(kHspNumMax);
         BOOST_REQUIRE_EQUAL(100, hsp_list->allocated);
@@ -1139,15 +1163,15 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
     BOOST_AUTO_TEST_CASE(testCheckHSPCommonEndpoints) {
         const int kHspCountStart = 9;
         const int kHspCountEnd = 3;
-        const int kScores[kHspCountStart] = 
+        const int kScores[kHspCountStart] =
             { 1044, 995, 965, 219, 160, 125, 110, 107, 103 };
-        const int kQueryOffsets[kHspCountStart] = 
+        const int kQueryOffsets[kHspCountStart] =
             { 2, 2, 2, 236, 88, 259, 278, 259, 278 };
-        const int kQueryEnds[kHspCountStart] = 
+        const int kQueryEnds[kHspCountStart] =
             { 322, 336, 300, 322, 182, 322, 341, 341, 341 };
-        const int kSubjectOffsets[kHspCountStart] = 
+        const int kSubjectOffsets[kHspCountStart] =
             { 7, 7, 7, 194, 2, 194, 197, 194, 197 };
-        const int kSubjectEnds[kHspCountStart] = 
+        const int kSubjectEnds[kHspCountStart] =
             { 292, 293, 301, 292, 96, 292, 260, 260, 266 };
         const int kSurvivingIndices[kHspCountEnd] = { 4, 0, 6 };
         EBlastProgramType program;
@@ -1158,7 +1182,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
             BlastHSP* hsp;
             Blast_HSPInit(kQueryOffsets[index], kQueryEnds[index],
                   kSubjectOffsets[index], kSubjectEnds[index],
-                  0, 0, 
+                  0, 0,
                   0, 0, 0,
                   kScores[index], NULL, &hsp);
             Blast_HSPListSaveHSP(hsp_list, hsp);
@@ -1167,31 +1191,31 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
 
         // Check first that if program is set to PHI BLAST, nothing will be done.
         program = eBlastTypePhiBlastp;
-        BOOST_REQUIRE_EQUAL(kHspCountStart, 
-                             Blast_HSPListPurgeHSPsWithCommonEndpoints(program, 
+        BOOST_REQUIRE_EQUAL(kHspCountStart,
+                             Blast_HSPListPurgeHSPsWithCommonEndpoints(program,
                                                                        hsp_list, FALSE));
 
         // Now check that for a non-PHI program the routine works properly.
         program = eBlastTypeBlastp;
-        BOOST_REQUIRE_EQUAL(kHspCountEnd, 
-                             Blast_HSPListPurgeHSPsWithCommonEndpoints(program, 
+        BOOST_REQUIRE_EQUAL(kHspCountEnd,
+                             Blast_HSPListPurgeHSPsWithCommonEndpoints(program,
                                                                        hsp_list, FALSE));
 
         BlastHSP** hsp_array = hsp_list->hsp_array;
         for (int index = 0; index < kHspCountEnd; ++index) {
             int index_orig = kSurvivingIndices[index];
             BOOST_REQUIRE_EQUAL(kScores[index_orig], hsp_array[index]->score);
-            BOOST_REQUIRE_EQUAL(kQueryOffsets[index_orig], 
+            BOOST_REQUIRE_EQUAL(kQueryOffsets[index_orig],
                                  hsp_array[index]->query.offset);
-            BOOST_REQUIRE_EQUAL(kSubjectOffsets[index_orig], 
+            BOOST_REQUIRE_EQUAL(kSubjectOffsets[index_orig],
                                  hsp_array[index]->subject.offset);
-            BOOST_REQUIRE_EQUAL(kQueryEnds[index_orig], 
+            BOOST_REQUIRE_EQUAL(kQueryEnds[index_orig],
                                  hsp_array[index]->query.end);
-            BOOST_REQUIRE_EQUAL(kSubjectEnds[index_orig], 
+            BOOST_REQUIRE_EQUAL(kSubjectEnds[index_orig],
                                  hsp_array[index]->subject.end);
             sfree(hsp_array[index]);
         }
-        
+
         hsp_list = Blast_HSPListFree(hsp_list);
         BOOST_REQUIRE(hsp_list == NULL);
    }
@@ -1204,7 +1228,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         BlastScoringOptionsNew(kProgram, &scoring_options);
 
         BlastExtensionOptions* ext_options = NULL;
-        BlastExtensionOptionsNew(kProgram, &ext_options, 
+        BlastExtensionOptionsNew(kProgram, &ext_options,
                                  scoring_options->gapped_calculation);
 
         BlastHitSavingOptions* hit_options = NULL;
@@ -1220,7 +1244,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         ext_options = BlastExtensionOptionsFree(ext_options);
         BOOST_REQUIRE(ext_options == NULL);
 
-        BOOST_REQUIRE_EQUAL(blasthit_params->prelim_hitlist_size, 
+        BOOST_REQUIRE_EQUAL(blasthit_params->prelim_hitlist_size,
              hit_options->hitlist_size+50);
 
         ext_options = BlastExtensionOptionsFree(ext_options);
@@ -1240,7 +1264,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         scoring_options->gapped_calculation = FALSE;
 
         BlastExtensionOptions* ext_options = NULL;
-        BlastExtensionOptionsNew(kProgram, &ext_options, 
+        BlastExtensionOptionsNew(kProgram, &ext_options,
                                  scoring_options->gapped_calculation);
 
         BlastHitSavingOptions* hit_options = NULL;
@@ -1248,7 +1272,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
                                  scoring_options->gapped_calculation);
 
         SBlastHitsParameters* blasthit_params=NULL;
-        SBlastHitsParametersNew(hit_options, ext_options, scoring_options, 
+        SBlastHitsParametersNew(hit_options, ext_options, scoring_options,
                                 &blasthit_params);
 
         scoring_options = BlastScoringOptionsFree(scoring_options);
@@ -1256,7 +1280,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         ext_options = BlastExtensionOptionsFree(ext_options);
         BOOST_REQUIRE(ext_options == NULL);
 
-        BOOST_REQUIRE_EQUAL(blasthit_params->prelim_hitlist_size, 
+        BOOST_REQUIRE_EQUAL(blasthit_params->prelim_hitlist_size,
              hit_options->hitlist_size);
 
         ext_options = BlastExtensionOptionsFree(ext_options);
@@ -1275,7 +1299,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         BlastScoringOptionsNew(kProgram, &scoring_options);
 
         BlastExtensionOptions* ext_options = NULL;
-        BlastExtensionOptionsNew(kProgram, &ext_options, 
+        BlastExtensionOptionsNew(kProgram, &ext_options,
                                  scoring_options->gapped_calculation);
 
         BlastHitSavingOptions* hit_options = NULL;
@@ -1294,7 +1318,7 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
         ext_options = BlastExtensionOptionsFree(ext_options);
         BOOST_REQUIRE(ext_options == NULL);
 
-        BOOST_REQUIRE_EQUAL(blasthit_params->prelim_hitlist_size, 
+        BOOST_REQUIRE_EQUAL(blasthit_params->prelim_hitlist_size,
              (2*hit_options->hitlist_size)+50);
 
         ext_options = BlastExtensionOptionsFree(ext_options);
@@ -1308,14 +1332,14 @@ BOOST_AUTO_TEST_CASE(BlastTargetSequence)
     BOOST_AUTO_TEST_CASE(testAdjustOddBlastnScores) {
         const int kHspCnt = 10;
         const bool kGapped = TRUE;
-        
+
 
         BlastHSPList* hsp_list = Blast_HSPListNew(kHspCnt);
         BlastScoreBlk sb;
         // sb.kbp_gap = (Blast_KarlinBlk**) calloc(1, sizeof(Blast_KarlinBlk*));
         // sb.kbp_gap[0] = (Blast_KarlinBlk*) calloc(1, sizeof(Blast_KarlinBlk));
         sb.round_down = true;
-        
+
         // Check that NULL input or hsp_list with no HSPs do not cause trouble.
         Blast_HSPListAdjustOddBlastnScores(NULL, kGapped, &sb);
         Blast_HSPListAdjustOddBlastnScores(hsp_list, kGapped, &sb);
diff --git a/c++/src/algo/blast/unit_tests/api/blastoptions_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/blastoptions_unit_test.cpp
index d002cb0..c0ca089 100644
--- a/c++/src/algo/blast/unit_tests/api/blastoptions_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/blastoptions_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastoptions_unit_test.cpp 462040 2015-03-16 13:14:29Z vasilche $
+/*  $Id: blastoptions_unit_test.cpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -306,7 +306,7 @@ s_GetInitialWordParameters(EBlastProgramType program_number,
 
    LookupTableOptionsNew(program_number, &lookup_options);
    LookupTableWrapInit(query_blk, lookup_options, query_options, blast_seq_loc,
-                       sbp, &lookup_wrap, NULL, NULL);
+                       sbp, &lookup_wrap, NULL, NULL, NULL);
    BlastInitialWordParametersNew(program_number, word_options, hit_params,
       lookup_wrap, sbp, query_info, subject_length, &word_params);
 
@@ -1321,7 +1321,6 @@ BOOST_AUTO_TEST_CASE( testInitialWordParamNewSomeInvalidKbp )
 
 BOOST_AUTO_TEST_CASE( testRemoteFilterString)
 {
-       typedef ncbi::objects::CBlast4_parameters TBlast4Opts;
        CBlastOptions opts(CBlastOptions::eRemote);
 
        opts.SetProgram(eBlastn);
diff --git a/c++/src/algo/blast/unit_tests/api/blastsetup_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/blastsetup_unit_test.cpp
index ed72206..c25e5c5 100644
--- a/c++/src/algo/blast/unit_tests/api/blastsetup_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/blastsetup_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastsetup_unit_test.cpp 500367 2016-05-04 12:06:01Z ivanov $
+/*  $Id: blastsetup_unit_test.cpp 512603 2016-09-01 16:55:07Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -741,12 +741,12 @@ BOOST_AUTO_TEST_CASE(GetSequenceProteinWithSelenocysteine) {
     // Check that there are no warning
     BOOST_REQUIRE(warnings.empty());
 
-    // Check that the sequence has its selenocysteine residues replaced by
-    // C's (positions 10 and 15, without counting sentinels);
+    // Check that the sequence has its selenocysteine residues unchanged
+    // U's (positions 10 and 15, without counting sentinels);
     const TSeqPos kReplacedPositions[] = { 10+1, 15+1 };
-    const Uint1 kCresidue = AMINOACID_TO_NCBISTDAA[(int)'C'];
+    const Uint1 kUresidue = AMINOACID_TO_NCBISTDAA[(int)'U'];
     for (TSeqPos i = 0; i < DIM(kReplacedPositions); i++) {
-        BOOST_REQUIRE_EQUAL((int)kCresidue, 
+        BOOST_REQUIRE_EQUAL((int)kUresidue, 
                                 (int)seq.data.get()[kReplacedPositions[i]]);
     }
 
@@ -834,8 +834,8 @@ BOOST_AUTO_TEST_CASE(testCalcEffLengths)
     const EProgram kProgram[kNumPrograms] = 
         { eBlastn, eBlastp, eBlastx, eTblastn, eTblastx, eRPSBlast, 
         eRPSTblastn };
-    const TGi kNuclGi = GI_FROM(TIntId, 555);
-    const TGi kProtGi = GI_FROM(TIntId, 129295);
+    const TGi kNuclGi = GI_CONST(555);
+    const TGi kProtGi = GI_CONST(129295);
     // Use values for database length and number of sequences that 
     // approximate the real ones for nt.00 and nr as of 12/17/2004.
     const Int8 kNuclDbLength = (Int8) 39855e+5;
diff --git a/c++/src/algo/blast/unit_tests/api/data/magicblast_paired.asn b/c++/src/algo/blast/unit_tests/api/data/magicblast_paired.asn
new file mode 100644
index 0000000..8465cd9
--- /dev/null
+++ b/c++/src/algo/blast/unit_tests/api/data/magicblast_paired.asn
@@ -0,0 +1,50 @@
+Bioseq-set ::= {
+  seq-set {
+    seq {
+      id {
+        local str "SRR2833414.2.1"
+      },
+      descr {
+        title "lcl|SRR2833414.2.1",
+        user {
+          type str "Mapping",
+          data {
+            {
+              label str "has_pair",
+              data int 1
+            }
+          }
+        }
+      },
+      inst {
+        repr raw,
+        mol na,
+        length 75,
+        seq-data iupacna "NACGGAATTCAGCAACGGATCTCTTGGCTCTCGCATCGATGAAGAACGCAGCGAAATGCGATACGTAATGTGAAT"
+      }
+    },
+    seq {
+      id {
+        local str "SRR2833414.2.2"
+      },
+      descr {
+        title "lcl|SRR2833414.2.2",
+        user {
+          type str "Mapping",
+          data {
+            {
+              label str "has_pair",
+              data int 2
+            }
+          }
+        }
+      },
+      inst {
+        repr raw,
+        mol na,
+        length 75,
+        seq-data iupacna "NATGACACTCAAACAGGCATGCCTTTGGTAGAACCCAAAGGCGCAATGTGCGTTCAAAGATTCGATGATTCACGG"
+      }
+    }
+  }
+}
diff --git a/c++/src/algo/blast/unit_tests/api/data/magicblast_queries.asn b/c++/src/algo/blast/unit_tests/api/data/magicblast_queries.asn
new file mode 100644
index 0000000..7f4de89
--- /dev/null
+++ b/c++/src/algo/blast/unit_tests/api/data/magicblast_queries.asn
@@ -0,0 +1,74 @@
+Bioseq-set ::= {
+  seq-set {
+    seq {
+      id {
+        local str "SRR1561624.14400126"
+      },
+      descr {
+        title "lcl|SRR1561624.14400126"
+      },
+      inst {
+        repr raw,
+        mol na,
+        length 49,
+        seq-data iupacna "CAAAGTTCTCGGACGTACTGGATCTCGTGGTGGTGTTACTCAAGTCCGT"
+      }
+    },
+    seq {
+      id {
+        local str "SRR1561624.14400656"
+      },
+      descr {
+        title "lcl|SRR1561624.14400656"
+      },
+      inst {
+        repr raw,
+        mol na,
+        length 49,
+        seq-data iupacna "CTTATACTGAAATATGGGATCTACTTCTTGAAACAAACACAAAATACTG"
+      }
+    },
+    seq {
+      id {
+        local str "SRR1561624.14401073"
+      },
+      descr {
+        title "lcl|SRR1561624.14401073"
+      },
+      inst {
+        repr raw,
+        mol na,
+        length 49,
+        seq-data iupacna "CAACATGTCTCTGGTTGTTCCCGACAATTTCCAACACATTCTCCGTCTC"
+      }
+    },
+    seq {
+      id {
+        local str "SRR1561624.14401077"
+      },
+      descr {
+        title "lcl|SRR1561624.14401077"
+      },
+      inst {
+        repr raw,
+        mol na,
+        length 49,
+        seq-data iupacna "GGTTGTTCCCGACAATTTCCAACACATTCTCCGTCTCCTCAACACCAAC"
+      }
+    },
+    seq {
+      id {
+        local str "SRR1561624.14401721"
+      },
+      descr {
+        title "lcl|SRR1561624.14401721"
+      },
+      inst {
+        repr raw,
+        mol na,
+        length 49,
+        seq-data iupacna "GTTCTGGTTCTAAATTGTCTAAGATTAAGACTACCCGCAAGGACATTGC"
+      }
+    }
+  }
+}
diff --git a/c++/src/algo/blast/unit_tests/api/data/pombe.nhr b/c++/src/algo/blast/unit_tests/api/data/pombe.nhr
new file mode 100644
index 0000000..28bd577
Binary files /dev/null and b/c++/src/algo/blast/unit_tests/api/data/pombe.nhr differ
diff --git a/c++/src/algo/blast/unit_tests/api/data/pombe.nin b/c++/src/algo/blast/unit_tests/api/data/pombe.nin
new file mode 100644
index 0000000..d2cbbcc
Binary files /dev/null and b/c++/src/algo/blast/unit_tests/api/data/pombe.nin differ
diff --git a/c++/src/algo/blast/unit_tests/api/data/pombe.nog b/c++/src/algo/blast/unit_tests/api/data/pombe.nog
new file mode 100644
index 0000000..e4342d3
Binary files /dev/null and b/c++/src/algo/blast/unit_tests/api/data/pombe.nog differ
diff --git a/c++/src/algo/blast/unit_tests/api/data/pombe.nsd b/c++/src/algo/blast/unit_tests/api/data/pombe.nsd
new file mode 100644
index 0000000..3b8485b
--- /dev/null
+++ b/c++/src/algo/blast/unit_tests/api/data/pombe.nsd
@@ -0,0 +1,2 @@
+nc_0034210
+nc_003421.20
diff --git a/c++/src/algo/blast/unit_tests/api/data/pombe.nsi b/c++/src/algo/blast/unit_tests/api/data/pombe.nsi
new file mode 100644
index 0000000..1e9e1c4
Binary files /dev/null and b/c++/src/algo/blast/unit_tests/api/data/pombe.nsi differ
diff --git a/c++/src/algo/blast/unit_tests/api/data/pombe.nsq b/c++/src/algo/blast/unit_tests/api/data/pombe.nsq
new file mode 100644
index 0000000..aaba660
Binary files /dev/null and b/c++/src/algo/blast/unit_tests/api/data/pombe.nsq differ
diff --git a/c++/src/algo/blast/unit_tests/api/delta_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/delta_unit_test.cpp
index 3490642..967c245 100644
--- a/c++/src/algo/blast/unit_tests/api/delta_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/delta_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: delta_unit_test.cpp 498724 2016-04-19 13:36:57Z ivanov $
+/*  $Id: delta_unit_test.cpp 507726 2016-07-21 14:42:04Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -284,7 +284,7 @@ BOOST_AUTO_TEST_CASE(TestSingleQuery_CBS)
     BOOST_REQUIRE(pssm->HasQuery());
     BOOST_REQUIRE(pssm->GetQuery().GetSeq().IsSetInst());
     BOOST_REQUIRE_EQUAL(pssm->GetQuery().GetSeq().GetFirstId()->GetGi(),
-                        GI_FROM(TIntId, 129295));
+                        GI_CONST(129295));
 
     // check alignments from sequence search results
 
@@ -292,7 +292,7 @@ BOOST_AUTO_TEST_CASE(TestSingleQuery_CBS)
 
     BOOST_REQUIRE_EQUAL(
                 results[0].GetSeqAlign()->Get().front()->GetSeq_id(0).GetGi(),
-                GI_FROM(TIntId, 129295));
+                GI_CONST(129295));
 
     const int kNumExpectedMatchingSeqs = 8;
     CConstRef<CSeq_align_set> sas = results[0].GetSeqAlign();
@@ -545,7 +545,7 @@ BOOST_AUTO_TEST_CASE(TestSingleQuery_NoCBS)
     BOOST_REQUIRE(pssm->HasQuery());
     BOOST_REQUIRE(pssm->GetQuery().GetSeq().IsSetInst());
     BOOST_REQUIRE_EQUAL(pssm->GetQuery().GetSeq().GetFirstId()->GetGi(),
-                        GI_FROM(TIntId, 129295));
+                        GI_CONST(129295));
 
     // check alignments from sequence search results
 
@@ -553,7 +553,7 @@ BOOST_AUTO_TEST_CASE(TestSingleQuery_NoCBS)
 
     BOOST_REQUIRE_EQUAL(
                 results[0].GetSeqAlign()->Get().front()->GetSeq_id(0).GetGi(),
-                GI_FROM(TIntId, 129295));
+                GI_CONST(129295));
 
     const int kNumExpectedMatchingSeqs = 5;
     CConstRef<CSeq_align_set> sas = results[0].GetSeqAlign();
@@ -683,7 +683,7 @@ BOOST_AUTO_TEST_CASE(TestMultipleQueries)
     // verify query id in Seq_aligns
     BOOST_REQUIRE_EQUAL(
                  results[0].GetSeqAlign()->Get().front()->GetSeq_id(0).GetGi(),
-                 GI_FROM(TIntId, 129295));
+                 GI_CONST(129295));
 
     BOOST_REQUIRE_EQUAL(
      results[1].GetSeqAlign()->Get().front()->GetSeq_id(0).GetPir().GetName(),
@@ -693,7 +693,7 @@ BOOST_AUTO_TEST_CASE(TestMultipleQueries)
     // verify query id in PSSMs
     BOOST_REQUIRE_EQUAL(
            deltablast.GetPssm(0)->GetQuery().GetSeq().GetFirstId()->GetGi(),
-           GI_FROM(TIntId, 129295));
+           GI_CONST(129295));
     
     BOOST_REQUIRE_EQUAL(
      deltablast.GetPssm(1)->GetQuery().GetSeq().GetFirstId()->GetPir().GetName(),
diff --git a/c++/src/algo/blast/unit_tests/api/hspfilter_besthit_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/hspfilter_besthit_unit_test.cpp
index 921361d..2a842a1 100644
--- a/c++/src/algo/blast/unit_tests/api/hspfilter_besthit_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/hspfilter_besthit_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: hspfilter_besthit_unit_test.cpp 462040 2015-03-16 13:14:29Z vasilche $
+/*  $Id: hspfilter_besthit_unit_test.cpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(HSPBestHitWriter)
     BOOST_REQUIRE(writer_info);
     BOOST_REQUIRE(writer_info->NewFnPtr);
     BOOST_REQUIRE(writer_info->params);
-    BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, &query_info);
+    BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, &query_info, NULL);
     BOOST_REQUIRE(writer_info == NULL);
     BOOST_REQUIRE(writer);
     // Following call also frees best_hit_params
diff --git a/c++/src/algo/blast/unit_tests/api/hspfilter_culling_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/hspfilter_culling_unit_test.cpp
index 36e2903..28bae86 100644
--- a/c++/src/algo/blast/unit_tests/api/hspfilter_culling_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/hspfilter_culling_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: hspfilter_culling_unit_test.cpp 462040 2015-03-16 13:14:29Z vasilche $
+/*  $Id: hspfilter_culling_unit_test.cpp 504861 2016-06-20 15:45:40Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(HSPCullingWriter)
     BOOST_REQUIRE(writer_info);
     BOOST_REQUIRE(writer_info->NewFnPtr);
     BOOST_REQUIRE(writer_info->params);
-    BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, &query_info);
+    BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, &query_info, NULL);
     BOOST_REQUIRE(writer_info == NULL);
     BOOST_REQUIRE(writer);
     // Following call also frees culling_params
diff --git a/c++/src/algo/blast/unit_tests/api/hspstream_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/hspstream_unit_test.cpp
index a98b852..0b6d80a 100644
--- a/c++/src/algo/blast/unit_tests/api/hspstream_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/hspstream_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: hspstream_unit_test.cpp 462040 2015-03-16 13:14:29Z vasilche $
+/*  $Id: hspstream_unit_test.cpp 504861 2016-06-20 15:45:40Z boratyng $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -84,7 +84,7 @@ void testHSPStream(EHSPStreamType stream_type) {
 
     BlastHSPWriterInfo * writer_info = BlastHSPCollectorInfoNew(col_params);
 
-	BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL);
+	BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL, NULL);
     BOOST_REQUIRE(writer_info == NULL);
 
     BlastHSPStream* hsp_stream = BlastHSPStreamNew(kProgram, ext_options, TRUE,
@@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(testMultiSeqHSPCollector) {
         hit_options, ext_options->compositionBasedStats,
         scoring_options->gapped_calculation));
 
-	BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL);
+	BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL, NULL);
     BOOST_REQUIRE(writer_info == NULL);
 
     BlastHSPStream* hsp_stream = BlastHSPStreamNew(
diff --git a/c++/src/algo/blast/unit_tests/api/linkhsp_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/linkhsp_unit_test.cpp
index b321ea2..017c55d 100644
--- a/c++/src/algo/blast/unit_tests/api/linkhsp_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/linkhsp_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: linkhsp_unit_test.cpp 462040 2015-03-16 13:14:29Z vasilche $
+/*  $Id: linkhsp_unit_test.cpp 504861 2016-06-20 15:45:40Z boratyng $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -477,7 +477,7 @@ struct LinkHspTestFixture {
         LookupTableOptions* lookup_options = NULL;
         BlastSeqLoc* blast_seq_loc = BlastSeqLocNew(NULL, 0, m_QueryInfo->contexts[0].query_length-1);
         LookupTableOptionsNew(m_ProgramType, &lookup_options);
-        LookupTableWrapInit(query_blk, lookup_options, query_options, blast_seq_loc, m_ScoreBlk, &lookup_wrap, NULL, NULL);
+        LookupTableWrapInit(query_blk, lookup_options, query_options, blast_seq_loc, m_ScoreBlk, &lookup_wrap, NULL, NULL, NULL);
         query_options = BlastQuerySetUpOptionsFree(query_options);
         BOOST_REQUIRE(query_options == NULL);
 
diff --git a/c++/src/algo/blast/unit_tests/api/magicblast_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/magicblast_unit_test.cpp
new file mode 100644
index 0000000..9896430
--- /dev/null
+++ b/c++/src/algo/blast/unit_tests/api/magicblast_unit_test.cpp
@@ -0,0 +1,447 @@
+/*  $Id: magicblast_unit_test.cpp 517506 2016-10-25 17:22:36Z ivanov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  Greg Boratyn
+ *
+ * Test module for Magic-BLAST API
+ */
+
+#include <ncbi_pch.hpp>
+#include <corelib/test_boost.hpp>
+
+// Serial library includes
+#include <serial/serial.hpp>
+#include <serial/objistr.hpp>
+
+// Object includes
+#include <objects/seqalign/Seq_align.hpp>
+#include <objects/seqalign/Seq_align_set.hpp>
+#include <objects/seqalign/Spliced_seg.hpp>
+#include <objects/seqalign/Spliced_exon.hpp>
+#include <objects/seqalign/Splice_site.hpp>
+#include <objects/seqalign/Product_pos.hpp>
+
+#include <objects/seqset/Bioseq_set.hpp>
+#include <objects/seqset/Seq_entry.hpp>
+#include <objects/seq/Bioseq.hpp>
+#include <objects/seq/Seq_descr.hpp>
+
+#include <objects/general/User_object.hpp>
+
+// BLAST includes
+#include <algo/blast/api/magicblast.hpp>
+#include <algo/blast/api/objmgrfree_query_data.hpp>
+#include <algo/blast/api/magicblast_options.hpp>
+#include <algo/blast/api/local_db_adapter.hpp>
+
+using namespace std;
+using namespace ncbi;
+using namespace ncbi::objects;
+using namespace ncbi::blast;
+
+struct CMagicBlastTestFixture {
+
+    CRef<CMagicBlastOptionsHandle> m_OptHandle;
+    CRef<CSearchDatabase> m_Db;
+
+    /// Contains a single Bioseq
+    CRef<CBioseq_set> m_Queries;
+
+
+    CMagicBlastTestFixture() {
+        m_OptHandle.Reset(new CMagicBlastOptionsHandle);
+        m_Db.Reset(new CSearchDatabase("data/pombe",
+                                       CSearchDatabase::eBlastDbIsNucleotide));
+
+        m_Queries.Reset(new CBioseq_set);
+    }
+
+
+    ~CMagicBlastTestFixture() {
+        m_OptHandle.Reset();
+        m_Db.Reset();
+        m_Queries.Reset();
+    }
+};
+
+
+BOOST_FIXTURE_TEST_SUITE(magicblast, CMagicBlastTestFixture)
+
+
+struct SExon
+{
+    unsigned int prod_start;
+    unsigned int prod_end;
+    unsigned int gen_start;
+    unsigned int gen_end;
+
+    ENa_strand prod_strand;
+    ENa_strand gen_strand;
+    string acceptor;
+    string donor;
+};
+
+struct SMatch
+{
+    int score;
+    unsigned int prod_length;
+    vector<SExon> exons;
+};
+
+
+BOOST_AUTO_TEST_CASE(MappingNoPairs)
+{
+    ifstream istr("data/magicblast_queries.asn");
+    BOOST_REQUIRE(istr);
+    istr >> MSerial_AsnText >> *m_Queries;
+
+    CRef<IQueryFactory> query_factory(new CObjMgrFree_QueryFactory(m_Queries));
+    CRef<CLocalDbAdapter> db_adapter(new CLocalDbAdapter(*m_Db));
+    CMagicBlast magicblast(query_factory, db_adapter, m_OptHandle);
+    CRef<CSeq_align_set> results = magicblast.Run();
+
+    const size_t kExpectedNumResults = 5;
+    BOOST_REQUIRE_EQUAL(results->Get().size(), kExpectedNumResults);
+
+    SExon exon;
+    vector<SMatch> expected_hits(kExpectedNumResults);
+
+    // expected HSPs
+
+    int results_idx = 0;
+    // HSP #1
+    expected_hits[results_idx].score = 49;
+    expected_hits[results_idx].prod_length = 49;
+
+    exon.prod_start = 0;
+    exon.prod_end = 21;
+    exon.gen_start = 1827220;
+    exon.gen_end = 1827241;
+    exon.prod_strand = eNa_strand_minus;
+    exon.gen_strand = eNa_strand_plus;
+    exon.acceptor = "";
+    exon.donor = "CT";
+    expected_hits[results_idx].exons.push_back(exon);
+
+    exon.prod_start = 22;
+    exon.prod_end = 48;
+    exon.gen_start = 1827292;
+    exon.gen_end = 1827318;
+    exon.prod_strand = eNa_strand_minus;
+    exon.gen_strand = eNa_strand_plus;
+    exon.acceptor = "AC";
+    exon.donor = "";
+    expected_hits[results_idx].exons.push_back(exon);
+
+    // HSP #2
+    results_idx++;
+    expected_hits[results_idx].score = 49;
+    expected_hits[results_idx].prod_length = 49;
+
+    exon.prod_start = 0;
+    exon.prod_end = 28;
+    exon.gen_start = 181290;
+    exon.gen_end = 181318;
+    exon.prod_strand = eNa_strand_minus;
+    exon.gen_strand = eNa_strand_plus;
+    exon.acceptor = "";
+    exon.donor = "CT";
+    expected_hits[results_idx].exons.push_back(exon);
+
+    exon.prod_start = 29;
+    exon.prod_end = 48;
+    exon.gen_start = 181367;
+    exon.gen_end = 181386;
+    exon.prod_strand = eNa_strand_minus;
+    exon.gen_strand = eNa_strand_plus;
+    exon.acceptor = "AC";
+    exon.donor = "";
+    expected_hits[results_idx].exons.push_back(exon);
+
+    // HSP #3
+    results_idx++;
+    expected_hits[results_idx].score = 49;
+    expected_hits[results_idx].prod_length = 49;
+
+    exon.prod_start = 0;
+    exon.prod_end = 20;
+    exon.gen_start = 1033352;
+    exon.gen_end = 1033372;
+    exon.prod_strand = eNa_strand_minus;
+    exon.gen_strand = eNa_strand_plus;
+    exon.acceptor = "";
+    exon.donor = "CT";
+    expected_hits[results_idx].exons.push_back(exon);
+
+    exon.prod_start = 21;
+    exon.prod_end = 48;
+    exon.gen_start = 1033432;
+    exon.gen_end = 1033459;
+    exon.prod_strand = eNa_strand_minus;
+    exon.gen_strand = eNa_strand_plus;
+    exon.acceptor = "AC";
+    exon.donor = "";
+    expected_hits[results_idx].exons.push_back(exon);
+
+    // HSP #4
+    results_idx++;
+    expected_hits[results_idx].score = 33;
+    expected_hits[results_idx].prod_length = 49;
+
+    exon.prod_start = 0;
+    exon.prod_end = 32;
+    exon.gen_start = 1033340;
+    exon.gen_end = 1033372;
+    exon.prod_strand = eNa_strand_minus;
+    exon.gen_strand = eNa_strand_plus;
+    exon.acceptor = "";
+    exon.donor = "CT";
+    expected_hits[results_idx].exons.push_back(exon);
+
+    // HSP #5
+    results_idx++;
+    expected_hits[results_idx].score = 49;
+    expected_hits[results_idx].prod_length = 49;
+
+    exon.prod_start = 0;
+    exon.prod_end = 23;
+    exon.gen_start = 89112;
+    exon.gen_end = 89135;
+    exon.prod_strand = eNa_strand_minus;
+    exon.gen_strand = eNa_strand_plus;
+    exon.acceptor = "";
+    exon.donor = "CT";
+    expected_hits[results_idx].exons.push_back(exon);
+
+    exon.prod_start = 24;
+    exon.prod_end = 48;
+    exon.gen_start = 89420;
+    exon.gen_end = 89444;
+    exon.prod_strand = eNa_strand_minus;
+    exon.gen_strand = eNa_strand_plus;
+    exon.acceptor = "AC";
+    exon.donor = "";
+    expected_hits[results_idx].exons.push_back(exon);
+
+    // compare computed HSPs with the expected ones
+    results_idx = 0;
+    for (auto it: results->Get()) {
+
+        // we do not expect paired results
+        BOOST_REQUIRE(it->GetSegs().IsSpliced());
+
+        int score;
+        it->GetNamedScore("score", score);
+        BOOST_REQUIRE_EQUAL(score, expected_hits[results_idx].score);
+
+        const CSpliced_seg& seg = it->GetSegs().GetSpliced();
+        BOOST_REQUIRE_EQUAL(seg.GetProduct_length(),
+                            expected_hits[results_idx].prod_length);
+
+        BOOST_REQUIRE_EQUAL(seg.GetExons().size(),
+                            expected_hits[results_idx].exons.size());
+
+        // compare exon data
+        auto expected_exon = expected_hits[results_idx].exons.begin();
+        for (auto exon: seg.GetExons()) {
+
+            // exon starts and stops
+            BOOST_REQUIRE_EQUAL(exon->GetProduct_start().GetNucpos(),
+                                expected_exon->prod_start);
+
+            BOOST_REQUIRE_EQUAL(exon->GetProduct_end().GetNucpos(),
+                                expected_exon->prod_end);
+
+            BOOST_REQUIRE_EQUAL(exon->GetGenomic_start(),
+                                expected_exon->gen_start);
+
+            BOOST_REQUIRE_EQUAL(exon->GetGenomic_end(),
+                                expected_exon->gen_end);
+
+            // strands
+            BOOST_REQUIRE_EQUAL(exon->GetProduct_strand(),
+                                expected_exon->prod_strand);
+
+            BOOST_REQUIRE_EQUAL(exon->GetGenomic_strand(),
+                                expected_exon->gen_strand);
+
+            // splice signals
+            if (!expected_exon->acceptor.empty()) {
+                BOOST_REQUIRE(exon->CanGetAcceptor_before_exon());
+                BOOST_REQUIRE_EQUAL(exon->GetAcceptor_before_exon().GetBases(),
+                                    expected_exon->acceptor);
+            }
+
+            if (!expected_exon->donor.empty()) {
+                BOOST_REQUIRE(exon->CanGetDonor_after_exon());
+                BOOST_REQUIRE_EQUAL(exon->GetDonor_after_exon().GetBases(),
+                                    expected_exon->donor);
+            }
+
+            ++expected_exon;
+        }
+        results_idx++;
+    }
+}
+
+
+BOOST_AUTO_TEST_CASE(MappingPaired)
+{
+    ifstream istr("data/magicblast_paired.asn");
+    BOOST_REQUIRE(istr);
+    istr >> MSerial_AsnText >> *m_Queries;
+
+    bool queries_paired = false;
+    auto q = m_Queries->GetSeq_set().begin();
+    BOOST_REQUIRE(q != m_Queries->GetSeq_set().end());
+    const CBioseq& bioseq = (*q)->GetSeq();
+    BOOST_REQUIRE(bioseq.CanGetDescr());
+    for (auto it: bioseq.GetDescr().Get()) {
+        if (it->IsUser()) {
+            const CUser_object& obj = it->GetUser();
+            if (obj.GetType().IsStr() && obj.GetType().GetStr() == "Mapping") {
+                queries_paired = obj.HasField("has_pair");
+            }
+        }
+    }
+    BOOST_REQUIRE(queries_paired);
+
+    CRef<IQueryFactory> query_factory(new CObjMgrFree_QueryFactory(m_Queries));
+    CRef<CLocalDbAdapter> db_adapter(new CLocalDbAdapter(*m_Db));
+
+    m_OptHandle->SetPaired(true);
+    CMagicBlast magicblast(query_factory, db_adapter, m_OptHandle);
+    CRef<CSeq_align_set> results = magicblast.Run();
+
+    const size_t kExpectedNumResults = 1;
+    BOOST_REQUIRE_EQUAL(results->Get().size(), kExpectedNumResults);
+
+    SExon exon;
+    vector<SMatch> expected_hits(2 * kExpectedNumResults);
+
+    // expected HSPs
+
+    int results_idx = 0;
+    // HSP #1
+    expected_hits[results_idx].score = 68;
+    expected_hits[results_idx].prod_length = 75;
+
+    exon.prod_start = 7;
+    exon.prod_end = 74;
+    exon.gen_start = 2443260;
+    exon.gen_end = 2443327;
+    exon.prod_strand = eNa_strand_plus;
+    exon.gen_strand = eNa_strand_plus;
+    exon.acceptor = "CT";
+    exon.donor = "";
+    expected_hits[results_idx].exons.push_back(exon);
+
+    // HSP #2
+    results_idx++;
+    expected_hits[results_idx].score = 71;
+    expected_hits[results_idx].prod_length = 75;
+
+    exon.prod_start = 0;
+    exon.prod_end = 70;
+    exon.gen_start = 2443337;
+    exon.gen_end = 2443407;
+    exon.prod_strand = eNa_strand_minus;
+    exon.gen_strand = eNa_strand_plus;
+    exon.acceptor = "";
+    exon.donor = "CA";
+    expected_hits[results_idx].exons.push_back(exon);
+
+    // compare computed HSPs with the expected ones
+    results_idx = 0;
+    for (auto seg: results->Get()) {
+
+        // we do not expect paired results
+        BOOST_REQUIRE(seg->GetSegs().IsDisc());
+        BOOST_REQUIRE_EQUAL(seg->GetSegs().GetDisc().Get().size(), 2u);
+
+        for (auto it: seg->GetSegs().GetDisc().Get()) {
+
+            BOOST_REQUIRE(it->GetSegs().IsSpliced());
+
+            int score;
+            it->GetNamedScore("score", score);
+            BOOST_REQUIRE_EQUAL(score, expected_hits[results_idx].score);
+
+
+            const CSpliced_seg& seg = it->GetSegs().GetSpliced();
+            BOOST_REQUIRE_EQUAL(seg.GetProduct_length(),
+                                expected_hits[results_idx].prod_length);
+
+            BOOST_REQUIRE_EQUAL(seg.GetExons().size(),
+                                expected_hits[results_idx].exons.size());
+
+            // compare exon data
+            auto expected_exon = expected_hits[results_idx].exons.begin();
+            for (auto exon: seg.GetExons()) {
+
+                // exon starts and stops
+                BOOST_REQUIRE_EQUAL(exon->GetProduct_start().GetNucpos(),
+                                    expected_exon->prod_start);
+
+                BOOST_REQUIRE_EQUAL(exon->GetProduct_end().GetNucpos(),
+                                    expected_exon->prod_end);
+
+                BOOST_REQUIRE_EQUAL(exon->GetGenomic_start(),
+                                    expected_exon->gen_start);
+
+                BOOST_REQUIRE_EQUAL(exon->GetGenomic_end(),
+                                    expected_exon->gen_end);
+
+                // strands
+                BOOST_REQUIRE_EQUAL(exon->GetProduct_strand(),
+                                expected_exon->prod_strand);
+
+                BOOST_REQUIRE_EQUAL(exon->GetGenomic_strand(),
+                                    expected_exon->gen_strand);
+
+                // splice signals
+                if (!expected_exon->acceptor.empty()) {
+                    BOOST_REQUIRE(exon->CanGetAcceptor_before_exon());
+                    BOOST_REQUIRE_EQUAL(
+                                 exon->GetAcceptor_before_exon().GetBases(),
+                                 expected_exon->acceptor);
+                }
+
+                if (!expected_exon->donor.empty()) {
+                    BOOST_REQUIRE(exon->CanGetDonor_after_exon());
+                    BOOST_REQUIRE_EQUAL(exon->GetDonor_after_exon().GetBases(),
+                                        expected_exon->donor);
+                }
+
+                ++expected_exon;
+            }
+            results_idx++;
+        }
+    }
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/c++/src/algo/blast/unit_tests/api/magicblast_unit_test.ini b/c++/src/algo/blast/unit_tests/api/magicblast_unit_test.ini
new file mode 100644
index 0000000..7bd19f9
--- /dev/null
+++ b/c++/src/algo/blast/unit_tests/api/magicblast_unit_test.ini
@@ -0,0 +1,3 @@
+; $Id: magicblast_unit_test.ini 517501 2016-10-25 17:21:06Z ivanov $
+[UNITTESTS_DISABLE]
+GLOBAL = OS_Solaris | PLATFORM_Bits32
diff --git a/c++/src/algo/blast/unit_tests/api/ntlookup_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/ntlookup_unit_test.cpp
index f98033d..fc4ea03 100644
--- a/c++/src/algo/blast/unit_tests/api/ntlookup_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/ntlookup_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ntlookup_unit_test.cpp 462040 2015-03-16 13:14:29Z vasilche $
+/*  $Id: ntlookup_unit_test.cpp 506102 2016-07-01 15:48:06Z boratyng $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -55,6 +55,7 @@
 #include <algo/blast/api/blastx_options.hpp>
 #include <algo/blast/api/tblastn_options.hpp>
 #include <algo/blast/api/blast_nucl_options.hpp>
+#include <algo/blast/api/uniform_search.hpp>
 #include <algo/blast/api/disc_nucl_options.hpp>
 #include <algo/blast/core/blast_nalookup.h>
 #include <algo/blast/core/lookup_util.h>
@@ -187,7 +188,7 @@ BOOST_AUTO_TEST_CASE(testStdLookupTable) {
 	LookupTableWrap* lookup_wrap_ptr;
  	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
                              lookup_options, query_options, lookup_segments, 
-                             0, &lookup_wrap_ptr, NULL, NULL), 0);
+                             0, &lookup_wrap_ptr, NULL, NULL, NULL), 0);
     query_options = BlastQuerySetUpOptionsFree(query_options);
     BOOST_REQUIRE(query_options == NULL);
     BOOST_REQUIRE_EQUAL(eSmallNaLookupTable,
@@ -221,8 +222,8 @@ BOOST_AUTO_TEST_CASE(testMegablastLookupTable)
     BlastQuerySetUpOptionsNew(&query_options);
 	LookupTableWrap* lookup_wrap_ptr;
  	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
-                                       lookup_options, query_options, lookup_segments, 
-                                       0, &lookup_wrap_ptr, NULL, NULL), 0);
+                               lookup_options, query_options, lookup_segments, 
+                               0, &lookup_wrap_ptr, NULL, NULL, NULL), 0);
         query_options = BlastQuerySetUpOptionsFree(query_options);
         BOOST_REQUIRE(query_options == NULL);
 	BOOST_REQUIRE_EQUAL((ELookupTableType)lookup_wrap_ptr->lut_type, 
@@ -265,8 +266,8 @@ BOOST_AUTO_TEST_CASE(testDiscontiguousMBLookupTableCodingWordSize11) {
     BlastQuerySetUpOptionsNew(&query_options);
 	LookupTableWrap* lookup_wrap_ptr;
  	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
-                                          lookup_options, query_options, lookup_segments, 
-                                          0, &lookup_wrap_ptr, NULL, NULL), 0);
+                               lookup_options, query_options, lookup_segments, 
+                               0, &lookup_wrap_ptr, NULL, NULL, NULL), 0);
         query_options = BlastQuerySetUpOptionsFree(query_options);
         BOOST_REQUIRE(query_options == NULL);
 	BOOST_REQUIRE_EQUAL(eMBLookupTable, (ELookupTableType)lookup_wrap_ptr->lut_type);
@@ -311,8 +312,8 @@ BOOST_AUTO_TEST_CASE(testDiscontiguousMBLookupTableCodingWordSize12) {
     BlastQuerySetUpOptionsNew(&query_options);
 	LookupTableWrap* lookup_wrap_ptr;
  	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
-                                        lookup_options, query_options, lookup_segments, 
-                                        0, &lookup_wrap_ptr, NULL, NULL), 0);
+                              lookup_options, query_options, lookup_segments, 
+                               0, &lookup_wrap_ptr, NULL, NULL, NULL), 0);
     query_options = BlastQuerySetUpOptionsFree(query_options);
     BOOST_REQUIRE(query_options == NULL);
 	BOOST_REQUIRE_EQUAL(eMBLookupTable, (ELookupTableType)lookup_wrap_ptr->lut_type);
@@ -357,8 +358,8 @@ BOOST_AUTO_TEST_CASE(testDiscontiguousMBLookupTableOptimalWordSize11) {
     BlastQuerySetUpOptionsNew(&query_options);
 	LookupTableWrap* lookup_wrap_ptr;
  	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
-                                           lookup_options, query_options, lookup_segments, 
-                                           0, &lookup_wrap_ptr, NULL, NULL), 0);
+                              lookup_options, query_options, lookup_segments, 
+                              0, &lookup_wrap_ptr, NULL, NULL, NULL), 0);
     query_options = BlastQuerySetUpOptionsFree(query_options);
     BOOST_REQUIRE(query_options == NULL);
 	BOOST_REQUIRE_EQUAL(eMBLookupTable, (ELookupTableType)lookup_wrap_ptr->lut_type);
@@ -403,8 +404,8 @@ BOOST_AUTO_TEST_CASE(testDiscontiguousMBLookupTableOptimalWordSize12) {
     BlastQuerySetUpOptionsNew(&query_options);
 	LookupTableWrap* lookup_wrap_ptr;
  	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
-                                            lookup_options, query_options, lookup_segments, 
-                                            0, &lookup_wrap_ptr, NULL, NULL), 0);
+                              lookup_options, query_options, lookup_segments, 
+                              0, &lookup_wrap_ptr, NULL, NULL, NULL), 0);
     query_options = BlastQuerySetUpOptionsFree(query_options);
     BOOST_REQUIRE(query_options == NULL);
 	BOOST_REQUIRE_EQUAL(eMBLookupTable, (ELookupTableType)lookup_wrap_ptr->lut_type);
@@ -449,8 +450,8 @@ BOOST_AUTO_TEST_CASE(testDiscontiguousMBLookupTableTwoTemplatesWordSize11) {
     BlastQuerySetUpOptionsNew(&query_options);
 	LookupTableWrap* lookup_wrap_ptr;
  	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
-                                         lookup_options, query_options, lookup_segments, 
-                                         0, &lookup_wrap_ptr, NULL, NULL), 0);
+                             lookup_options, query_options, lookup_segments, 
+                             0, &lookup_wrap_ptr, NULL, NULL, NULL), 0);
     query_options = BlastQuerySetUpOptionsFree(query_options);
     BOOST_REQUIRE(query_options == NULL);
 	BOOST_REQUIRE_EQUAL(eMBLookupTable, (ELookupTableType)lookup_wrap_ptr->lut_type);
@@ -486,6 +487,160 @@ BOOST_AUTO_TEST_CASE(testDiscontiguousMBLookupTableTwoTemplatesWordSize11) {
 }
 
 
+BOOST_AUTO_TEST_CASE(testHashLookupTableWordSize16) {
+
+    SetUpQuery(LARGE_QUERY_GI);
+	LookupTableOptions* lookup_options;
+	LookupTableOptionsNew(eBlastTypeMapping, &lookup_options);
+	BLAST_FillLookupTableOptions(lookup_options, eBlastTypeMapping,
+                                 FALSE, 0, 0);
+
+    QuerySetUpOptions* query_options = NULL;
+    BlastQuerySetUpOptionsNew(&query_options);
+	LookupTableWrap* lookup_wrap_ptr;
+ 	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
+                             lookup_options, query_options, lookup_segments, 
+                             0, &lookup_wrap_ptr, NULL, NULL, NULL), 0);
+    query_options = BlastQuerySetUpOptionsFree(query_options);
+    BOOST_REQUIRE(query_options == NULL);
+	BOOST_REQUIRE_EQUAL(eNaHashLookupTable,
+                        (ELookupTableType)lookup_wrap_ptr->lut_type);
+
+	BlastNaHashLookupTable* lookup =
+        (BlastNaHashLookupTable*)lookup_wrap_ptr->lut;
+	BOOST_REQUIRE_EQUAL(16, (int)lookup->lut_word_length); 
+	BOOST_REQUIRE_EQUAL(1, lookup->scan_step);
+	BOOST_REQUIRE_EQUAL(10, lookup->longest_chain);
+    BOOST_REQUIRE_EQUAL(16777216, lookup->backbone_size);
+    BOOST_REQUIRE_EQUAL(24, lookup->offsets_size);
+    BOOST_REQUIRE_EQUAL(11, lookup->pv_array_bts);
+	BOOST_REQUIRE_EQUAL(11, lookup->pv_array_bts);
+    BOOST_REQUIRE(lookup->hash_callback);
+
+    Uint4 pv_array_size = 1u << (32 - 10);
+	int pv_array_hash =
+            EndianIndependentBufferHash((char*) lookup->pv,
+                                        pv_array_size * sizeof(PV_ARRAY_TYPE),
+                                        sizeof(PV_ARRAY_TYPE));
+	BOOST_REQUIRE_EQUAL(-1839333193, pv_array_hash);
+
+    TNaLookupHashFunction hash_func =
+        (TNaLookupHashFunction)lookup->hash_callback;
+
+    // locate the first sequence word in the lookup table
+    // get the word in BLASTNA
+    Uint4 word = 0;
+    for (int i=0;i < 16;i++) {
+        BOOST_REQUIRE((query_blk->sequence[i] & 0xfc) == 0);
+        word = (word << 2) | query_blk->sequence[i];
+    }
+    // hash the word
+    Uint4 hashed_word = hash_func((Uint1*)&word, lookup->mask);
+    // the word must be present in the lookup table ...
+    BOOST_REQUIRE(lookup->thick_backbone[hashed_word].num_words > 0);
+    BOOST_REQUIRE_EQUAL(word, lookup->thick_backbone[hashed_word].words[0]);
+    BOOST_REQUIRE(lookup->thick_backbone[hashed_word].num_offsets[0] <
+                  NA_OFFSETS_PER_HASH);
+    // ... at position zero
+    BOOST_REQUIRE_EQUAL(0, lookup->thick_backbone[hashed_word].offsets[0]);
+
+	lookup_wrap_ptr = LookupTableWrapFree(lookup_wrap_ptr);
+        BOOST_REQUIRE(lookup_wrap_ptr == NULL);
+	lookup_options = LookupTableOptionsFree(lookup_options);
+        BOOST_REQUIRE(lookup_options == NULL);
+}
+
+
+BOOST_AUTO_TEST_CASE(testHashLookupTableWordSize16WithDbFilter) {
+
+    SetUpQuery(LARGE_QUERY_GI);
+	LookupTableOptions* lookup_options;
+	LookupTableOptionsNew(eBlastTypeMapping, &lookup_options);
+	BLAST_FillLookupTableOptions(lookup_options, eBlastTypeMapping,
+                                 FALSE, 0, 0);
+    lookup_options->db_filter = TRUE;
+
+    CSearchDatabase db("data/pombe", CSearchDatabase::eBlastDbIsNucleotide);
+    CLocalDbAdapter db_adapter(db);
+    BlastSeqSrc* seqsrc = db_adapter.MakeSeqSrc();
+    BOOST_REQUIRE(seqsrc);
+
+    QuerySetUpOptions* query_options = NULL;
+    BlastQuerySetUpOptionsNew(&query_options);
+
+    BOOST_REQUIRE(lookup_options->db_filter);
+	LookupTableWrap* lookup_wrap_ptr;
+    BOOST_REQUIRE(lookup_options->db_filter);
+ 	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
+                             lookup_options, query_options, lookup_segments, 
+                             0, &lookup_wrap_ptr, NULL, NULL, seqsrc), 0);
+    query_options = BlastQuerySetUpOptionsFree(query_options);
+    BOOST_REQUIRE(query_options == NULL);
+	BOOST_REQUIRE_EQUAL(eNaHashLookupTable,
+                        (ELookupTableType)lookup_wrap_ptr->lut_type);
+
+	BlastNaHashLookupTable* lookup =
+        (BlastNaHashLookupTable*)lookup_wrap_ptr->lut;
+	BOOST_REQUIRE_EQUAL(16, (int)lookup->lut_word_length); 
+	BOOST_REQUIRE_EQUAL(1, lookup->scan_step);
+	BOOST_REQUIRE_EQUAL(10, lookup->longest_chain);
+    BOOST_REQUIRE_EQUAL(16777216, lookup->backbone_size);
+    BOOST_REQUIRE_EQUAL(12, lookup->offsets_size);
+    BOOST_REQUIRE_EQUAL(11, lookup->pv_array_bts);
+	BOOST_REQUIRE_EQUAL(11, lookup->pv_array_bts);
+    BOOST_REQUIRE(lookup->hash_callback);
+
+    Uint4 pv_array_size = 1u << (32 - 10);
+	int pv_array_hash =
+            EndianIndependentBufferHash((char*) lookup->pv,
+                                        pv_array_size * sizeof(PV_ARRAY_TYPE),
+                                        sizeof(PV_ARRAY_TYPE));
+	BOOST_REQUIRE_EQUAL(2116636124, pv_array_hash);
+
+
+    TNaLookupHashFunction hash_func =
+        (TNaLookupHashFunction)lookup->hash_callback;
+
+    // locate the first sequence word in the lookup table
+    Uint4 word = 0;
+    for (int i=0;i < 16;i++) {
+        BOOST_REQUIRE((query_blk->sequence[i] & 0xfc) == 0);
+        word = (word << 2) | query_blk->sequence[i];
+    }
+    Uint4 hashed_word = hash_func((Uint1*)&word, lookup->mask);
+    // the word was filtered out and is not in the lookup table
+    BOOST_REQUIRE(lookup->thick_backbone[hashed_word].num_words == 0);
+
+	lookup_wrap_ptr = LookupTableWrapFree(lookup_wrap_ptr);
+        BOOST_REQUIRE(lookup_wrap_ptr == NULL);
+	lookup_options = LookupTableOptionsFree(lookup_options);
+        BOOST_REQUIRE(lookup_options == NULL);
+}
+
+
+BOOST_AUTO_TEST_CASE(testHashLookupTableMissingSeqSrc) {
+
+    SetUpQuery(LARGE_QUERY_GI);
+	LookupTableOptions* lookup_options;
+	LookupTableOptionsNew(eBlastTypeMapping, &lookup_options);
+	BLAST_FillLookupTableOptions(lookup_options, eBlastTypeMapping,
+                                 FALSE, 0, 0);
+    lookup_options->db_filter = TRUE;
+
+    QuerySetUpOptions* query_options = NULL;
+    BlastQuerySetUpOptionsNew(&query_options);
+
+    BOOST_REQUIRE(lookup_options->db_filter);
+	LookupTableWrap* lookup_wrap_ptr;
+    BOOST_REQUIRE(lookup_options->db_filter);
+ 	BOOST_REQUIRE((int)LookupTableWrapInit(query_blk, 
+                             lookup_options, query_options, lookup_segments, 
+                             0, &lookup_wrap_ptr, NULL, NULL, NULL) !=  0);
+
+	lookup_options = LookupTableOptionsFree(lookup_options);
+        BOOST_REQUIRE(lookup_options == NULL);
+}
+
 BOOST_AUTO_TEST_CASE(testStdLookupTableDebruijn) {
 
 	const int alphabet_size=4;	// in alphabet there are A,C,G,T
@@ -502,8 +657,8 @@ BOOST_AUTO_TEST_CASE(testStdLookupTableDebruijn) {
     BlastQuerySetUpOptionsNew(&query_options);
 	LookupTableWrap* lookup_wrap_ptr;
  	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
-                                            lookup_options, query_options, lookup_segments, 
-                                            0, &lookup_wrap_ptr, NULL, NULL), 0);
+                             lookup_options, query_options, lookup_segments, 
+                             0, &lookup_wrap_ptr, NULL, NULL, NULL), 0);
     query_options = BlastQuerySetUpOptionsFree(query_options);
     BOOST_REQUIRE(query_options == NULL);
 	BOOST_REQUIRE_EQUAL(eNaLookupTable, (ELookupTableType)lookup_wrap_ptr->lut_type);
@@ -548,8 +703,8 @@ BOOST_AUTO_TEST_CASE(testMegablastLookupTableDebruijn) {
     BlastQuerySetUpOptionsNew(&query_options);
 	LookupTableWrap* lookup_wrap_ptr;
  	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
-                                           lookup_options, query_options, lookup_segments, 
-                                           0, &lookup_wrap_ptr, NULL, NULL), 0);
+                              lookup_options, query_options, lookup_segments, 
+                              0, &lookup_wrap_ptr, NULL, NULL, NULL), 0);
     query_options = BlastQuerySetUpOptionsFree(query_options);
     BOOST_REQUIRE(query_options == NULL);
 	BOOST_REQUIRE_EQUAL(eMBLookupTable, (ELookupTableType)lookup_wrap_ptr->lut_type);
@@ -598,8 +753,8 @@ BOOST_AUTO_TEST_CASE(testStdTableSmallUnmaskedRegion) {
     BlastQuerySetUpOptionsNew(&query_options);
 	LookupTableWrap* lookup_wrap_ptr;
  	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
-                                              lookup_options, query_options, segments, 
-                                              0, &lookup_wrap_ptr, NULL, NULL), 0);
+                                 lookup_options, query_options, segments, 
+                                 0, &lookup_wrap_ptr, NULL, NULL, NULL), 0);
     query_options = BlastQuerySetUpOptionsFree(query_options);
     BOOST_REQUIRE(query_options == NULL);
 	BOOST_REQUIRE_EQUAL(eSmallNaLookupTable, 
@@ -652,8 +807,8 @@ BOOST_AUTO_TEST_CASE(testMegablastTableSmallUnmaskedRegion) {
     BlastQuerySetUpOptionsNew(&query_options);
 	LookupTableWrap* lookup_wrap_ptr;
  	BOOST_REQUIRE_EQUAL((int)LookupTableWrapInit(query_blk, 
-                                            lookup_options, query_options, segments, 0, 
-                                            &lookup_wrap_ptr, NULL, NULL), 0);
+                                  lookup_options, query_options, segments, 0, 
+                                  &lookup_wrap_ptr, NULL, NULL, NULL), 0);
     query_options = BlastQuerySetUpOptionsFree(query_options);
     BOOST_REQUIRE(query_options == NULL);
 	BOOST_REQUIRE_EQUAL((ELookupTableType)lookup_wrap_ptr->lut_type, eMBLookupTable);
diff --git a/c++/src/algo/blast/unit_tests/api/ntlookup_unit_test.ini b/c++/src/algo/blast/unit_tests/api/ntlookup_unit_test.ini
index 80f54cf..dab8e62 100644
--- a/c++/src/algo/blast/unit_tests/api/ntlookup_unit_test.ini
+++ b/c++/src/algo/blast/unit_tests/api/ntlookup_unit_test.ini
@@ -1,3 +1,5 @@
-; $Id: ntlookup_unit_test.ini 454210 2014-12-11 18:20:43Z camacho $
+; $Id: ntlookup_unit_test.ini 507273 2016-07-18 13:56:27Z boratyng $
 [UNITTESTS_DISABLE]
 GLOBAL = OS_Solaris
+testHashLookupTableWordSize16 = PLATFORM_Bits32
+testHashLookupTableWordSize16WithDbFilter = PLATFORM_Bits32
diff --git a/c++/src/algo/blast/unit_tests/api/ntscan_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/ntscan_unit_test.cpp
index 4c183d4..8451a8f 100644
--- a/c++/src/algo/blast/unit_tests/api/ntscan_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/ntscan_unit_test.cpp
@@ -1,4 +1,4 @@
-/* $Id: ntscan_unit_test.cpp 462040 2015-03-16 13:14:29Z vasilche $
+/* $Id: ntscan_unit_test.cpp 504861 2016-06-20 15:45:40Z boratyng $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -289,6 +289,7 @@ struct TestFixture {
                             sbp,
                             &lookup_wrap_ptr,
                             NULL /* RPS Info */,
+                            NULL,
                             NULL);
         BOOST_REQUIRE_EQUAL(0, status);
         BlastChooseNaExtend(lookup_wrap_ptr);
diff --git a/c++/src/algo/blast/unit_tests/api/phiblast_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/phiblast_unit_test.cpp
index f9bb4d9..c9fcb76 100644
--- a/c++/src/algo/blast/unit_tests/api/phiblast_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/phiblast_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: phiblast_unit_test.cpp 462040 2015-03-16 13:14:29Z vasilche $
+/*  $Id: phiblast_unit_test.cpp 504861 2016-06-20 15:45:40Z boratyng $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -121,7 +121,7 @@ public:
         lookup_options->phi_pattern = strdup(pattern.c_str());
         // Lookup segments and rps info arguments are irrelevant and passed as 
         // NULL.
-        LookupTableWrapInit(NULL, lookup_options, NULL, NULL, m_ScoreBlk, &m_Lookup, NULL, NULL);
+        LookupTableWrapInit(NULL, lookup_options, NULL, NULL, m_ScoreBlk, &m_Lookup, NULL, NULL, NULL);
     }
 
     ~CPhiblastTestFixture() {
diff --git a/c++/src/algo/blast/unit_tests/api/psiblast_iteration_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/psiblast_iteration_unit_test.cpp
index d684086..948ec40 100644
--- a/c++/src/algo/blast/unit_tests/api/psiblast_iteration_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/psiblast_iteration_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: psiblast_iteration_unit_test.cpp 401131 2013-05-28 18:34:25Z grichenk $
+/*  $Id: psiblast_iteration_unit_test.cpp 507726 2016-07-21 14:42:04Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(TestAsLoopCounter) {
             itr.Advance(ids);
         }
 
-        BOOST_REQUIRE_EQUAL(gi, GI_FROM(unsigned int, kNumIterations));
+        BOOST_REQUIRE_EQUAL(gi, GI_CONST(kNumIterations));
         BOOST_REQUIRE_EQUAL(kNumIterations+1, itr.GetIterationNumber());
         BOOST_REQUIRE_EQUAL(false, itr.HasMoreIterations());
         BOOST_REQUIRE_EQUAL(false, itr.HasConverged());
@@ -70,8 +70,8 @@ BOOST_AUTO_TEST_CASE(TestConvergence) {
         BOOST_REQUIRE_EQUAL(false, itr.HasConverged());
         BOOST_REQUIRE_EQUAL(1U, itr.GetIterationNumber());
         CPsiBlastIterationState::TSeqIds ids, ids_plus_1;
-        ids.insert(CSeq_id_Handle::GetHandle(GI_FROM(TIntId, 555)));
-        ids_plus_1.insert(CSeq_id_Handle::GetHandle(GI_FROM(TIntId, 556)));
+        ids.insert(CSeq_id_Handle::GetHandle(GI_CONST(555)));
+        ids_plus_1.insert(CSeq_id_Handle::GetHandle(GI_CONST(556)));
 
         itr.Advance(ids);
         BOOST_REQUIRE_EQUAL(false, itr.HasConverged());
@@ -97,9 +97,9 @@ BOOST_AUTO_TEST_CASE(TestConvergence2) {
         BOOST_REQUIRE_EQUAL(false, itr.HasConverged());
         BOOST_REQUIRE_EQUAL(1U, itr.GetIterationNumber());
         CPsiBlastIterationState::TSeqIds ids_itr1, ids_itr2;
-        ids_itr1.insert(CSeq_id_Handle::GetHandle(GI_FROM(TIntId, 555)));
-        ids_itr1.insert(CSeq_id_Handle::GetHandle(GI_FROM(TIntId, 556)));
-        ids_itr2.insert(CSeq_id_Handle::GetHandle(GI_FROM(TIntId, 555)));
+        ids_itr1.insert(CSeq_id_Handle::GetHandle(GI_CONST(555)));
+        ids_itr1.insert(CSeq_id_Handle::GetHandle(GI_CONST(556)));
+        ids_itr2.insert(CSeq_id_Handle::GetHandle(GI_CONST(555)));
 
         itr.Advance(ids_itr1);
         BOOST_REQUIRE_EQUAL(false, itr.HasConverged());
@@ -117,8 +117,8 @@ BOOST_AUTO_TEST_CASE(TestModifyingConvergedIterationState) {
         BOOST_REQUIRE_EQUAL(false, itr.HasConverged());
 
         CPsiBlastIterationState::TSeqIds ids;
-        ids.insert(CSeq_id_Handle::GetHandle(GI_FROM(TIntId, 555)));
-        ids.insert(CSeq_id_Handle::GetHandle(GI_FROM(TIntId, 555)));
+        ids.insert(CSeq_id_Handle::GetHandle(GI_CONST(555)));
+        ids.insert(CSeq_id_Handle::GetHandle(GI_CONST(555)));
         itr.Advance(ids);
         BOOST_REQUIRE_EQUAL(false, itr.HasConverged());
 
diff --git a/c++/src/algo/blast/unit_tests/api/psiblast_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/psiblast_unit_test.cpp
index 867c747..3dfcb76 100644
--- a/c++/src/algo/blast/unit_tests/api/psiblast_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/psiblast_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: psiblast_unit_test.cpp 498724 2016-04-19 13:36:57Z ivanov $
+/*  $Id: psiblast_unit_test.cpp 498248 2016-04-14 15:42:26Z boratyng $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/unit_tests/api/querydata_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/querydata_unit_test.cpp
index f82207e..22149fd 100644
--- a/c++/src/algo/blast/unit_tests/api/querydata_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/querydata_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: querydata_unit_test.cpp 401131 2013-05-28 18:34:25Z grichenk $
+/*  $Id: querydata_unit_test.cpp 507726 2016-07-21 14:42:04Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -567,9 +567,9 @@ BOOST_FIXTURE_TEST_SUITE(QueryData, CQueryDataTestFixture)
 
 BOOST_AUTO_TEST_CASE(ObjMgr_QueryFactory_LocalData_GetSumOfSequenceLengths) {
     vector<TGi> gis;
-    gis.push_back(GI_FROM(TIntId, 26));
-    gis.push_back(GI_FROM(TIntId, 555));
-    gis.push_back(GI_FROM(TIntId, 556));
+    gis.push_back(GI_CONST(26));
+    gis.push_back(GI_CONST(555));
+    gis.push_back(GI_CONST(556));
     CRef<CBioseq_set> bs(new CBioseq_set);
     ITERATE(vector<TGi>, itr, gis) {
         CBioseq_Handle bh = CSimpleOM::GetBioseqHandle(*itr);
@@ -599,31 +599,31 @@ BOOST_AUTO_TEST_CASE(ObjMgr_QueryFactory_LocalData_GetSumOfSequenceLengths) {
 
 BOOST_AUTO_TEST_CASE(ObjMgr_QueryFactory_LocalDataFromTSeqLocVector_Protein) {
     vector<TGi> gis;
-    gis.push_back(GI_FROM(TIntId, 38092615));
-    gis.push_back(GI_FROM(TIntId, 4506509));
+    gis.push_back(GI_CONST(38092615));
+    gis.push_back(GI_CONST(4506509));
     s_ObjMgr_QueryFactory_LocalDataFromTSeqLocVector(gis);
 }
 
 BOOST_AUTO_TEST_CASE(ObjMgr_QueryFactory_LocalDataFromTSeqLocVector_Nucleotide) {
     vector<TGi> gis;
-    gis.push_back(GI_FROM(TIntId, 555));
-    gis.push_back(GI_FROM(TIntId, 556));
-    gis.push_back(GI_FROM(TIntId, 26));
+    gis.push_back(GI_CONST(555));
+    gis.push_back(GI_CONST(556));
+    gis.push_back(GI_CONST(26));
     s_ObjMgr_QueryFactory_LocalDataFromTSeqLocVector(gis);
 }
 
 BOOST_AUTO_TEST_CASE(ObjMgr_QueryFactory_LocalDataFromBlastQueryVector_Protein) {
     vector<TGi> gis;
-    gis.push_back(GI_FROM(TIntId, 38092615));
-    gis.push_back(GI_FROM(TIntId, 4506509));
+    gis.push_back(GI_CONST(38092615));
+    gis.push_back(GI_CONST(4506509));
     s_ObjMgr_QueryFactory_LocalDataFromBlastQueryVector(gis);
 }
 
 BOOST_AUTO_TEST_CASE(ObjMgr_QueryFactory_LocalDataFromBlastQueryVector_Nucleotide) {
     vector<TGi> gis;
-    gis.push_back(GI_FROM(TIntId, 555));
-    gis.push_back(GI_FROM(TIntId, 556));
-    gis.push_back(GI_FROM(TIntId, 26));
+    gis.push_back(GI_CONST(555));
+    gis.push_back(GI_CONST(556));
+    gis.push_back(GI_CONST(26));
     s_ObjMgr_QueryFactory_LocalDataFromBlastQueryVector(gis);
 }
 
@@ -634,7 +634,7 @@ BOOST_AUTO_TEST_CASE(ObjMgr_QueryFactory_RemoteData_SingleBioseqFromTSeqLocVecto
     auto_ptr<SSeqLoc> sl(CTestObjMgr::Instance().CreateSSeqLoc(qid));
     queries.push_back(*sl);
     CRef<IQueryFactory> query_factory(new CObjMgr_QueryFactory(queries));
-    CSequenceDataTester(query_factory, GI_FROM(int, kGi))();
+    CSequenceDataTester(query_factory, GI_CONST(kGi))();
 }
 
 BOOST_AUTO_TEST_CASE(ObjMgr_QueryFactory_RemoteData_SingleBioseqFromBlastQueryVector) {
@@ -649,7 +649,7 @@ BOOST_AUTO_TEST_CASE(ObjMgr_QueryFactory_RemoteData_SingleBioseqFromBlastQueryVe
     queries->AddQuery(sq);
     
     CRef<IQueryFactory> query_factory(new CObjMgr_QueryFactory(*queries));
-    CSequenceDataTester(query_factory, GI_FROM(TIntId, kGi))();
+    CSequenceDataTester(query_factory, GI_CONST(kGi))();
 }
 
 BOOST_AUTO_TEST_CASE(ObjMgr_QueryFactory_EmptyTSeqLocVector) {
@@ -665,28 +665,28 @@ BOOST_AUTO_TEST_CASE(ObjMgr_QueryFactory_EmptyBlastQueryVector) {
 //
 
 BOOST_AUTO_TEST_CASE(ObjMgrFree_QueryFactory_LocalDataFromBioseq_Protein) {
-    const TGi kGi = GI_FROM(TIntId, 129295);
+    const TGi kGi = GI_CONST(129295);
     s_ObjMgrFree_QueryFactory_LocalDataFromBioseq(kGi);
 }
 
 BOOST_AUTO_TEST_CASE(ObjMgrFree_QueryFactory_LocalDataFromBioseq_Nucleotide) {
-    const TGi kGi = GI_FROM(TIntId, 555);
+    const TGi kGi = GI_CONST(555);
     s_ObjMgrFree_QueryFactory_LocalDataFromBioseq(kGi);
 }
 
 BOOST_AUTO_TEST_CASE(ObjMgrFree_QueryFactory_LocalDataFromBioseq_set_Protein) {
     vector<TGi> gis;
-    gis.push_back(GI_FROM(TIntId, 129295));
-    gis.push_back(GI_FROM(TIntId, 87));
-    gis.push_back(GI_FROM(TIntId, 1900));
+    gis.push_back(GI_CONST(129295));
+    gis.push_back(GI_CONST(87));
+    gis.push_back(GI_CONST(1900));
     s_ObjMgrFree_QueryFactory_LocalDataFromBioseq_set(gis);
 }
 
 BOOST_AUTO_TEST_CASE(ObjMgrFree_QueryFactory_LocalDataFromBioseq_set_Nucleotide) {
     vector<TGi> gis;
-    gis.push_back(GI_FROM(TIntId, 26));
-    gis.push_back(GI_FROM(TIntId, 555));
-    gis.push_back(GI_FROM(TIntId, 556));
+    gis.push_back(GI_CONST(26));
+    gis.push_back(GI_CONST(555));
+    gis.push_back(GI_CONST(556));
     s_ObjMgrFree_QueryFactory_LocalDataFromBioseq_set(gis);
 }
 
diff --git a/c++/src/algo/blast/unit_tests/api/queryinfo_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/queryinfo_unit_test.cpp
index 654fef2..c325f9c 100644
--- a/c++/src/algo/blast/unit_tests/api/queryinfo_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/queryinfo_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: queryinfo_unit_test.cpp 345770 2011-11-30 13:58:31Z madden $
+/*  $Id: queryinfo_unit_test.cpp 506956 2016-07-13 16:19:54Z boratyng $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -145,5 +145,77 @@ BOOST_AUTO_TEST_CASE(BlastnGetQueryIndex) {
     BOOST_REQUIRE_EQUAL(1, query_index);
 }
 
+BOOST_AUTO_TEST_CASE(BlastnSearchContextInfo)
+{
+    CSeq_id id1("gi|3090");
+    CSeq_id id2("gi|555");
+    auto_ptr<SSeqLoc> qsl1(CTestObjMgr::Instance().CreateSSeqLoc(id1));
+    auto_ptr<SSeqLoc> qsl2(CTestObjMgr::Instance().CreateSSeqLoc(id2));
+    TSeqLocVector query_v;
+    query_v.push_back(*qsl1);
+    query_v.push_back(*qsl2);
+    CBlastQueryInfo query_info;
+    CRef<CBlastOptionsHandle> opts(CBlastOptionsFactory::Create(eBlastn));
+
+    const CBlastOptions& kOpts = opts->GetOptions();
+    EBlastProgramType prog = kOpts.GetProgramType();
+    ENa_strand strand_opt = kOpts.GetStrandOption();
+
+    SetupQueryInfo(query_v, prog, strand_opt, &query_info);
+
+    int length_1 = qsl1->scope->GetSequenceLength(id1);
+    int length_2 = qsl2->scope->GetSequenceLength(id2);
+
+    // test min and max query length
+    BOOST_REQUIRE_EQUAL(query_info->min_length, min(length_1, length_2));
+    BOOST_REQUIRE_EQUAL(query_info->max_length, max(length_1, length_2));
+
+    // test context for zero position in each sequence strand
+    BOOST_REQUIRE_EQUAL(0, BSearchContextInfo(0, query_info.Get()));
+    BOOST_REQUIRE_EQUAL(1, BSearchContextInfo(length_1 + 1, query_info.Get()));
+    BOOST_REQUIRE_EQUAL(2, BSearchContextInfo(2 * (length_1 + 1),
+                                              query_info.Get()));
+
+    BOOST_REQUIRE_EQUAL(3, BSearchContextInfo(2 * (length_1 + 1) + length_2 + 1,
+                                              query_info.Get()));
+}
+
+BOOST_AUTO_TEST_CASE(BlastnSearchContextInfoSingleStrand)
+{
+    CSeq_id id1("gi|555");
+    CSeq_id id2("gi|3090");
+    // only plus strand for the first sequence
+    auto_ptr<SSeqLoc> qsl1(CTestObjMgr::Instance().CreateSSeqLoc(id1,
+                                                           eNa_strand_plus));
+    auto_ptr<SSeqLoc> qsl2(CTestObjMgr::Instance().CreateSSeqLoc(id2));
+    TSeqLocVector query_v;
+    query_v.push_back(*qsl1);
+    query_v.push_back(*qsl2);
+    CBlastQueryInfo query_info;
+    CRef<CBlastOptionsHandle> opts(CBlastOptionsFactory::Create(eBlastn));
+
+    const CBlastOptions& kOpts = opts->GetOptions();
+    EBlastProgramType prog = kOpts.GetProgramType();
+    ENa_strand strand_opt = kOpts.GetStrandOption();
+
+    SetupQueryInfo(query_v, prog, strand_opt, &query_info);
+
+    // pre condition: empty context in query info
+    BOOST_REQUIRE_EQUAL(query_info->contexts[1].query_length, 0);
+
+    int length_1 = qsl1->scope->GetSequenceLength(id1);
+    int length_2 = qsl2->scope->GetSequenceLength(id2);
+
+    // test min and max query length
+    BOOST_REQUIRE_EQUAL(query_info->min_length, 0u);
+    BOOST_REQUIRE_EQUAL(query_info->max_length, max(length_1, length_2));
+
+    // test context for zero position in each sequence strand
+    BOOST_REQUIRE_EQUAL(0, BSearchContextInfo(0, query_info.Get()));
+    BOOST_REQUIRE_EQUAL(2, BSearchContextInfo(length_1 + 1, query_info.Get()));
+    BOOST_REQUIRE_EQUAL(3, BSearchContextInfo(length_1 + length_2 + 2,
+                                              query_info.Get()));
+}
+
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/c++/src/algo/blast/unit_tests/api/redoalignment_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/redoalignment_unit_test.cpp
index 1c7c750..995b586 100644
--- a/c++/src/algo/blast/unit_tests/api/redoalignment_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/redoalignment_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: redoalignment_unit_test.cpp 498724 2016-04-19 13:36:57Z ivanov $ 
+/*  $Id: redoalignment_unit_test.cpp 504861 2016-06-20 15:45:40Z boratyng $ 
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -290,7 +290,7 @@ void CRedoAlignmentTestFixture::
 		hitsaving_opts, ext_options->compositionBasedStats,
         scoring_opts->gapped_calculation));
 
-    BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL);
+    BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL, NULL);
     BOOST_REQUIRE(writer_info == NULL);
 
     BlastHSPStream* hsp_stream = BlastHSPStreamNew(
diff --git a/c++/src/algo/blast/unit_tests/api/remote_blast_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/remote_blast_unit_test.cpp
index 94abdde..286dbd5 100644
--- a/c++/src/algo/blast/unit_tests/api/remote_blast_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/remote_blast_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: remote_blast_unit_test.cpp 454692 2014-12-17 15:16:27Z camacho $
+/*  $Id: remote_blast_unit_test.cpp 507726 2016-07-21 14:42:04Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE(CheckRemoteRPSBlastOptionsHandle) {
     rmt_blaster.SetDatabase("cdd");
     CRemoteBlast::TSeqLocList query_seqlocs;
     CRef<CSeq_loc> sl(new CSeq_loc);
-    sl->SetWhole().SetGi(GI_FROM(TIntId, 129295));
+    sl->SetWhole().SetGi(GI_CONST(129295));
     query_seqlocs.push_back(sl);
     rmt_blaster.SetQueries(query_seqlocs);
 
diff --git a/c++/src/algo/blast/unit_tests/api/rps_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/rps_unit_test.cpp
index f1a35ad..2568e34 100644
--- a/c++/src/algo/blast/unit_tests/api/rps_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/rps_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: rps_unit_test.cpp 498724 2016-04-19 13:36:57Z ivanov $
+/*  $Id: rps_unit_test.cpp 505234 2016-06-23 13:16:57Z fongah2 $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -41,6 +41,7 @@
 #include <algo/blast/api/local_blast.hpp>
 #include <algo/blast/api/objmgr_query_data.hpp>
 #include <algo/blast/api/blast_rps_options.hpp>
+#include <algo/blast/api/rpstblastn_options.hpp>
 #include <blast_seqalign.hpp>
 
 #include <algo/blast/core/lookup_wrap.h>
@@ -184,8 +185,11 @@ struct RpsTestFixture {
     }
 
     void NuclSearch(ENa_strand strand) {
-        CRef<CBlastOptionsHandle> 
-            opts(CBlastOptionsFactory::Create(eRPSTblastn));
+        CRef<CBlastOptionsHandle> opts(CBlastOptionsFactory::Create(eRPSTblastn));
+        opts->SetFilterString("F");
+        CRPSTBlastnOptionsHandle *
+            rpstblastn_opts(dynamic_cast<CRPSTBlastnOptionsHandle*> (opts.GetPointer()));
+        rpstblastn_opts->SetCompositionBasedStats(false);
         opts->SetFilterString("F");
 
         CSeq_id id("gi|19572546");
diff --git a/c++/src/algo/blast/unit_tests/api/split_query_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/split_query_unit_test.cpp
index e8b2cd9..e5b0850 100644
--- a/c++/src/algo/blast/unit_tests/api/split_query_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/split_query_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: split_query_unit_test.cpp 401131 2013-05-28 18:34:25Z grichenk $
+/*  $Id: split_query_unit_test.cpp 497783 2016-04-11 12:27:40Z madden $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -913,7 +913,7 @@ return; // FIXME
     {
         retval.clear();
         vector<string> tokens;
-        NStr::Tokenize(input, ",", tokens);
+        NStr::Split(input, ",", tokens);
         retval.reserve(tokens.size());
         ITERATE(vector<string>, token, tokens) {
             retval.push_back(NStr::StringToInt(NStr::TruncateSpaces(*token)));
diff --git a/c++/src/algo/blast/unit_tests/api/stat_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/stat_unit_test.cpp
index 3a555a6..122f4fb 100644
--- a/c++/src/algo/blast/unit_tests/api/stat_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/stat_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: stat_unit_test.cpp 498724 2016-04-19 13:36:57Z ivanov $
+/*  $Id: stat_unit_test.cpp 498248 2016-04-14 15:42:26Z boratyng $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/algo/blast/unit_tests/api/stat_unit_test.ini b/c++/src/algo/blast/unit_tests/api/stat_unit_test.ini
new file mode 100644
index 0000000..883af81
--- /dev/null
+++ b/c++/src/algo/blast/unit_tests/api/stat_unit_test.ini
@@ -0,0 +1,3 @@
+; $Id: stat_unit_test.ini 504636 2016-06-16 19:14:01Z boratyng $
+[UNITTESTS_DISABLE]
+GLOBAL = OS_Solaris
diff --git a/c++/src/algo/blast/unit_tests/api/traceback_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/traceback_unit_test.cpp
index 8917818..025ece1 100644
--- a/c++/src/algo/blast/unit_tests/api/traceback_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/traceback_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: traceback_unit_test.cpp 462040 2015-03-16 13:14:29Z vasilche $
+/*  $Id: traceback_unit_test.cpp 516338 2016-10-12 17:32:04Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -125,7 +125,7 @@ public:
                                              opt.GetExtnOpts()->compositionBasedStats, 
                                              opt.GetScoringOpts()->gapped_calculation));
 
-        BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL);
+        BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL, NULL);
         BOOST_REQUIRE(writer_info == NULL);
         return BlastHSPStreamNew(opt.GetProgramType(), opt.GetExtnOpts(), 
                                  FALSE, 1, writer);
@@ -298,8 +298,8 @@ BOOST_AUTO_TEST_CASE(testBLASTNTraceBack) {
     const int score_final[k_num_hsps_end] = { 252, 226, 182, 54, 40, 26, 24};
     const int context_final[k_num_hsps_end] = { 0, 0, 0, 0, 0, 1, 1};
     const int subject_frame_final[k_num_hsps_end] = { 1, 1, 1, 1, 1, 1, 1};
-    const int query_gapped_start_final[k_num_hsps_end] = { 6035, 6625, 5295, 7199, 5209, 7414, 3824};
-    const int subject_gapped_start_final[k_num_hsps_end] = { 116, 244, 16, 386, 10, 69, 77};
+    const int query_gapped_start_final[k_num_hsps_end] = { 6035, 6625, 5295, 7193, 5199, 7409, 3819};
+    const int subject_gapped_start_final[k_num_hsps_end] = { 116, 244, 16, 380, 0, 64, 72};
     const int num_ident_final[k_num_hsps_end] = { 135, 134, 91, 36, 20, 25, 12};
 
     // One hsp is dropped when the function runs.
@@ -795,7 +795,7 @@ BOOST_AUTO_TEST_CASE(testNoHSPEvalueCutoffBeforeLink) {
 			hit_options, ext_options->compositionBasedStats,
             scoring_options->gapped_calculation));
 
-	BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL);
+	BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL, NULL);
     BOOST_REQUIRE(writer_info == NULL);
     BlastHSPStream* hsp_stream = BlastHSPStreamNew(
 			kProgramType, ext_options, FALSE, 1, writer);
diff --git a/c++/src/algo/blast/unit_tests/api/tracebacksearch_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/tracebacksearch_unit_test.cpp
index 1434f34..7dc6ed2 100644
--- a/c++/src/algo/blast/unit_tests/api/tracebacksearch_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/tracebacksearch_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: tracebacksearch_unit_test.cpp 457458 2015-01-23 12:27:33Z madden $
+/*  $Id: tracebacksearch_unit_test.cpp 520431 2016-11-28 18:26:12Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -46,6 +46,7 @@
 #include <algo/blast/api/seqsrc_seqdb.hpp>
 #include <algo/blast/api/blast_seqinfosrc.hpp>
 #include <algo/blast/api/seqinfosrc_seqdb.hpp>
+#include <objects/general/User_object.hpp>
 
 
 // needed for objmgr dependent tests of query data interface
@@ -93,7 +94,7 @@ public:
                                 opts->GetExtnOpts()->compositionBasedStats,
                                 opts->GetScoringOpts()->gapped_calculation));
         
-        BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL);
+    BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL, NULL);
         BOOST_REQUIRE(writer_info == NULL);
         
         BlastHSPStream* hsp_stream = BlastHSPStreamNew(
@@ -177,7 +178,7 @@ public:
                                     opts->GetExtnOpts()->compositionBasedStats,
                                     opts->GetScoringOpts()->gapped_calculation));
 
-        BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL);
+        BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL, NULL);
         BOOST_REQUIRE(writer_info == NULL);
         
         BlastHSPStream* hsp_stream = BlastHSPStreamNew(
@@ -218,67 +219,31 @@ public:
         return hsps;
     }
 
-    void x_FindUsedGis(const CDense_seg & dseg, set<int> & used)
-    {
-        typedef vector< CRef< CScore > > TScoreList;
-        
-        if (dseg.CanGetScores()) {
-            const TScoreList & scores = dseg.GetScores();
-            
-            ITERATE(TScoreList, sc, scores) {
-                const CScore & sc1 = **sc;
-                
-                if (sc1.CanGetId() && sc1.GetId().IsStr()) {
-                    string id_name = sc1.GetId().GetStr();
-                    
-                    if (id_name == "use_this_gi") {
-                        BOOST_REQUIRE(sc1.CanGetValue());
-                        BOOST_REQUIRE(sc1.GetValue().IsInt());
-                        
-                        used.insert(sc1.GetValue().GetInt());
-                    }
-                }
-            }
-        }
-    }
-    
-    typedef vector< CRef< CScore > > TScoreList;
-    
-    void x_FindUsedGis(const TScoreList & scores, set<int> & used)
-    {
-        ITERATE(TScoreList, sc, scores) {
-            const CScore & sc1 = **sc;
-            
-            if (sc1.CanGetId() && sc1.GetId().IsStr()) {
-                string id_name = sc1.GetId().GetStr();
-                
-                if (id_name == "use_this_gi") {
-                    BOOST_REQUIRE(sc1.CanGetValue());
-                    BOOST_REQUIRE(sc1.GetValue().IsInt());
-                        
-                    used.insert(sc1.GetValue().GetInt());
-                }
-            }
-        }
-    }
-    
-    void x_FindUsedGis(const CSeq_align_set & aset, set<int> & used)
+    void x_FindUsedGis(const CSeq_align_set & aset, set<string> & used)
     {
+	used.clear();
         ITERATE(CSeq_align_set::Tdata, align, aset.Get()) {
-            CSeq_align::C_Segs::E_Choice ch = (**align).GetSegs().Which();
-            
-            if ((**align).CanGetScore()) {
-                x_FindUsedGis((**align).GetScore(), used);
-            }
-            
-            if (ch == CSeq_align::C_Segs::e_Disc) {
-                x_FindUsedGis((**align).GetSegs().GetDisc(), used);
-            } else if (ch == CSeq_align::C_Segs::e_Denseg) {
-//                 x_FindUsedGis((**align).GetSegs().GetDenseg(), used);
-            } else {
-                BOOST_REQUIRE_EQUAL((int)ch, 0);
-            }
-        }
+		if((**align).CanGetExt() && (**align).GetExt().size() > 0)
+		{
+		    CRef<CUser_object> uObject = (**align).GetExt().front();
+		    if(uObject->IsSetType() && uObject->GetType().IsStr() && 
+				uObject->GetType().GetStr() == "use_this_seqid" && uObject->IsSetData())
+		    {
+			const CUser_object::TData& fields = uObject->GetData();
+			for(CUser_object::TData::const_iterator fit = fields.begin(); fit != fields.end(); ++fit)
+			{
+				const CUser_field& field = **fit;
+				if (field.IsSetLabel() && field.GetLabel().IsStr() && field.GetLabel().GetStr() == "SEQIDS")
+				{
+					const vector< CStringUTF8 >& giStrings = field.GetData().GetStrs();
+					ITERATE(vector< CStringUTF8 >, str, giStrings) {
+						used.insert(*str);
+					}
+				}
+			}
+		    }
+		}
+	}
     }
     
     CSearchResultSet x_Traceback(CSeqDBGiList * gi_list)
@@ -340,7 +305,7 @@ BOOST_FIXTURE_TEST_SUITE(tracebacksearch, CTracebackSearchTestFixture)
 BOOST_AUTO_TEST_CASE(Traceback) {
     CSearchResultSet rset = x_Traceback(0);
     
-    set<int> use_these;
+    set<string> use_these;
     x_FindUsedGis(*rset[0].GetSeqAlign(), use_these);
     
     BOOST_REQUIRE(use_these.empty());
@@ -446,11 +411,11 @@ BOOST_AUTO_TEST_CASE(TracebackEntrez) {
     
     CSearchResultSet rset = x_Traceback(gi_list.GetPointerOrNull());
     
-    set<int> use_these;
+    set<string> use_these;
     x_FindUsedGis(*rset[0].GetSeqAlign(), use_these);
     
     BOOST_REQUIRE_EQUAL((int)use_these.size(), 1);
-    BOOST_REQUIRE_EQUAL(*use_these.begin(), 158292535);
+    BOOST_REQUIRE(*(use_these.begin()) == "gi:158292535");
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/c++/src/algo/blast/unit_tests/api/version_reference_unit_test.cpp b/c++/src/algo/blast/unit_tests/api/version_reference_unit_test.cpp
index 5f1bb6d..f4f29d6 100644
--- a/c++/src/algo/blast/unit_tests/api/version_reference_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/api/version_reference_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: version_reference_unit_test.cpp 500531 2016-05-05 14:28:38Z ivanov $
+/*  $Id: version_reference_unit_test.cpp 521263 2016-12-07 15:18:43Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -43,7 +43,7 @@ BOOST_AUTO_TEST_SUITE(version_reference)
 
 BOOST_AUTO_TEST_CASE(testVersion) {
     const int kMajor = 2;
-    const int kMinor = 4;
+    const int kMinor = 6;
     const int kPatch = 0;
     blast::CBlastVersion v;
     BOOST_REQUIRE_EQUAL(kMajor, v.GetMajor());
diff --git a/c++/src/algo/blast/unit_tests/blast_format/Makefile.blast_format_unit_test.app b/c++/src/algo/blast/unit_tests/blast_format/Makefile.blast_format_unit_test.app
index 96ce71a..4927ae8 100644
--- a/c++/src/algo/blast/unit_tests/blast_format/Makefile.blast_format_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/blast_format/Makefile.blast_format_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.blast_format_unit_test.app 421234 2013-12-10 19:27:57Z camacho $
+# $Id: Makefile.blast_format_unit_test.app 500512 2016-05-05 13:14:49Z gouriano $
 
 APP = blast_format_unit_test
 SRC = seqalignfilter_unit_test blastfmtutil_unit_test build_archive_unit_test vecscreen_run_unit_test
@@ -7,7 +7,7 @@ CPPFLAGS = -DNCBI_MODULE=BLASTFORMAT $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
 CXXFLAGS = $(FAST_CXXFLAGS) 
 LDFLAGS = $(FAST_LDFLAGS) 
 
-LIB_ = test_boost $(BLAST_FORMATTER_LIBS) ncbi_xloader_blastdb_rmt \
+LIB_ = test_boost $(BLAST_FORMATTER_LIBS) \
     $(BLAST_LIBS) $(OBJMGR_LIBS)
 
 LIB = $(LIB_:%=%$(STATIC))
diff --git a/c++/src/algo/blast/unit_tests/blast_format/blastfmtutil_unit_test.cpp b/c++/src/algo/blast/unit_tests/blast_format/blastfmtutil_unit_test.cpp
index 253e631..b8df80b 100644
--- a/c++/src/algo/blast/unit_tests/blast_format/blastfmtutil_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/blast_format/blastfmtutil_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastfmtutil_unit_test.cpp 456661 2015-01-14 15:22:43Z fongah2 $
+/*  $Id: blastfmtutil_unit_test.cpp 507726 2016-07-21 14:42:04Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(GetAlnScoresAndGetScoreString)
                                    sum_n, num_ident, use_this_gi);
     BOOST_REQUIRE(score == 1296); 
     BOOST_REQUIRE(sum_n == -1);
-    BOOST_REQUIRE(use_this_gi.front() == GI_FROM(TIntId, 18426812));
+    BOOST_REQUIRE(use_this_gi.front() == GI_CONST(18426812));
     BOOST_REQUIRE_CLOSE(evalue, 217774e-146, kMaxDoubleDiff);
     BOOST_REQUIRE_CLOSE(bits, 503.263, 0.0001);
     BOOST_REQUIRE(num_ident == 331);
diff --git a/c++/src/algo/blast/unit_tests/blast_format/vecscreen_run_unit_test.cpp b/c++/src/algo/blast/unit_tests/blast_format/vecscreen_run_unit_test.cpp
index c0c97bd..8907396 100644
--- a/c++/src/algo/blast/unit_tests/blast_format/vecscreen_run_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/blast_format/vecscreen_run_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: vecscreen_run_unit_test.cpp 401131 2013-05-28 18:34:25Z grichenk $
+/*  $Id: vecscreen_run_unit_test.cpp 507726 2016-07-21 14:42:04Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(VecscreenRunWithHits)
     CRef<CScope> scope = ss.NewScope();
 
     CRef<CSeq_loc> query_loc(new CSeq_loc());
-    query_loc->SetWhole().SetGi(GI_FROM(TIntId, 555));
+    query_loc->SetWhole().SetGi(GI_CONST(555));
 
     CVecscreenRun vs_run(query_loc, scope);
 
@@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE(VecscreenRunWithNoHits)
     CRef<CScope> scope = ss.NewScope();
 
     CRef<CSeq_loc> query_loc(new CSeq_loc());
-    query_loc->SetWhole().SetGi(GI_FROM(TIntId, 405832));
+    query_loc->SetWhole().SetGi(GI_CONST(405832));
 
     CVecscreenRun vs_run(query_loc, scope);
 
@@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(VecscreenRunWithNoDataLoader)
     CRef<CScope> scope(new CScope(*object_manager));
 
     CRef<CSeq_loc> query_loc(new CSeq_loc());
-    query_loc->SetWhole().SetGi(GI_FROM(TIntId, 555));
+    query_loc->SetWhole().SetGi(GI_CONST(555));
 
     BOOST_REQUIRE_THROW(CVecscreenRun vs_run(query_loc, scope), blast::CBlastException);
 }
diff --git a/c++/src/algo/blast/unit_tests/blastdb/Makefile.bdbloader_unit_test.app b/c++/src/algo/blast/unit_tests/blastdb/Makefile.bdbloader_unit_test.app
index a607541..ac8d4d5 100644
--- a/c++/src/algo/blast/unit_tests/blastdb/Makefile.bdbloader_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/blastdb/Makefile.bdbloader_unit_test.app
@@ -1,12 +1,11 @@
-# $Id: Makefile.bdbloader_unit_test.app 421234 2013-12-10 19:27:57Z camacho $
+# $Id: Makefile.bdbloader_unit_test.app 500512 2016-05-05 13:14:49Z gouriano $
 
 APP = bdbloader_unit_test
 SRC = bdbloader_unit_test
 
 CPPFLAGS = -DNCBI_MODULE=BLASTDB $(ORIG_CPPFLAGS) $(BOOST_INCLUDE) -I../
 
-LIB_ = test_boost $(BLAST_INPUT_LIBS) ncbi_xloader_blastdb_rmt \
-    $(BLAST_LIBS) $(OBJMGR_LIBS)
+LIB_ = test_boost $(BLAST_INPUT_LIBS) $(BLAST_LIBS) $(OBJMGR_LIBS)
 LIB = $(LIB_:%=%$(STATIC))
 
 LIBS = $(NETWORK_LIBS) $(CMPRS_LIBS) $(DL_LIBS) $(ORIG_LIBS)
diff --git a/c++/src/algo/blast/unit_tests/seqdb_reader/Makefile.seqdb_unit_test.app b/c++/src/algo/blast/unit_tests/seqdb_reader/Makefile.seqdb_unit_test.app
index 1cc778f..89086b6 100644
--- a/c++/src/algo/blast/unit_tests/seqdb_reader/Makefile.seqdb_unit_test.app
+++ b/c++/src/algo/blast/unit_tests/seqdb_reader/Makefile.seqdb_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.seqdb_unit_test.app 421234 2013-12-10 19:27:57Z camacho $
+# $Id: Makefile.seqdb_unit_test.app 505858 2016-06-29 16:55:21Z elisovdn $
 
 APP = seqdb_unit_test
 SRC = seqdb_unit_test
diff --git a/c++/src/algo/blast/unit_tests/seqdb_reader/seqdb_unit_test.cpp b/c++/src/algo/blast/unit_tests/seqdb_reader/seqdb_unit_test.cpp
index d98d545..85317fb 100644
--- a/c++/src/algo/blast/unit_tests/seqdb_reader/seqdb_unit_test.cpp
+++ b/c++/src/algo/blast/unit_tests/seqdb_reader/seqdb_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdb_unit_test.cpp 488259 2015-12-29 14:32:15Z camacho $
+/*  $Id: seqdb_unit_test.cpp 512373 2016-08-30 14:51:51Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -98,7 +98,10 @@ static void s_TestPartialAmbig(CSeqDB & db, TGi nt_gi)
     int oid(-1);
     bool success = db.GiToOid(nt_gi, oid);
 
-    BOOST_REQUIRE(success);
+    CNcbiOstrstream oss;
+    oss << "GI " << nt_gi << " was not found in nt";
+    string msg = CNcbiOstrstreamToString(oss);
+    BOOST_REQUIRE_MESSAGE(success, msg);
 
     int length = db.GetSeqLength(oid);
 
@@ -2152,7 +2155,7 @@ BOOST_AUTO_TEST_CASE(PartialSequences)
 
     s_TestPartialAmbig(nt, 57340989);
     s_TestPartialAmbig(nt, 24430781);
-    s_TestPartialAmbig(nt, 8885782);
+    s_TestPartialAmbig(nt, 1059791394);
 }
 
 BOOST_AUTO_TEST_CASE(GiListInOidRangeIteration)
@@ -2501,7 +2504,7 @@ BOOST_AUTO_TEST_CASE(IntersectionGiList)
     // the other to verify that the code computing the intersection
     // correctly sorts its inputs.
 
-    TGi special = GI_FROM(int, 41);
+    TGi special = GI_CONST(41);
 
     // Add to start of a3
     a3.push_back(special);
@@ -2542,7 +2545,7 @@ BOOST_AUTO_TEST_CASE(IntersectionNegGiList)
     // the other to verify that the code computing the intersection
     // correctly sorts its inputs.
 
-    TGi special = GI_FROM(int, 41);
+    TGi special = GI_CONST(41);
 
     // Add to start of a3
     a3.push_back(special);
@@ -2557,7 +2560,7 @@ BOOST_AUTO_TEST_CASE(IntersectionNegGiList)
 
     // Add to end of a5
     a5.push_back(special);
-    a5.push_back(GI_FROM(int, 1000));
+    a5.push_back(GI_CONST(1000));
 
     CSeqDBNegativeList gi3;
     gi3.SetGiList(a3);
diff --git a/c++/src/algo/blast/unit_tests/seqdb_reader/seqdb_unit_test.ini b/c++/src/algo/blast/unit_tests/seqdb_reader/seqdb_unit_test.ini
index b6341a5..b4ed4aa 100644
--- a/c++/src/algo/blast/unit_tests/seqdb_reader/seqdb_unit_test.ini
+++ b/c++/src/algo/blast/unit_tests/seqdb_reader/seqdb_unit_test.ini
@@ -1,4 +1,4 @@
-; $Id: seqdb_unit_test.ini 403238 2013-06-13 14:36:54Z camacho $
+; $Id: seqdb_unit_test.ini 520559 2016-11-29 19:17:28Z ivanov $
 
 [UNITTESTS_DISABLE]
 ; TestOidNotFoundWithUserAliasFileAndGiList = true
@@ -10,3 +10,11 @@
 ; Temporarily disable due to wgs transition
 GlobalMemoryBound = true
 DeltaSequenceHash = true
+
+FilteredHeaders = OS_Windows && PLATFORM_Bits32
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; FIXME: this is a temporary workaround for SB-1826
+OidAndGiLists=true
+NrAndSwissProt=true
+NegativeListNr=true
diff --git a/c++/src/app/Makefile.in b/c++/src/app/Makefile.in
index 615e6e6..fb347bb 100644
--- a/c++/src/app/Makefile.in
+++ b/c++/src/app/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in 490144 2016-01-21 16:27:21Z bollin $
+# $Id: Makefile.in 507812 2016-07-21 17:53:16Z boratyng $
 
 # Miscellaneous applications
 #################################
@@ -11,10 +11,10 @@ SUB_PROJ = asn2asn asn2fasta asn2flat asnval asn_cleanup \
            bdb_env_keeper nw_aligner speedtest idmapper formatguess \
            multireader read_blast_result splign hfilter \
            annotwriter compart streamtest lds2_indexer \
-           discrep_report discrepancy_report biosample_chk gap_stats table2asn \
-           srcchk tableval ncbi_encrypt ssub_fork
+           discrepancy_report biosample_chk gap_stats table2asn \
+           srcchk tableval ncbi_encrypt ssub_fork asn_cache magicblast
 
-EXPENDABLE_SUB_PROJ = split_cache wig2table netcache rmblastn dblb tls
+EXPENDABLE_SUB_PROJ = split_cache wig2table netcache rmblastn dblb tls idfetch
 
 REQUIRES = app
 
diff --git a/c++/src/app/blast/Makefile.blastn.app b/c++/src/app/blast/Makefile.blastn.app
index fd0e731..2f1794f 100644
--- a/c++/src/app/blast/Makefile.blastn.app
+++ b/c++/src/app/blast/Makefile.blastn.app
@@ -1,10 +1,11 @@
-# $Id: Makefile.blastn.app 474746 2015-07-31 13:51:46Z madden $
+# $Id: Makefile.blastn.app 504861 2016-06-20 15:45:40Z boratyng $
 
 WATCHERS = camacho madden fongah2
 
 APP = blastn
 SRC = blastn_app
-LIB_ = $(BLAST_INPUT_LIBS) $(BLAST_LIBS) $(OBJMGR_LIBS)
+LIB_ = xformat xcleanup valid gbseq mlacli mla medlars pubmed submit xregexp $(PCRE_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
diff --git a/c++/src/app/blast/Makefile.in b/c++/src/app/blast/Makefile.in
index 9038f9d..62866b5 100644
--- a/c++/src/app/blast/Makefile.in
+++ b/c++/src/app/blast/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in 371962 2012-08-14 09:45:56Z coulouri $
+# $Id: Makefile.in 507582 2016-07-20 14:22:33Z boratyng $
 
 # Meta-makefile("APP" project)
 #################################
diff --git a/c++/src/app/blast/blast_app_util.cpp b/c++/src/app/blast/blast_app_util.cpp
index f40fa93..0b34899 100644
--- a/c++/src/app/blast/blast_app_util.cpp
+++ b/c++/src/app/blast/blast_app_util.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_app_util.cpp 500374 2016-05-04 13:30:40Z ivanov $
+/*  $Id: blast_app_util.cpp 509280 2016-08-04 16:03:11Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  *  Utility functions for BLAST command line applications
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_app_util.cpp 500374 2016-05-04 13:30:40Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "blast_app_util.hpp"
 
@@ -53,9 +48,6 @@ static char const rcsid[] =
 #include <algo/blast/blastinput/blast_scope_src.hpp>
 #include <objmgr/util/sequence.hpp>
 
-#include <objects/seq/Seq_ext.hpp>
-#include <objects/seq/Delta_seq.hpp>
-#include <objects/seq/Delta_ext.hpp>
 #include <objects/scoremat/Pssm.hpp>
 #include <serial/typeinfo.hpp>      // for CTypeInfo, needed by SerialClone
 #include <objtools/data_loaders/blastdb/bdbloader_rmt.hpp>
@@ -645,22 +637,6 @@ SaveSearchStrategy(const CArgs& args,
                            pssm, num_iters);
 }
 
-struct CConstRefCSeqId_LessThan
-{
-    bool operator() (const CConstRef<CSeq_id>& a, const CConstRef<CSeq_id>& b) const {
-        if (a.Empty() && b.NotEmpty()) {
-            return true;
-        } else if (a.NotEmpty() && b.Empty()) {
-            return false;
-        } else if (a.Empty() && b.Empty()) {
-            return true;
-        } else {
-            _ASSERT(a.NotEmpty() && b.NotEmpty());
-            return *a < *b;
-        }
-    }
-};
-
 /// Extracts the subject sequence IDs and ranges from the BLAST results
 /// @note if this ever needs to be refactored for popular developer
 /// consumption, this function should operate on CSeq_align_set as opposed to
@@ -722,70 +698,75 @@ s_IsUsingRemoteBlastDbDataLoader()
     return false;
 }
 
-void BlastFormatter_PreFetchSequenceData(const blast::CSearchResultSet&
-                                         results, CRef<CScope> scope)
+static bool
+s_IsPrefetchFormat(blast::CFormattingArgs::EOutputFormat format_type)
+{
+	if ((format_type == CFormattingArgs::eAsnText) ||
+	    (format_type == CFormattingArgs::eAsnBinary) ||
+	    (format_type == CFormattingArgs::eArchiveFormat)||
+	    (format_type == CFormattingArgs::eJsonSeqalign)) {
+		return false;
+	}
+	return true;
+}
+
+static bool
+s_PreFetchSeqs(const blast::CSearchResultSet& results,
+		       blast::CFormattingArgs::EOutputFormat format_type)
+{
+	{
+		char * pre_fetch_limit_str = getenv("PRE_FETCH_SEQS_LIMIT");
+		if (pre_fetch_limit_str) {
+			int pre_fetch_limit = NStr::StringToInt(pre_fetch_limit_str);
+			if(pre_fetch_limit == 0) {
+				return false;
+			}
+			if(pre_fetch_limit == INT_MAX){
+				return true;
+			}
+			int num_of_seqs = 0;
+			for(unsigned int i=0; i < results.GetNumResults(); i++) {
+				if(results[i].HasAlignments()) {
+					num_of_seqs += results[i].GetSeqAlign()->Size();
+				}
+			}
+			if(num_of_seqs > pre_fetch_limit) {
+				return false;
+			}
+		}
+	}
+
+	return s_IsPrefetchFormat(format_type);
+}
+
+void BlastFormatter_PreFetchSequenceData(const blast::CSearchResultSet& results,
+		                                 CRef<CScope> scope,
+		                                 blast::CFormattingArgs::EOutputFormat format_type)
 {
     _ASSERT(scope.NotEmpty());
     if (results.size() == 0) {
         return;
     }
-    // Only useful if we're dealing with then remote BLAST DB data loader
-    if (! s_IsUsingRemoteBlastDbDataLoader() ) {
-        return;
+    if(!s_PreFetchSeqs(results, format_type)){
+    	return;
     }
-
-    CScope::TIds ids;
-    vector<TSeqRange> ranges;
-    s_ExtractSeqidsAndRanges(results, ids, ranges);
-    _TRACE("Prefetching " << ids.size() << " sequence lengths");
-
     try {
-        CScope::TBioseqHandles bhs = scope->GetBioseqHandles(ids);
-
-        // Per Eugene Vasilchenko's suggestion, via email on 6/8/10:
-        // "With the current API you can make artificial delta sequence
-        // referencing several other sequences and use its CSeqMap to load them
-        // all in one call. There is no straightforward way to do this, sorry."
-
-        // Create virtual delta sequence
-        CRef<CBioseq> top_seq(new CBioseq);
-        CSeq_inst& inst = top_seq->SetInst();
-        inst.SetRepr(CSeq_inst::eRepr_virtual);
-        inst.SetMol(CSeq_inst::eMol_not_set);
-        CDelta_ext& delta = inst.SetExt().SetDelta();
-        int i = 0;
-        ITERATE(CScope::TBioseqHandles, it, bhs) {
-            CRef<CDelta_seq> seq(new CDelta_seq);
-            CSeq_interval& interval = seq->SetLoc().SetInt();
-            interval.SetId
-                (*SerialClone(*it->GetAccessSeq_id_Handle().GetSeqId()));
-            if (ranges[i].GetFrom() > ranges[i].GetToOpen()) {
-                TSeqPos length = it->GetBioseqLength();
-                interval.SetFrom(length - ranges[i].GetTo());
-                interval.SetTo(length - ranges[i].GetFrom());
-            } else {
-            interval.SetFrom(ranges[i].GetFrom());
-            interval.SetTo(ranges[i].GetTo());
-            }
-            i++;
-            delta.Set().push_back(seq);
-        }
-
-        // Add it to the scope
-        CBioseq_Handle top_bh = scope->AddBioseq(*top_seq);
-
-        // prepare selector. SetLinkUsedTSE() is necessary for batch loading
-        SSeqMapSelector sel(CSeqMap::fFindAnyLeaf, kInvalidSeqPos);
-        sel.SetLinkUsedTSE(top_bh.GetTSE_Handle());
+       CScope::TIds ids;
+       vector<TSeqRange> ranges;
+       s_ExtractSeqidsAndRanges(results, ids, ranges);
+       _TRACE("Prefetching " << ids.size() << " sequence lengths");
+       LoadSequencesToScope(ids, ranges, scope);
+	} catch (CException& e) {
+	   if(s_IsUsingRemoteBlastDbDataLoader()) {
+          NCBI_THROW(CBlastSystemException, eNetworkError,
+                     "Error fetching sequence data from BLAST databases at NCBI, "
+                     "please try again later");
+	   }
+	   else {
+          NCBI_RETHROW_SAME(e, "Error pre-fetching sequence data ");
+	   }
+   }
 
-        // and get all sequence data in batch mode
-        _TRACE("Prefetching " << ids.size() << " sequences");
-        top_bh.GetSeqMap().CanResolveRange(&*scope, sel);
-    } catch (const CException&) {
-        NCBI_THROW(CBlastSystemException, eNetworkError, 
-                   "Error fetching sequence data from BLAST databases at NCBI, "
-                   "please try again later");
-    }
 }
 
 /// Auxiliary function to extract the ancillary data from the PSSM.
diff --git a/c++/src/app/blast/blast_app_util.hpp b/c++/src/app/blast/blast_app_util.hpp
index 6abed4f..59c6881 100644
--- a/c++/src/app/blast/blast_app_util.hpp
+++ b/c++/src/app/blast/blast_app_util.hpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_app_util.hpp 495291 2016-03-16 14:52:25Z ivanov $
+/*  $Id: blast_app_util.hpp 509280 2016-08-04 16:03:11Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -265,15 +265,15 @@ SaveSearchStrategy(const CArgs& args,
                      = CRef<objects::CPssmWithParameters>(),
                    unsigned int num_iters = 0);
 
-/// This method needs to be invoked for optimizing the retrieval of
-/// sequence data from the remote BLAST database data loader (exercised
-/// when there are no locally available BLAST databases)
+/// This method optimize the retrieval of sequence data to scope
 /// @param results BLAST results [in]
 /// @param scope CScope object from which the sequence data will be fetched
 /// [in]
+/// @param format_type  Blast output fomat type
 void 
 BlastFormatter_PreFetchSequenceData(const blast::CSearchResultSet&
-                                    results, CRef<CScope> scope);
+                                    results, CRef<CScope> scope,
+                                    blast::CFormattingArgs::EOutputFormat format_type);
 
 /// Auxiliary function to extract the ancillary data from the PSSM.
 /// Used in PSI-BLAST and DELTA-BLAST
diff --git a/c++/src/app/blast/blast_formatter.cpp b/c++/src/app/blast/blast_formatter.cpp
index 5eeaaa0..2d09372 100644
--- a/c++/src/app/blast/blast_formatter.cpp
+++ b/c++/src/app/blast/blast_formatter.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_formatter.cpp 495294 2016-03-16 14:53:17Z ivanov $
+/*  $Id: blast_formatter.cpp 509280 2016-08-04 16:03:11Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Stand-alone command line formatter for BLAST.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blast_formatter.cpp 495294 2016-03-16 14:53:17Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <corelib/ncbistre.hpp>
@@ -353,7 +348,8 @@ int CBlastFormatterApp::PrintFormattedOutput(void)
     } else {
         while (1)
 	{
-        	BlastFormatter_PreFetchSequenceData(*results, scope);
+        	BlastFormatter_PreFetchSequenceData(*results, scope,
+                		                        fmt_args.GetFormattedOutputChoice());
     		ITERATE(CSearchResultSet, result, *results) {
     			if(isPsiBlast)
     			{
@@ -471,6 +467,6 @@ int CBlastFormatterApp::Run(void)
 #ifndef SKIP_DOXYGEN_PROCESSING
 int main(int argc, const char* argv[] /*, const char* envp[]*/)
 {
-    return CBlastFormatterApp().AppMain(argc, argv, 0, eDS_Default, "");
+    return CBlastFormatterApp().AppMain(argc, argv);
 }
 #endif /* SKIP_DOXYGEN_PROCESSING */
diff --git a/c++/src/app/blast/blastn_app.cpp b/c++/src/app/blast/blastn_app.cpp
index 78ed419..08d4fd6 100644
--- a/c++/src/app/blast/blastn_app.cpp
+++ b/c++/src/app/blast/blastn_app.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastn_app.cpp 495294 2016-03-16 14:53:17Z ivanov $
+/*  $Id: blastn_app.cpp 509280 2016-08-04 16:03:11Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * BLASTN command line application
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-	"$Id: blastn_app.cpp 495294 2016-03-16 14:53:17Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <algo/blast/api/local_blast.hpp>
@@ -213,7 +208,8 @@ int CBlastnApp::Run(void)
                 formatter.WriteArchive(*queries, *opts_hndl, *results, 0, bah.GetMessages());
                 bah.ResetMessages();
             } else {
-                BlastFormatter_PreFetchSequenceData(*results, scope);
+                BlastFormatter_PreFetchSequenceData(*results, scope,
+                			                        fmt_args->GetFormattedOutputChoice());
                 ITERATE(CSearchResultSet, result, *results) {
                     formatter.PrintOneResultSet(**result, query_batch);
                 }
diff --git a/c++/src/app/blast/blastp_app.cpp b/c++/src/app/blast/blastp_app.cpp
index 5369ac3..6251d9a 100644
--- a/c++/src/app/blast/blastp_app.cpp
+++ b/c++/src/app/blast/blastp_app.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastp_app.cpp 495295 2016-03-16 14:53:41Z ivanov $
+/*  $Id: blastp_app.cpp 509280 2016-08-04 16:03:11Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * BLASTP command line application
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-	"$Id: blastp_app.cpp 495295 2016-03-16 14:53:41Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <algo/blast/api/local_blast.hpp>
@@ -192,7 +187,8 @@ int CBlastpApp::Run(void)
                 formatter.WriteArchive(*queries, *opts_hndl, *results,  0, bah.GetMessages());
                 bah.ResetMessages();
             } else {
-                BlastFormatter_PreFetchSequenceData(*results, scope);
+                BlastFormatter_PreFetchSequenceData(*results, scope,
+                		                            fmt_args->GetFormattedOutputChoice());
                 ITERATE(CSearchResultSet, result, *results) {
                     formatter.PrintOneResultSet(**result, query_batch);
                 }
diff --git a/c++/src/app/blast/blastx_app.cpp b/c++/src/app/blast/blastx_app.cpp
index b215164..2e9fcca 100644
--- a/c++/src/app/blast/blastx_app.cpp
+++ b/c++/src/app/blast/blastx_app.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastx_app.cpp 495295 2016-03-16 14:53:41Z ivanov $
+/*  $Id: blastx_app.cpp 509280 2016-08-04 16:03:11Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * BLASTX command line application
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-	"$Id: blastx_app.cpp 495295 2016-03-16 14:53:41Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <algo/blast/api/local_blast.hpp>
@@ -190,7 +185,8 @@ int CBlastxApp::Run(void)
                 formatter.WriteArchive(*queries, *opts_hndl, *results, 0, bah.GetMessages());
                 bah.ResetMessages();
             } else {
-                BlastFormatter_PreFetchSequenceData(*results, scope);
+                BlastFormatter_PreFetchSequenceData(*results, scope,
+                		                            fmt_args->GetFormattedOutputChoice());
             	ITERATE(CSearchResultSet, result, *results) {
                	    formatter.PrintOneResultSet(**result, query_batch);
             	}
diff --git a/c++/src/app/blast/deltablast_app.cpp b/c++/src/app/blast/deltablast_app.cpp
index c6f6d84..1162ea4 100644
--- a/c++/src/app/blast/deltablast_app.cpp
+++ b/c++/src/app/blast/deltablast_app.cpp
@@ -1,4 +1,4 @@
-/*  $Id: deltablast_app.cpp 495295 2016-03-16 14:53:41Z ivanov $
+/*  $Id: deltablast_app.cpp 509280 2016-08-04 16:03:11Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * DELTA-BLAST command line application
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-        "$Id: deltablast_app.cpp 495295 2016-03-16 14:53:41Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbistl.hpp>
 #include <corelib/ncbiapp.hpp>
@@ -357,9 +352,11 @@ int CDeltaBlastApp::Run(void)
                     formatter.WriteArchive(*queries, *opts_hndl, *results, 0, m_bah.GetMessages());
                     m_bah.ResetMessages();
                 } else {
-                    BlastFormatter_PreFetchSequenceData(*results, scope);
+                    BlastFormatter_PreFetchSequenceData(*results, scope,
+                    		                            fmt_args->GetFormattedOutputChoice());
                     if (m_CmdLineArgs->GetShowDomainHits()) {
-                        BlastFormatter_PreFetchSequenceData(*results, scope);
+                        BlastFormatter_PreFetchSequenceData(*domain_results, scope,
+                        		                            fmt_args->GetFormattedOutputChoice());
                     }
                     ITERATE(blast::CSearchResultSet, result, *results) {
                         if (m_CmdLineArgs->GetShowDomainHits()) {
@@ -477,7 +474,8 @@ CDeltaBlastApp::DoPsiBlastIterations(CRef<CBlastOptionsHandle> opts_hndl,
 
     CRef<IQueryFactory> query_factory(new CObjMgr_QueryFactory(*query));
 
-    BlastFormatter_PreFetchSequenceData(*results, scope);
+    BlastFormatter_PreFetchSequenceData(*results, scope,
+    		 m_CmdLineArgs->GetFormattingArgs()->GetFormattedOutputChoice());
     if (CFormattingArgs::eArchiveFormat ==
         m_CmdLineArgs->GetFormattingArgs()->GetFormattedOutputChoice()) {
         formatter.WriteArchive(*query_factory, *opts_hndl, *results,
@@ -524,7 +522,8 @@ CDeltaBlastApp::DoPsiBlastIterations(CRef<CBlastOptionsHandle> opts_hndl,
         psiblast->SetNumberOfThreads(m_CmdLineArgs->GetNumThreads());
         results = psiblast->Run();
 
-        BlastFormatter_PreFetchSequenceData(*results, scope);
+        BlastFormatter_PreFetchSequenceData(*results, scope,
+        		m_CmdLineArgs->GetFormattingArgs()->GetFormattedOutputChoice());
         if (CFormattingArgs::eArchiveFormat ==
             m_CmdLineArgs->GetFormattingArgs()->GetFormattedOutputChoice()) {
             formatter.WriteArchive(*pssm, *opts_hndl, *results,
@@ -586,7 +585,7 @@ CDeltaBlastApp::ComputePssmForNextPsiBlastIteration(const CBioseq& bioseq,
 #ifndef SKIP_DOXYGEN_PROCESSING
 int main(int argc, const char* argv[] /*, const char* envp[]*/)
 {
-    return CDeltaBlastApp().AppMain(argc, argv, 0, eDS_Default, "");
+    return CDeltaBlastApp().AppMain(argc, argv);
 }
 #endif /* SKIP_DOXYGEN_PROCESSING */
 
diff --git a/c++/src/app/blast/psiblast_app.cpp b/c++/src/app/blast/psiblast_app.cpp
index 0b33701..c4dde7d 100644
--- a/c++/src/app/blast/psiblast_app.cpp
+++ b/c++/src/app/blast/psiblast_app.cpp
@@ -1,4 +1,4 @@
-/*  $Id: psiblast_app.cpp 495295 2016-03-16 14:53:41Z ivanov $
+/*  $Id: psiblast_app.cpp 509280 2016-08-04 16:03:11Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * PSI-BLAST command line application
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-        "$Id: psiblast_app.cpp 495295 2016-03-16 14:53:41Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <corelib/ncbifile.hpp>
@@ -249,13 +244,15 @@ CPsiBlastApp::x_RunLocalPsiBlastIterations(CRef<CBlastQueryVector> query,
                    CLocalBlast lcl_blast(query_factory, CRef<CBlastOptionsHandle>(phi_opts), db_adapter);
                    lcl_blast.SetNumberOfThreads(m_CmdLineArgs->GetNumThreads());
                    results = lcl_blast.Run();
-                   BlastFormatter_PreFetchSequenceData(*results, scope);
+                   BlastFormatter_PreFetchSequenceData(*results, scope,
+                		   m_CmdLineArgs->GetFormattingArgs()->GetFormattedOutputChoice());
                    formatter.PrintPhiResult(*results, query, itr.GetIterationNumber(),  itr.GetPreviouslyFoundSeqIds());
                 }
                 else
                 {
                    results = psiblast->Run();
-                   BlastFormatter_PreFetchSequenceData(*results, scope);
+                   BlastFormatter_PreFetchSequenceData(*results, scope,
+                		   m_CmdLineArgs->GetFormattingArgs()->GetFormattedOutputChoice());
                    if(CFormattingArgs::eArchiveFormat ==
                 	  m_CmdLineArgs->GetFormattingArgs()->GetFormattedOutputChoice())
                    {
@@ -360,7 +357,8 @@ CPsiBlastApp::DoIterations(CRef<CBlastOptionsHandle> opts_hndl,
         }
         else
         {
-            BlastFormatter_PreFetchSequenceData(*results, scope);
+            BlastFormatter_PreFetchSequenceData(*results, scope,
+            		m_CmdLineArgs->GetFormattingArgs()->GetFormattedOutputChoice());
             ITERATE(CSearchResultSet, result, *results) {
                 formatter.PrintOneResultSet(**result, query);
             }
@@ -566,6 +564,6 @@ int CPsiBlastApp::Run(void)
 #ifndef SKIP_DOXYGEN_PROCESSING
 int main(int argc, const char* argv[] /*, const char* envp[]*/)
 {
-    return CPsiBlastApp().AppMain(argc, argv, 0, eDS_Default, "");
+    return CPsiBlastApp().AppMain(argc, argv);
 }
 #endif /* SKIP_DOXYGEN_PROCESSING */
diff --git a/c++/src/app/blast/rpsblast_app.cpp b/c++/src/app/blast/rpsblast_app.cpp
index 37e5ca7..b2f7a5c 100644
--- a/c++/src/app/blast/rpsblast_app.cpp
+++ b/c++/src/app/blast/rpsblast_app.cpp
@@ -1,4 +1,4 @@
-/*  $Id: rpsblast_app.cpp 495295 2016-03-16 14:53:41Z ivanov $
+/*  $Id: rpsblast_app.cpp 509280 2016-08-04 16:03:11Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * RPSBLAST command line application
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-	"$Id: rpsblast_app.cpp 495295 2016-03-16 14:53:41Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <algo/blast/api/local_blast.hpp>
@@ -196,7 +191,8 @@ int CRPSBlastApp::Run(void)
                 formatter.WriteArchive(*queries, *opts_hndl, *results, 0, bah.GetMessages());
                 bah.ResetMessages();
             } else {
-               BlastFormatter_PreFetchSequenceData(*results, scope);
+               BlastFormatter_PreFetchSequenceData(*results, scope,
+            		                               fmt_args->GetFormattedOutputChoice());
                 ITERATE(CSearchResultSet, result, *results) {
                     formatter.PrintOneResultSet(**result, query_batch);
                 }
@@ -220,7 +216,7 @@ int CRPSBlastApp::Run(void)
 #ifndef SKIP_DOXYGEN_PROCESSING
 int main(int argc, const char* argv[] /*, const char* envp[]*/)
 {
-	int status = CRPSBlastApp().AppMain(argc, argv, 0, eDS_Default, "");
+	int status = CRPSBlastApp().AppMain(argc, argv);
 
 	return status;
 }
diff --git a/c++/src/app/blast/rpstblastn_app.cpp b/c++/src/app/blast/rpstblastn_app.cpp
index f30ad75..1586abd 100644
--- a/c++/src/app/blast/rpstblastn_app.cpp
+++ b/c++/src/app/blast/rpstblastn_app.cpp
@@ -1,4 +1,4 @@
-/*  $Id: rpstblastn_app.cpp 495295 2016-03-16 14:53:41Z ivanov $
+/*  $Id: rpstblastn_app.cpp 509280 2016-08-04 16:03:11Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * RPS TBLASTN command line application
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-	"$Id: rpstblastn_app.cpp 495295 2016-03-16 14:53:41Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <algo/blast/api/local_blast.hpp>
@@ -193,7 +188,8 @@ int CRPSTBlastnApp::Run(void)
                 formatter.WriteArchive(*queries, *opts_hndl, *results, 0, bah.GetMessages());
                 bah.ResetMessages();
             } else {
-                BlastFormatter_PreFetchSequenceData(*results, scope);
+                BlastFormatter_PreFetchSequenceData(*results, scope,
+                		                            fmt_args->GetFormattedOutputChoice());
                 ITERATE(CSearchResultSet, result, *results) {
                     formatter.PrintOneResultSet(**result, query_batch);
                 }
@@ -217,6 +213,6 @@ int CRPSTBlastnApp::Run(void)
 #ifndef SKIP_DOXYGEN_PROCESSING
 int main(int argc, const char* argv[] /*, const char* envp[]*/)
 {
-    return CRPSTBlastnApp().AppMain(argc, argv, 0, eDS_Default, "");
+    return CRPSTBlastnApp().AppMain(argc, argv);
 }
 #endif /* SKIP_DOXYGEN_PROCESSING */
diff --git a/c++/src/app/blast/seedtop_app.cpp b/c++/src/app/blast/seedtop_app.cpp
index 0eb12c4..17ad329 100644
--- a/c++/src/app/blast/seedtop_app.cpp
+++ b/c++/src/app/blast/seedtop_app.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seedtop_app.cpp 473030 2015-07-15 19:29:59Z camacho $
+/*  $Id: seedtop_app.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * SEEDTOP command line application
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-	"$Id: seedtop_app.cpp 473030 2015-07-15 19:29:59Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <algo/blast/api/seedtop.hpp>
@@ -241,6 +236,6 @@ int CSeedTopApp::Run(void)
 #ifndef SKIP_DOXYGEN_PROCESSING
 int main(int argc, const char* argv[] /*, const char* envp[]*/)
 {
-    return CSeedTopApp().AppMain(argc, argv, 0, eDS_Default, "");
+    return CSeedTopApp().AppMain(argc, argv);
 }
 #endif /* SKIP_DOXYGEN_PROCESSING */
diff --git a/c++/src/app/blast/tblastn_app.cpp b/c++/src/app/blast/tblastn_app.cpp
index 38e85a5..d163d19 100644
--- a/c++/src/app/blast/tblastn_app.cpp
+++ b/c++/src/app/blast/tblastn_app.cpp
@@ -1,4 +1,4 @@
-/*  $Id: tblastn_app.cpp 495295 2016-03-16 14:53:41Z ivanov $
+/*  $Id: tblastn_app.cpp 509280 2016-08-04 16:03:11Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * TBLASTN command line application
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-	"$Id: tblastn_app.cpp 495295 2016-03-16 14:53:41Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <algo/blast/api/local_blast.hpp>
@@ -211,7 +206,8 @@ int CTblastnApp::Run(void)
                     formatter.WriteArchive(*query_factory, *opts_hndl, *results, 0, bah.GetMessages());
                     bah.ResetMessages();
                 } else {
-                    BlastFormatter_PreFetchSequenceData(*results, scope);
+                    BlastFormatter_PreFetchSequenceData(*results, scope,
+                    		                            fmt_args->GetFormattedOutputChoice());
                     ITERATE(CSearchResultSet, result, *results) {
                         formatter.PrintOneResultSet(**result, query);
                     }
@@ -246,7 +242,8 @@ int CTblastnApp::Run(void)
                 formatter.WriteArchive(*query_factory, *opts_hndl, *results, 0, bah.GetMessages());
                 bah.ResetMessages();
             } else {
-                BlastFormatter_PreFetchSequenceData(*results, scope);
+                BlastFormatter_PreFetchSequenceData(*results, scope,
+                		                            fmt_args->GetFormattedOutputChoice());
                 ITERATE(CSearchResultSet, result, *results) {
                     formatter.PrintOneResultSet(**result, query);
                 }
diff --git a/c++/src/app/blast/tblastx_app.cpp b/c++/src/app/blast/tblastx_app.cpp
index 808f133..91af153 100644
--- a/c++/src/app/blast/tblastx_app.cpp
+++ b/c++/src/app/blast/tblastx_app.cpp
@@ -1,4 +1,4 @@
-/*  $Id: tblastx_app.cpp 495295 2016-03-16 14:53:41Z ivanov $
+/*  $Id: tblastx_app.cpp 509280 2016-08-04 16:03:11Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * TBLASTX command line application
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-	"$Id: tblastx_app.cpp 495295 2016-03-16 14:53:41Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <algo/blast/api/local_blast.hpp>
@@ -190,7 +185,8 @@ int CTblastxApp::Run(void)
                 formatter.WriteArchive(*queries, *opts_hndl, *results, 0, bah.GetMessages());
                 bah.ResetMessages();
             } else {
-                BlastFormatter_PreFetchSequenceData(*results, scope);
+                BlastFormatter_PreFetchSequenceData(*results, scope,
+                		                            fmt_args->GetFormattedOutputChoice());
                 ITERATE(CSearchResultSet, result, *results) {
                     formatter.PrintOneResultSet(**result, query_batch);
                 }
diff --git a/c++/src/app/blast/update_blastdb.pl b/c++/src/app/blast/update_blastdb.pl
index 4aba43a..76a046e 100755
--- a/c++/src/app/blast/update_blastdb.pl
+++ b/c++/src/app/blast/update_blastdb.pl
@@ -1,5 +1,5 @@
 #!/usr/bin/perl
-# $Id: update_blastdb.pl 446062 2014-09-10 21:38:05Z camacho $
+# $Id: update_blastdb.pl 504861 2016-06-20 15:45:40Z boratyng $
 # ===========================================================================
 #
 #                            PUBLIC DOMAIN NOTICE
@@ -82,7 +82,7 @@ $|++;
 # Connect and download files
 my $ftp = &connect_to_ftp() unless ($opt_show_version);
 if ($opt_show_version) {
-    my $revision = '$Revision: 446062 $';
+    my $revision = '$Revision: 504861 $';
     $revision =~ s/\$Revision: | \$//g;
     print "$0 version $revision\n";
 } elsif ($opt_showall) {
diff --git a/c++/src/app/blastdb/Makefile.convert2blastmask.app b/c++/src/app/blastdb/Makefile.convert2blastmask.app
index 611960c..ff73281 100644
--- a/c++/src/app/blastdb/Makefile.convert2blastmask.app
+++ b/c++/src/app/blastdb/Makefile.convert2blastmask.app
@@ -5,7 +5,7 @@ REQUIRES = objects
 APP = convert2blastmask
 SRC = convert2blastmask
 
-LIB = seqmasks_io $(BLAST_LIBS) $(OBJMGR_LIBS:%=%$(STATIC))
+LIB = $(BLAST_LIBS) $(OBJMGR_LIBS)
 
 CFLAGS   = $(FAST_CFLAGS)
 CXXFLAGS = $(FAST_CXXFLAGS)
diff --git a/c++/src/app/blastdb/Makefile.makeblastdb.app b/c++/src/app/blastdb/Makefile.makeblastdb.app
index c9ab8bb..405031a 100644
--- a/c++/src/app/blastdb/Makefile.makeblastdb.app
+++ b/c++/src/app/blastdb/Makefile.makeblastdb.app
@@ -2,7 +2,7 @@ WATCHERS = camacho fongah2
 
 APP = makeblastdb
 SRC = makeblastdb masked_range_set
-LIB_ = $(BLAST_INPUT_LIBS) writedb $(BLAST_LIBS) $(OBJMGR_LIBS)
+LIB_ = writedb $(BLAST_INPUT_LIBS) $(BLAST_LIBS) $(OBJMGR_LIBS)
 LIB = $(LIB_:%=%$(STATIC))
 
 CFLAGS   = $(FAST_CFLAGS)
diff --git a/c++/src/app/blastdb/Makefile.makeprofiledb.app b/c++/src/app/blastdb/Makefile.makeprofiledb.app
index 476ca1b..88c7292 100644
--- a/c++/src/app/blastdb/Makefile.makeprofiledb.app
+++ b/c++/src/app/blastdb/Makefile.makeprofiledb.app
@@ -2,7 +2,7 @@ WATCHERS = fongah2
 
 APP = makeprofiledb
 SRC = makeprofiledb
-LIB_ = $(BLAST_INPUT_LIBS) writedb $(BLAST_LIBS) $(OBJMGR_LIBS)
+LIB_ = writedb $(BLAST_INPUT_LIBS) $(BLAST_LIBS) $(OBJMGR_LIBS)
 LIB = $(LIB_:%=%$(STATIC))
 
 CFLAGS   = $(FAST_CFLAGS)
diff --git a/c++/src/app/blastdb/blastdb_aliastool.cpp b/c++/src/app/blastdb/blastdb_aliastool.cpp
index 304ab2a..5827a7b 100644
--- a/c++/src/app/blastdb/blastdb_aliastool.cpp
+++ b/c++/src/app/blastdb/blastdb_aliastool.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastdb_aliastool.cpp 488259 2015-12-29 14:32:15Z camacho $
+/*  $Id: blastdb_aliastool.cpp 519975 2016-11-21 18:09:00Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Command line tool to create BLAST database aliases and associated files. 
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blastdb_aliastool.cpp 488259 2015-12-29 14:32:15Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <corelib/ncbistre.hpp>
@@ -108,9 +103,9 @@ const char * const CBlastDBAliasApp::DOCUMENTATION = "\n\n"
 "   binary format. This can be provided as an argument to the -gilist option\n"
 "   of the BLAST search command line binaries or to the -gilist option of\n"
 "   this program to create an alias file for a BLAST database (see below).\n\n"
-"2) Alias file creation (restricting with GI List):\n"
-"   Creates an alias for a BLAST database and a GI list which restricts this\n"
-"   database. This is useful if one often searches a subset of a database\n"
+"2) Alias file creation (restricting with GI List or Sequence ID List):\n"
+"   Creates an alias for a BLAST database and a GI or ID list which restricts\n"
+"   this database. This is useful if one often searches a subset of a database\n"
 "   (e.g., based on organism or a curated list). The alias file makes the\n"
 "   search appear as if one were searching a regular BLAST database rather\n"
 "   than the subset of one.\n\n"
@@ -135,7 +130,8 @@ void CBlastDBAliasApp::Init()
     dflt += " with the .bgl extension";
 
     const char* exclusions[]  = { kArgDb.c_str(), kArgDbType.c_str(), kArgDbTitle.c_str(), 
-		kArgGiList.c_str(), kArgOutput.c_str(), "dblist", "num_volumes", "vdblist" };
+              kArgGiList.c_str(), kArgSeqIdList.c_str(), kArgOutput.c_str(),
+              "dblist", "num_volumes", "vdblist" };
     arg_desc->SetCurrentGroup("GI file conversion options");
     arg_desc->AddOptionalKey("gi_file_in", "input_file",
                      "Text file to convert, should contain one GI per line",
@@ -158,7 +154,6 @@ void CBlastDBAliasApp::Init()
     arg_desc->SetCurrentGroup("Alias file creation options");
     arg_desc->AddOptionalKey(kArgDb, "dbname", "BLAST database name", 
                              CArgDescriptions::eString);
-    arg_desc->SetDependency(kArgDb, CArgDescriptions::eRequires, kArgGiList);
     arg_desc->SetDependency(kArgDb, CArgDescriptions::eRequires, kOutput);
 
     arg_desc->AddDefaultKey(kArgDbType, "molecule_type",
@@ -181,6 +176,16 @@ void CBlastDBAliasApp::Init()
                              "to binary",
                              CArgDescriptions::eInputFile);
     arg_desc->SetDependency(kArgGiList, CArgDescriptions::eRequires, kOutput);
+
+    arg_desc->AddOptionalKey(kArgSeqIdList, "input_file", 
+                             "Text sequence id or accession file to restrict "
+                             "the BLAST database provided in -db argument",
+                             CArgDescriptions::eInputFile);
+
+    arg_desc->SetDependency(kArgSeqIdList, CArgDescriptions::eRequires, kOutput);
+    arg_desc->SetDependency(kArgSeqIdList, CArgDescriptions::eExcludes,
+                            kArgGiList);
+
 #ifdef NCBI_TI
     arg_desc->AddFlag("process_as_tis", 
                       "Process all numeric ID lists as TIs instead of GIs", true);
@@ -226,6 +231,7 @@ void CBlastDBAliasApp::Init()
                              CArgDescriptions::eInteger);
     arg_desc->SetDependency("num_volumes", CArgDescriptions::eExcludes, kArgDb);
     arg_desc->SetDependency("num_volumes", CArgDescriptions::eExcludes, kArgGiList);
+    arg_desc->SetDependency("num_volumes", CArgDescriptions::eExcludes, kArgSeqIdList);
     arg_desc->SetDependency("num_volumes", CArgDescriptions::eRequires, kOutput);
     arg_desc->SetDependency("num_volumes", CArgDescriptions::eRequires, kArgDbType);
     arg_desc->SetDependency("num_volumes", CArgDescriptions::eRequires, kArgDbTitle);
@@ -284,12 +290,25 @@ CBlastDBAliasApp::CreateAliasFile() const
     if (args.Exist("process_as_tis") && args["process_as_tis"]) {
         isTiList = true;
     }
+
+    if (args[kArgDb].HasValue() && !args[kArgGiList].HasValue() &&
+        !args[kArgSeqIdList].HasValue()) {
+
+        NCBI_THROW(CInputException, eInvalidInput, "Either gilist or "
+                   "seqid_list must be specified if database name is used");
+    }
+
     if (args[kArgDbTitle].HasValue()) {
         title = args[kArgDbTitle].AsString();
     } else if (args[kArgDb].HasValue()) {
-        _ASSERT(args[kArgGiList].HasValue());
-        title = args[kArgDb].AsString() + " limited by " + 
-            args[kArgGiList].AsString();
+        _ASSERT(args[kArgGiList].HasValue() || args[kArgSeqIdList].HasValue());
+        title = args[kArgDb].AsString() + " limited by ";
+        if (args[kArgGiList]) {
+            title += args[kArgGiList].AsString();
+        }
+        else {
+            title += args[kArgSeqIdList].AsString();
+        }
     }
     const CWriteDB::ESeqType seq_type = 
         args[kArgDbType].AsString() == "prot"
@@ -316,6 +335,14 @@ CBlastDBAliasApp::CreateAliasFile() const
         }
     }
 
+    string seqid_list = args[kArgSeqIdList] ? args[kArgSeqIdList].AsString() :
+        kEmptyStr;
+    if ( !seqid_list.empty() ) {
+        if ( !CFile(seqid_list).Exists() ) {
+            NCBI_THROW(CSeqDBException, eFileErr, seqid_list + " not found");
+        }
+    }
+
     const EAliasFileFilterType alias_type = (isTiList ? eTiList : eGiList);
     if (args["dblist"].HasValue() || args["dblist_file"].HasValue()) {
         vector<string> dbs2aggregate = x_GetDbsToAggregate("dblist", "dblist_file");
@@ -326,11 +353,16 @@ CBlastDBAliasApp::CreateAliasFile() const
             static_cast<unsigned int>(args["num_volumes"].AsInteger());
         CWriteDB_CreateAliasFile(args[kOutput].AsString(), num_vols, seq_type,
                                  title);
-    } else if (args[kArgDb].HasValue()){
+    } else if (args[kArgDb].HasValue() && args[kArgGiList]){
         CWriteDB_CreateAliasFile(args[kOutput].AsString(),
                                  args[kArgDb].AsString(),
                                  seq_type, gilist,
                                  title, alias_type);
+    } else {
+        CWriteDB_CreateAliasFile(args[kOutput].AsString(),
+                                 args[kArgDb].AsString(),
+                                 seq_type, seqid_list,
+                                 title, eSeqIdList);
     }
 
     if (args["vdblist"].HasValue() || args["vdblist_file"].HasValue()) {
@@ -425,6 +457,6 @@ int CBlastDBAliasApp::Run(void)
 #ifndef SKIP_DOXYGEN_PROCESSING
 int main(int argc, const char* argv[] /*, const char* envp[]*/)
 {
-    return CBlastDBAliasApp().AppMain(argc, argv, 0, eDS_Default, "");
+    return CBlastDBAliasApp().AppMain(argc, argv);
 }
 #endif /* SKIP_DOXYGEN_PROCESSING */
diff --git a/c++/src/app/blastdb/blastdbcheck.cpp b/c++/src/app/blastdb/blastdbcheck.cpp
index dd36992..802b7c2 100644
--- a/c++/src/app/blastdb/blastdbcheck.cpp
+++ b/c++/src/app/blastdb/blastdbcheck.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastdbcheck.cpp 473030 2015-07-15 19:29:59Z camacho $
+/*  $Id: blastdbcheck.cpp 492284 2016-02-16 16:55:37Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1515,6 +1515,6 @@ void CBlastDbCheckApplication::Exit(void)
 int main(int argc, const char* argv[])
 {
     // Execute main application function
-    return CBlastDbCheckApplication().AppMain(argc, argv, 0, eDS_Default, "");
+    return CBlastDbCheckApplication().AppMain(argc, argv);
 #endif /* SKIP_DOXYGEN_PROCESSING */
 }
diff --git a/c++/src/app/blastdb/blastdbcmd.cpp b/c++/src/app/blastdb/blastdbcmd.cpp
index 814e97a..282c0ee 100644
--- a/c++/src/app/blastdb/blastdbcmd.cpp
+++ b/c++/src/app/blastdb/blastdbcmd.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastdbcmd.cpp 489108 2016-01-08 15:13:21Z fongah2 $
+/*  $Id: blastdbcmd.cpp 518486 2016-11-03 16:05:31Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,18 +32,13 @@
  * successor to fastacmd from the C toolkit
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: blastdbcmd.cpp 489108 2016-01-08 15:13:21Z fongah2 $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <algo/blast/api/version.hpp>
 #include <objtools/blast/seqdb_reader/seqdbexpert.hpp>
 #include <algo/blast/api/blast_exception.hpp>
 #include <algo/blast/blastinput/blast_input_aux.hpp>
-#include <objtools/blast/blastdb_format/seq_writer.hpp>
+#include <objtools/blast/blastdb_format/seq_formatter.hpp>
 #include <objtools/blast/blastdb_format/blastdb_formatter.hpp>
 #include <objtools/blast/blastdb_format/blastdb_seqid.hpp>
 
@@ -77,22 +72,22 @@ private:
     CRef<CSeqDBExpert> m_BlastDb;
     /// Is the database protein
     bool m_DbIsProtein;
-    /// Sequence range, non-empty if provided as command line argument
-    TSeqRange m_SeqRange;
-    /// Strand to retrieve
-    ENa_strand m_Strand;
     /// output is FASTA
     bool m_FASTA;
     /// output is ASN.1 defline
-    bool m_Asn1DeflineOutput;
+    bool m_Asn1Bioseq;
     /// should we find duplicate entries?
     bool m_GetDuplicates;
     /// should we output target sequence only?
     bool m_TargetOnly;
 
+    CBlastDB_FormatterConfig m_Config;
+
     /// Initializes the application's data members
     void x_InitApplicationData();
 
+    string x_InitSearchRequest();
+
     /// Prints the BLAST database information (e.g.: handles -info command line
     /// option)
     void x_PrintBlastDatabaseInformation();
@@ -101,159 +96,192 @@ private:
     /// @return 0 on success; 1 if some sequences were not retrieved
     int x_ProcessSearchRequest();
 
-    /// Vector of sequence identifiers in a BLAST database
-    typedef vector< CRef<CBlastDBSeqId> > TQueries;
-
-    /// Extract the queries for the BLAST database from the command line
-    /// options
-    /// @param queries queries to retrieve [in|out]
+    /// Process batch entry with range, strand and filter id
+    /// @param args program input args
+    /// @param seq_fmt sequence formatter object
     /// @return 0 on sucess; 1 if some queries were not processed
-    int x_GetQueries(TQueries& queries) const;
-
-    /// Add a query ID for processing
-    /// @param retval the return value where the queries will be added [in|out]
-    /// @param entry the user's query [in]
-    /// @return 0 on sucess; 1 if some seqid is not translated
-    int x_AddSeqId(CBlastDBCmdApp::TQueries& retval, const string& entry) const;
+    int x_ProcessBatchEntry(CBlastDB_Formatter & seq_fmt);
 
-    /// Add an OID for processing
-    /// @param retval the return value where the queries will be added [in|out]
-    /// @param entry the user's query [in]
-    void x_AddOid(CBlastDBCmdApp::TQueries& retval, const int oid, bool check=false) const;
-
-    /// Process batch entry with range, strand and filter id
+    /// Process entry with range, strand and filter id
     /// @param args program input args
     /// @param seq_fmt sequence formatter object
     /// @return 0 on sucess; 1 if some queries were not processed
-    int x_ProcessBatchEntry(const CArgs& args, CSeqFormatter & seq_fmt);
-};
+    int x_ProcessEntry(CBlastDB_Formatter & fmt);
 
-int
-CBlastDBCmdApp::x_AddSeqId(CBlastDBCmdApp::TQueries& retval,
-                           const string& entry) const
-{
-    // Process get dups
-    if (m_GetDuplicates) {
-        vector<int> oids;
-        m_BlastDb->AccessionToOids(entry, oids);
-        ITERATE(vector<int>, oid, oids) {
-            x_AddOid(retval, *oid, true);
-        }
-        return 0;
-    }
+    int x_ProcessSearchType(CBlastDB_Formatter & fmt);
 
-    // FASTA / target_only just need one id
-    if (m_TargetOnly) {
-        retval.push_back(CRef<CBlastDBSeqId>(new CBlastDBSeqId(entry)));
-        return 0;
-    }
+    bool x_GetOids(const string & acc, vector<int> & oids);
 
-    // Default: find oid first and add all pertinent
-    vector<int> oids;
-    m_BlastDb->AccessionToOids(entry, oids);
-    if (!oids.empty()) {
-        x_AddOid(retval, oids[0], true);
-        return 0;
-    }
+    int x_ModifyConfigForBatchEntry(const vector<string> & tmp);
+
+    bool x_UseLongSeqIds();
+};
 
-    ERR_POST(Error << entry << ": OID not found");
-    return 1;
+bool
+CBlastDBCmdApp::x_GetOids(const string & acc, vector<int> & oids)
+{
+	Int8 num_id = NStr::StringToNumeric<Int8>(acc, NStr::fConvErr_NoThrow);
+	if(!errno) {
+		int gi_oid = -1;
+		m_BlastDb->GiToOidwFilterCheck(num_id, gi_oid);
+		if(gi_oid < 0) {
+			m_BlastDb->AccessionToOids(acc, oids);
+		}
+		else {
+			oids.push_back(gi_oid);
+		}
+			
+	}
+	else {
+		m_BlastDb->AccessionToOids(acc, oids);
+	}
+	if(oids.empty()) {
+		ERR_POST(Error <<  "Entry not found: " << acc);
+		return false;
+	}
+	return true;
 }
 
-void
-CBlastDBCmdApp::x_AddOid(CBlastDBCmdApp::TQueries& retval,
-                         const int oid,
-                         bool check) const
+int
+CBlastDBCmdApp::x_ProcessEntry(CBlastDB_Formatter & fmt)
 {
-    // check to see if this oid has been excluded
-    if (check) {
-        list< CRef<CSeq_id> > filtered_ids = m_BlastDb->GetSeqIDs(oid);
-        if (filtered_ids.empty()) {
-            return;
-        }
-    }
+	unsigned int err_found = 0;
+    const CArgs& args = GetArgs();
+    _ASSERT(m_BlastDb.NotEmpty());
 
-    // FASTA output just need one id
-    if (m_FASTA || m_Asn1DeflineOutput) {
-        CRef<CBlastDBSeqId> blastdb_seqid(new CBlastDBSeqId());
-        blastdb_seqid->SetOID(oid);
-        retval.push_back(blastdb_seqid);
-        return;
+   	if (args["pig"].HasValue()) {
+    	CSeqDB::TOID oid;
+    	m_BlastDb->PigToOid(args["pig"].AsInteger(),oid);
+   		fmt.Write(oid, m_Config);
+    } else if (args["entry"].HasValue()) {
+    	static const string kDelim(",");
+    	const string& entry = args["entry"].AsString();
+
+    	vector<string> queries;
+       	if (entry.find(kDelim[0]) != string::npos) {
+           	NStr::Split(entry, kDelim, queries, NStr::fSplit_NoMergeDelims);
+       	} else {
+       		queries.resize(1);
+       		queries[0]  = entry;
+     	}
+   		for(unsigned int i=0; i < queries.size(); i++) {
+     		vector<CSeqDB::TOID> oids;
+     		if(x_GetOids(queries[i], oids)) {
+     			if (m_GetDuplicates) {
+     				for(unsigned int j=0; j < oids.size(); j++) {
+     					fmt.Write(oids[j], m_Config);
+     				}
+     			}
+     			else {
+     				if(m_TargetOnly) {
+     					fmt.Write(oids[0], m_Config, queries[i]);
+     				}
+     				else {
+     					fmt.Write(oids[0], m_Config);
+     				}
+     			}
+     		}
+     		else {
+     			err_found ++;
+     		}
+     	}
+   		if(err_found == queries.size()) {
+   			NCBI_THROW(CInputException, eInvalidInput,
+   		               "Entry or entries not found in BLAST database");
+   		}
     }
+   	return (err_found) ? 1:0;
+}
 
-    // Not a NR database, add oid instead
-    vector<TGi> gis;
-    m_BlastDb->GetGis(oid, gis);
-    if (gis.empty()) {
-	list< CRef<CSeq_id> > ids = m_BlastDb->GetSeqIDs(oid);
-	ITERATE(list< CRef<CSeq_id> > , id, ids) {
-		CRef<CBlastDBSeqId> blastdb_seqid(new CBlastDBSeqId((*id)->AsFastaString()));
-        	retval.push_back(blastdb_seqid);
+bool s_IsMaskAlgoIdValid(CSeqDB & blastdb, int id)
+{
+	if (id >= 0) {
+	    vector<int> algo_id(1, id);
+	    vector<int> invalid_algo_ids = blastdb.ValidateMaskAlgorithms(algo_id);
+	    if ( !invalid_algo_ids.empty()) {
+	    	ERR_POST(Error << "Invalid filtering algorithm ID: " << NStr::IntToString(id));
+	    	return false;
+	    }
 	}
-        return;
-    }
+	return true;
+}
 
-    // Default:  add all possible ids
-    ITERATE(vector<TGi>, gi, gis) {
-        retval.push_back(CRef<CBlastDBSeqId>
-                         (new CBlastDBSeqId(NStr::IntToString(GI_TO(TIntId, *gi)))));
+int CBlastDBCmdApp::x_ModifyConfigForBatchEntry(const vector<string> & tmp)
+{
+	int status = 0;
+	if (!m_DbIsProtein) {
+		m_Config.m_Strand = eNa_strand_plus;
+	}
+   	m_Config.m_SeqRange = TSeqRange::GetEmpty();
+   	m_Config.m_FiltAlgoId = -1;
+   	for(unsigned int i=1; i < tmp.size(); i++) {
+   		if(tmp[i].find('-')!= string::npos)
+    	{
+    		try {
+    			m_Config.m_SeqRange = ParseSequenceRangeOpenEnd(tmp[i]);
+    		} catch (...) {
+    		}
+    	}
+    	else if (!m_DbIsProtein && NStr::EqualNocase(tmp[i].c_str(), "minus")) {
+    		m_Config.m_Strand = eNa_strand_minus;
+    	}
+    	else {
+    		m_Config.m_FiltAlgoId = NStr::StringToNonNegativeInt(tmp[i]);
+    		if(!s_IsMaskAlgoIdValid(*m_BlastDb, m_Config.m_FiltAlgoId)){
+    			status = 1;
+    		}
+    	}
     }
+   	return status;
 }
 
 int
-CBlastDBCmdApp::x_GetQueries(CBlastDBCmdApp::TQueries& retval) const
+CBlastDBCmdApp::x_ProcessBatchEntry(CBlastDB_Formatter & fmt)
 {
-    int err_found = 0;
-    int err_here;
-    const CArgs& args = GetArgs();
-
-    retval.clear();
-
-    _ASSERT(m_BlastDb.NotEmpty());
-
-    if (args["pig"].HasValue()) {
-        retval.reserve(1);
-        retval.push_back(CRef<CBlastDBSeqId>
-                         (new CBlastDBSeqId(args["pig"].AsInteger())));
+	int err_found = 0;
+   	const CArgs& args = GetArgs();
+    CNcbiIstream& input = args["entry_batch"].AsInputFile();
 
-    } else if (args["entry"].HasValue()) {
+    while (input) {
+        string line;
+        NcbiGetlineEOL(input, line);
+        if ( !line.empty() ) {
+        	vector<string> tmp;
+        	NStr::Split(line, " \t", tmp, NStr::fSplit_MergeDelims);
+        	if(tmp.empty()) {
+        		continue;
+        	}
+        	if(x_ModifyConfigForBatchEntry(tmp))  {
+        		err_found ++;
+        		ERR_POST (Error << "Skipped " << tmp[0]);
+        		continue;
+        	}
+   			vector<int> oids;
+         	if(!x_GetOids(tmp[0], oids)) {
+         		err_found ++;
+        		ERR_POST (Error << "Skipped " << tmp[0]);
+        		continue;
+         	}
 
-        static const string kDelim(",");
-        const string& entry = args["entry"].AsString();
-
-        if (entry.find(kDelim[0]) != string::npos) {
-            vector<string> tokens;
-            NStr::Split(entry, kDelim, tokens, NStr::fSplit_NoMergeDelims);
-            ITERATE(vector<string>, itr, tokens) {
-                err_found += (err_here = x_AddSeqId(retval, *itr));
-                if (err_here) {
-                    ERR_POST(Error << *itr << ": OID not found");
-                }
-            }
-        } else if (entry == "all") {
-            for (int i = 0; m_BlastDb->CheckOrFindOID(i); i++) {
-                x_AddOid(retval, i);
-            }
-        } else {
-            err_found += (err_here = x_AddSeqId(retval, entry));
-            if (err_here) {
-                ERR_POST(Error << entry << ": OID not found");
-            }
+         	if (m_GetDuplicates) {
+         		for(unsigned int j=0; j < oids.size(); j++) {
+         			fmt.Write(oids[j], m_Config);
+         		}
+           	}
+         	else {
+         		if(m_TargetOnly) {
+         			fmt.Write(oids[0], m_Config, tmp[0]);
+         		}
+         		else {
+         			fmt.Write(oids[0], m_Config);
+         		}
+         	}
         }
-
-    } else {
-        NCBI_THROW(CInputException, eInvalidInput,
-                   "Must specify query type: one of 'entry', 'entry_batch', or 'pig'");
     }
-
-    if (retval.empty()) {
-        NCBI_THROW(CInputException, eInvalidInput,
-                   "Entry or entries not found in BLAST database");
-    }
-
     return (err_found) ? 1 : 0;
 }
 
+
 void
 CBlastDBCmdApp::x_InitApplicationData()
 {
@@ -261,28 +289,7 @@ CBlastDBCmdApp::x_InitApplicationData()
 
     CSeqDB::ESeqType seqtype = ParseMoleculeTypeString(args[kArgDbType].AsString());
     m_BlastDb.Reset(new CSeqDBExpert(args[kArgDb].AsString(), seqtype));
-
     m_DbIsProtein = static_cast<bool>(m_BlastDb->GetSequenceType() == CSeqDB::eProtein);
-
-    m_SeqRange = TSeqRange::GetEmpty();
-    if (args["range"].HasValue()) {
-        m_SeqRange = ParseSequenceRangeOpenEnd(args["range"].AsString());
-    }
-
-    m_Strand = eNa_strand_unknown;
-    if (args["strand"].HasValue() && !m_DbIsProtein) {
-        if (args["strand"].AsString() == "plus") {
-            m_Strand = eNa_strand_plus;
-        } else if (args["strand"].AsString() == "minus") {
-            m_Strand = eNa_strand_minus;
-        } else {
-            abort();    // both strands not supported
-        }
-    }
-
-    m_GetDuplicates = args["get_dups"];
-
-    m_TargetOnly = args["target_only"];
 }
 
 void
@@ -293,7 +300,7 @@ CBlastDBCmdApp::x_PrintBlastDatabaseInformation()
     const string kLetters = m_DbIsProtein ? "residues" : "bases";
     const CArgs& args = GetArgs();
 
-    CNcbiOstream& out = args["out"].AsOutputFile();
+    CNcbiOstream& out = args[kArgOutput].AsOutputFile();
 
     // Print basic database information
     out << "Database: " << m_BlastDb->GetTitle() << endl
@@ -324,168 +331,159 @@ CBlastDBCmdApp::x_PrintBlastDatabaseInformation()
     }
 }
 
-int
-CBlastDBCmdApp::x_ProcessSearchRequest()
+string
+CBlastDBCmdApp::x_InitSearchRequest()
 {
-    const CArgs& args = GetArgs();
-    CNcbiOstream& out = args["out"].AsOutputFile();
-
-    CSeqFormatterConfig conf;
-    conf.m_LineWidth = args["line_length"].AsInteger();
-    conf.m_SeqRange = m_SeqRange;
-    conf.m_Strand = m_Strand;
-    conf.m_TargetOnly = m_TargetOnly;
-    conf.m_UseCtrlA = args["ctrl_a"];
-    if (args["mask_sequence_with"].HasValue()) {
-    	 conf.m_FiltAlgoId = -1;
-    	 conf.m_FiltAlgoId = NStr::StringToInt(args["mask_sequence_with"].AsString(), NStr::fConvErr_NoThrow);
-    	 if(errno)
-    		 conf.m_FiltAlgoId = m_BlastDb->GetMaskAlgorithmId(args["mask_sequence_with"].AsString());
-    }
+   	const CArgs& args = GetArgs();
+    m_GetDuplicates = args["get_dups"];
+    m_TargetOnly = args["target_only"];
 
-    string outfmt;
+    string outfmt = kEmptyStr;
     if (args["outfmt"].HasValue()) {
-        outfmt = args["outfmt"].AsString();
+    	outfmt = args["outfmt"].AsString();
         m_FASTA = false;
-        m_Asn1DeflineOutput = false;
+        m_Asn1Bioseq = false;
+
+        if ((outfmt.find("%f") != string::npos &&
+           	(outfmt.find("%b") != string::npos || outfmt.find("%d") != string::npos)) ||
+            (outfmt.find("%b") != string::npos && outfmt.find("%d") != string::npos)) {
+           	NCBI_THROW(CInputException, eInvalidInput,
+                    	"The %f, %b, %d output format options cannot be specified together.");
+        }
 
-        if (outfmt.find("%f") != string::npos &&
-            outfmt.find("%d") != string::npos) {
-            NCBI_THROW(CInputException, eInvalidInput,
-                "The %d and %f output format options cannot be specified together.");
+        if (outfmt.find("%b") != string::npos) {
+           	outfmt = "%b";
+           	m_Asn1Bioseq = true;
         }
 
         // If "%f" is found within outfmt, discard everything else
         if (outfmt.find("%f") != string::npos) {
-            outfmt = "%f";
-            m_FASTA = true;
+           	outfmt = "%f";
+           	m_FASTA = true;
         }
-        // If "%d" is found within outfmt, discard everything else
+
         if (outfmt.find("%d") != string::npos) {
-            outfmt = "%d";
-            m_Asn1DeflineOutput = true;
+           	outfmt = "%d";
         }
+
         if (outfmt.find("%m") != string::npos) {
-            int algo_id = 0;
-            size_t i = outfmt.find("%m") + 2;
-            bool found = false;
-            while (i < outfmt.size()
-                && outfmt[i] >= '0' && outfmt[i] <= '9') {
-                algo_id = algo_id * 10 + (outfmt[i] - '0');
-                outfmt.erase(i, 1);
-                found = true;
+           	int algo_id = 0;
+           	size_t i = outfmt.find("%m") + 2;
+           	bool found = false;
+           	while (i < outfmt.size() && outfmt[i] >= '0' && outfmt[i] <= '9') {
+           		algo_id = algo_id * 10 + (outfmt[i] - '0');
+               	outfmt.erase(i, 1);
+               	found = true;
             }
             if (!found) {
-                NCBI_THROW(CInputException, eInvalidInput,
-                    "The option '-outfmt %m' is not followed by a masking algo ID.");
+               	NCBI_THROW(CInputException, eInvalidInput,
+                       	   "The option '-outfmt %m' is not followed by a masking algo ID.");
             }
-            conf.m_FmtAlgoId = algo_id;
-        }
-    }
-
-    bool errors_found = false;
-    CSeqFormatter seq_fmt(outfmt, *m_BlastDb, out, conf);
-
-    /* Special case: full db dump when no range and mask data is specified */
-    if (m_FASTA &&
-        args["entry"].HasValue() && args["entry"].AsString() == "all" &&
-        ! args["mask_sequence_with"].HasValue() &&
-        ! args["range"].HasValue()) {
-
-        try {
-            seq_fmt.DumpAll(*m_BlastDb, conf);
-        } catch (const CException& e) {
-            ERR_POST(Error << e.GetMsg());
-            errors_found = true;
-        } catch (...) {
-            ERR_POST(Error << "Failed to retrieve requested item");
-            errors_found = true;
+            m_Config.m_FmtAlgoId = algo_id;
+    		if(!s_IsMaskAlgoIdValid(*m_BlastDb, m_Config.m_FmtAlgoId)) {
+    			NCBI_THROW(CInvalidDataException, eInvalidInput,
+    				                   "Invalid filtering algorithm ID for outfmt %m.");
+    		}
         }
-        return errors_found ? 1 : 0;
     }
 
-    if (args["entry_batch"].HasValue()) {
-       	return x_ProcessBatchEntry(args, seq_fmt);
+    if (args["strand"].HasValue() && !m_DbIsProtein) {
+    	if (args["strand"].AsString() == "plus") {
+                m_Config.m_Strand = eNa_strand_plus;
+            } else if (args["strand"].AsString() == "minus") {
+                m_Config.m_Strand = eNa_strand_minus;
+            } else {
+            	NCBI_THROW(CInputException, eInvalidInput,
+            	           "Both strands is not supported");
+            }
     }
-
-    TQueries queries;
-	errors_found = (x_GetQueries(queries) > 0 ? true : false);
-    _ASSERT( !queries.empty() );
-
-    NON_CONST_ITERATE(TQueries, itr, queries) {
-        try {
-            seq_fmt.Write(**itr);
-        } catch (const CException& e) {
-            ERR_POST(Error << e.GetMsg());
-            errors_found = true;
-        } catch (...) {
-            ERR_POST(Error << "Failed to retrieve requested item");
-            errors_found = true;
+    m_Config.m_UseCtrlA = args["ctrl_a"];
+    if (args["mask_sequence_with"].HasValue()) {
+    	m_Config.m_FiltAlgoId = -1;
+        m_Config.m_FiltAlgoId = NStr::StringToInt(args["mask_sequence_with"].AsString(), NStr::fConvErr_NoThrow);
+        if(errno) {
+        	m_Config.m_FiltAlgoId = m_BlastDb->GetMaskAlgorithmId(args["mask_sequence_with"].AsString());
         }
+   		if(!s_IsMaskAlgoIdValid(*m_BlastDb, m_Config.m_FiltAlgoId)){
+   			NCBI_THROW(CInvalidDataException, eInvalidInput,
+   		               "Invalid filtering algorithm ID for mask_sequence_with.");
+   		}
     }
-    return errors_found ? 1 : 0;
+    if (args["range"].HasValue()) {
+    	m_Config.m_SeqRange = ParseSequenceRangeOpenEnd(args["range"].AsString());
+    }
+     return outfmt;
 }
 
-int CBlastDBCmdApp::x_ProcessBatchEntry(const CArgs& args, CSeqFormatter & seq_fmt)
+int
+CBlastDBCmdApp::x_ProcessSearchType(CBlastDB_Formatter & fmt)
 {
-    CNcbiIstream& input = args["entry_batch"].AsInputFile();
-    bool err_found = false;
-    while (input) {
-        string line;
-        NcbiGetlineEOL(input, line);
-        if ( !line.empty() ) {
-        	vector<string> tmp;
-        	NStr::Split(line, " \t", tmp, NStr::fSplit_MergeDelims);
-        	if(tmp.empty())
-        		continue;
+   	const CArgs& args = GetArgs();
+	if (args["entry"].HasValue() && args["entry"].AsString() == "all") {
+		fmt.DumpAll(m_Config);
+	}
+	else if (args["entry_batch"].HasValue()) {
+		return x_ProcessBatchEntry(fmt);
+	}
+	else if (args["entry"].HasValue() || args["pig"].HasValue()) {
+		return x_ProcessEntry(fmt);
+	}
+	else {
+		NCBI_THROW(CInputException, eInvalidInput,
+		       	   "Must specify query type: one of 'entry', 'entry_batch', or 'pig'");
+	}
+	return 0;
+}
 
-        	TQueries queries;
-        	if(x_AddSeqId(queries, tmp[0]) > 0 )
-        			err_found = true;
-
-            if(queries.empty())
-            	continue;
-
-           	TSeqRange seq_range(TSeqRange::GetEmpty());
-            ENa_strand seq_strand = eNa_strand_plus;
-           	int seq_algo_id = -1;
-
-           	for(unsigned int i=1; i < tmp.size(); i++) {
-
-           		if(tmp[i].find('-')!= string::npos)
-            	{
-            		try {
-            			seq_range = ParseSequenceRangeOpenEnd(tmp[i]);
-            		} catch (...) {
-            			seq_range = TSeqRange::GetEmpty();
-            		}
-            	}
-            	else if (!m_DbIsProtein && NStr::EqualNocase(tmp[i].c_str(), "minus")) {
-            		seq_strand = eNa_strand_minus;
-            	}
-            	else {
-            		seq_algo_id = NStr::StringToNonNegativeInt(tmp[i]);
-            	}
-            }
+bool CBlastDBCmdApp::x_UseLongSeqIds()
+{
+	const CArgs& args = GetArgs();
+	if (args["long_seqids"].AsBoolean()) {
+		return true;
+	}
+	CNcbiApplication* app = CNcbiApplication::Instance();
+	if (app) {
+		 const CNcbiRegistry& registry = app->GetConfig();
+		 if (registry.Get("BLAST", "LONG_SEQID") == "1") {
+			 return true;
+		 }
+	}
+	return false;
+}
 
-           	seq_fmt.SetConfig(seq_range, seq_strand, seq_algo_id);
-           	NON_CONST_ITERATE(TQueries, itr, queries) {
-           	    try {
-           	        seq_fmt.Write(**itr);
-           	    } catch (const CException& e) {
-           	        ERR_POST(Error << e.GetMsg() << ": " << **itr);
-           	        err_found = true;
-           	    } catch (...) {
-           	        ERR_POST(Error << "Failed to retrieve requested item: "
-           	                << **itr);
-           	        err_found = true;
-           	    }
-           	}
-        }
+int
+CBlastDBCmdApp::x_ProcessSearchRequest()
+{
+   	int err_found = 0;
+    try {
+    	const CArgs& args = GetArgs();
+    	CNcbiOstream& out = args[kArgOutput].AsOutputFile();
+    	string outfmt = x_InitSearchRequest();
+    	/* Special case: full db dump when no range and mask data is specified */
+    	if (m_FASTA) {
+    		CBlastDB_FastaFormatter fasta_fmt(*m_BlastDb, out, args["line_length"].AsInteger(), x_UseLongSeqIds());
+    		err_found = x_ProcessSearchType(fasta_fmt);
+    	}
+    	else if (m_Asn1Bioseq) {
+    		CBlastDB_BioseqFormatter bioseq_fmt(*m_BlastDb, out);
+    		err_found = x_ProcessSearchType(bioseq_fmt);
+    	}
+    	else {
+    		CBlastDB_SeqFormatter seq_fmt(outfmt, *m_BlastDb, out);
+    		err_found = x_ProcessSearchType(seq_fmt);
+    	}
+    }
+    catch (const CException& e) {
+    	ERR_POST(Error << e.GetMsg());
+        err_found = 1;
+    } catch (...) {
+        ERR_POST(Error << "Failed to retrieve requested item");
+        err_found = 1;
     }
-    return err_found ? 1:0;
+	return err_found;
 }
 
+
 void CBlastDBCmdApp::Init()
 {
     HideStdArgs(fHideConffile | fHideFullVersion | fHideXmlHelp | fHideDryRun);
@@ -620,7 +618,7 @@ void CBlastDBCmdApp::Init()
     arg_desc->SetCurrentGroup("Output configuration options for FASTA format");
     arg_desc->AddDefaultKey("line_length", "number", "Line length for output",
                         CArgDescriptions::eInteger,
-                        NStr::IntToString(CSeqFormatterConfig().m_LineWidth));
+                        NStr::IntToString(80));
     arg_desc->SetConstraint("line_length",
                             new CArgAllowValuesGreaterThanOrEqual(1));
 
@@ -679,6 +677,8 @@ void CBlastDBCmdApp::Init()
     arg_desc->AddFlag("exact_length", "Get exact length for db info", true);
     arg_desc->SetDependency("exact_length", CArgDescriptions::eRequires,
                             "info");
+    arg_desc->AddFlag("long_seqids", "Use long seq id for fasta deflines", true);
+    arg_desc->SetDependency("long_seqids", CArgDescriptions::eExcludes, "info");
     SetupArgDescriptions(arg_desc.release());
 }
 
@@ -692,7 +692,6 @@ int CBlastDBCmdApp::Run(void)
     SetDiagPostLevel(eDiag_Warning);
     SetDiagPostPrefix("blastdbcmd");
 
-
     try {
         CNcbiOstream& out = args["out"].AsOutputFile();
         if (args["show_blastdb_search_path"]) {
@@ -717,11 +716,11 @@ int CBlastDBCmdApp::Run(void)
         }
 
         x_InitApplicationData();
-
         if (args["info"]) {
             x_PrintBlastDatabaseInformation();
         } else {
-            status = x_ProcessSearchRequest();
+        	x_InitSearchRequest();
+       		status = x_ProcessSearchRequest();
         }
 
     } CATCH_ALL(status)
@@ -732,6 +731,6 @@ int CBlastDBCmdApp::Run(void)
 #ifndef SKIP_DOXYGEN_PROCESSING
 int main(int argc, const char* argv[] /*, const char* envp[]*/)
 {
-    return CBlastDBCmdApp().AppMain(argc, argv, 0, eDS_Default, "");
+    return CBlastDBCmdApp().AppMain(argc, argv);
 }
 #endif /* SKIP_DOXYGEN_PROCESSING */
diff --git a/c++/src/app/blastdb/blastdbcp.cpp b/c++/src/app/blastdb/blastdbcp.cpp
index fed381d..bf09b92 100644
--- a/c++/src/app/blastdb/blastdbcp.cpp
+++ b/c++/src/app/blastdb/blastdbcp.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastdbcp.cpp 485504 2015-11-23 14:41:02Z rackerst $
+/*  $Id: blastdbcp.cpp 492284 2016-02-16 16:55:37Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -470,5 +470,5 @@ void BlastdbCopyApplication::Exit(void)
 int main(int argc, const char* argv[])
 {
     // Execute main application function
-    return BlastdbCopyApplication().AppMain(argc, argv, 0, eDS_Default, "");
+    return BlastdbCopyApplication().AppMain(argc, argv);
 }
diff --git a/c++/src/app/blastdb/convert2blastmask.cpp b/c++/src/app/blastdb/convert2blastmask.cpp
index cdf2340..954ff68 100644
--- a/c++/src/app/blastdb/convert2blastmask.cpp
+++ b/c++/src/app/blastdb/convert2blastmask.cpp
@@ -1,4 +1,4 @@
-/*  # $Id: convert2blastmask.cpp 473030 2015-07-15 19:29:59Z camacho $
+/*  # $Id: convert2blastmask.cpp 492284 2016-02-16 16:55:37Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -230,7 +230,7 @@ void CConvert2BlastMaskApplication::Exit(void)
 int main(int argc, const char* argv[])
 {
     // Execute main application function
-    return CConvert2BlastMaskApplication().AppMain(argc, argv, 0, eDS_Default, "");
+    return CConvert2BlastMaskApplication().AppMain(argc, argv);
 }
 #endif /* SKIP_DOXYGEN_PROCESSING */
 
diff --git a/c++/src/app/blastdb/makeblastdb.cpp b/c++/src/app/blastdb/makeblastdb.cpp
index a856a22..3cac9db 100644
--- a/c++/src/app/blastdb/makeblastdb.cpp
+++ b/c++/src/app/blastdb/makeblastdb.cpp
@@ -1,4 +1,4 @@
-/*  $Id: makeblastdb.cpp 488259 2015-12-29 14:32:15Z camacho $
+/*  $Id: makeblastdb.cpp 516397 2016-10-13 12:26:46Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,11 +32,6 @@
  * formatdb from the C toolkit
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: makeblastdb.cpp 488259 2015-12-29 14:32:15Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <algo/blast/api/version.hpp>
 #include <algo/blast/blastinput/blast_input_aux.hpp>
@@ -816,7 +811,7 @@ void CMakeBlastDBApp::x_ProcessMaskData()
     vector<string> gi_mask_names;
 
     if (! files.HasValue()) return;
-    NStr::Tokenize(NStr::TruncateSpaces(files.AsString()), ",", file_list,
+    NStr::Split(NStr::TruncateSpaces(files.AsString()), ",", file_list,
                    NStr::eNoMergeDelims);
     if (! file_list.size()) {
         NCBI_THROW(CInvalidDataException, eInvalidInput,
@@ -841,7 +836,7 @@ void CMakeBlastDBApp::x_ProcessMaskData()
     }
 
     if (descs.HasValue()) {
-        NStr::Tokenize(NStr::TruncateSpaces(descs.AsString()), ",", desc_list,
+        NStr::Split(NStr::TruncateSpaces(descs.AsString()), ",", desc_list,
                    NStr::eNoMergeDelims);
         if (file_list.size() != desc_list.size()) {
             NCBI_THROW(CInvalidDataException, eInvalidInput,
@@ -854,7 +849,7 @@ void CMakeBlastDBApp::x_ProcessMaskData()
     }
 
     if (gi_names.HasValue()) {
-        NStr::Tokenize(NStr::TruncateSpaces(gi_names.AsString()), ",", gi_mask_names,
+        NStr::Split(NStr::TruncateSpaces(gi_names.AsString()), ",", gi_mask_names,
                    NStr::eNoMergeDelims);
         if (file_list.size() != gi_mask_names.size()) {
             NCBI_THROW(CInvalidDataException, eInvalidInput,
@@ -1089,12 +1084,20 @@ void CMakeBlastDBApp::x_BuildDatabase()
     indexing |= (hash_index ? CWriteDB::eAddHash : 0);
     indexing |= (parse_seqids ? CWriteDB::eFullIndex : 0);
 
+    bool long_seqids = false;
+    CNcbiApplication* app = CNcbiApplication::Instance();
+    if (app) {
+        const CNcbiRegistry& registry = app->GetConfig();
+        long_seqids = (registry.Get("BLAST", "LONG_SEQID") == "1");
+    }
+
     m_DB.Reset(new CBuildDatabase(dbname,
                                   title,
                                   is_protein,
                                   indexing,
                                   use_gi_mask,
-                                  m_LogFile));
+                                  m_LogFile,
+                                  long_seqids));
 
 #if _BLAST_DEBUG
     if (args["verbose"]) {
@@ -1163,6 +1166,6 @@ int CMakeBlastDBApp::Run(void)
 #ifndef SKIP_DOXYGEN_PROCESSING
 int main(int argc, const char* argv[] /*, const char* envp[]*/)
 {
-    return CMakeBlastDBApp().AppMain(argc, argv, 0, eDS_Default, "");
+    return CMakeBlastDBApp().AppMain(argc, argv);
 }
 #endif /* SKIP_DOXYGEN_PROCESSING */
diff --git a/c++/src/app/blastdb/makeprofiledb.cpp b/c++/src/app/blastdb/makeprofiledb.cpp
index efe8480..9635f86 100644
--- a/c++/src/app/blastdb/makeprofiledb.cpp
+++ b/c++/src/app/blastdb/makeprofiledb.cpp
@@ -1,4 +1,4 @@
-/*  $Id: makeprofiledb.cpp 489108 2016-01-08 15:13:21Z fongah2 $
+/*  $Id: makeprofiledb.cpp 492284 2016-02-16 16:55:37Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1710,7 +1710,7 @@ int CMakeProfileDBApp::Run(void)
 #ifndef SKIP_DOXYGEN_PROCESSING
 int main(int argc, const char* argv[] /*, const char* envp[]*/)
 {
-		return CMakeProfileDBApp().AppMain(argc, argv, 0, eDS_Default, "");
+		return CMakeProfileDBApp().AppMain(argc, argv);
 }
 
 
diff --git a/c++/src/app/dustmasker/Makefile.dustmasker.app b/c++/src/app/dustmasker/Makefile.dustmasker.app
index c2c4892..a85b0df 100644
--- a/c++/src/app/dustmasker/Makefile.dustmasker.app
+++ b/c++/src/app/dustmasker/Makefile.dustmasker.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.dustmasker.app 398472 2013-05-06 19:02:03Z kornbluh $
+# $Id: Makefile.dustmasker.app 500573 2016-05-05 16:42:41Z gouriano $
 
 REQUIRES = objects algo
 
@@ -8,7 +8,7 @@ APP = dustmasker
 SRC = main dust_mask_app
 
 LIB = xalgodustmask seqmasks_io $(OBJREAD_LIBS) xobjutil \
-	$(OBJREAD_LIBS) seqdb blastdb $(OBJMGR_LIBS:%=%$(STATIC))
+      seqdb blastdb $(OBJMGR_LIBS:%=%$(STATIC))
 
 LIBS = $(CMPRS_LIBS) $(NETWORK_LIBS) $(DL_LIBS) $(ORIG_LIBS)
 
diff --git a/c++/src/app/dustmasker/main.cpp b/c++/src/app/dustmasker/main.cpp
index d5ea758..fae1708 100644
--- a/c++/src/app/dustmasker/main.cpp
+++ b/c++/src/app/dustmasker/main.cpp
@@ -1,4 +1,4 @@
-/*  $Id: main.cpp 473030 2015-07-15 19:29:59Z camacho $
+/*  $Id: main.cpp 492284 2016-02-16 16:55:37Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -38,5 +38,5 @@ USING_NCBI_SCOPE;
 
 int main( int argc, char * argv[] )
 {
-    return CDustMaskApplication().AppMain(argc, argv, 0, eDS_Default, "");
+    return CDustMaskApplication().AppMain(argc, argv);
 }
diff --git a/c++/src/app/segmasker/Makefile.segmasker.app b/c++/src/app/segmasker/Makefile.segmasker.app
index 9fb7ee7..48561b7 100644
--- a/c++/src/app/segmasker/Makefile.segmasker.app
+++ b/c++/src/app/segmasker/Makefile.segmasker.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.segmasker.app 208957 2010-10-21 19:23:10Z camacho $
+# $Id: Makefile.segmasker.app 500573 2016-05-05 16:42:41Z gouriano $
 
 REQUIRES = objects algo
 
@@ -7,7 +7,7 @@ ASN_DEP = seq
 APP = segmasker
 SRC = segmasker
 
-LIB_ = xobjsimple seqmasks_io xalgosegmask $(BLAST_LIBS) $(OBJMGR_LIBS)
+LIB_ = xobjsimple xalgosegmask $(BLAST_LIBS) $(OBJMGR_LIBS)
 LIB = $(LIB_:%=%$(STATIC))
 
 LIBS = $(CMPRS_LIBS) $(NETWORK_LIBS) $(DL_LIBS) $(ORIG_LIBS)
diff --git a/c++/src/app/segmasker/segmasker.cpp b/c++/src/app/segmasker/segmasker.cpp
index 51cb183..8d1af22 100644
--- a/c++/src/app/segmasker/segmasker.cpp
+++ b/c++/src/app/segmasker/segmasker.cpp
@@ -1,4 +1,4 @@
-/*  $Id: segmasker.cpp 473030 2015-07-15 19:29:59Z camacho $
+/*  $Id: segmasker.cpp 492284 2016-02-16 16:55:37Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -269,7 +269,7 @@ void SegMaskerApplication::Exit(void)
 int main(int argc, const char* argv[])
 {
     // Execute main application function
-    return SegMaskerApplication().AppMain(argc, argv, 0, eDS_Default, "");
+    return SegMaskerApplication().AppMain(argc, argv);
 }
 #endif /* SKIP_DOXYGEN_PROCESSING */
 
diff --git a/c++/src/app/winmasker/Makefile.winmasker.app b/c++/src/app/winmasker/Makefile.winmasker.app
index b780f7a..eb68d9d 100644
--- a/c++/src/app/winmasker/Makefile.winmasker.app
+++ b/c++/src/app/winmasker/Makefile.winmasker.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.winmasker.app 398558 2013-05-07 11:21:36Z kornbluh $
+# $Id: Makefile.winmasker.app 500573 2016-05-05 16:42:41Z gouriano $
 
 WATCHERS = morgulis camacho mozese2
 
@@ -9,8 +9,8 @@ ASN_DEP = seq
 APP = windowmasker
 SRC = main win_mask_app win_mask_sdust_masker
 
-LIB = xalgowinmask xalgodustmask blast composition_adjustment seqdb blastdb \
-	seqmasks_io tables $(OBJREAD_LIBS) xobjutil \
+LIB = xalgowinmask xalgodustmask blast composition_adjustment \
+        seqmasks_io seqdb blastdb tables $(OBJREAD_LIBS) xobjutil \
 	$(OBJMGR_LIBS:%=%$(STATIC))
 
 LIBS = $(CMPRS_LIBS) $(NETWORK_LIBS) $(DL_LIBS) $(ORIG_LIBS)
diff --git a/c++/src/app/winmasker/main.cpp b/c++/src/app/winmasker/main.cpp
index 0ddf8ba..c062f2d 100644
--- a/c++/src/app/winmasker/main.cpp
+++ b/c++/src/app/winmasker/main.cpp
@@ -1,4 +1,4 @@
-/*  $Id: main.cpp 473030 2015-07-15 19:29:59Z camacho $
+/*  $Id: main.cpp 492284 2016-02-16 16:55:37Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -38,5 +38,5 @@ USING_NCBI_SCOPE;
 
 int main( int argc, char * argv[] )
 {
-    return CWinMaskApplication().AppMain(argc, argv, 0, eDS_Default, "");
+    return CWinMaskApplication().AppMain(argc, argv);
 }
diff --git a/c++/src/build-system/Makefile.app.in b/c++/src/build-system/Makefile.app.in
index 7555933..27768b0 100644
--- a/c++/src/build-system/Makefile.app.in
+++ b/c++/src/build-system/Makefile.app.in
@@ -1,6 +1,6 @@
 # -*- makefile-gmake -*-
 #################################
-# $Id: Makefile.app.in 492296 2016-02-16 17:41:47Z ivanov $
+# $Id: Makefile.app.in 492189 2016-02-12 20:50:52Z ucko $
 # Author:  Denis Vakatov (vakatov at ncbi.nlm.nih.gov)
 #################################
 # This can be used to build/install/clean
diff --git a/c++/src/build-system/Makefile.meta_l b/c++/src/build-system/Makefile.meta_l
index d16157d..db20437 100644
--- a/c++/src/build-system/Makefile.meta_l
+++ b/c++/src/build-system/Makefile.meta_l
@@ -1,5 +1,5 @@
 # -*- makefile-gmake -*-
-# $Id: Makefile.meta_l 487127 2015-12-15 17:04:00Z ivanov $
+# $Id: Makefile.meta_l 507305 2016-07-18 16:19:28Z ucko $
 
 ### Rules for building within a single directory
 
@@ -81,6 +81,7 @@ endif
 # 1: proj_name, 2: lock_map?, 3: command, 4: target, 5: ext, 6: cleanup,
 # 7: error_status, 8: is_expendable?
 define make_one_leaf_proj
+NCBICXX_TESTING_REQS=1 $(3) -q requirements REQUIRES= && \
 $(if $(8),NCBI_BUT_EXPENDABLE=$(but_exp);,) \
 if NCBICXX_TESTING_REQS=1 $(3) -q requirements; then \
     if $(3) -q depend >/dev/null 2>&1 && $(3) -q $(4) >/dev/null 2>&1; then \
@@ -207,6 +208,7 @@ endif
 # 1: proj_name
 define add_one_check
 @i=$(1) ; \
+NCBICXX_TESTING_REQS=1 $(MAKE_APP) -q requirements REQUIRES= && \
 if NCBICXX_TESTING_REQS=1 $(MAKE_APP) -q requirements >/dev/null 2>&1; then \
     $(check_add) $(abs_srcdir) $(1) $(signature) $(subdir)  ||  exit 5 ; \
 else \
diff --git a/c++/src/build-system/Makefile.mk.in b/c++/src/build-system/Makefile.mk.in
index 755b876..e05b5c3 100644
--- a/c++/src/build-system/Makefile.mk.in
+++ b/c++/src/build-system/Makefile.mk.in
@@ -1,5 +1,5 @@
 #################################
-# $Id: Makefile.mk.in 493416 2016-02-26 18:48:41Z ivanov $
+# $Id: Makefile.mk.in 512372 2016-08-30 14:51:36Z ivanov $
 # Author:  Denis Vakatov (vakatov at ncbi.nlm.nih.gov)
 #################################
 #
@@ -152,7 +152,8 @@ CXXCPP = $(CONF_CXXCPP)
 AR     = $(CONF_AR)
 RANLIB = $(CONF_RANLIB)
 LINK   = $(CONF_LINK)
-C_LINK = $(CONF_C_LINK) # Linker for pure-C programs
+# Linker for pure-C programs
+C_LINK = $(CONF_C_LINK)
 STRIP  = $(CONF_STRIP)
 
 CFLAGS   = $(CONF_CFLAGS)
@@ -164,7 +165,8 @@ LDFLAGS  = $(CONF_LDFLAGS)
 APP_LDFLAGS = $(CONF_APP_LDFLAGS)
 DLL_LDFLAGS = $(CONF_DLL_LDFLAGS)
 LIBS     = $(CONF_LIBS)
-C_LIBS   = $(CONF_C_LIBS) # Libraries for pure-C programs
+# Libraries for pure-C programs
+C_LIBS   = $(CONF_C_LIBS)
 PRE_LIBS =
 
 # To add directory /foo to the list to search at runtime, you can add
@@ -516,11 +518,20 @@ NCBILS_LIB       = $(NCBILS2_LIB)
 
 # NCBI SRA/VDB Toolkit
 VDB_INCLUDE     = @VDB_INCLUDE@
-VDB_LIB         = @VDB_LIB@
 VDB_LIBS        = @VDB_LIBS@
 VDB_STATIC_LIBS = @VDB_STATIC_LIBS@
 VDB_REQ         = @VDB_REQ@
 VDB_POST_LINK   = @VDB_POST_LINK@
+bamread               = @bamread@
+sraread               = @sraread@
+ncbi_id2proc_snp      = @ncbi_id2proc_snp@
+ncbi_id2proc_wgs      = @ncbi_id2proc_wgs@
+ncbi_xloader_bam      = @ncbi_xloader_bam@
+ncbi_xloader_csra     = @ncbi_xloader_csra@
+ncbi_xloader_snp      = @ncbi_xloader_snp@
+ncbi_xloader_sra      = @ncbi_xloader_sra@
+ncbi_xloader_vdbgraph = @ncbi_xloader_vdbgraph@
+ncbi_xloader_wgs      = @ncbi_xloader_wgs@
 
 # SP:  headers, libraries
 SP_INCLUDE = @SP_INCLUDE@
@@ -652,6 +663,14 @@ MONGODB_STATIC_LIBS = @MONGODB_STATIC_LIBS@
 GMOCK_INCLUDE = @GMOCK_INCLUDE@
 GMOCK_LIBS    = @GMOCK_LIBS@
 
+# LAPACK
+LAPACK_INCLUDE = @LAPACK_INCLUDE@
+LAPACK_LIBS    = @LAPACK_LIBS@
+
+# LMDB
+LMDB_INCLUDE = @LMDB_INCLUDE@
+LMDB_LIBS    = @LMDB_LIBS@
+
 # Compress
 COMPRESS_LDEP = $(CMPRS_LIB)
 COMPRESS_LIBS = xcompress $(COMPRESS_LDEP)
@@ -669,7 +688,7 @@ GENBANK_READER_LIBS = ncbi_xreader $(GENBANK_READER_LDEP)
 # In-house-only PubSeqOS loader (not always built)
 ncbi_xreader_pubseqos = @ncbi_xreader_pubseqos@
 ncbi_xreader_pubseqos2 = @ncbi_xreader_pubseqos2@
-GENBANK_READER_PUBSEQOS_LDEP = $(XCONNEXT) xconnect $(DBAPI_DRIVER) $(GENBANK_READER_LIBS)
+GENBANK_READER_PUBSEQOS_LDEP = $(DBAPI_DRIVER) $(GENBANK_READER_LIBS)
 # @UNLESS_PUBSEQOS@ GENBANK_READER_PUBSEQOS_LDEP = xconnect $(GENBANK_READER_LIBS)
 GENBANK_READER_PUBSEQOS_LIBS = $(ncbi_xreader_pubseqos) $(GENBANK_READER_PUBSEQOS_LDEP)
 
@@ -712,3 +731,15 @@ XFORMAT_LIBS = xformat xcleanup gbseq submit mlacli mla medlars pubmed valid tax
 
 # object editing library
 OBJEDIT_LIBS = xobjedit $(OBJREAD_LIBS) taxon3
+
+# standard data loader configuration, plus supporting libraries
+DATA_LOADERS_UTIL_LIB = data_loaders_util \
+                        ncbi_xloader_asn_cache asn_cache bdb \
+                        ncbi_xloader_lds2 lds2 $(OBJREAD_LIBS) sqlitewrapp \
+                        ncbi_xloader_blastdb seqdb blastdb \
+                        $(ncbi_xreader_pubseqos2) ncbi_xdbapi_ftds $(FTDS_LIB) \
+                        $(ncbi_xloader_wgs) $(ncbi_xloader_csra) \
+                        $(SRAREAD_LIBS)
+
+DATA_LOADERS_UTIL_LIBS = $(BERKELEYDB_LIBS) $(SQLITE3_LIBS) $(FTDS_LIBS) \
+                         $(VDB_LIBS)
diff --git a/c++/src/build-system/Makefile.rules.in b/c++/src/build-system/Makefile.rules.in
index 37814f3..3d5a279 100644
--- a/c++/src/build-system/Makefile.rules.in
+++ b/c++/src/build-system/Makefile.rules.in
@@ -1,5 +1,5 @@
 #################################
-# $Id: Makefile.rules.in 493416 2016-02-26 18:48:41Z ivanov $
+# $Id: Makefile.rules.in 497672 2016-04-08 18:34:20Z ucko $
 # Author:  Denis Vakatov (vakatov at ncbi.nlm.nih.gov),
 #          Aaron Ucko    (ucko at ncbi.nlm.nih.gov)
 #################################
@@ -113,7 +113,7 @@ clean-common:
 	-$(RMDIR) ii_files
 	-$(RMDIR) ti_files
 	-$(RM) .make.state
-	-$(RM) $(SOURCES:=.d)
+	-$(RM) $(SOURCES:=.d) $(SOURCES:=.gcda) $(SOURCES:=.gcno)
 	-$(RM) ir.out
 ifeq "$(APP)" ""
 	-$(RM) $(status_dir)/.$(LIB).disabled
diff --git a/c++/src/build-system/NEWS b/c++/src/build-system/NEWS
index d867b99..ab2c721 100644
--- a/c++/src/build-system/NEWS
+++ b/c++/src/build-system/NEWS
@@ -19,3 +19,5 @@ installations.
 2015-06-01: additional @VDB_*@ variables @VDB_REQ@ and @VDB_POST_LINK at .
 
 2015-12-17: new variables for FreeTDS 0.95.
+
+2016-06-20: variables for libraries dependent on SRA/VDB.
diff --git a/c++/src/build-system/aclocal.m4 b/c++/src/build-system/aclocal.m4
index 58ac6e4..ddf1fce 100644
--- a/c++/src/build-system/aclocal.m4
+++ b/c++/src/build-system/aclocal.m4
@@ -268,17 +268,16 @@ AC_DEFUN(_NCBI_CHECK_PYTHON,
 [AC_PATH_PROG($1, python$2, [],
     [${PYTHON_PATH+$PYTHON_PATH/bin:}$PATH:/usr/local/python-$2/bin])
  if test -x "[$]$1"; then
-    $1_VERSION=`[$]$1 -c 'from distutils import sysconfig; print(sysconfig.get_config_var("VERSION"))' 2>/dev/null`
+    pyconf="$real_srcdir/scripts/common/impl/python-config.py"
+    $1_VERSION=`DYLD_BIND_AT_LAUNCH=1 "[$]$1" "$pyconf" --version 2>&AS_MESSAGE_LOG_FD`
  else
     $1_VERSION=
     [ncbi_cv_lib_]m4_tolower($1)=no
  fi
  if test -n "[$]$1_VERSION"; then
-    $1_INCLUDE=`[$]$1 -c 'from distutils import sysconfig; f=sysconfig.get_python_inc; print("-I%s -I%s" % (f(), f(True)))'`
-    $1_LIBPATH=`[$]$1 -c 'from distutils import sysconfig; print(" ".join(sysconfig.get_config_vars("LIBDIR", "LIBPL")))'`
-    $1_DEPS=`[$]$1 -c 'from distutils import sysconfig; print(" ".join(sysconfig.get_config_vars("LIBS", "SYSLIBS")))'`
-    $1_LDVERSION=`[$]$1 -c 'from distutils import sysconfig; print(sysconfig.get_config_var("LDVERSION") or sysconfig.get_config_var("VERSION"))' 2>/dev/null`
-    NCBI_RPATHIFY($1_LIBS, [$]$1_LIBPATH, [ ]-lpython[$]$1_LDVERSION [$]$1_DEPS)
+    $1_INCLUDE=`"[$]$1" "$pyconf" --include`
+    $1_LIBPATH=`"[$]$1" "$pyconf" --libpath`
+    NCBI_RPATHIFY($1_LIBS, [$]$1_LIBPATH, [ ]`"[$]$1" "$pyconf" --libs`)
     CPPFLAGS="[$]$1_INCLUDE $orig_CPPFLAGS"
     LIBS="[$]$1_LIBS $orig_LIBS"
     AC_CACHE_CHECK([for usable Python [$]$1_VERSION libraries],
@@ -296,6 +295,7 @@ AC_DEFUN(_NCBI_CHECK_PYTHON,
            [[ncbi_cv_lib_]m4_tolower($1)=yes],
            [[ncbi_cv_lib_]m4_tolower($1)=no])])
  else
+    $1=
     [ncbi_cv_lib_]m4_tolower($1)=no
  fi
  if test "[$ncbi_cv_lib_]m4_tolower($1)" = "no"; then
@@ -314,7 +314,7 @@ AC_DEFUN(NCBI_LOCAL_FTDS,
       if test $try_local = yes -a -f "${real_srcdir}/src/$d/Makefile.in" ; then
          test "$ftds_ver" = $1  &&  FTDS_PATH="<$d>"
          FTDS$1[_CTLIB_LIB]="ct_ftds$1${STATIC} tds_ftds$1${STATIC}"
-         FTDS$1[_CTLIB_LIBS]='$(ICONV_LIBS) $(KRB5_LIBS)'
+         FTDS$1[_CTLIB_LIBS]='$(ICONV_LIBS) $(KRB5_LIBS) $(NETWORK_LIBS)'
          FTDS$1[_CTLIB_INCLUDE]="-I\$(includedir)/$d -I\$(includedir0)/$d"
          freetds=freetds
       elif test -d "$FTDS_PATH" ; then
diff --git a/c++/src/build-system/config.h.in b/c++/src/build-system/config.h.in
index 422f58e..ff0e35b 100644
--- a/c++/src/build-system/config.h.in
+++ b/c++/src/build-system/config.h.in
@@ -3,6 +3,9 @@
 /* Define to 1 if necessary to get FIONBIO (e.g., on Solaris) */
 #undef BSD_COMP
 
+/* Define to 1 if you have the <Accelerate/Accelerate.h> header file. */
+#undef HAVE_ACCELERATE_ACCELERATE_H
+
 /* Define to 1 if you have the `alarm' function. */
 #undef HAVE_ALARM
 
@@ -65,6 +68,12 @@
 /* Define to 1 if the `Boost.Thread' library is available. */
 #undef HAVE_BOOST_THREAD
 
+/* Define to 1 if you have the <clapack.h> header file. */
+#undef HAVE_CLAPACK_H
+
+/* Define to 1 if you have the <common/ncbi_build_ver.h> header file. */
+#undef HAVE_COMMON_NCBI_BUILD_VER_H
+
 /* Define to 1 if the preprocessor supports GNU-style variadic macros. */
 #undef HAVE_CPP_GNU_VARARGS
 
@@ -203,6 +212,12 @@
 /* Define to 1 if you have `ios(_base)::register_callback'. */
 #undef HAVE_IOS_REGISTER_CALLBACK
 
+/* Define to 1 if you have the <lapacke.h> header file. */
+#undef HAVE_LAPACKE_H
+
+/* Define to 1 if you have the <lapacke/lapacke.h> header file. */
+#undef HAVE_LAPACKE_LAPACKE_H
+
 /* Define to 1 if you have the `lchown' function. */
 #undef HAVE_LCHOWN
 
@@ -290,6 +305,12 @@
    the standard libraries. */
 #undef HAVE_LIBKSTAT
 
+/* Define to 1 if liblapack is available. */
+#undef HAVE_LIBLAPACK
+
+/* Define to 1 if liblmdb is available. */
+#undef HAVE_LIBLMDB
+
 /* Define to 1 if liblzo2 is available. */
 #undef HAVE_LIBLZO
 
@@ -415,6 +436,9 @@
 /* Define to 1 if the real version of ncbi_crypt support is available. */
 #undef HAVE_NCBI_CRYPT
 
+/* Define to 1 if you have NCBI's SRA/VDB SDK/Toolkit. */
+#undef HAVE_NCBI_VDB
+
 /* Define to 1 if you have the <netdb.h> header file. */
 #undef HAVE_NETDB_H
 
@@ -484,6 +508,9 @@
 /* Define to 1 if Python 2.7 libraries are available. */
 #undef HAVE_PYTHON27
 
+/* Define to 1 if Python 3 libraries are available. */
+#undef HAVE_PYTHON3
+
 /* Define to 1 if you have the `readpassphrase' function. */
 #undef HAVE_READPASSPHRASE
 
@@ -709,6 +736,9 @@
 /* Define to 1 if Zorba is available. */
 #undef HAVE_ZORBA
 
+/* Define to 1 if the system has the type `__CLPK_integer'. */
+#undef HAVE___CLPK_INTEGER
+
 /* Full GNU-style system type */
 #undef HOST
 
@@ -870,9 +900,6 @@
    variables, or leave undefined if it doesn't. */
 #undef NCBI_TLS_VAR
 
-/* Define to 1 if building universal (multi-architecture) binaries. */
-#undef NCBI_UNIVERSAL_BUILD
-
 /* Define to 1 if building plugins as bundles, as Mac OS X traditionally
    required. */
 #undef NCBI_USE_BUNDLES
diff --git a/c++/src/build-system/configure b/c++/src/build-system/configure
index 5749672..b5294ea 100755
--- a/c++/src/build-system/configure
+++ b/c++/src/build-system/configure
@@ -829,6 +829,10 @@ MONGODB_INCLUDE
 MONGODB_LIBS
 GMOCK_INCLUDE
 GMOCK_LIBS
+LAPACK_INCLUDE
+LAPACK_LIBS
+LMDB_INCLUDE
+LMDB_LIBS
 signature
 build_root
 top_srcdir
@@ -1004,9 +1008,18 @@ LIBSSSUTILS
 LIBSSSDB
 sssutils
 VDB_INCLUDE
-VDB_LIB
 VDB_LIBS
 VDB_STATIC_LIBS
+bamread
+sraread
+ncbi_id2proc_snp
+ncbi_id2proc_wgs
+ncbi_xloader_bam
+ncbi_xloader_csra
+ncbi_xloader_snp
+ncbi_xloader_sra
+ncbi_xloader_vdbgraph
+ncbi_xloader_wgs
 VDB_REQ
 VDB_POST_LINK
 SP_INCLUDE
@@ -1076,6 +1089,9 @@ compiler_version
 COMPILER
 OSTYPE
 NCBI_PLATFORM_BITS
+NCBI_TEAMCITY_BUILD_NUMBER
+NCBI_SUBVERSION_REVISION
+NCBI_SC_VERSION
 LIBOBJS
 LTLIBOBJS'
 ac_subst_files=''
@@ -1591,21 +1607,21 @@ esac
 #### Check the passed arguments against the list of available ones
 x_with_list="\
 debug max-debug symbols optimization profiling tcheck dll static static-exe \
-plugin-auto-load bundles bin-release mt 64 universal exe runpath hard-runpath \
+plugin-auto-load bundles bin-release mt 64 exe runpath hard-runpath \
 lfs limited-linker openmp \
 autodep suffix hostspec version execopy bincopy lib-rebuilds lib-rebuilds=ask \
 deactivation makefile-auto-update projects flat-makefile configure-dialog \
 check ncbi-public strip pch caution ccache distcc \
 ncbi-c wxwidgets wxwidgets-ucs fastcgi sss sssdb sssutils included-sss \
-geo included-geo vdb downloaded-vdb \
-z bz2 lzo pcre gmp gcrypt nettle gnutls openssl krb5 \
+geo included-geo vdb downloaded-vdb static-vdb \
+z bz2 lzo pcre gmp gcrypt nettle gnutls static-gnutls openssl krb5 \
 sybase sybase-local sybase-new ftds mysql \
 orbacus freetype ftgl opengl mesa glut glew glew-mx \
 bdb python perl jni sqlite3 icu boost boost-tag \
 sp expat sablot libxml libxslt libexslt xerces xalan zorba \
 oechem sge muparser hdf5 \
 gif jpeg tiff png xpm \
-magic curl mimetic gsoap avro cereal sasl2 mongodb gmock 3psw \
+magic curl mimetic gsoap avro cereal sasl2 mongodb gmock lapack lmdb 3psw \
 local-lbsm ncbi-crypt connext \
 serial objects dbapi app ctools gui algo internal gbench"
 
@@ -1675,7 +1691,7 @@ for x_arg in "$@" ; do
       | --with-jpeg=* | --with-png=* | --with-tiff=* | --with-xpm=* \
       | --with-magic=* | --with-curl=* | --with-mimetic=* | --with-gsoap=* \
       | --with-avro=* | --with-cereal=* | --with-sasl2* | --with-mongodb=* \
-      | --with-gmock=* )
+      | --with-gmock=* | --with-lapack=* | --with-lmdb=* )
       # Confirm that the specified directory exists and is readable.
       dir=`echo $x_arg | sed -e 's/^[^=]*=//'`
       case "$x_arg" in
@@ -1699,7 +1715,7 @@ for x_arg in "$@" ; do
       | --silent | --cache-file=* | -C | --config-cache | -n | --no-create \
       | --no-recursion | --prefix=* | --exec-prefix=* | --bindir=* \
       | --libdir=* | --includedir=* | --build=* | --host=* | --target=* \
-      | --with-universal=* | --with-runpath=* | --with-relative-runpath=* \
+      | --with-runpath=* | --with-relative-runpath=* \
       | --with-experimental=* | --with-extra-action=* | --with-build-root=* \
       | --with-fake-root=* | --with-build-root-sfx=* | --with-check=* \
       | --with-check-tools=* | --with-ftds=[0-9]* | --with-fastcgi=[0-9]* \
@@ -1820,8 +1836,6 @@ Optional Packages:
  --without-mt            support only single-threaded operation
  --with-openmp           enable OpenMP extensions for all projects
  --with-64               compile to 64-bit code
- --with-universal        build universal binaries on Mac OS X
- --with-universal=CPUs   build universal binaries targeting the given CPUs
  --without-exe           do not build executables
  --with-runpath=PATH     specify the usual runtime path to DLLs
  --with-relative-runpath=P specify an executable-relative DLL search path
@@ -1866,6 +1880,7 @@ Optional Packages:
  --with-vdb=DIR          use NCBI SRA/VDB Toolkit installation in DIR
  --without-vdb           do not use the NCBI SRA/VDB Toolkit
  --with-downloaded-vdb   download and build SRA/VDB from GitHub
+ --with-static-vdb       always link statically against SRA/VDB
  --with-z=DIR            use zlib installation in DIR
  --without-z             use internal copy of zlib
  --with-bz2=DIR          use bzlib installation in DIR
@@ -1882,6 +1897,7 @@ Optional Packages:
  --without-nettle        do not use Nettle
  --with-gnutls=DIR       use GNUTLS installation in DIR
  --without-gnutls        do not use GNUTLS
+ --with-static-gnutls    link GNUTLS statically if possible
  --with-openssl=DIR      use OpenSSL installation in DIR
  --without-openssl       do not use OpenSSL
  --with-krb5=DIR         use Kerberos 5 installation in DIR
@@ -1986,6 +2002,10 @@ Optional Packages:
  --without-mongodb       do not use MongoDB
  --with-gmock=DIR        use Google Mock installation in DIR
  --without-gmock         do not use Google Mock
+ --with-lapack=DIR       use LAPACK installation in DIR
+ --without-lapack        do not use LAPACK
+ --with-lmdb=DIR         use LMDB installation in DIR
+ --without-lmdb          do not use LMDB
  --with-3psw=std:netopt  favor standard (system) builds of the above pkgs.
  --without-3psw          do not use any of the above packages
  --without-local-lbsm    turn off support for IPC with locally running LBSMD
@@ -2245,6 +2265,12 @@ case "$with_3psw" in
          else
             with_boost=no
          fi
+        if test "${with_lmdb-no}" != "no"; then
+            { echo "$as_me: error: incompatible options: --with-lmdb but --without-3psw" >&2
+   { (exit 1); exit 1; }; }
+         else
+            with_lmdb=no
+         fi
         if test "${with_sybase-no}" != "no"; then
             { echo "$as_me: error: incompatible options: --with-sybase but --without-3psw" >&2
    { (exit 1); exit 1; }; }
@@ -2521,6 +2547,12 @@ case "$with_3psw" in
          else
             with_gmock=no
          fi
+        if test "${with_lapack-no}" != "no"; then
+            { echo "$as_me: error: incompatible options: --with-lapack but --without-3psw" >&2
+   { (exit 1); exit 1; }; }
+         else
+            with_lapack=no
+         fi
 
       $as_unset NCBI || test "${NCBI+set}" != set || { NCBI=; export NCBI; }
       ;;
@@ -2999,18 +3031,6 @@ if test "${with_64+set}" = set; then
 fi
 
 
-# Check whether --with-universal was given.
-if test "${with_universal+set}" = set; then
-  withval=$with_universal;
-fi
-
-
-# Check whether --with-universal2 was given.
-if test "${with_universal2+set}" = set; then
-  withval=$with_universal2;
-fi
-
-
 # Check whether --with-exe was given.
 if test "${with_exe+set}" = set; then
   withval=$with_exe;
@@ -3278,6 +3298,12 @@ if test "${with_downloaded_vdb+set}" = set; then
 fi
 
 
+# Check whether --with-static-vdb was given.
+if test "${with_static_vdb+set}" = set; then
+  withval=$with_static_vdb;
+fi
+
+
 ## Third-party and system packages
 
 # Check whether --with-z was given.
@@ -3376,6 +3402,12 @@ if test "${with_gnutls2+set}" = set; then
 fi
 
 
+# Check whether --with-static-gnutls was given.
+if test "${with_static_gnutls+set}" = set; then
+  withval=$with_static_gnutls;
+fi
+
+
 # Check whether --with-openssl was given.
 if test "${with_openssl+set}" = set; then
   withval=$with_openssl;
@@ -4000,6 +4032,30 @@ if test "${with_gmock2+set}" = set; then
 fi
 
 
+# Check whether --with-lapack was given.
+if test "${with_lapack+set}" = set; then
+  withval=$with_lapack;
+fi
+
+
+# Check whether --with-lapack2 was given.
+if test "${with_lapack2+set}" = set; then
+  withval=$with_lapack2;
+fi
+
+
+# Check whether --with-lmdb was given.
+if test "${with_lmdb+set}" = set; then
+  withval=$with_lmdb;
+fi
+
+
+# Check whether --with-lmdb was given.
+if test "${with_lmdb+set}" = set; then
+  withval=$with_lmdb;
+fi
+
+
 # Check whether --with-3psw was given.
 if test "${with_3psw+set}" = set; then
   withval=$with_3psw;
@@ -4116,56 +4172,105 @@ if test "$with_gbench" = "yes" ; then
 echo "$as_me: error: incompatible options: --without-dll but --with-gbench" >&2;}
    { (exit 1); exit 1; }; }
       else
-         with_dll=yes
+         : ${with_dll:=yes}
       fi
      if test "$with_mt" = "no"; then
          { { echo "$as_me:$LINENO: error: incompatible options: --without-mt but --with-gbench" >&5
 echo "$as_me: error: incompatible options: --without-mt but --with-gbench" >&2;}
    { (exit 1); exit 1; }; }
       else
-         with_mt=yes
+         : ${with_mt:=yes}
       fi
      if test "$with_gui" = "no"; then
          { { echo "$as_me:$LINENO: error: incompatible options: --without-gui but --with-gbench" >&5
 echo "$as_me: error: incompatible options: --without-gui but --with-gbench" >&2;}
    { (exit 1); exit 1; }; }
       else
-         with_gui=yes
+         : ${with_gui:=yes}
       fi
      if test "$with_exe" = "no"; then
          { { echo "$as_me:$LINENO: error: incompatible options: --without-exe but --with-gbench" >&5
 echo "$as_me: error: incompatible options: --without-exe but --with-gbench" >&2;}
    { (exit 1); exit 1; }; }
       else
-         with_exe=yes
+         : ${with_exe:=yes}
       fi
      if test "$with_serial" = "no"; then
          { { echo "$as_me:$LINENO: error: incompatible options: --without-serial but --with-gbench" >&5
 echo "$as_me: error: incompatible options: --without-serial but --with-gbench" >&2;}
    { (exit 1); exit 1; }; }
       else
-         with_serial=yes
+         : ${with_serial:=yes}
       fi
      if test "$with_objects" = "no"; then
          { { echo "$as_me:$LINENO: error: incompatible options: --without-objects but --with-gbench" >&5
 echo "$as_me: error: incompatible options: --without-objects but --with-gbench" >&2;}
    { (exit 1); exit 1; }; }
       else
-         with_objects=yes
+         : ${with_objects:=yes}
       fi
      if test "$with_algo" = "no"; then
          { { echo "$as_me:$LINENO: error: incompatible options: --without-algo but --with-gbench" >&5
 echo "$as_me: error: incompatible options: --without-algo but --with-gbench" >&2;}
    { (exit 1); exit 1; }; }
       else
-         with_algo=yes
+         : ${with_algo:=yes}
       fi
      if test "$with_glew_mx" = "no"; then
          { { echo "$as_me:$LINENO: error: incompatible options: --without-glew_mx but --with-gbench" >&5
 echo "$as_me: error: incompatible options: --without-glew_mx but --with-gbench" >&2;}
    { (exit 1); exit 1; }; }
       else
-         with_glew_mx=yes
+         : ${with_glew_mx:=yes}
+      fi
+     if test "$with_wxwidgets" = "no"; then
+         { { echo "$as_me:$LINENO: error: incompatible options: --without-wxwidgets but --with-gbench" >&5
+echo "$as_me: error: incompatible options: --without-wxwidgets but --with-gbench" >&2;}
+   { (exit 1); exit 1; }; }
+      else
+         : ${with_wxwidgets:=yes}
+      fi
+     if test "$with_ftgl" = "no"; then
+         { { echo "$as_me:$LINENO: error: incompatible options: --without-ftgl but --with-gbench" >&5
+echo "$as_me: error: incompatible options: --without-ftgl but --with-gbench" >&2;}
+   { (exit 1); exit 1; }; }
+      else
+         : ${with_ftgl:=yes}
+      fi
+     if test "$with_sqlite3" = "no"; then
+         { { echo "$as_me:$LINENO: error: incompatible options: --without-sqlite3 but --with-gbench" >&5
+echo "$as_me: error: incompatible options: --without-sqlite3 but --with-gbench" >&2;}
+   { (exit 1); exit 1; }; }
+      else
+         : ${with_sqlite3:=yes}
+      fi
+     if test "$with_bdb" = "no"; then
+         { { echo "$as_me:$LINENO: error: incompatible options: --without-bdb but --with-gbench" >&5
+echo "$as_me: error: incompatible options: --without-bdb but --with-gbench" >&2;}
+   { (exit 1); exit 1; }; }
+      else
+         : ${with_bdb:=yes}
+      fi
+     if test "$with_boost" = "no"; then
+         { { echo "$as_me:$LINENO: error: incompatible options: --without-boost but --with-gbench" >&5
+echo "$as_me: error: incompatible options: --without-boost but --with-gbench" >&2;}
+   { (exit 1); exit 1; }; }
+      else
+         : ${with_boost:=yes}
+      fi
+     if test "$with_xslt" = "no"; then
+         { { echo "$as_me:$LINENO: error: incompatible options: --without-xslt but --with-gbench" >&5
+echo "$as_me: error: incompatible options: --without-xslt but --with-gbench" >&2;}
+   { (exit 1); exit 1; }; }
+      else
+         : ${with_xslt:=yes}
+      fi
+     if test "$with_gnutls" = "no"; then
+         { { echo "$as_me:$LINENO: error: incompatible options: --without-gnutls but --with-gbench" >&5
+echo "$as_me: error: incompatible options: --without-gnutls but --with-gbench" >&2;}
+   { (exit 1); exit 1; }; }
+      else
+         : ${with_gnutls:=yes}
       fi
 
    : ${with_projects=scripts/projects/ncbi_gbench.lst}
@@ -4237,6 +4342,34 @@ echo "$as_me: error: incompatible options: --without-vdb but
       ;;
 esac
 
+case "$with_static_vdb:$with_vdb" in
+   yes:no )
+      { { echo "$as_me:$LINENO: error: incompatible options: --without-vdb but --with-static-vdb" >&5
+echo "$as_me: error: incompatible options: --without-vdb but --with-static-vdb" >&2;}
+   { (exit 1); exit 1; }; }
+      ;;
+   yes: )
+      with_vdb=yes
+      ;;
+   :* )
+      with_static_vdb=$with_bin_release
+      ;;
+esac
+
+case "$with_static_gnutls:$with_gnutls" in
+   yes:no )
+      { { echo "$as_me:$LINENO: error: incompatible options: --without-gnutls but --with-static-gnutls" >&5
+echo "$as_me: error: incompatible options: --without-gnutls but --with-static-gnutls" >&2;}
+   { (exit 1); exit 1; }; }
+      ;;
+   yes: )
+      with_gnutls=yes
+      ;;
+   :* )
+      with_static_gnutls=$with_bin_release
+      ;;
+esac
+
 #### Check for special options
 if test "$with_extra_action" = "yes" ; then
    { { echo "$as_me:$LINENO: error: --with-extra-action must have a value after =" >&5
@@ -4304,12 +4437,18 @@ USER_LDFLAGS=$LDFLAGS
 if test -n "$with_experimental"; then
    for x in `echo $with_experimental | tr , ' '`; do
       case "$x" in
+         ChaosMonkey )
+            CPPFLAGS="$CPPFLAGS -DNCBI_MONKEY"
+                      WithFeatures="$WithFeatures${WithFeaturesSep}ChaosMonkey"; WithFeaturesSep=" "
+            ;;
          Int8GI )
             CPPFLAGS="$CPPFLAGS -DNCBI_INT8_GI"
+            NCBI_C_PATH_TAGS="/ncbi.gi64 .gi64"
                       WithFeatures="$WithFeatures${WithFeaturesSep}Int8GI"; WithFeaturesSep=" "
             ;;
          StrictGI )
             CPPFLAGS="$CPPFLAGS -DNCBI_STRICT_GI"
+            NCBI_C_PATH_TAGS="/ncbi.gi64 .gi64"
                       WithFeatures="$WithFeatures${WithFeaturesSep}Int8GI"; WithFeaturesSep=" "
                       WithFeatures="$WithFeatures${WithFeaturesSep}StrictGI"; WithFeaturesSep=" "
             ;;
@@ -4329,6 +4468,50 @@ cat >>confdefs.h <<\_ACEOF
 _ACEOF
 
 
+{ echo "$as_me:$LINENO: checking TeamCity build number" >&5
+echo $ECHO_N "checking TeamCity build number... $ECHO_C" >&6; }
+if test -n "$TEAMCITY_VERSION" -a -n "$BUILD_NUMBER"; then
+   { echo "$as_me:$LINENO: result: $BUILD_NUMBER" >&5
+echo "${ECHO_T}$BUILD_NUMBER" >&6; }
+   NCBI_TEAMCITY_BUILD_NUMBER=$BUILD_NUMBER
+else
+   { echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6; }
+   NCBI_TEAMCITY_BUILD_NUMBER=0
+fi
+
+{ echo "$as_me:$LINENO: checking Subversion revision" >&5
+echo $ECHO_N "checking Subversion revision... $ECHO_C" >&6; }
+svnrev=`svn info "$srcdir" 2>/dev/null | sed -ne 's/^Revision: //p'`
+if test -n "$svnrev"; then
+   { echo "$as_me:$LINENO: result: $svnrev" >&5
+echo "${ECHO_T}$svnrev" >&6; }
+   NCBI_SUBVERSION_REVISION=$svnrev
+else
+   { echo "$as_me:$LINENO: result: unknown" >&5
+echo "${ECHO_T}unknown" >&6; }
+   NCBI_SUBVERSION_REVISION=0
+fi
+
+{ echo "$as_me:$LINENO: checking NCBI stable components' version" >&5
+echo $ECHO_N "checking NCBI stable components' version... $ECHO_C" >&6; }
+scver=`svn info "$srcdir/src/build-system" 2>/dev/null |
+ sed -ne 's,^URL: .*/production/components/[^/]*/\([1-9][0-9]*\)\..*,\1,p'`
+if test -n "$scver"; then
+   { echo "$as_me:$LINENO: result: $scver" >&5
+echo "${ECHO_T}$scver" >&6; }
+   NCBI_SC_VERSION=$scver
+else
+   { echo "$as_me:$LINENO: result: unknown" >&5
+echo "${ECHO_T}unknown" >&6; }
+   NCBI_SC_VERSION=0
+fi
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_COMMON_NCBI_BUILD_VER_H 1
+_ACEOF
+
 
 #### Get the running host's properties
 ac_aux_dir=
@@ -7693,14 +7876,15 @@ echo "$as_me: WARNING: $msg" >&2;}; with_mt=no ;;
    esac
 fi
 
+case "$host_os:$compiler" in
+  solaris2.10:GCC ) : ${THREAD_LIBS:="-lposix4"} ;;
+  solaris*        ) : ${THREAD_LIBS:="-lpthread -lposix4"} ;;
+  freebsd*        ) ;; # -pthread already substitutes libc_r for libc
+  *               ) : ${THREAD_LIBS:="-lpthread"} ;;
+esac
+
 if test "$with_mt" != "no" ; then
    CPPFLAGS="$CPPFLAGS -D_MT -D_REENTRANT -D_THREAD_SAFE"
-   case "$host_os:$compiler" in
-     solaris2.10:GCC ) : ${THREAD_LIBS:="-lposix4"} ;;
-     solaris*        ) : ${THREAD_LIBS:="-lpthread -lposix4"} ;;
-     freebsd*        ) ;; # -pthread already substitutes libc_r for libc
-     *               ) : ${THREAD_LIBS:="-lpthread"} ;;
-   esac
    LIBS="$LIBS $THREAD_LIBS"
    case "$host_os:$compiler" in
      solaris2.??:* | solaris*:GCC | *:Compaq | irix* | aix* | darwin* | cygwin*)
@@ -7747,7 +7931,6 @@ if test "$with_mt" != "no" ; then
 else
    CPPFLAGS="$CPPFLAGS -DNCBI_WITHOUT_MT"
    MT_FLAG=
-   THREAD_LIBS=
    NCBIATOMIC_LIB=
    OPENMP_FLAGS=
    mt_sfx=""
@@ -7936,9 +8119,6 @@ case "$host_os:$compiler" in
             darwin?.* | darwin10.* ) # Mac OS X 10.6.x or older
                TARGET='-mmacosx-version-min=10.5'
                sdks="/Developer/SDKs/MacOSX10.6.sdk"
-               if test "$with_64:${with_universal-no}" != "yes:no"; then
-                  sdks="/Developer/SDKs/MacOSX10.5.sdk $sdks"
-               fi
                ;;
             * )
                TARGET='-mmacosx-version-min=10.7'
@@ -8029,58 +8209,7 @@ C_LIBS=$LIBS
 
 ARCH_CPPFLAGS=
 #### architecture settings, and extra C++ LIBS
-if test "${with_universal-no}" != "no" ; then
-   bit64_sfx= #"Univ"
-   case "$host" in
-    *-*-darwin[89].* | *-*-darwin[1-9][0-9]* )
-      case "$with_universal" in
-       yes )
-          case "$with_64:$host_os" in
-           yes:darwin8.* )
-             { { echo "$as_me:$LINENO: error: Unable to build 64-bit universal binaries on $host" >&5
-echo "$as_me: error: Unable to build 64-bit universal binaries on $host" >&2;}
-   { (exit 1); exit 1; }; }
-             ;;
-           yes:* )
-             ARCH_CFLAGS="-arch ppc64 -arch x86_64"
-             ARCH_CPPFLAGS="-m64"
-             ;;
-           * )
-             ARCH_CFLAGS="-arch ppc -arch i386"
-             ARCH_CPPFLAGS="-m32"
-             ;;
-          esac
-          ;;
-       * )
-         ARCH_CFLAGS="-arch `echo $with_universal | sed -e 's/,/ -arch /g'`"
-         ARCH_CPPFLAGS="-arch `echo $with_universal | sed -e 's/,.*//'`"
-         ;;
-      esac
-      case "$host" in
-       p*pc*-*-darwin8.*)
-         # Must specify -isysroot ..., but only once; anyway, the preprocessor
-         # needs to see it, and naturally can't cope with multiple -arch flags.
-         # The -mmacosx-version-min flag avoids link errors under OS 10.5
-         # (Darwin 9), which otherwise tries to use crt1.10.5.o despite the
-         # request for a sysroot lacking that file.
-         SYSROOT="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4"
-         #ARCH_CFLAGS="$SYSROOT $ARCH_CFLAGS"
-         CC="$CC $SYSROOT"
-         CXX="$CXX $SYSROOT"
-         ;;
-      esac
-      ;;
-    * ) { { echo "$as_me:$LINENO: error: Do not know how to build universal binaries on $host" >&5
-echo "$as_me: error: Do not know how to build universal binaries on $host" >&2;}
-   { (exit 1); exit 1; }; } ;;
-   esac
-
-cat >>confdefs.h <<\_ACEOF
-#define NCBI_UNIVERSAL_BUILD 1
-_ACEOF
-
-   with_distcc=no
-elif test "$with_64" = "yes" ; then
+if test "$with_64" = "yes" ; then
    bit64_sfx="64"
    case "$host:$compiler" in
     sparc-sun-solaris*:WorkShop5 | sparc-sun-solaris*:KCC )
@@ -8288,6 +8417,59 @@ echo "$as_me: error: cannot continue; please try different options" >&2;}
    fi
 fi
 
+#### Don't let Clang pick up old (pre-C++11) system standard
+#### library installations on Linux.
+case "$host_os:/$CXX" in
+   linux*:*/clang* )
+      gccver=4.9.3
+      gccdir=/opt/ncbi/gcc/$gccver
+      if test -d $gccdir; then
+         for d in `$gccdir/bin/g++ -v -E -x c++ $ARCH_CFLAGS $ARCH_CPPFLAGS - \
+                   </dev/null 2>&1 | fgrep 'include/c++' | tac`; do
+            ncbi_fix_dir_tmp=`if cd $d; then $as_unset PWD || test "${PWD+set}" != set || { PWD=; export PWD; }; /bin/pwd; fi`
+ case "$ncbi_fix_dir_tmp" in
+    /.*) ncbi_fix_dir_tmp2=`cd $d && $smart_pwd 2>/dev/null`
+         if test -n "$ncbi_fix_dir_tmp2" -a -d "$ncbi_fix_dir_tmp2"; then
+            d=$ncbi_fix_dir_tmp2
+         else
+            case "$d" in
+               /*) ;;
+               * ) d=$ncbi_fix_dir_tmp ;;
+            esac
+         fi
+         ;;
+    /*) d=$ncbi_fix_dir_tmp ;;
+ esac
+            # We don't use a dedicated CXXCPPFLAGS variable, but sticking
+            # with -isystem rather than -cxx-isystem avoids spurious
+            # warnings when also using ccache or distcc, and should still
+            # be safe in practice.  (The three libstdc++ headers that have
+            # the same names as system headers all arrange to include
+            # those headers via #include_next, and to conditionalize any
+            # C++ declarations on compiling as actual C++.)
+            CPPFLAGS="-isystem $d $CPPFLAGS"
+         done
+         CPPFLAGS="-nostdinc++ $CPPFLAGS"
+         libstdcxx=`$gccdir/bin/g++ --print-file-name=libstdc++.a`
+         d=`dirname $libstdcxx`
+         ncbi_fix_dir_tmp=`if cd $d; then $as_unset PWD || test "${PWD+set}" != set || { PWD=; export PWD; }; /bin/pwd; fi`
+ case "$ncbi_fix_dir_tmp" in
+    /.*) ncbi_fix_dir_tmp2=`cd $d && $smart_pwd 2>/dev/null`
+         if test -n "$ncbi_fix_dir_tmp2" -a -d "$ncbi_fix_dir_tmp2"; then
+            d=$ncbi_fix_dir_tmp2
+         else
+            case "$d" in
+               /*) ;;
+               * ) d=$ncbi_fix_dir_tmp ;;
+            esac
+         fi
+         ;;
+    /*) d=$ncbi_fix_dir_tmp ;;
+ esac
+         LDFLAGS="-L$d -Wl,-rpath,$d $LDFLAGS"
+      fi
+      ;;
+esac
 
 case "$host_os:$compiler" in
    darwin*:GCC )
@@ -8676,16 +8858,6 @@ fi
 echo "${ECHO_T}$ac_cv_have_decl__LIBCPP_VERSION" >&6; }
 
 
-case "$ac_cv_have_decl__LIBCPP_VERSION:$compiler:$compiler_version" in
-   no:GCC:4[0-6]? | no:ICC:1[01]?? )
-     ncbi_cv_prog_cxx_11=no
-     ncbi_cv_prog_c_99=no
-     ;;
-   *:ICC:* )
-     ncbi_cv_prog_c_99='-std=gnu99 -fgnu89-inline'
-     ;;
-esac
-
 { echo "$as_me:$LINENO: checking how to enable C++ '11 features in $CXX" >&5
 echo $ECHO_N "checking how to enable C++ '11 features in $CXX... $ECHO_C" >&6; }
 if test "${ncbi_cv_prog_cxx_11+set}" = set; then
@@ -8693,7 +8865,7 @@ if test "${ncbi_cv_prog_cxx_11+set}" = set; then
 else
   orig_CXX=$CXX
     ncbi_cv_prog_cxx_11=no
-    for x in -std=gnu++11 -std=gnu++0x; do
+    for x in -std=gnu++11 -std=gnu++0x ''; do
        CXX="$orig_CXX $x"
        cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -8701,11 +8873,11 @@ _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-
+#include <memory>
 int
 main ()
 {
-
+std::unique_ptr<int> x;
   ;
   return 0;
 }
@@ -8760,7 +8932,13 @@ rm -f core conftest.err conftest.$ac_objext \
 fi
 { echo "$as_me:$LINENO: result: $ncbi_cv_prog_cxx_11" >&5
 echo "${ECHO_T}$ncbi_cv_prog_cxx_11" >&6; }
-test "$ncbi_cv_prog_cxx_11" = no  ||  CXX="$CXX $ncbi_cv_prog_cxx_11"
+if test "$ncbi_cv_prog_cxx_11" = no; then
+   { { echo "$as_me:$LINENO: error: Please upgrade to a compiler supporting C++ '11, such as GCC 4.8 or newer." >&5
+echo "$as_me: error: Please upgrade to a compiler supporting C++ '11, such as GCC 4.8 or newer." >&2;}
+   { (exit 1); exit 1; }; }
+else
+   CXX="$CXX $ncbi_cv_prog_cxx_11"
+fi
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -9168,7 +9346,11 @@ echo "$as_me: WARNING: Unable to find static libstdc++ requested by --with-bin-r
     DLL_LDFLAGS="-static-intel -diag-disable 10237 -nodefaultlibs $DLL_LDFLAGS"
     # Redundant for apps, but necessary for plugins to be adequately
     # self-contained, at least on 32-bit Linux.
-    LIBS="$LIBS -lstdc++"
+    if test "$with_bin_release" = "yes"; then
+       LDFLAGS="$LDFLAGS -static-libstdc++"
+    elif test "$with_dll" != "no"; then
+       LIBS="$LIBS -lstdc++"
+    fi
     LINK="$LINK -Kc++"
     # Defining _GCC_NEXT_LIMITS_H ensures that <limits.h> chaining doesn't
     # stop short, as can otherwise happen. :-/
@@ -9458,8 +9640,7 @@ fi
 
 ### Support for precompiled headers
 GCCPCH="#"
-if test "$compiler" = GCC -a "$with_pch" = "yes" \
-     -a "${with_universal-no}" = "no"; then
+if test "$compiler" = GCC -a "$with_pch" = "yes"; then
    { echo "$as_me:$LINENO: checking whether $CXX supports precompiled headers" >&5
 echo $ECHO_N "checking whether $CXX supports precompiled headers... $ECHO_C" >&6; }
 if test "${ncbi_cv_cxx_pch+set}" = set; then
@@ -11245,8 +11426,7 @@ _ACEOF
 
 fi
 
-if test "${with_universal-no}" = "no"; then
-   { echo "$as_me:$LINENO: checking for size_t" >&5
+{ echo "$as_me:$LINENO: checking for size_t" >&5
 echo $ECHO_N "checking for size_t... $ECHO_C" >&6; }
 if test "${ac_cv_type_size_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -11746,16 +11926,15 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-   ac_cv_sizeof_size_t=`echo "$ac_cv_sizeof_size_t" | tr -d '\r'`
-   NCBI_PLATFORM_BITS=`expr 8 \* $ac_cv_sizeof_size_t`
+ac_cv_sizeof_size_t=`echo "$ac_cv_sizeof_size_t" | tr -d '\r'`
+NCBI_PLATFORM_BITS=`expr 8 \* $ac_cv_sizeof_size_t`
 
 cat >>confdefs.h <<_ACEOF
 #define NCBI_PLATFORM_BITS $NCBI_PLATFORM_BITS
 _ACEOF
 
-   if test $NCBI_PLATFORM_BITS -eq 64; then
-      bit64_sfx=64
-   fi
+if test $NCBI_PLATFORM_BITS -eq 64; then
+   bit64_sfx=64
 fi
 
 if test "$bit64_sfx" = 64 -o "$with_lfs" = "yes"; then
@@ -16851,8 +17030,7 @@ fi
 
 
 ### Check for C standard types and sizes
-if test "${with_universal-no}" = "no"; then
-   { echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+{ echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
 echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; }
 if test "${ac_cv_c_bigendian+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -17214,7 +17392,7 @@ _ACEOF
 
 fi
 
-   { echo "$as_me:$LINENO: checking for char" >&5
+{ echo "$as_me:$LINENO: checking for char" >&5
 echo $ECHO_N "checking for char... $ECHO_C" >&6; }
 if test "${ac_cv_type_char+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -17714,7 +17892,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-   { echo "$as_me:$LINENO: checking for double" >&5
+{ echo "$as_me:$LINENO: checking for double" >&5
 echo $ECHO_N "checking for double... $ECHO_C" >&6; }
 if test "${ac_cv_type_double+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -18214,7 +18392,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-   { echo "$as_me:$LINENO: checking for float" >&5
+{ echo "$as_me:$LINENO: checking for float" >&5
 echo $ECHO_N "checking for float... $ECHO_C" >&6; }
 if test "${ac_cv_type_float+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -18714,7 +18892,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-   { echo "$as_me:$LINENO: checking for int" >&5
+{ echo "$as_me:$LINENO: checking for int" >&5
 echo $ECHO_N "checking for int... $ECHO_C" >&6; }
 if test "${ac_cv_type_int+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -19214,7 +19392,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-   { echo "$as_me:$LINENO: checking for long" >&5
+{ echo "$as_me:$LINENO: checking for long" >&5
 echo $ECHO_N "checking for long... $ECHO_C" >&6; }
 if test "${ac_cv_type_long+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -19714,7 +19892,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-   { echo "$as_me:$LINENO: checking for long double" >&5
+{ echo "$as_me:$LINENO: checking for long double" >&5
 echo $ECHO_N "checking for long double... $ECHO_C" >&6; }
 if test "${ac_cv_type_long_double+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -20214,7 +20392,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-   { echo "$as_me:$LINENO: checking for long long" >&5
+{ echo "$as_me:$LINENO: checking for long long" >&5
 echo $ECHO_N "checking for long long... $ECHO_C" >&6; }
 if test "${ac_cv_type_long_long+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -20714,7 +20892,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-   { echo "$as_me:$LINENO: checking for short" >&5
+{ echo "$as_me:$LINENO: checking for short" >&5
 echo $ECHO_N "checking for short... $ECHO_C" >&6; }
 if test "${ac_cv_type_short+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -21214,7 +21392,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-   { echo "$as_me:$LINENO: checking for void*" >&5
+{ echo "$as_me:$LINENO: checking for void*" >&5
 echo $ECHO_N "checking for void*... $ECHO_C" >&6; }
 if test "${ac_cv_type_voidp+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -21714,7 +21892,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-   { echo "$as_me:$LINENO: checking for wchar_t" >&5
+{ echo "$as_me:$LINENO: checking for wchar_t" >&5
 echo $ECHO_N "checking for wchar_t... $ECHO_C" >&6; }
 if test "${ac_cv_type_wchar_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -22221,7 +22399,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-   { echo "$as_me:$LINENO: checking for __int64" >&5
+{ echo "$as_me:$LINENO: checking for __int64" >&5
 echo $ECHO_N "checking for __int64... $ECHO_C" >&6; }
 if test "${ac_cv_type___int64+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -22721,7 +22899,6 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-fi
 { echo "$as_me:$LINENO: checking for intptr_t" >&5
 echo $ECHO_N "checking for intptr_t... $ECHO_C" >&6; }
 if test "${ac_cv_type_intptr_t+set}" = set; then
@@ -29636,6 +29813,28 @@ if test "x$with_gnutls" != xno -a -n "$GNUTLS_CONFIG_LIBS"; then
        *\ -lgcrypt* ) ;;
        *            ) GNUTLS_LIBS="$GNUTLS_LIBS $GCRYPT_LIBS" ;;
    esac
+   if test "$with_static_gnutls" = yes; then
+      dirs=''
+      sep=''
+      static_libs=''
+      for x in $GNUTLS_LIBS; do
+         case $x in
+            -L* ) dirs="$dirs `echo _$x | cut -c4-`" ;;
+            -l* )
+                want=lib`echo _$x | cut -c4-`-static.a
+                for d in $dirs; do
+                   if test -f $d/$want; then
+                      x=$x-static
+                      break
+                   fi
+                done
+                ;;
+         esac
+         static_libs=$static_libs$sep$x
+         sep=' '
+      done
+      GNUTLS_LIBS=$static_libs
+   fi
 fi
 
 if test "$with_openssl" != "no"; then
@@ -29832,6 +30031,7 @@ else
    TLS_LIBS=$OPENSSL_LIBS
 fi
 
+NETWORK_LIBS="$TLS_LIBS $NETWORK_LIBS"
 
 case "$with_krb5" in
    no )       ac_cv_path_KRB5_CONFIG=no    ;;
@@ -30761,9 +30961,9 @@ if test "$with_ftds" != "no" ; then
    ftds_ver=64
    try_local=yes
    case "$with_ftds" in
-      64 | 0.64 | yes | '' )
+      64 | 0.64 )
          ;;
-      95 | 0.95 )
+      95 | 0.95 | yes | '' )
          ftds_ver=95
          ;;
       * )
@@ -30771,7 +30971,7 @@ if test "$with_ftds" != "no" ; then
          try_local=no
          ;;
    esac
-   : ${FTDS_CTLIBS:="-lct -ltds"}
+   : ${FTDS_CTLIBS:="-lct -ltds $NETWORK_LIBS"}
    ncbi_rp_L_flags=
  ncbi_rp_L_sep=$CONF_f_libpath
  if test "x${CONF_f_runpath}" = "x${CONF_f_libpath}"; then
@@ -30807,7 +31007,7 @@ if test "$with_ftds" != "no" ; then
       if test $try_local = yes -a -f "${real_srcdir}/src/$d/Makefile.in" ; then
          test "$ftds_ver" = 64  &&  FTDS_PATH="<$d>"
          FTDS64_CTLIB_LIB="ct_ftds64${STATIC} tds_ftds64${STATIC}"
-         FTDS64_CTLIB_LIBS='$(ICONV_LIBS) $(KRB5_LIBS)'
+         FTDS64_CTLIB_LIBS='$(ICONV_LIBS) $(KRB5_LIBS) $(NETWORK_LIBS)'
          FTDS64_CTLIB_INCLUDE="-I\$(includedir)/$d -I\$(includedir0)/$d"
          freetds=freetds
       elif test -d "$FTDS_PATH" ; then
@@ -30823,7 +31023,7 @@ if test "$with_ftds" != "no" ; then
       if test $try_local = yes -a -f "${real_srcdir}/src/$d/Makefile.in" ; then
          test "$ftds_ver" = 95  &&  FTDS_PATH="<$d>"
          FTDS95_CTLIB_LIB="ct_ftds95${STATIC} tds_ftds95${STATIC}"
-         FTDS95_CTLIB_LIBS='$(ICONV_LIBS) $(KRB5_LIBS)'
+         FTDS95_CTLIB_LIBS='$(ICONV_LIBS) $(KRB5_LIBS) $(NETWORK_LIBS)'
          FTDS95_CTLIB_INCLUDE="-I\$(includedir)/$d -I\$(includedir0)/$d"
          freetds=freetds
       elif test -d "$FTDS_PATH" ; then
@@ -31352,15 +31552,21 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
+cat >/dev/null <<_NCBI_EOF
 #include <db.h>
-ncbi_cv_lib_berkeley_db_version=DB_VERSION_MAJOR.DB_VERSION_MINOR.DB_VERSION_PATCH
+_NCBI_EOF
+get_DB_VERSION() {
+    grep '^[^#]' <<_NCBI_EOF
+DB_VERSION_MAJOR.DB_VERSION_MINOR.DB_VERSION_PATCH
+_NCBI_EOF
+}
+ncbi_cv_lib_berkeley_db_version=\`get_DB_VERSION | tr -cd 0123456789.\`
 
 _ACEOF
-          eval "$ac_cpp $BERKELEYDB_INCLUDE conftest.$ac_ext" \
-             2>&5 | grep '^ncbi_cv_' \
-             | tr -d "$wschars" > conftest.sh
+          eval "$ac_cpp $BERKELEYDB_INCLUDE conftest.$ac_ext" > conftest.sh \
+             2>&5
           . ./conftest.sh
-          rm -f contest*
+          rm -f conftest*
 
 fi
 { echo "$as_me:$LINENO: result: $ncbi_cv_lib_berkeley_db_version" >&5
@@ -32147,16 +32353,15 @@ fi
 
 
  if test -x "$PYTHON"; then
-    PYTHON_VERSION=`$PYTHON -c 'from distutils import sysconfig; print(sysconfig.get_config_var("VERSION"))' 2>/dev/null`
+    pyconf="$real_srcdir/scripts/common/impl/python-config.py"
+    PYTHON_VERSION=`DYLD_BIND_AT_LAUNCH=1 "$PYTHON" "$pyconf" --version 2>&5`
  else
     PYTHON_VERSION=
     ncbi_cv_lib_python=no
  fi
  if test -n "$PYTHON_VERSION"; then
-    PYTHON_INCLUDE=`$PYTHON -c 'from distutils import sysconfig; f=sysconfig.get_python_inc; print("-I%s -I%s" % (f(), f(True)))'`
-    PYTHON_LIBPATH=`$PYTHON -c 'from distutils import sysconfig; print(" ".join(sysconfig.get_config_vars("LIBDIR", "LIBPL")))'`
-    PYTHON_DEPS=`$PYTHON -c 'from distutils import sysconfig; print(" ".join(sysconfig.get_config_vars("LIBS", "SYSLIBS")))'`
-    PYTHON_LDVERSION=`$PYTHON -c 'from distutils import sysconfig; print(sysconfig.get_config_var("LDVERSION") or sysconfig.get_config_var("VERSION"))' 2>/dev/null`
+    PYTHON_INCLUDE=`"$PYTHON" "$pyconf" --include`
+    PYTHON_LIBPATH=`"$PYTHON" "$pyconf" --libpath`
     ncbi_rp_L_flags=
  ncbi_rp_L_sep=$CONF_f_libpath
  if test "x${CONF_f_runpath}" = "x${CONF_f_libpath}"; then
@@ -32169,7 +32374,7 @@ fi
        ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
        ncbi_rp_L_sep=" $CONF_f_libpath"
     done
-    PYTHON_LIBS="${ncbi_rp_L_flags} -lpython$PYTHON_LDVERSION $PYTHON_DEPS"
+    PYTHON_LIBS="${ncbi_rp_L_flags} `"$PYTHON" "$pyconf" --libs`"
  else
     ncbi_rp_R_flags=
     ncbi_rp_R_sep=" $CONF_f_runpath"
@@ -32185,7 +32390,7 @@ fi
        ncbi_rp_R_flags="${ncbi_rp_R_flags}${ncbi_rp_R_sep}$x"
        ncbi_rp_R_sep=:
     done
-    PYTHON_LIBS="${ncbi_rp_L_flags}${ncbi_rp_R_flags} -lpython$PYTHON_LDVERSION $PYTHON_DEPS"
+    PYTHON_LIBS="${ncbi_rp_L_flags}${ncbi_rp_R_flags} `"$PYTHON" "$pyconf" --libs`"
  fi
     CPPFLAGS="$PYTHON_INCLUDE $orig_CPPFLAGS"
     LIBS="$PYTHON_LIBS $orig_LIBS"
@@ -32264,6 +32469,7 @@ fi
 { echo "$as_me:$LINENO: result: $ncbi_cv_lib_python" >&5
 echo "${ECHO_T}$ncbi_cv_lib_python" >&6; }
  else
+    PYTHON=
     ncbi_cv_lib_python=no
  fi
  if test "$ncbi_cv_lib_python" = "no"; then
@@ -32322,16 +32528,15 @@ fi
 
 
  if test -x "$PYTHON25"; then
-    PYTHON25_VERSION=`$PYTHON25 -c 'from distutils import sysconfig; print(sysconfig.get_config_var("VERSION"))' 2>/dev/null`
+    pyconf="$real_srcdir/scripts/common/impl/python-config.py"
+    PYTHON25_VERSION=`DYLD_BIND_AT_LAUNCH=1 "$PYTHON25" "$pyconf" --version 2>&5`
  else
     PYTHON25_VERSION=
     ncbi_cv_lib_python25=no
  fi
  if test -n "$PYTHON25_VERSION"; then
-    PYTHON25_INCLUDE=`$PYTHON25 -c 'from distutils import sysconfig; f=sysconfig.get_python_inc; print("-I%s -I%s" % (f(), f(True)))'`
-    PYTHON25_LIBPATH=`$PYTHON25 -c 'from distutils import sysconfig; print(" ".join(sysconfig.get_config_vars("LIBDIR", "LIBPL")))'`
-    PYTHON25_DEPS=`$PYTHON25 -c 'from distutils import sysconfig; print(" ".join(sysconfig.get_config_vars("LIBS", "SYSLIBS")))'`
-    PYTHON25_LDVERSION=`$PYTHON25 -c 'from distutils import sysconfig; print(sysconfig.get_config_var("LDVERSION") or sysconfig.get_config_var("VERSION"))' 2>/dev/null`
+    PYTHON25_INCLUDE=`"$PYTHON25" "$pyconf" --include`
+    PYTHON25_LIBPATH=`"$PYTHON25" "$pyconf" --libpath`
     ncbi_rp_L_flags=
  ncbi_rp_L_sep=$CONF_f_libpath
  if test "x${CONF_f_runpath}" = "x${CONF_f_libpath}"; then
@@ -32344,7 +32549,7 @@ fi
        ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
        ncbi_rp_L_sep=" $CONF_f_libpath"
     done
-    PYTHON25_LIBS="${ncbi_rp_L_flags} -lpython$PYTHON25_LDVERSION $PYTHON25_DEPS"
+    PYTHON25_LIBS="${ncbi_rp_L_flags} `"$PYTHON25" "$pyconf" --libs`"
  else
     ncbi_rp_R_flags=
     ncbi_rp_R_sep=" $CONF_f_runpath"
@@ -32360,7 +32565,7 @@ fi
        ncbi_rp_R_flags="${ncbi_rp_R_flags}${ncbi_rp_R_sep}$x"
        ncbi_rp_R_sep=:
     done
-    PYTHON25_LIBS="${ncbi_rp_L_flags}${ncbi_rp_R_flags} -lpython$PYTHON25_LDVERSION $PYTHON25_DEPS"
+    PYTHON25_LIBS="${ncbi_rp_L_flags}${ncbi_rp_R_flags} `"$PYTHON25" "$pyconf" --libs`"
  fi
     CPPFLAGS="$PYTHON25_INCLUDE $orig_CPPFLAGS"
     LIBS="$PYTHON25_LIBS $orig_LIBS"
@@ -32439,6 +32644,7 @@ fi
 { echo "$as_me:$LINENO: result: $ncbi_cv_lib_python25" >&5
 echo "${ECHO_T}$ncbi_cv_lib_python25" >&6; }
  else
+    PYTHON25=
     ncbi_cv_lib_python25=no
  fi
  if test "$ncbi_cv_lib_python25" = "no"; then
@@ -32497,16 +32703,15 @@ fi
 
 
  if test -x "$PYTHON26"; then
-    PYTHON26_VERSION=`$PYTHON26 -c 'from distutils import sysconfig; print(sysconfig.get_config_var("VERSION"))' 2>/dev/null`
+    pyconf="$real_srcdir/scripts/common/impl/python-config.py"
+    PYTHON26_VERSION=`DYLD_BIND_AT_LAUNCH=1 "$PYTHON26" "$pyconf" --version 2>&5`
  else
     PYTHON26_VERSION=
     ncbi_cv_lib_python26=no
  fi
  if test -n "$PYTHON26_VERSION"; then
-    PYTHON26_INCLUDE=`$PYTHON26 -c 'from distutils import sysconfig; f=sysconfig.get_python_inc; print("-I%s -I%s" % (f(), f(True)))'`
-    PYTHON26_LIBPATH=`$PYTHON26 -c 'from distutils import sysconfig; print(" ".join(sysconfig.get_config_vars("LIBDIR", "LIBPL")))'`
-    PYTHON26_DEPS=`$PYTHON26 -c 'from distutils import sysconfig; print(" ".join(sysconfig.get_config_vars("LIBS", "SYSLIBS")))'`
-    PYTHON26_LDVERSION=`$PYTHON26 -c 'from distutils import sysconfig; print(sysconfig.get_config_var("LDVERSION") or sysconfig.get_config_var("VERSION"))' 2>/dev/null`
+    PYTHON26_INCLUDE=`"$PYTHON26" "$pyconf" --include`
+    PYTHON26_LIBPATH=`"$PYTHON26" "$pyconf" --libpath`
     ncbi_rp_L_flags=
  ncbi_rp_L_sep=$CONF_f_libpath
  if test "x${CONF_f_runpath}" = "x${CONF_f_libpath}"; then
@@ -32519,7 +32724,7 @@ fi
        ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
        ncbi_rp_L_sep=" $CONF_f_libpath"
     done
-    PYTHON26_LIBS="${ncbi_rp_L_flags} -lpython$PYTHON26_LDVERSION $PYTHON26_DEPS"
+    PYTHON26_LIBS="${ncbi_rp_L_flags} `"$PYTHON26" "$pyconf" --libs`"
  else
     ncbi_rp_R_flags=
     ncbi_rp_R_sep=" $CONF_f_runpath"
@@ -32535,7 +32740,7 @@ fi
        ncbi_rp_R_flags="${ncbi_rp_R_flags}${ncbi_rp_R_sep}$x"
        ncbi_rp_R_sep=:
     done
-    PYTHON26_LIBS="${ncbi_rp_L_flags}${ncbi_rp_R_flags} -lpython$PYTHON26_LDVERSION $PYTHON26_DEPS"
+    PYTHON26_LIBS="${ncbi_rp_L_flags}${ncbi_rp_R_flags} `"$PYTHON26" "$pyconf" --libs`"
  fi
     CPPFLAGS="$PYTHON26_INCLUDE $orig_CPPFLAGS"
     LIBS="$PYTHON26_LIBS $orig_LIBS"
@@ -32614,6 +32819,7 @@ fi
 { echo "$as_me:$LINENO: result: $ncbi_cv_lib_python26" >&5
 echo "${ECHO_T}$ncbi_cv_lib_python26" >&6; }
  else
+    PYTHON26=
     ncbi_cv_lib_python26=no
  fi
  if test "$ncbi_cv_lib_python26" = "no"; then
@@ -32672,16 +32878,15 @@ fi
 
 
  if test -x "$PYTHON27"; then
-    PYTHON27_VERSION=`$PYTHON27 -c 'from distutils import sysconfig; print(sysconfig.get_config_var("VERSION"))' 2>/dev/null`
+    pyconf="$real_srcdir/scripts/common/impl/python-config.py"
+    PYTHON27_VERSION=`DYLD_BIND_AT_LAUNCH=1 "$PYTHON27" "$pyconf" --version 2>&5`
  else
     PYTHON27_VERSION=
     ncbi_cv_lib_python27=no
  fi
  if test -n "$PYTHON27_VERSION"; then
-    PYTHON27_INCLUDE=`$PYTHON27 -c 'from distutils import sysconfig; f=sysconfig.get_python_inc; print("-I%s -I%s" % (f(), f(True)))'`
-    PYTHON27_LIBPATH=`$PYTHON27 -c 'from distutils import sysconfig; print(" ".join(sysconfig.get_config_vars("LIBDIR", "LIBPL")))'`
-    PYTHON27_DEPS=`$PYTHON27 -c 'from distutils import sysconfig; print(" ".join(sysconfig.get_config_vars("LIBS", "SYSLIBS")))'`
-    PYTHON27_LDVERSION=`$PYTHON27 -c 'from distutils import sysconfig; print(sysconfig.get_config_var("LDVERSION") or sysconfig.get_config_var("VERSION"))' 2>/dev/null`
+    PYTHON27_INCLUDE=`"$PYTHON27" "$pyconf" --include`
+    PYTHON27_LIBPATH=`"$PYTHON27" "$pyconf" --libpath`
     ncbi_rp_L_flags=
  ncbi_rp_L_sep=$CONF_f_libpath
  if test "x${CONF_f_runpath}" = "x${CONF_f_libpath}"; then
@@ -32694,7 +32899,7 @@ fi
        ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
        ncbi_rp_L_sep=" $CONF_f_libpath"
     done
-    PYTHON27_LIBS="${ncbi_rp_L_flags} -lpython$PYTHON27_LDVERSION $PYTHON27_DEPS"
+    PYTHON27_LIBS="${ncbi_rp_L_flags} `"$PYTHON27" "$pyconf" --libs`"
  else
     ncbi_rp_R_flags=
     ncbi_rp_R_sep=" $CONF_f_runpath"
@@ -32710,7 +32915,7 @@ fi
        ncbi_rp_R_flags="${ncbi_rp_R_flags}${ncbi_rp_R_sep}$x"
        ncbi_rp_R_sep=:
     done
-    PYTHON27_LIBS="${ncbi_rp_L_flags}${ncbi_rp_R_flags} -lpython$PYTHON27_LDVERSION $PYTHON27_DEPS"
+    PYTHON27_LIBS="${ncbi_rp_L_flags}${ncbi_rp_R_flags} `"$PYTHON27" "$pyconf" --libs`"
  fi
     CPPFLAGS="$PYTHON27_INCLUDE $orig_CPPFLAGS"
     LIBS="$PYTHON27_LIBS $orig_LIBS"
@@ -32789,6 +32994,7 @@ fi
 { echo "$as_me:$LINENO: result: $ncbi_cv_lib_python27" >&5
 echo "${ECHO_T}$ncbi_cv_lib_python27" >&6; }
  else
+    PYTHON27=
     ncbi_cv_lib_python27=no
  fi
  if test "$ncbi_cv_lib_python27" = "no"; then
@@ -32847,16 +33053,15 @@ fi
 
 
  if test -x "$PYTHON3"; then
-    PYTHON3_VERSION=`$PYTHON3 -c 'from distutils import sysconfig; print(sysconfig.get_config_var("VERSION"))' 2>/dev/null`
+    pyconf="$real_srcdir/scripts/common/impl/python-config.py"
+    PYTHON3_VERSION=`DYLD_BIND_AT_LAUNCH=1 "$PYTHON3" "$pyconf" --version 2>&5`
  else
     PYTHON3_VERSION=
     ncbi_cv_lib_python3=no
  fi
  if test -n "$PYTHON3_VERSION"; then
-    PYTHON3_INCLUDE=`$PYTHON3 -c 'from distutils import sysconfig; f=sysconfig.get_python_inc; print("-I%s -I%s" % (f(), f(True)))'`
-    PYTHON3_LIBPATH=`$PYTHON3 -c 'from distutils import sysconfig; print(" ".join(sysconfig.get_config_vars("LIBDIR", "LIBPL")))'`
-    PYTHON3_DEPS=`$PYTHON3 -c 'from distutils import sysconfig; print(" ".join(sysconfig.get_config_vars("LIBS", "SYSLIBS")))'`
-    PYTHON3_LDVERSION=`$PYTHON3 -c 'from distutils import sysconfig; print(sysconfig.get_config_var("LDVERSION") or sysconfig.get_config_var("VERSION"))' 2>/dev/null`
+    PYTHON3_INCLUDE=`"$PYTHON3" "$pyconf" --include`
+    PYTHON3_LIBPATH=`"$PYTHON3" "$pyconf" --libpath`
     ncbi_rp_L_flags=
  ncbi_rp_L_sep=$CONF_f_libpath
  if test "x${CONF_f_runpath}" = "x${CONF_f_libpath}"; then
@@ -32869,7 +33074,7 @@ fi
        ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
        ncbi_rp_L_sep=" $CONF_f_libpath"
     done
-    PYTHON3_LIBS="${ncbi_rp_L_flags} -lpython$PYTHON3_LDVERSION $PYTHON3_DEPS"
+    PYTHON3_LIBS="${ncbi_rp_L_flags} `"$PYTHON3" "$pyconf" --libs`"
  else
     ncbi_rp_R_flags=
     ncbi_rp_R_sep=" $CONF_f_runpath"
@@ -32885,7 +33090,7 @@ fi
        ncbi_rp_R_flags="${ncbi_rp_R_flags}${ncbi_rp_R_sep}$x"
        ncbi_rp_R_sep=:
     done
-    PYTHON3_LIBS="${ncbi_rp_L_flags}${ncbi_rp_R_flags} -lpython$PYTHON3_LDVERSION $PYTHON3_DEPS"
+    PYTHON3_LIBS="${ncbi_rp_L_flags}${ncbi_rp_R_flags} `"$PYTHON3" "$pyconf" --libs`"
  fi
     CPPFLAGS="$PYTHON3_INCLUDE $orig_CPPFLAGS"
     LIBS="$PYTHON3_LIBS $orig_LIBS"
@@ -32964,6 +33169,7 @@ fi
 { echo "$as_me:$LINENO: result: $ncbi_cv_lib_python3" >&5
 echo "${ECHO_T}$ncbi_cv_lib_python3" >&6; }
  else
+    PYTHON3=
     ncbi_cv_lib_python3=no
  fi
  if test "$ncbi_cv_lib_python3" = "no"; then
@@ -33569,16 +33775,27 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
+cat >/dev/null <<_NCBI_EOF
 #include <boost/version.hpp>
-ncbi_cv_lib_boost_version_num=BOOST_VERSION
-ncbi_cv_lib_boost_version=BOOST_LIB_VERSION
+_NCBI_EOF
+get_BOOST_VERSION() {
+    grep '^[^#]' <<_NCBI_EOF
+BOOST_VERSION
+_NCBI_EOF
+}
+get_BOOST_LIB_VERSION() {
+    grep '^[^#]' <<_NCBI_EOF
+BOOST_LIB_VERSION
+_NCBI_EOF
+}
+ncbi_cv_lib_boost_version_num=\`get_BOOST_VERSION\`
+ncbi_cv_lib_boost_version=\`get_BOOST_LIB_VERSION | tr -d '"'\`
 
 _ACEOF
-          eval "$ac_cpp $BOOST_INCLUDE conftest.$ac_ext" \
-             2>&5 | grep '^ncbi_cv_' \
-             | tr -d "$wschars" > conftest.sh
+          eval "$ac_cpp $BOOST_INCLUDE conftest.$ac_ext" > conftest.sh \
+             2>&5
           . ./conftest.sh
-          rm -f contest*
+          rm -f conftest*
 
 fi
 { echo "$as_me:$LINENO: result: $ncbi_cv_lib_boost_version" >&5
@@ -33620,7 +33837,7 @@ echo "$as_me: error: --with-boost:  Boost library is too old" >&2;}
          fi
          with_boost=no
          ;;
-      1_3[5-9] | 1_3[5-9]_* | 1_[45]* | 1_60 | 1_60_* ) ;;
+      1_3[5-9] | 1_3[5-9]_* | 1_[45]* | 1_6[0-2] | 1_6[0-2]_* ) ;;
       '' ) with_boost=no ;;
       * )
          { echo "$as_me:$LINENO: WARNING: Untested Boost version; may prove incompatible." >&5
@@ -34518,6 +34735,14 @@ if test "$with_ncbi_c" != "no" ; then
    if test "$ncbi_compiler" = ICC -a -d "$NCBI_C_PATH/ncbi_icc"; then
       NCBI_C_PATH=$NCBI_C_PATH/ncbi_icc
    fi
+   if test -n "$NCBI_C_PATH_TAGS"; then
+      for x in $NCBI_C_PATH_TAGS; do
+         if test -d "$NCBI_C_PATH$x"; then
+            NCBI_C_PATH=$NCBI_C_PATH$x
+            break
+         fi
+      done
+   fi
 
    NCBI_C_INCLUDE="-I$NCBI_C_PATH/include${bit64_sfx}"
    if test "$with_debug" = "no" ; then
@@ -40850,6 +41075,12 @@ VDB_REQ=VDB
 if test "$with_vdb" != "no" ; then
    # CURL?
    vdb_deps="$LIBXML_LIBS $NETWORK_LIBS $BZ2_LIBS $Z_LIBS $DL_LIBS"
+   # In MT builds, ORIG_LIBS already contains THREAD_LIBS.  However,
+   # VDB is always threaded, and may need explicit THREAD_LIBS when
+   # used statically.
+   if test "$with_mt" = no; then
+      vdb_deps="$vdb_deps $THREAD_LIBS"
+   fi
    if test "${with_vdb:-yes}" != "yes" -a -d "$with_vdb"; then
       VDB_PATH=$with_vdb
    fi
@@ -40904,13 +41135,30 @@ echo "$as_me: WARNING: $message" >&2;}  ;;
          in_path=" in $VDB_PATH"
          for x in interfaces include; do
             if test -d "$VDB_PATH/$x"; then
-               : ${VDB_INCLUDE="-I$VDB_PATH/$x"}
+               vdb_inc_root=$VDB_PATH/$x
+               : ${VDB_INCLUDE="-I$vdb_inc_root"}
                break
             fi
          done
+         vdb_inc_subdirs=cc/gcc
+         case "$host_cpu:$bit64_sfx" in
+            *86*:64 ) vdb_inc_subdirs="cc/gcc/x86_64 $vdb_inc_subdirs" ;;
+            *86*:*  ) vdb_inc_subdirs="cc/gcc/fat86 $vdb_inc_subdirs" ;;
+         esac
+         if test "$ncbi_compiler" = ICC; then
+            vdb_inc_subdirs="cc/icc $vdb_inc_subdirs"
+         fi
+         case "$host_os" in
+            darwin*  ) vdb_inc_subdirs="os/mac os/unix $vdb_inc_subdirs" ;;
+            linux*   ) vdb_inc_subdirs="os/linux os/unix $vdb_inc_subdirs" ;;
+            solaris* ) vdb_inc_subdirs="os/sun os/unix $vdb_inc_subdirs" ;;
+         esac
+         for x in $vdb_inc_subdirs; do
+            VDB_INCLUDE="$VDB_INCLUDE -I$vdb_inc_root/$x"
+         done
          case "$DEBUG_SFX" in
             Debug )
-               VDB_INCLUDE="$VDB_INCLUDE $VDB_INCLUDE/cc/gcc -D_DEBUGGING"
+               VDB_INCLUDE="$VDB_INCLUDE -D_DEBUGGING"
                vdb_mode=debug
                ;;
             Release )
@@ -41042,9 +41290,11 @@ fi
 echo "${ECHO_T}$ncbi_cv_lib_ncbi_vdb" >&6; }
       if test "$ncbi_cv_lib_ncbi_vdb" = yes; then
                    WithPackages="$WithPackages${WithPackagesSep}VDB"; WithPackagesSep=" "
-         VDB_LIB=
          if test -f "$VDB_LIBDIR/libncbi-vdb-static.a"; then
             VDB_STATIC_LIBS="-L$VDB_LIBDIR -lncbi-vdb-static $vdb_deps"
+            if test "$with_static_vdb" = yes; then
+               VDB_LIBS=$VDB_STATIC_LIBS
+            fi
          else
             VDB_STATIC_LIBS=$VDB_LIBS
          fi
@@ -41061,10 +41311,35 @@ echo "${ECHO_T}$ncbi_cv_lib_ncbi_vdb" >&6; }
                esac
                ;;
          esac
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_NCBI_VDB 1
+_ACEOF
+
+         bamread=bamread
+         sraread=sraread
+         ncbi_id2proc_snp=ncbi_id2proc_snp
+         ncbi_id2proc_wgs=ncbi_id2proc_wgs
+         ncbi_xloader_bam=ncbi_xloader_bam
+         ncbi_xloader_csra=ncbi_xloader_csra
+         ncbi_xloader_snp=ncbi_xloader_snp
+         ncbi_xloader_sra=ncbi_xloader_sra
+         ncbi_xloader_vdbgraph=ncbi_xloader_vdbgraph
+         ncbi_xloader_wgs=ncbi_xloader_wgs
       else
          VDB_INCLUDE=
          VDB_LIBS=
          VDB_STATIC_LIBS=
+         bamread=
+         sraread=
+         ncbi_id2proc_snp=
+         ncbi_id2proc_wgs=
+         ncbi_xloader_bam=
+         ncbi_xloader_csra=
+         ncbi_xloader_snp=
+         ncbi_xloader_sra=
+         ncbi_xloader_vdbgraph=
+         ncbi_xloader_wgs=
       fi
    # else ...
    # fi
@@ -45300,6 +45575,652 @@ _ACEOF
 
 
 
+# LAPACK
+CPPFLAGS="-DHAVE_LAPACK_CONFIG_H $orig_CPPFLAGS"
+case "$with_lapack" in
+   yes | no | '' ) ;;
+   *             ) LAPACK_PATH=$with_lapack ;;
+esac
+if test -d "$LAPACK_PATH"; then
+   ncbi_fix_dir_tmp=`if cd $LAPACK_PATH; then $as_unset PWD || test "${PWD+set}" != set || { PWD=; export PWD; }; /bin/pwd; fi`
+ case "$ncbi_fix_dir_tmp" in
+    /.*) ncbi_fix_dir_tmp2=`cd $LAPACK_PATH && $smart_pwd 2>/dev/null`
+         if test -n "$ncbi_fix_dir_tmp2" -a -d "$ncbi_fix_dir_tmp2"; then
+            LAPACK_PATH=$ncbi_fix_dir_tmp2
+         else
+            case "$LAPACK_PATH" in
+               /*) ;;
+               * ) LAPACK_PATH=$ncbi_fix_dir_tmp ;;
+            esac
+         fi
+         ;;
+    /*) LAPACK_PATH=$ncbi_fix_dir_tmp ;;
+ esac
+   CPPFLAGS="-I$LAPACK_PATH/include $CPPFLAGS"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+for ac_header in lapacke.h lapacke/lapacke.h clapack.h Accelerate/Accelerate.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ---------------------------------------- ##
+## Report this to cpp-core at ncbi.nlm.nih.gov ##
+## ---------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+if test "$ac_cv_header_clapack_h:$ac_cv_header_Accelerate_Accelerate_h" != no:no; then
+   { echo "$as_me:$LINENO: checking for __CLPK_integer" >&5
+echo $ECHO_N "checking for __CLPK_integer... $ECHO_C" >&6; }
+if test "${ac_cv_type___CLPK_integer+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef HAVE_CLAPACK_H
+        #  include <clapack.h>
+        #else
+        #  include <Accelerate/Accelerate.h>
+        #endif
+
+typedef __CLPK_integer ac__type_new_;
+int
+main ()
+{
+if ((ac__type_new_ *) 0)
+  return 0;
+if (sizeof (ac__type_new_))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type___CLPK_integer=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_type___CLPK_integer=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_type___CLPK_integer" >&5
+echo "${ECHO_T}$ac_cv_type___CLPK_integer" >&6; }
+if test $ac_cv_type___CLPK_integer = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE___CLPK_INTEGER 1
+_ACEOF
+
+
+fi
+
+fi
+
+if test "$with_lapack" != "no"; then
+    case "$with_lapack" in
+       yes | "" ) ;;
+       *        ) LAPACK_PATH=$with_lapack ;;
+    esac
+    if test "$LAPACK_PATH" != /usr -a -d "$LAPACK_PATH"; then
+       in_path=" in $LAPACK_PATH"
+       if test -z "$LAPACK_INCLUDE" -a -d "$LAPACK_PATH/include"; then
+          LAPACK_INCLUDE="-I$LAPACK_PATH/include"
+       fi
+       if test -n "$LAPACK_LIBPATH"; then
+          :
+       elif test -d "$LAPACK_PATH/lib${bit64_sfx}"; then
+          ncbi_rp_L_flags=
+ ncbi_rp_L_sep=$CONF_f_libpath
+ if test "x${CONF_f_runpath}" = "x${CONF_f_libpath}"; then
+    for x in $LAPACK_PATH/lib${bit64_sfx}; do
+       case "$x" in
+          /lib | /usr/lib | /usr/lib32 | /usr/lib64 | /usr/lib/$multiarch )
+             continue
+             ;;
+       esac
+       ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
+       ncbi_rp_L_sep=" $CONF_f_libpath"
+    done
+    LAPACK_LIBPATH="${ncbi_rp_L_flags}"
+ else
+    ncbi_rp_R_flags=
+    ncbi_rp_R_sep=" $CONF_f_runpath"
+    for x in $LAPACK_PATH/lib${bit64_sfx}; do
+       case "$x" in
+          /lib | /usr/lib | /usr/lib32 | /usr/lib64 | /usr/lib/$multiarch )
+             continue
+             ;;
+       esac
+       ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
+       ncbi_rp_L_sep=" $CONF_f_libpath"
+       x=`echo $x | sed -e "$ncbi_rpath_sed"`
+       ncbi_rp_R_flags="${ncbi_rp_R_flags}${ncbi_rp_R_sep}$x"
+       ncbi_rp_R_sep=:
+    done
+    LAPACK_LIBPATH="${ncbi_rp_L_flags}${ncbi_rp_R_flags}"
+ fi
+       elif test -d "$LAPACK_PATH/lib"; then
+          ncbi_rp_L_flags=
+ ncbi_rp_L_sep=$CONF_f_libpath
+ if test "x${CONF_f_runpath}" = "x${CONF_f_libpath}"; then
+    for x in $LAPACK_PATH/lib; do
+       case "$x" in
+          /lib | /usr/lib | /usr/lib32 | /usr/lib64 | /usr/lib/$multiarch )
+             continue
+             ;;
+       esac
+       ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
+       ncbi_rp_L_sep=" $CONF_f_libpath"
+    done
+    LAPACK_LIBPATH="${ncbi_rp_L_flags}"
+ else
+    ncbi_rp_R_flags=
+    ncbi_rp_R_sep=" $CONF_f_runpath"
+    for x in $LAPACK_PATH/lib; do
+       case "$x" in
+          /lib | /usr/lib | /usr/lib32 | /usr/lib64 | /usr/lib/$multiarch )
+             continue
+             ;;
+       esac
+       ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
+       ncbi_rp_L_sep=" $CONF_f_libpath"
+       x=`echo $x | sed -e "$ncbi_rpath_sed"`
+       ncbi_rp_R_flags="${ncbi_rp_R_flags}${ncbi_rp_R_sep}$x"
+       ncbi_rp_R_sep=:
+    done
+    LAPACK_LIBPATH="${ncbi_rp_L_flags}${ncbi_rp_R_flags}"
+ fi
+       fi
+       LAPACK_LIBS="$LAPACK_LIBPATH -llapack -lblas"
+    else
+       LAPACK_INCLUDE=""
+       LAPACK_LIBS="-llapack -lblas"
+       in_path=
+    fi
+    { echo "$as_me:$LINENO: checking for liblapack$in_path" >&5
+echo $ECHO_N "checking for liblapack$in_path... $ECHO_C" >&6; }
+if test "${ncbi_cv_lib_lapack+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  CPPFLAGS=" $LAPACK_INCLUDE $orig_CPPFLAGS"
+       LIBS="$LAPACK_LIBS  $orig_LIBS"
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+extern "C" int dsyev_();
+int
+main ()
+{
+return dsyev_();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ncbi_cv_lib_lapack=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ncbi_cv_lib_lapack=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ncbi_cv_lib_lapack" >&5
+echo "${ECHO_T}$ncbi_cv_lib_lapack" >&6; }
+    if test "$ncbi_cv_lib_lapack" = "no"; then
+       if test "${with_lapack:=no}" != no; then
+       { { echo "$as_me:$LINENO: error: --with-lapack explicitly specified, but no usable version found." >&5
+echo "$as_me: error: --with-lapack explicitly specified, but no usable version found." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    fi
+ fi
+ if test "$with_lapack" = "no"; then
+    LAPACK_PATH="No_LAPACK"
+    LAPACK_INCLUDE=
+    LAPACK_LIBS=
+ else
+              WithPackages="$WithPackages${WithPackagesSep}LAPACK"; WithPackagesSep=" "
+    LAPACK_INCLUDE=" $LAPACK_INCLUDE"
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBLAPACK 1
+_ACEOF
+
+ fi
+
+
+
+
+# LMDB
+if test "$with_lmdb" != "no"; then
+    case "$with_lmdb" in
+       yes | "" ) ;;
+       *        ) LMDB_PATH=$with_lmdb ;;
+    esac
+    if test "$LMDB_PATH" != /usr -a -d "$LMDB_PATH"; then
+       in_path=" in $LMDB_PATH"
+       if test -z "$LMDB_INCLUDE" -a -d "$LMDB_PATH/include"; then
+          LMDB_INCLUDE="-I$LMDB_PATH/include"
+       fi
+       if test -n "$LMDB_LIBPATH"; then
+          :
+       elif test -d "$LMDB_PATH/lib${bit64_sfx}"; then
+          ncbi_rp_L_flags=
+ ncbi_rp_L_sep=$CONF_f_libpath
+ if test "x${CONF_f_runpath}" = "x${CONF_f_libpath}"; then
+    for x in $LMDB_PATH/lib${bit64_sfx}; do
+       case "$x" in
+          /lib | /usr/lib | /usr/lib32 | /usr/lib64 | /usr/lib/$multiarch )
+             continue
+             ;;
+       esac
+       ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
+       ncbi_rp_L_sep=" $CONF_f_libpath"
+    done
+    LMDB_LIBPATH="${ncbi_rp_L_flags}"
+ else
+    ncbi_rp_R_flags=
+    ncbi_rp_R_sep=" $CONF_f_runpath"
+    for x in $LMDB_PATH/lib${bit64_sfx}; do
+       case "$x" in
+          /lib | /usr/lib | /usr/lib32 | /usr/lib64 | /usr/lib/$multiarch )
+             continue
+             ;;
+       esac
+       ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
+       ncbi_rp_L_sep=" $CONF_f_libpath"
+       x=`echo $x | sed -e "$ncbi_rpath_sed"`
+       ncbi_rp_R_flags="${ncbi_rp_R_flags}${ncbi_rp_R_sep}$x"
+       ncbi_rp_R_sep=:
+    done
+    LMDB_LIBPATH="${ncbi_rp_L_flags}${ncbi_rp_R_flags}"
+ fi
+       elif test -d "$LMDB_PATH/lib"; then
+          ncbi_rp_L_flags=
+ ncbi_rp_L_sep=$CONF_f_libpath
+ if test "x${CONF_f_runpath}" = "x${CONF_f_libpath}"; then
+    for x in $LMDB_PATH/lib; do
+       case "$x" in
+          /lib | /usr/lib | /usr/lib32 | /usr/lib64 | /usr/lib/$multiarch )
+             continue
+             ;;
+       esac
+       ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
+       ncbi_rp_L_sep=" $CONF_f_libpath"
+    done
+    LMDB_LIBPATH="${ncbi_rp_L_flags}"
+ else
+    ncbi_rp_R_flags=
+    ncbi_rp_R_sep=" $CONF_f_runpath"
+    for x in $LMDB_PATH/lib; do
+       case "$x" in
+          /lib | /usr/lib | /usr/lib32 | /usr/lib64 | /usr/lib/$multiarch )
+             continue
+             ;;
+       esac
+       ncbi_rp_L_flags="${ncbi_rp_L_flags}${ncbi_rp_L_sep}$x"
+       ncbi_rp_L_sep=" $CONF_f_libpath"
+       x=`echo $x | sed -e "$ncbi_rpath_sed"`
+       ncbi_rp_R_flags="${ncbi_rp_R_flags}${ncbi_rp_R_sep}$x"
+       ncbi_rp_R_sep=:
+    done
+    LMDB_LIBPATH="${ncbi_rp_L_flags}${ncbi_rp_R_flags}"
+ fi
+       fi
+       LMDB_LIBS="$LMDB_LIBPATH -llmdb "
+    else
+       LMDB_INCLUDE=""
+       LMDB_LIBS="-llmdb "
+       in_path=
+    fi
+    { echo "$as_me:$LINENO: checking for liblmdb$in_path" >&5
+echo $ECHO_N "checking for liblmdb$in_path... $ECHO_C" >&6; }
+if test "${ncbi_cv_lib_lmdb+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  CPPFLAGS=" $LMDB_INCLUDE $orig_CPPFLAGS"
+       LIBS="$LMDB_LIBS  $orig_LIBS"
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <lmdb.h>
+int
+main ()
+{
+MDB_env *env; return mdb_env_create(&env);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ncbi_cv_lib_lmdb=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ncbi_cv_lib_lmdb=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ncbi_cv_lib_lmdb" >&5
+echo "${ECHO_T}$ncbi_cv_lib_lmdb" >&6; }
+    if test "$ncbi_cv_lib_lmdb" = "no"; then
+       if test "${with_lmdb:=no}" != no; then
+       { { echo "$as_me:$LINENO: error: --with-lmdb explicitly specified, but no usable version found." >&5
+echo "$as_me: error: --with-lmdb explicitly specified, but no usable version found." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    fi
+ fi
+ if test "$with_lmdb" = "no"; then
+    LMDB_PATH="No_LMDB"
+    LMDB_INCLUDE=
+    LMDB_LIBS=
+ else
+              WithPackages="$WithPackages${WithPackagesSep}LMDB"; WithPackagesSep=" "
+    LMDB_INCLUDE=" $LMDB_INCLUDE"
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBLMDB 1
+_ACEOF
+
+ fi
+
+
+
+
 ### Restore original compiler/linker flags
 LIBS="$orig_LIBS"
 CPPFLAGS="$orig_CPPFLAGS"
@@ -45622,6 +46543,14 @@ if test "$with_gbench" != "no"  -a  -d "$real_srcdir/src/app/gbench"; then
      reason="$reason${sep}OpenGL"
      sep=", "
    fi
+   if test "$with_glew_mx" = "no"; then
+     reason="$reason${sep}GLEWmx"
+     sep=", "
+   fi
+   if test "$with_ftgl" = "no"; then
+     reason="$reason${sep}FTGL"
+     sep=", "
+   fi
    if test "$with_sqlite3" = "no"; then
      reason="$reason${sep}SQLite 3.x"
      sep=", "
@@ -45630,6 +46559,18 @@ if test "$with_gbench" != "no"  -a  -d "$real_srcdir/src/app/gbench"; then
      reason="$reason${sep}Berkeley DB"
      sep=", "
    fi
+   if test "$ncbi_cv_lib_boost_spirit" != "yes"; then
+     reason=Boost.Spirit
+     sep=", "
+   fi
+   if test "$with_libxslt" = "no"; then
+     reason="$reason${sep}libxslt"
+     sep=", "
+   fi
+   if test "$with_gnutls" = "no"; then
+     reason="$reason${sep}GNUTLS"
+     sep=", "
+   fi
    if test "$with_mt" = "no"; then
      reason="$reason${sep}multithreading"
      sep=", "
@@ -45723,7 +46664,7 @@ FEATURES="$WithFeatures $WithPackages $WithProjects"
 
 ### Compute Without{Features,Packages,Projects}.  Takes quadratic time,
 ### but that's life.
-for x in Int8GI StrictGI GCC KCC ICC VisualAge CompaqCompiler Cray WorkShop MIPSpro MSVC MT LFS DLL DLL_BUILD MaxDebug MSWin unix WinMain AIX BSD Cygwin CygwinMT Darwin XCODE IRIX Linux OSF Solaris MacOS in-house-resources JDK Ncbi-JNI PubSeqOS check Valgrind LimitedLinker; do
+for x in ChaosMonkey Int8GI StrictGI GCC KCC ICC VisualAge CompaqCompiler Cray WorkShop MIPSpro MSVC MT LFS DLL DLL_BUILD MaxDebug MSWin unix WinMain AIX BSD Cygwin CygwinMT Darwin XCODE IRIX Linux OSF Solaris MacOS in-house-resources JDK Ncbi-JNI PubSeqOS check Valgrind LimitedLinker; do
       case " $WithFeatures " in
          *" $x "*) ;;
          *) WithoutFeatures="$WithoutFeatures$WithoutFeaturesSep$x"
@@ -45732,7 +46673,7 @@ for x in Int8GI StrictGI GCC KCC ICC VisualAge CompaqCompiler Cray WorkShop MIPS
           ;;
       esac
    done
-  for x in UUID FUSE Iconv Z LocalZ BZ2 LocalBZ2 LZO PCRE LocalPCRE GMP GCRYPT NETTLE GNUTLS OPENSSL KRB5 CURL Sybase DBLib FreeTDS MySQL BerkeleyDB BerkeleyDB++ ODBC PYTHON PYTHON25 PYTHON26 PYTHON27 PYTHON3 PERL Boost.Filesystem Boost.Iostreams Boost.Program-Options Boost.Regex Boost.Spirit Boost.System Boost.Test Boost.Test.Included Boost.Thread C-Toolkit OpenGL MESA GLUT GLEW wxWidgets wx2.8 Fast-CGI LocalSSS LocalMSGMAIL2 SSSUTILS LocalNCBILS NCBILS2 SSSDB SP ORBacus ICU EXPAT SABLO [...]
+  for x in UUID FUSE Iconv Z LocalZ BZ2 LocalBZ2 LZO PCRE LocalPCRE GMP GCRYPT NETTLE GNUTLS OPENSSL KRB5 CURL Sybase DBLib FreeTDS MySQL BerkeleyDB BerkeleyDB++ ODBC PYTHON PYTHON25 PYTHON26 PYTHON27 PYTHON3 PERL Boost.Filesystem Boost.Iostreams Boost.Program-Options Boost.Regex Boost.Spirit Boost.System Boost.Test Boost.Test.Included Boost.Thread C-Toolkit OpenGL MESA GLUT GLEW wxWidgets wx2.8 Fast-CGI LocalSSS LocalMSGMAIL2 SSSUTILS LocalNCBILS NCBILS2 SSSDB SP ORBacus ICU EXPAT SABLO [...]
       case " $WithPackages " in
          *" $x "*) ;;
          *) WithoutPackages="$WithoutPackages$WithoutPackagesSep$x"
@@ -46113,6 +47054,18 @@ c_ncbi_runpath=`echo "$ncbi_runpath" | sed -e 's:\\$\\$:\\$:g'`
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
 #############################################################################
 ### Create output files and do some post-configuration
 
@@ -46139,7 +47092,7 @@ ac_config_headers="$ac_config_headers ${ncbiconf}:src/build-system/config.h.in"
 ##
 ## Configure makefiles, shell scripts, etc.
 ##
-ac_config_files="$ac_config_files $configurables $srcdir/./Makefile:src/build-system/Makefile.in.top"
+ac_config_files="$ac_config_files $configurables $srcdir/./Makefile:src/build-system/Makefile.in.top $build_root/inc/common/ncbi_build_ver.h:include/common/ncbi_build_ver.h.in"
 
 
 ac_config_commands="$ac_config_commands default"
@@ -46726,6 +47679,7 @@ do
     "${ncbiconf}") CONFIG_HEADERS="$CONFIG_HEADERS ${ncbiconf}:src/build-system/config.h.in" ;;
     "$configurables") CONFIG_FILES="$CONFIG_FILES $configurables" ;;
     "$srcdir/./Makefile") CONFIG_FILES="$CONFIG_FILES $srcdir/./Makefile:src/build-system/Makefile.in.top" ;;
+    "$build_root/inc/common/ncbi_build_ver.h") CONFIG_FILES="$CONFIG_FILES $build_root/inc/common/ncbi_build_ver.h:include/common/ncbi_build_ver.h.in" ;;
     "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
 
   *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
@@ -47092,6 +48046,10 @@ MONGODB_INCLUDE!$MONGODB_INCLUDE$ac_delim
 MONGODB_LIBS!$MONGODB_LIBS$ac_delim
 GMOCK_INCLUDE!$GMOCK_INCLUDE$ac_delim
 GMOCK_LIBS!$GMOCK_LIBS$ac_delim
+LAPACK_INCLUDE!$LAPACK_INCLUDE$ac_delim
+LAPACK_LIBS!$LAPACK_LIBS$ac_delim
+LMDB_INCLUDE!$LMDB_INCLUDE$ac_delim
+LMDB_LIBS!$LMDB_LIBS$ac_delim
 signature!$signature$ac_delim
 build_root!$build_root$ac_delim
 top_srcdir!$top_srcdir$ac_delim
@@ -47158,10 +48116,6 @@ lib_pre!$lib_pre$ac_delim
 lib_l_pre!$lib_l_pre$ac_delim
 lib_ext!$lib_ext$ac_delim
 dll_ext!$dll_ext$ac_delim
-loadable_ext!$loadable_ext$ac_delim
-lib_l_ext!$lib_l_ext$ac_delim
-exe_ext!$exe_ext$ac_delim
-f_compile!$f_compile$ac_delim
 _ACEOF
 
   if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -47203,6 +48157,10 @@ _ACEOF
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   cat >conf$$subs.sed <<_ACEOF
+loadable_ext!$loadable_ext$ac_delim
+lib_l_ext!$lib_l_ext$ac_delim
+exe_ext!$exe_ext$ac_delim
+f_compile!$f_compile$ac_delim
 f_outobj!$f_outobj$ac_delim
 f_outlib!$f_outlib$ac_delim
 f_libpath!$f_libpath$ac_delim
@@ -47296,10 +48254,6 @@ GLEW_STATIC_LIBS!$GLEW_STATIC_LIBS$ac_delim
 WXWIDGETS_INCLUDE!$WXWIDGETS_INCLUDE$ac_delim
 WXWIDGETS_LIBS!$WXWIDGETS_LIBS$ac_delim
 WXWIDGETS_STATIC_LIBS!$WXWIDGETS_STATIC_LIBS$ac_delim
-WXWIDGETS_GL_LIBS!$WXWIDGETS_GL_LIBS$ac_delim
-WXWIDGETS_GL_STATIC_LIBS!$WXWIDGETS_GL_STATIC_LIBS$ac_delim
-WXWIDGETS_POST_LINK!$WXWIDGETS_POST_LINK$ac_delim
-FASTCGI_INCLUDE!$FASTCGI_INCLUDE$ac_delim
 _ACEOF
 
   if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -47341,6 +48295,10 @@ _ACEOF
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   cat >conf$$subs.sed <<_ACEOF
+WXWIDGETS_GL_LIBS!$WXWIDGETS_GL_LIBS$ac_delim
+WXWIDGETS_GL_STATIC_LIBS!$WXWIDGETS_GL_STATIC_LIBS$ac_delim
+WXWIDGETS_POST_LINK!$WXWIDGETS_POST_LINK$ac_delim
+FASTCGI_INCLUDE!$FASTCGI_INCLUDE$ac_delim
 FASTCGI_LIBS!$FASTCGI_LIBS$ac_delim
 FASTCGI_OBJS!$FASTCGI_OBJS$ac_delim
 NCBI_SSS_INCLUDE!$NCBI_SSS_INCLUDE$ac_delim
@@ -47349,9 +48307,18 @@ LIBSSSUTILS!$LIBSSSUTILS$ac_delim
 LIBSSSDB!$LIBSSSDB$ac_delim
 sssutils!$sssutils$ac_delim
 VDB_INCLUDE!$VDB_INCLUDE$ac_delim
-VDB_LIB!$VDB_LIB$ac_delim
 VDB_LIBS!$VDB_LIBS$ac_delim
 VDB_STATIC_LIBS!$VDB_STATIC_LIBS$ac_delim
+bamread!$bamread$ac_delim
+sraread!$sraread$ac_delim
+ncbi_id2proc_snp!$ncbi_id2proc_snp$ac_delim
+ncbi_id2proc_wgs!$ncbi_id2proc_wgs$ac_delim
+ncbi_xloader_bam!$ncbi_xloader_bam$ac_delim
+ncbi_xloader_csra!$ncbi_xloader_csra$ac_delim
+ncbi_xloader_snp!$ncbi_xloader_snp$ac_delim
+ncbi_xloader_sra!$ncbi_xloader_sra$ac_delim
+ncbi_xloader_vdbgraph!$ncbi_xloader_vdbgraph$ac_delim
+ncbi_xloader_wgs!$ncbi_xloader_wgs$ac_delim
 VDB_REQ!$VDB_REQ$ac_delim
 VDB_POST_LINK!$VDB_POST_LINK$ac_delim
 SP_INCLUDE!$SP_INCLUDE$ac_delim
@@ -47421,11 +48388,13 @@ compiler_version!$compiler_version$ac_delim
 COMPILER!$COMPILER$ac_delim
 OSTYPE!$OSTYPE$ac_delim
 NCBI_PLATFORM_BITS!$NCBI_PLATFORM_BITS$ac_delim
+NCBI_TEAMCITY_BUILD_NUMBER!$NCBI_TEAMCITY_BUILD_NUMBER$ac_delim
+NCBI_SUBVERSION_REVISION!$NCBI_SUBVERSION_REVISION$ac_delim
+NCBI_SC_VERSION!$NCBI_SC_VERSION$ac_delim
 LIBOBJS!$LIBOBJS$ac_delim
-LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 82; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -47444,6 +48413,48 @@ fi
 
 cat >>$CONFIG_STATUS <<_ACEOF
 cat >"\$tmp/subs-5.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+CEOF$ac_eof
+_ACEOF
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  cat >conf$$subs.sed <<_ACEOF
+LTLIBOBJS!$LTLIBOBJS$ac_delim
+_ACEOF
+
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 1; then
+    break
+  elif $ac_last_try; then
+    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+   { (exit 1); exit 1; }; }
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+  ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-6.sed" <<\CEOF$ac_eof
 /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
 _ACEOF
 sed '
@@ -47748,7 +48759,7 @@ s&@abs_builddir@&$ac_abs_builddir&;t t
 s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
 s&@INSTALL@&$ac_INSTALL&;t t
 $ac_datarootdir_hack
-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" | sed -f "$tmp/subs-3.sed" | sed -f "$tmp/subs-4.sed" | sed -f "$tmp/subs-5.sed" >$tmp/out
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" | sed -f "$tmp/subs-3.sed" | sed -f "$tmp/subs-4.sed" | sed -f "$tmp/subs-5.sed" | sed -f "$tmp/subs-6.sed" >$tmp/out
 
 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
   { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
@@ -47931,17 +48942,19 @@ else
    rm -f "$build_root/inc/ncbiconf_extra.h"
 fi
 
-ncbicfg="$builddir/corelib/ncbicfg.c"
-if test -f "$ncbicfg.last" && cmp -s "$ncbicfg.last" "$ncbicfg"; then
-   echo "$ncbicfg" is unchanged
-   touch -r "$ncbicfg.last" "$ncbicfg"
-elif test -f "$ncbicfg"; then
-   echo "$ncbicfg" is updated
-   rm -f "$ncbicfg.last"
-   cp -p "$ncbicfg" "$ncbicfg.last"
-else
-   echo "$ncbicfg" is not present
-fi
+for f in "$builddir/corelib/ncbicfg.c" \
+         "$build_root/inc/common/ncbi_build_ver.h"; do
+   if test -f "$f.last" && cmp -s "$f.last" "$f"; then
+      echo "$f" is unchanged
+      touch -r "$f.last" "$f"
+   elif test -f "$f"; then
+      echo "$f" is updated
+      rm -f "$f.last"
+      cp -p "$f" "$f.last"
+   else
+      echo "$f" is not present
+   fi
+done
 
 (cd $builddir/build-system/helpers && $MAKE -k)
 
diff --git a/c++/src/build-system/configure.ac b/c++/src/build-system/configure.ac
index fd0d72d..73537f0 100644
--- a/c++/src/build-system/configure.ac
+++ b/c++/src/build-system/configure.ac
@@ -1,5 +1,5 @@
 #############################################################################
-#  $Id: configure.ac 500366 2016-05-04 12:05:44Z ivanov $
+#  $Id: configure.ac 521038 2016-12-05 16:02:28Z ivanov $
 #  Derived from configure.in version 1.173.
 # ==========================================================================
 #
@@ -65,13 +65,13 @@ case "$with_3psw" in
          with_ncbi_c=no
       fi
       m4_foreach(X, [sss, sssutils, sssdb, vdb, z, bz2, lzo, pcre,
-                     gmp, gcrypt, nettle, gnutls, openssl, krb5, boost,
+                     gmp, gcrypt, nettle, gnutls, openssl, krb5, boost, lmdb,
                      sybase, ftds, mysql, opengl, mesa, glut, glew,
                      wxwidgets, freetype, ftgl, fastcgi, bdb, orbacus, odbc,
                      python, perl, jni, sqlite3, mimetic, sge, icu, sp, expat,
                      sablot, libxml, libxslt, libexslt, xerces, xalan, zorba,
-                     oechem, muparser, hdf5, gif, jpeg, png, tiff, xpm,
-                     magic, curl, gsoap, avro, cereal, sasl2, mongodb, gmock],
+                     oechem, muparser, hdf5, gif, jpeg, png, tiff, xpm, magic,
+                     curl, gsoap, avro, cereal, sasl2, mongodb, gmock, lapack],
         [if test "${[with_]X-no}" != "no"; then
             AC_MSG_ERROR([incompatible options: --with-]X[ but --without-3psw])
          else
@@ -147,10 +147,6 @@ AC_ARG_WITH(openmp,
    [ --with-openmp           enable OpenMP extensions for all projects])
 AC_ARG_WITH(64,
    [ --with-64               compile to 64-bit code])
-AC_ARG_WITH(universal,
-   [ --with-universal        build universal binaries on Mac OS X])
-AC_ARG_WITH(universal2,
-   [ --with-universal=CPUs   build universal binaries targeting the given CPUs])
 AC_ARG_WITH(exe,
    [ --without-exe           do not build executables])
 AC_ARG_WITH(runpath,
@@ -243,6 +239,8 @@ AC_ARG_WITH(vdb2,
    [ --without-vdb           do not use the NCBI SRA/VDB Toolkit])
 AC_ARG_WITH(downloaded-vdb,
    [ --with-downloaded-vdb   download and build SRA/VDB from GitHub])
+AC_ARG_WITH(static-vdb,
+   [ --with-static-vdb       always link statically against SRA/VDB])
 
 ## Third-party and system packages
 AC_ARG_WITH(z,
@@ -277,6 +275,8 @@ AC_ARG_WITH(gnutls,
    [ --with-gnutls=DIR       use GNUTLS installation in DIR])
 AC_ARG_WITH(gnutls2,
    [ --without-gnutls        do not use GNUTLS])
+AC_ARG_WITH(static-gnutls,
+   [ --with-static-gnutls    link GNUTLS statically if possible])
 AC_ARG_WITH(openssl,
    [ --with-openssl=DIR      use OpenSSL installation in DIR])
 AC_ARG_WITH(openssl2,
@@ -485,6 +485,14 @@ AC_ARG_WITH(gmock,
    [ --with-gmock=DIR        use Google Mock installation in DIR])
 AC_ARG_WITH(gmock2,
    [ --without-gmock         do not use Google Mock])
+AC_ARG_WITH(lapack,
+   [ --with-lapack=DIR       use LAPACK installation in DIR])
+AC_ARG_WITH(lapack2,
+   [ --without-lapack        do not use LAPACK])
+AC_ARG_WITH(lmdb,
+   [ --with-lmdb=DIR         use LMDB installation in DIR])
+AC_ARG_WITH(lmdb,
+   [ --without-lmdb          do not use LMDB])
 AC_ARG_WITH(3psw,
    [ --with-3psw=std:netopt  favor standard (system) builds of the above pkgs.])
 AC_ARG_WITH(3psw2,
@@ -532,21 +540,21 @@ m4_rename([AS_MESSAGE_LOG_FD], [NCBI_ORIG_ASMLFD])
 #### Check the passed arguments against the list of available ones
 x_with_list="\
 debug max-debug symbols optimization profiling tcheck dll static static-exe \
-plugin-auto-load bundles bin-release mt 64 universal exe runpath hard-runpath \
+plugin-auto-load bundles bin-release mt 64 exe runpath hard-runpath \
 lfs limited-linker openmp \
 autodep suffix hostspec version execopy bincopy lib-rebuilds lib-rebuilds=ask \
 deactivation makefile-auto-update projects flat-makefile configure-dialog \
 check ncbi-public strip pch caution ccache distcc \
 ncbi-c wxwidgets wxwidgets-ucs fastcgi sss sssdb sssutils included-sss \
-geo included-geo vdb downloaded-vdb \
-z bz2 lzo pcre gmp gcrypt nettle gnutls openssl krb5 \
+geo included-geo vdb downloaded-vdb static-vdb \
+z bz2 lzo pcre gmp gcrypt nettle gnutls static-gnutls openssl krb5 \
 sybase sybase-local sybase-new ftds mysql \
 orbacus freetype ftgl opengl mesa glut glew glew-mx \
 bdb python perl jni sqlite3 icu boost boost-tag \
 sp expat sablot libxml libxslt libexslt xerces xalan zorba \
 oechem sge muparser hdf5 \
 gif jpeg tiff png xpm \
-magic curl mimetic gsoap avro cereal sasl2 mongodb gmock 3psw \
+magic curl mimetic gsoap avro cereal sasl2 mongodb gmock lapack lmdb 3psw \
 local-lbsm ncbi-crypt connext \
 serial objects dbapi app ctools gui algo internal gbench"
 
@@ -615,7 +623,7 @@ for x_arg in "$@" ; do
       | --with-jpeg=* | --with-png=* | --with-tiff=* | --with-xpm=* \
       | --with-magic=* | --with-curl=* | --with-mimetic=* | --with-gsoap=* \
       | --with-avro=* | --with-cereal=* | --with-sasl2* | --with-mongodb=* \
-      | --with-gmock=* )
+      | --with-gmock=* | --with-lapack=* | --with-lmdb=* )
       # Confirm that the specified directory exists and is readable.
       dir=`echo $x_arg | sed -e 's/^[[^=]]*=//'`
       case "$x_arg" in
@@ -637,7 +645,7 @@ for x_arg in "$@" ; do
       | --silent | --cache-file=* | -C | --config-cache | -n | --no-create \
       | --no-recursion | --prefix=* | --exec-prefix=* | --bindir=* \
       | --libdir=* | --includedir=* | --build=* | --host=* | --target=* \
-      | --with-universal=* | --with-runpath=* | --with-relative-runpath=* \
+      | --with-runpath=* | --with-relative-runpath=* \
       | --with-experimental=* | --with-extra-action=* | --with-build-root=* \
       | --with-fake-root=* | --with-build-root-sfx=* | --with-check=* \
       | --with-check-tools=* | --with-ftds=[[0-9]]* | --with-fastcgi=[[0-9]]* \
@@ -654,11 +662,11 @@ AC_DIVERT_POP
 
 
 if test "$with_gbench" = "yes" ; then
-   m4_foreach(OPT, [dll,mt,gui,exe,serial,objects,algo,glew_mx],
+   m4_foreach(OPT, [dll,mt,gui,exe,serial,objects,algo,glew_mx,wxwidgets,ftgl,sqlite3,bdb,boost,xslt,gnutls],
      [if test "$[with_]OPT" = "no"; then
          AC_MSG_ERROR([incompatible options: --without-]OPT[ but --with-gbench])
       else
-         [with_]OPT=yes
+         : ${[with_]OPT:=yes}
       fi
      ])
    : ${with_projects=scripts/projects/ncbi_gbench.lst}
@@ -712,6 +720,30 @@ case "$with_downloaded_vdb:$with_vdb" in
       ;;
 esac
 
+case "$with_static_vdb:$with_vdb" in
+   yes:no )
+      AC_MSG_ERROR([incompatible options: --without-vdb but --with-static-vdb])
+      ;;
+   yes: )
+      with_vdb=yes
+      ;;
+   :* )
+      with_static_vdb=$with_bin_release
+      ;;
+esac
+
+case "$with_static_gnutls:$with_gnutls" in
+   yes:no )
+      AC_MSG_ERROR([incompatible options: --without-gnutls but --with-static-gnutls])
+      ;;
+   yes: )
+      with_gnutls=yes
+      ;;
+   :* )
+      with_static_gnutls=$with_bin_release
+      ;;
+esac
+
 #### Check for special options
 if test "$with_extra_action" = "yes" ; then
    AC_MSG_ERROR([--with-extra-action must have a value after =])
@@ -765,12 +797,18 @@ USER_LDFLAGS=$LDFLAGS
 if test -n "$with_experimental"; then
    for x in `echo $with_experimental | tr , ' '`; do
       case "$x" in
+         ChaosMonkey )
+            CPPFLAGS="$CPPFLAGS -DNCBI_MONKEY"
+            NCBI_FEATURE(ChaosMonkey)
+            ;;
          Int8GI )
             CPPFLAGS="$CPPFLAGS -DNCBI_INT8_GI"
+            NCBI_C_PATH_TAGS="/ncbi.gi64 .gi64"
             NCBI_FEATURE(Int8GI)
             ;;
          StrictGI )
             CPPFLAGS="$CPPFLAGS -DNCBI_STRICT_GI"
+            NCBI_C_PATH_TAGS="/ncbi.gi64 .gi64"
             NCBI_FEATURE(Int8GI)
             NCBI_FEATURE(StrictGI)
             ;;
@@ -784,6 +822,38 @@ fi
 #### Always define this
 AC_DEFINE(NCBI_CXX_TOOLKIT, 1, [This is the NCBI C++ Toolkit.])
 
+AC_MSG_CHECKING([TeamCity build number])
+if test -n "$TEAMCITY_VERSION" -a -n "$BUILD_NUMBER"; then
+   AC_MSG_RESULT($BUILD_NUMBER)
+   NCBI_TEAMCITY_BUILD_NUMBER=$BUILD_NUMBER
+else
+   AC_MSG_RESULT(none)
+   NCBI_TEAMCITY_BUILD_NUMBER=0
+fi
+
+AC_MSG_CHECKING([Subversion revision])
+svnrev=`svn info "$srcdir" 2>/dev/null | sed -ne 's/^Revision: //p'`
+if test -n "$svnrev"; then
+   AC_MSG_RESULT($svnrev)
+   NCBI_SUBVERSION_REVISION=$svnrev
+else
+   AC_MSG_RESULT(unknown)
+   NCBI_SUBVERSION_REVISION=0
+fi
+
+AC_MSG_CHECKING([NCBI stable components' version])
+scver=`svn info "$srcdir/src/build-system" 2>/dev/null |
+ sed -ne ['s,^URL: .*/production/components/[^/]*/\([1-9][0-9]*\)\..*,\1,p']`
+if test -n "$scver"; then
+   AC_MSG_RESULT($scver)
+   NCBI_SC_VERSION=$scver
+else
+   AC_MSG_RESULT(unknown)
+   NCBI_SC_VERSION=0
+fi
+
+AC_DEFINE(HAVE_COMMON_NCBI_BUILD_VER_H, 1,
+   [Define to 1 if you have the <common/ncbi_build_ver.h> header file.])
 
 #### Get the running host's properties
 AC_CONFIG_AUX_DIR(src/build-system)
@@ -1139,14 +1209,15 @@ if test "$with_mt" != "no" ; then
    esac
 fi
 
+case "$host_os:$compiler" in
+  solaris2.10:GCC ) : ${THREAD_LIBS:="-lposix4"} ;;
+  solaris*        ) : ${THREAD_LIBS:="-lpthread -lposix4"} ;;
+  freebsd*        ) ;; # -pthread already substitutes libc_r for libc
+  *               ) : ${THREAD_LIBS:="-lpthread"} ;;
+esac
+
 if test "$with_mt" != "no" ; then
    CPPFLAGS="$CPPFLAGS -D_MT -D_REENTRANT -D_THREAD_SAFE"
-   case "$host_os:$compiler" in
-     solaris2.10:GCC ) : ${THREAD_LIBS:="-lposix4"} ;;
-     solaris*        ) : ${THREAD_LIBS:="-lpthread -lposix4"} ;;
-     freebsd*        ) ;; # -pthread already substitutes libc_r for libc
-     *               ) : ${THREAD_LIBS:="-lpthread"} ;;
-   esac
    LIBS="$LIBS $THREAD_LIBS"
    case "$host_os:$compiler" in
      solaris2.??:* | solaris*:GCC | *:Compaq | irix* | aix* | darwin* | cygwin*)
@@ -1193,7 +1264,6 @@ if test "$with_mt" != "no" ; then
 else
    CPPFLAGS="$CPPFLAGS -DNCBI_WITHOUT_MT"
    MT_FLAG=
-   THREAD_LIBS=
    NCBIATOMIC_LIB=
    OPENMP_FLAGS=
    mt_sfx=""
@@ -1382,9 +1452,6 @@ case "$host_os:$compiler" in
             darwin?.* | darwin10.* ) # Mac OS X 10.6.x or older
                TARGET='-mmacosx-version-min=10.5'
                sdks="/Developer/SDKs/MacOSX10.6.sdk"
-               if test "$with_64:${with_universal-no}" != "yes:no"; then
-                  sdks="/Developer/SDKs/MacOSX10.5.sdk $sdks"
-               fi
                ;;
             * )
                TARGET='-mmacosx-version-min=10.7'
@@ -1457,51 +1524,7 @@ C_LIBS=$LIBS
 
 ARCH_CPPFLAGS=
 #### architecture settings, and extra C++ LIBS
-if test "${with_universal-no}" != "no" ; then
-   bit64_sfx= #"Univ"
-   case "$host" in
-    *-*-darwin[[89]].* | *-*-darwin[[1-9]][[0-9]]* )
-      case "$with_universal" in
-       yes )
-          case "$with_64:$host_os" in
-           yes:darwin8.* )
-             AC_MSG_ERROR([Unable to build 64-bit universal binaries on $host])
-             ;;
-           yes:* )
-             ARCH_CFLAGS="-arch ppc64 -arch x86_64"
-             ARCH_CPPFLAGS="-m64"
-             ;;
-           * )
-             ARCH_CFLAGS="-arch ppc -arch i386"
-             ARCH_CPPFLAGS="-m32"
-             ;;
-          esac
-          ;;
-       * )
-         ARCH_CFLAGS="-arch `echo $with_universal | sed -e 's/,/ -arch /g'`"
-         ARCH_CPPFLAGS="-arch `echo $with_universal | sed -e 's/,.*//'`"
-         ;;
-      esac
-      case "$host" in
-       p*pc*-*-darwin8.*)
-         # Must specify -isysroot ..., but only once; anyway, the preprocessor
-         # needs to see it, and naturally can't cope with multiple -arch flags.
-         # The -mmacosx-version-min flag avoids link errors under OS 10.5
-         # (Darwin 9), which otherwise tries to use crt1.10.5.o despite the
-         # request for a sysroot lacking that file.
-         SYSROOT="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4"
-         #ARCH_CFLAGS="$SYSROOT $ARCH_CFLAGS"
-         CC="$CC $SYSROOT"
-         CXX="$CXX $SYSROOT"
-         ;;
-      esac
-      ;;
-    * ) AC_MSG_ERROR([Do not know how to build universal binaries on $host]) ;;
-   esac
-   AC_DEFINE(NCBI_UNIVERSAL_BUILD, 1,
-             [Define to 1 if building universal (multi-architecture) binaries.])
-   with_distcc=no
-elif test "$with_64" = "yes" ; then
+if test "$with_64" = "yes" ; then
    bit64_sfx="64"
    case "$host:$compiler" in
     sparc-sun-solaris*:WorkShop5 | sparc-sun-solaris*:KCC )
@@ -1640,6 +1663,33 @@ if test -n "$with_64"; then
    fi
 fi
 
+#### Don't let Clang pick up old (pre-C++11) system standard
+#### library installations on Linux.
+case "$host_os:/$CXX" in
+   linux*:*/clang* )
+      gccver=4.9.3
+      gccdir=/opt/ncbi/gcc/$gccver
+      if test -d $gccdir; then
+         for d in `$gccdir/bin/g++ -v -E -x c++ $ARCH_CFLAGS $ARCH_CPPFLAGS - \
+                   </dev/null 2>&1 | fgrep 'include/c++' | tac`; do
+            NCBI_FIX_DIR(d)
+            # We don't use a dedicated CXXCPPFLAGS variable, but sticking
+            # with -isystem rather than -cxx-isystem avoids spurious
+            # warnings when also using ccache or distcc, and should still
+            # be safe in practice.  (The three libstdc++ headers that have
+            # the same names as system headers all arrange to include
+            # those headers via #include_next, and to conditionalize any
+            # C++ declarations on compiling as actual C++.)
+            CPPFLAGS="-isystem $d $CPPFLAGS"
+         done
+         CPPFLAGS="-nostdinc++ $CPPFLAGS"
+         libstdcxx=`$gccdir/bin/g++ --print-file-name=libstdc++.a`
+         d=`dirname $libstdcxx`
+         NCBI_FIX_DIR(d)         
+         LDFLAGS="-L$d -Wl,-rpath,$d $LDFLAGS"
+      fi
+      ;;
+esac
 
 case "$host_os:$compiler" in
    darwin*:GCC )
@@ -1707,28 +1757,23 @@ fi
 
 AC_CHECK_DECL([_LIBCPP_VERSION], [], [], [#include <iosfwd>])
 
-case "$ac_cv_have_decl__LIBCPP_VERSION:$compiler:$compiler_version" in
-   no:GCC:4[[0-6]]? | no:ICC:1[[01]]?? )
-     ncbi_cv_prog_cxx_11=no
-     ncbi_cv_prog_c_99=no
-     ;;
-   *:ICC:* )
-     ncbi_cv_prog_c_99='-std=gnu99 -fgnu89-inline'
-     ;;
-esac
-
 AC_CACHE_CHECK([how to enable C++ '11 features in $CXX],
    ncbi_cv_prog_cxx_11,
    [orig_CXX=$CXX
     ncbi_cv_prog_cxx_11=no
-    for x in -std=gnu++11 -std=gnu++0x; do
+    for x in -std=gnu++11 -std=gnu++0x ''; do
        CXX="$orig_CXX $x"
-       AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
+       AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <memory>],
+          [std::unique_ptr<int> x;])],
           [ncbi_cv_prog_cxx_11=$x])
           test "x$ncbi_cv_prog_cxx_11" = "xno"  ||  break
        done
        CXX=$orig_CXX])
-test "$ncbi_cv_prog_cxx_11" = no  ||  CXX="$CXX $ncbi_cv_prog_cxx_11"
+if test "$ncbi_cv_prog_cxx_11" = no; then
+   AC_MSG_ERROR([Please upgrade to a compiler supporting C++ '11, such as GCC 4.8 or newer.])
+else
+   CXX="$CXX $ncbi_cv_prog_cxx_11"
+fi
 
 AC_LANG_PUSH(C)
 AC_CACHE_CHECK([how to enable C '11 or at least '99 features in $CC],
@@ -2022,7 +2067,11 @@ case "$compiler:$compiler_version:$with_bin_release" in
     DLL_LDFLAGS="-static-intel -diag-disable 10237 -nodefaultlibs $DLL_LDFLAGS"
     # Redundant for apps, but necessary for plugins to be adequately
     # self-contained, at least on 32-bit Linux.
-    LIBS="$LIBS -lstdc++"
+    if test "$with_bin_release" = "yes"; then
+       LDFLAGS="$LDFLAGS -static-libstdc++"
+    elif test "$with_dll" != "no"; then
+       LIBS="$LIBS -lstdc++"
+    fi
     LINK="$LINK -Kc++"
     # Defining _GCC_NEXT_LIMITS_H ensures that <limits.h> chaining doesn't
     # stop short, as can otherwise happen. :-/
@@ -2179,8 +2228,7 @@ fi
 
 ### Support for precompiled headers
 GCCPCH="#"
-if test "$compiler" = GCC -a "$with_pch" = "yes" \
-     -a "${with_universal-no}" = "no"; then
+if test "$compiler" = GCC -a "$with_pch" = "yes"; then
    AC_CACHE_CHECK([whether $CXX supports precompiled headers], ncbi_cv_cxx_pch,
       [echo '#include <iostream>' > conftest.hpp
        echo $CXX $CPPFLAGS $CXXFLAGS -xc++-header -c conftest.hpp >&AS_MESSAGE_LOG_FD
@@ -2504,15 +2552,13 @@ fi
 
 #### Determine whether this is implicitly a 64-bit platform
 AC_TYPE_SIZE_T
-if test "${with_universal-no}" = "no"; then
-   AC_CHECK_SIZEOF(size_t)
-   ac_cv_sizeof_size_t=`echo "$ac_cv_sizeof_size_t" | tr -d '\r'`
-   NCBI_PLATFORM_BITS=`expr 8 \* $ac_cv_sizeof_size_t`
-   AC_DEFINE_UNQUOTED(NCBI_PLATFORM_BITS, $NCBI_PLATFORM_BITS,
-                      [Define to the architecture size.])
-   if test $NCBI_PLATFORM_BITS -eq 64; then
-      bit64_sfx=64
-   fi
+AC_CHECK_SIZEOF(size_t)
+ac_cv_sizeof_size_t=`echo "$ac_cv_sizeof_size_t" | tr -d '\r'`
+NCBI_PLATFORM_BITS=`expr 8 \* $ac_cv_sizeof_size_t`
+AC_DEFINE_UNQUOTED(NCBI_PLATFORM_BITS, $NCBI_PLATFORM_BITS,
+                   [Define to the architecture size.])
+if test $NCBI_PLATFORM_BITS -eq 64; then
+   bit64_sfx=64
 fi
 
 if test "$bit64_sfx" = 64 -o "$with_lfs" = "yes"; then
@@ -3473,21 +3519,19 @@ fi
 AC_C_CONST
 
 ### Check for C standard types and sizes
-if test "${with_universal-no}" = "no"; then
-   AC_C_BIGENDIAN
-   AC_C_CHAR_UNSIGNED
-   AC_CHECK_SIZEOF(char)
-   AC_CHECK_SIZEOF(double)
-   AC_CHECK_SIZEOF(float)
-   AC_CHECK_SIZEOF(int)
-   AC_CHECK_SIZEOF(long)
-   AC_CHECK_SIZEOF(long double)
-   AC_CHECK_SIZEOF(long long)
-   AC_CHECK_SIZEOF(short)
-   AC_CHECK_SIZEOF(void*)
-   AC_CHECK_SIZEOF(wchar_t, [], [#include <wchar.h>])
-   AC_CHECK_SIZEOF(__int64)
-fi
+AC_C_BIGENDIAN
+AC_C_CHAR_UNSIGNED
+AC_CHECK_SIZEOF(char)
+AC_CHECK_SIZEOF(double)
+AC_CHECK_SIZEOF(float)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(long double)
+AC_CHECK_SIZEOF(long long)
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(void*)
+AC_CHECK_SIZEOF(wchar_t, [], [#include <wchar.h>])
+AC_CHECK_SIZEOF(__int64)
 AC_CHECK_TYPES([intptr_t, uintptr_t])
 
 AC_CHECK_MEMBER(struct sockaddr_in.sin_len,
@@ -4374,6 +4418,28 @@ if test "x$with_gnutls" != xno -a -n "$GNUTLS_CONFIG_LIBS"; then
        *\ -lgcrypt* ) ;;
        *            ) GNUTLS_LIBS="$GNUTLS_LIBS $GCRYPT_LIBS" ;;
    esac
+   if test "$with_static_gnutls" = yes; then
+      dirs=''
+      sep=''
+      static_libs=''
+      for x in $GNUTLS_LIBS; do
+         case $x in
+            -L* ) dirs="$dirs `echo _$x | cut -c4-`" ;;
+            -l* )
+                want=lib`echo _$x | cut -c4-`-static.a
+                for d in $dirs; do
+                   if test -f $d/$want; then
+                      x=$x-static
+                      break
+                   fi
+                done
+                ;;
+         esac
+         static_libs=$static_libs$sep$x
+         sep=' '
+      done
+      GNUTLS_LIBS=$static_libs
+   fi
 fi
 
 NCBI_CHECK_THIRD_PARTY_LIB_EX(openssl, OPENSSL, ssl,
@@ -4400,6 +4466,7 @@ else
    TLS_LIBS=$OPENSSL_LIBS
 fi
 
+NETWORK_LIBS="$TLS_LIBS $NETWORK_LIBS"
 
 case "$with_krb5" in
    no )       ac_cv_path_KRB5_CONFIG=no    ;;
@@ -4718,9 +4785,9 @@ if test "$with_ftds" != "no" ; then
    ftds_ver=64
    try_local=yes
    case "$with_ftds" in
-      64 | 0.64 | yes | '' )
+      64 | 0.64 )
          ;;
-      95 | 0.95 )
+      95 | 0.95 | yes | '' )
          ftds_ver=95
          ;;
       * )
@@ -4728,7 +4795,7 @@ if test "$with_ftds" != "no" ; then
          try_local=no
          ;;
    esac
-   : ${FTDS_CTLIBS:="-lct -ltds"}
+   : ${FTDS_CTLIBS:="-lct -ltds $NETWORK_LIBS"}
    NCBI_RPATHIFY(FTDS_CTLIBS,   $FTDS_PATH/lib,      [ ]$FTDS_CTLIBS)
    FTDS_INCLUDE="-I$FTDS_PATH/include"
    NCBI_LOCAL_FTDS(64)
@@ -4905,14 +4972,20 @@ if test "$with_bdb" != "no" ; then
       AC_CACHE_CHECK([Berkeley DB version (4.3 or newer required)],
          ncbi_cv_lib_berkeley_db_version,
          [AC_LANG_CONFTEST([AC_LANG_SOURCE([[
+cat >/dev/null <<_NCBI_EOF
 #include <db.h>
-ncbi_cv_lib_berkeley_db_version=DB_VERSION_MAJOR.DB_VERSION_MINOR.DB_VERSION_PATCH
+_NCBI_EOF
+get_DB_VERSION() {
+    grep '^[^#]' <<_NCBI_EOF
+DB_VERSION_MAJOR.DB_VERSION_MINOR.DB_VERSION_PATCH
+_NCBI_EOF
+}
+ncbi_cv_lib_berkeley_db_version=\`get_DB_VERSION | tr -cd 0123456789.\`
           ]])])
-          eval "$ac_cpp $BERKELEYDB_INCLUDE conftest.$ac_ext" \
-             2>&AS_MESSAGE_LOG_FD | grep '^ncbi_cv_' \
-             | tr -d "$wschars" > conftest.sh
+          eval "$ac_cpp $BERKELEYDB_INCLUDE conftest.$ac_ext" > conftest.sh \
+             2>&AS_MESSAGE_LOG_FD
           . ./conftest.sh
-          rm -f contest*
+          rm -f conftest*
          ])
       case "$ncbi_cv_lib_berkeley_db_version" in
          1.* | 2.* | 3.* | 4.[[0-2]].* )
@@ -5181,15 +5254,26 @@ if test "$with_boost" != "no"; then
       AC_CACHE_CHECK([Boost version],
          ncbi_cv_lib_boost_version,
          [AC_LANG_CONFTEST([AC_LANG_SOURCE([[
+cat >/dev/null <<_NCBI_EOF
 #include <boost/version.hpp>
-ncbi_cv_lib_boost_version_num=BOOST_VERSION
-ncbi_cv_lib_boost_version=BOOST_LIB_VERSION
+_NCBI_EOF
+get_BOOST_VERSION() {
+    grep '^[^#]' <<_NCBI_EOF
+BOOST_VERSION
+_NCBI_EOF
+}
+get_BOOST_LIB_VERSION() {
+    grep '^[^#]' <<_NCBI_EOF
+BOOST_LIB_VERSION
+_NCBI_EOF
+}
+ncbi_cv_lib_boost_version_num=\`get_BOOST_VERSION\`
+ncbi_cv_lib_boost_version=\`get_BOOST_LIB_VERSION | tr -d '"'\`
           ]])])
-          eval "$ac_cpp $BOOST_INCLUDE conftest.$ac_ext" \
-             2>&AS_MESSAGE_LOG_FD | grep '^ncbi_cv_' \
-             | tr -d "$wschars" > conftest.sh
+          eval "$ac_cpp $BOOST_INCLUDE conftest.$ac_ext" > conftest.sh \
+             2>&AS_MESSAGE_LOG_FD
           . ./conftest.sh
-          rm -f contest*
+          rm -f conftest*
          ])
       AC_DEFINE_UNQUOTED(NCBI_EXPECTED_BOOST_VERSION,
          $ncbi_cv_lib_boost_version_num,
@@ -5224,7 +5308,7 @@ ncbi_cv_lib_boost_version=BOOST_LIB_VERSION
          fi
          with_boost=no
          ;;
-      1_3[[5-9]] | 1_3[[5-9]]_* | 1_[[45]]* | 1_60 | 1_60_* ) ;;
+      1_3[[5-9]] | 1_3[[5-9]]_* | 1_[[45]]* | 1_6[[0-2]] | 1_6[[0-2]]_* ) ;;
       '' ) with_boost=no ;;
       * )
          AC_MSG_WARN(
@@ -5611,6 +5695,14 @@ if test "$with_ncbi_c" != "no" ; then
    if test "$ncbi_compiler" = ICC -a -d "$NCBI_C_PATH/ncbi_icc"; then
       NCBI_C_PATH=$NCBI_C_PATH/ncbi_icc
    fi
+   if test -n "$NCBI_C_PATH_TAGS"; then
+      for x in $NCBI_C_PATH_TAGS; do
+         if test -d "$NCBI_C_PATH$x"; then
+            NCBI_C_PATH=$NCBI_C_PATH$x
+            break
+         fi
+      done
+   fi
 
    NCBI_C_INCLUDE="-I$NCBI_C_PATH/include${bit64_sfx}"
    if test "$with_debug" = "no" ; then
@@ -6736,6 +6828,12 @@ VDB_REQ=VDB
 if test "$with_vdb" != "no" ; then
    # CURL?
    vdb_deps="$LIBXML_LIBS $NETWORK_LIBS $BZ2_LIBS $Z_LIBS $DL_LIBS"
+   # In MT builds, ORIG_LIBS already contains THREAD_LIBS.  However,
+   # VDB is always threaded, and may need explicit THREAD_LIBS when
+   # used statically.
+   if test "$with_mt" = no; then
+      vdb_deps="$vdb_deps $THREAD_LIBS"
+   fi
    if test "${with_vdb:-yes}" != "yes" -a -d "$with_vdb"; then
       VDB_PATH=$with_vdb
    fi
@@ -6772,13 +6870,30 @@ if test "$with_vdb" != "no" ; then
          in_path=" in $VDB_PATH"
          for x in interfaces include; do
             if test -d "$VDB_PATH/$x"; then
-               : ${VDB_INCLUDE="-I$VDB_PATH/$x"}
+               vdb_inc_root=$VDB_PATH/$x
+               : ${VDB_INCLUDE="-I$vdb_inc_root"}
                break
             fi
          done
+         vdb_inc_subdirs=cc/gcc
+         case "$host_cpu:$bit64_sfx" in
+            *86*:64 ) vdb_inc_subdirs="cc/gcc/x86_64 $vdb_inc_subdirs" ;;
+            *86*:*  ) vdb_inc_subdirs="cc/gcc/fat86 $vdb_inc_subdirs" ;;
+         esac
+         if test "$ncbi_compiler" = ICC; then
+            vdb_inc_subdirs="cc/icc $vdb_inc_subdirs"
+         fi
+         case "$host_os" in
+            darwin*  ) vdb_inc_subdirs="os/mac os/unix $vdb_inc_subdirs" ;;
+            linux*   ) vdb_inc_subdirs="os/linux os/unix $vdb_inc_subdirs" ;;
+            solaris* ) vdb_inc_subdirs="os/sun os/unix $vdb_inc_subdirs" ;;
+         esac
+         for x in $vdb_inc_subdirs; do
+            VDB_INCLUDE="$VDB_INCLUDE -I$vdb_inc_root/$x"
+         done
          case "$DEBUG_SFX" in
             Debug )
-               VDB_INCLUDE="$VDB_INCLUDE $VDB_INCLUDE/cc/gcc -D_DEBUGGING"
+               VDB_INCLUDE="$VDB_INCLUDE -D_DEBUGGING"
                vdb_mode=debug
                ;;
             Release )
@@ -6813,9 +6928,11 @@ if test "$with_vdb" != "no" ; then
             [ncbi_cv_lib_ncbi_vdb=yes], [ncbi_cv_lib_ncbi_vdb=no]))
       if test "$ncbi_cv_lib_ncbi_vdb" = yes; then
          NCBI_PACKAGE(VDB)
-         VDB_LIB=
          if test -f "$VDB_LIBDIR/libncbi-vdb-static.a"; then
             VDB_STATIC_LIBS="-L$VDB_LIBDIR -lncbi-vdb-static $vdb_deps"
+            if test "$with_static_vdb" = yes; then
+               VDB_LIBS=$VDB_STATIC_LIBS
+            fi
          else
             VDB_STATIC_LIBS=$VDB_LIBS
          fi
@@ -6832,10 +6949,32 @@ if test "$with_vdb" != "no" ; then
                esac
                ;;
          esac
+         AC_DEFINE(HAVE_NCBI_VDB, 1,
+            [Define to 1 if you have NCBI's SRA/VDB SDK/Toolkit.])
+         bamread=bamread
+         sraread=sraread
+         ncbi_id2proc_snp=ncbi_id2proc_snp
+         ncbi_id2proc_wgs=ncbi_id2proc_wgs
+         ncbi_xloader_bam=ncbi_xloader_bam
+         ncbi_xloader_csra=ncbi_xloader_csra
+         ncbi_xloader_snp=ncbi_xloader_snp
+         ncbi_xloader_sra=ncbi_xloader_sra
+         ncbi_xloader_vdbgraph=ncbi_xloader_vdbgraph
+         ncbi_xloader_wgs=ncbi_xloader_wgs
       else
          VDB_INCLUDE=
          VDB_LIBS=
          VDB_STATIC_LIBS=
+         bamread=
+         sraread=
+         ncbi_id2proc_snp=
+         ncbi_id2proc_wgs=
+         ncbi_xloader_bam=
+         ncbi_xloader_csra=
+         ncbi_xloader_snp=
+         ncbi_xloader_sra=
+         ncbi_xloader_vdbgraph=
+         ncbi_xloader_wgs=
       fi
    # else ...
    # fi
@@ -7280,6 +7419,38 @@ NCBI_CHECK_THIRD_PARTY_LIB(gmock,
    [-lgtest])
 
 
+# LAPACK
+CPPFLAGS="-DHAVE_LAPACK_CONFIG_H $orig_CPPFLAGS"
+case "$with_lapack" in
+   yes | no | '' ) ;;
+   *             ) LAPACK_PATH=$with_lapack ;;
+esac
+if test -d "$LAPACK_PATH"; then
+   NCBI_FIX_DIR(LAPACK_PATH)
+   CPPFLAGS="-I$LAPACK_PATH/include $CPPFLAGS"
+fi
+AC_LANG_PUSH(C)
+AC_CHECK_HEADERS(lapacke.h lapacke/lapacke.h clapack.h Accelerate/Accelerate.h)
+AC_LANG_POP(C)
+if test "$ac_cv_header_clapack_h:$ac_cv_header_Accelerate_Accelerate_h" != no:no; then
+   AC_CHECK_TYPES([__CLPK_integer], [], [],
+      [[#ifdef HAVE_CLAPACK_H
+        #  include <clapack.h>
+        #else
+        #  include <Accelerate/Accelerate.h>
+        #endif]])
+fi
+
+NCBI_CHECK_THIRD_PARTY_LIB(lapack,
+   [AC_LANG_PROGRAM([[extern "C" int dsyev_();]],
+      [[return dsyev_();]])],
+   [-lblas])
+
+# LMDB
+NCBI_CHECK_THIRD_PARTY_LIB(lmdb,
+   [AC_LANG_PROGRAM([[#include <lmdb.h>]],
+      [[MDB_env *env; return mdb_env_create(&env);]])])
+
 ### Restore original compiler/linker flags
 LIBS="$orig_LIBS"
 CPPFLAGS="$orig_CPPFLAGS"
@@ -7568,6 +7739,14 @@ if test "$with_gbench" != "no"  -a  -d "$real_srcdir/src/app/gbench"; then
      reason="$reason${sep}OpenGL"
      sep=", "
    fi
+   if test "$with_glew_mx" = "no"; then
+     reason="$reason${sep}GLEWmx"
+     sep=", "
+   fi
+   if test "$with_ftgl" = "no"; then
+     reason="$reason${sep}FTGL"
+     sep=", "
+   fi
    if test "$with_sqlite3" = "no"; then
      reason="$reason${sep}SQLite 3.x"
      sep=", "
@@ -7576,6 +7755,18 @@ if test "$with_gbench" != "no"  -a  -d "$real_srcdir/src/app/gbench"; then
      reason="$reason${sep}Berkeley DB"
      sep=", "
    fi
+   if test "$ncbi_cv_lib_boost_spirit" != "yes"; then
+     reason=Boost.Spirit
+     sep=", "
+   fi
+   if test "$with_libxslt" = "no"; then
+     reason="$reason${sep}libxslt"
+     sep=", "
+   fi
+   if test "$with_gnutls" = "no"; then
+     reason="$reason${sep}GNUTLS"
+     sep=", "
+   fi
    if test "$with_mt" = "no"; then
      reason="$reason${sep}multithreading"
      sep=", "
@@ -7956,9 +8147,18 @@ AC_SUBST(LIBSSSUTILS)
 AC_SUBST(LIBSSSDB)
 AC_SUBST(sssutils)
 AC_SUBST(VDB_INCLUDE)
-AC_SUBST(VDB_LIB)
 AC_SUBST(VDB_LIBS)
 AC_SUBST(VDB_STATIC_LIBS)
+AC_SUBST(bamread)
+AC_SUBST(sraread)
+AC_SUBST(ncbi_id2proc_snp)
+AC_SUBST(ncbi_id2proc_wgs)
+AC_SUBST(ncbi_xloader_bam)
+AC_SUBST(ncbi_xloader_csra)
+AC_SUBST(ncbi_xloader_snp)
+AC_SUBST(ncbi_xloader_sra)
+AC_SUBST(ncbi_xloader_vdbgraph)
+AC_SUBST(ncbi_xloader_wgs)
 AC_SUBST(VDB_REQ)
 AC_SUBST(VDB_POST_LINK)
 AC_SUBST(SP_INCLUDE)
@@ -8036,6 +8236,9 @@ AC_SUBST(COMPILER)
 AC_SUBST(OSTYPE)
 AC_SUBST(NCBI_PLATFORM_BITS)
 
+AC_SUBST(NCBI_TEAMCITY_BUILD_NUMBER)
+AC_SUBST(NCBI_SUBVERSION_REVISION)
+AC_SUBST(NCBI_SC_VERSION)
 
 #############################################################################
 ### Create output files and do some post-configuration
@@ -8064,7 +8267,9 @@ AC_CONFIG_HEADER(${ncbiconf}:src/build-system/config.h.in)
 ##
 ## Configure makefiles, shell scripts, etc.
 ##
-AC_CONFIG_FILES($configurables $srcdir/./Makefile:src/build-system/Makefile.in.top)
+AC_CONFIG_FILES($configurables \
+   $srcdir/./Makefile:src/build-system/Makefile.in.top \
+   $build_root/inc/common/ncbi_build_ver.h:include/common/ncbi_build_ver.h.in)
 
 AC_CONFIG_COMMANDS([default], [
 dnl make all shell scripts *.sh be executable
@@ -8137,18 +8342,20 @@ else
    rm -f "$build_root/inc/ncbiconf_extra.h"
 fi
 
-dnl Avoid gratuitous relinking
-ncbicfg="$builddir/corelib/ncbicfg.c"
-if test -f "$ncbicfg.last" && cmp -s "$ncbicfg.last" "$ncbicfg"; then
-   echo "$ncbicfg" is unchanged
-   touch -r "$ncbicfg.last" "$ncbicfg"
-elif test -f "$ncbicfg"; then
-   echo "$ncbicfg" is updated
-   rm -f "$ncbicfg.last"
-   cp -p "$ncbicfg" "$ncbicfg.last"
-else
-   echo "$ncbicfg" is not present
-fi
+dnl Avoid gratuitous rebuilding
+for f in "$builddir/corelib/ncbicfg.c" \
+         "$build_root/inc/common/ncbi_build_ver.h"; do
+   if test -f "$f.last" && cmp -s "$f.last" "$f"; then
+      echo "$f" is unchanged
+      touch -r "$f.last" "$f"
+   elif test -f "$f"; then
+      echo "$f" is updated
+      rm -f "$f.last"
+      cp -p "$f" "$f.last"
+   else
+      echo "$f" is not present
+   fi
+done
 
 dnl Try to build simple helpers
 (cd $builddir/build-system/helpers && $MAKE -k)
diff --git a/c++/src/build-system/datatool_version.txt b/c++/src/build-system/datatool_version.txt
index edcfe40..7524906 100644
--- a/c++/src/build-system/datatool_version.txt
+++ b/c++/src/build-system/datatool_version.txt
@@ -1 +1 @@
-2.14.0
+2.16.0
diff --git a/c++/src/build-system/helpers/Makefile.run_with_lock.app b/c++/src/build-system/helpers/Makefile.run_with_lock.app
index 97317f4..442fb76 100644
--- a/c++/src/build-system/helpers/Makefile.run_with_lock.app
+++ b/c++/src/build-system/helpers/Makefile.run_with_lock.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.run_with_lock.app 493416 2016-02-26 18:48:41Z ivanov $
+# $Id: Makefile.run_with_lock.app 492995 2016-02-23 17:06:47Z ucko $
 APP = run_with_lock
 SRC = run_with_lock
 
diff --git a/c++/src/build-system/helpers/run_with_lock.c b/c++/src/build-system/helpers/run_with_lock.c
index f492fb5..f0159b0 100644
--- a/c++/src/build-system/helpers/run_with_lock.c
+++ b/c++/src/build-system/helpers/run_with_lock.c
@@ -1,4 +1,4 @@
-/*  $Id: run_with_lock.c 500280 2016-05-03 17:21:37Z ivanov $
+/*  $Id: run_with_lock.c 520549 2016-11-29 18:58:00Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -185,13 +185,14 @@ int s_Tee(int in, FILE* out1, FILE* out2, EFilterState* state)
         if (*state == eFS_esc) {
             if (*p == '[') {
                 ++p;
-                --n;
+                /* --n; */ /* overadjusts when the final m turns up */
                 *state = eFS_csi;
             } else {
                 fputc('\033', out2);
                 *state = eFS_on;
             }
-        } else if (*state == eFS_csi) {
+        }
+        if (*state == eFS_csi) {
             p = memchr(buffer, 'm', n);
             if (p == NULL) {
                 continue;
@@ -211,23 +212,25 @@ int s_Tee(int in, FILE* out1, FILE* out2, EFilterState* state)
                 if (src > dest  &&  start > src) {
                     memmove(dest, src, start - src);
                 }
+                dest += start - src;
                 if (start == p + n - 1) {
                     *state = eFS_esc;
-                    n = start - p;
+                    n = dest - p;
                     break;
                 }
-                dest += start - src;
                 const char* end = memchr(start + 2, 'm', n - 2 - (start - p));
                 if (end == NULL) {
                     *state = eFS_csi;
-                    n = start - p;
+                    n = dest - p;
                     break;
                 } else {
                     src = end + 1;
                 }
             }
-            memmove(dest, src, n - (src - p));
-            n -= src - dest;
+            if (*state == eFS_on) {
+                memmove(dest, src, n - (src - p));
+                n -= src - dest;
+            }
         }
         if (fwrite(p, 1, n, out2) < n) {
             fprintf(stderr, "%s: Error logging process output: %s.\n",
@@ -256,7 +259,8 @@ static
 int s_OpenPipeOrPty(int fd_to_mimic, const char* label, int fds[2],
                     EFilterState* state)
 {
-    if (isatty(fd_to_mimic)) {
+    const char* term = getenv("TERM");
+    if (term != NULL  &&  strcmp(term, "dumb")  &&  isatty(fd_to_mimic)) {
         struct termios attr;
         const char*    name;
         *state = eFS_on;
diff --git a/c++/src/build-system/install.sh.in b/c++/src/build-system/install.sh.in
index 65791ce..4fd31d7 100644
--- a/c++/src/build-system/install.sh.in
+++ b/c++/src/build-system/install.sh.in
@@ -17,7 +17,7 @@
 
 echo "[`date`]"
 
-svn_location=`echo '$HeadURL: https://svn.ncbi.nlm.nih.gov/repos/toolkit/release/blast/2.4.0/c++/src/build-system/install.sh.in $' | sed "s%\\$[H]eadURL: *\\([^$][^$]*\\) \\$.*%\\1%"`
+svn_location=`echo '$HeadURL: https://svn.ncbi.nlm.nih.gov/repos/toolkit/release/blast/2.6.0/c++/src/build-system/install.sh.in $' | sed "s%\\$[H]eadURL: *\\([^$][^$]*\\) \\$.*%\\1%"`
 svn_revision=`echo '$Revision: 117476 $' | sed "s%\\$[R]evision: *\\([^$][^$]*\\) \\$.*%\\1%"`
 
 script_name=`basename $0`
diff --git a/c++/src/build-system/library_relations.txt b/c++/src/build-system/library_relations.txt
index 45ad8ab..279fae5 100644
--- a/c++/src/build-system/library_relations.txt
+++ b/c++/src/build-system/library_relations.txt
@@ -1,7 +1,8 @@
-# $Id: library_relations.txt 490610 2016-01-27 15:05:28Z syncbot $
+# $Id: library_relations.txt 507530 2016-07-19 20:26:26Z syncbot $
 # Pregenerated summary of library relations, for use by project_tree_builder.
 $(ORIG_LIBS) needs3party
 16S_common needs seqset
+16S_common needs xmlwrapp
 16S_summaries needs 16S_common
 16S_summaries needs gpipe_xmlutil
 16S_summaries needs xregexp
@@ -27,15 +28,12 @@ GLEW needs3party $(ORIG_LIBS)
 GLU needs3party $(ORIG_LIBS)
 GLU needs3party X11
 GLU needs3party Xext
-GMA needs $(SDBAPI_LIB)
-GMA needs xconnect
-GMA needs xutil
-GMC needs geomyncbi
+GMC needs $(CONNEXT)
+GMC needs softparse
 GMC needs xgridcgi
-GMU needs $(COMPRESS_LIBS)
-GMU needs geoauth
 OSMesa needs3party $(OPENGL_LIBS)
 OSMesa needs3party $(ORIG_LIBS)
+TxPubmedBackend needs txserv
 VDBUtils needs bdbasncli
 VDBUtils needs ncbi_xloader_csra
 VDBUtils needs ncbi_xloader_wgs
@@ -64,8 +62,6 @@ align_format needs taxon1
 align_format needs xalnmgr
 align_format needs xcgi
 align_format needs xhtml
-align_part_ci needs $(SEQ_LIBS)
-align_part_ci needs pub
 aligndb_client needs $(SEQ_LIBS)
 aligndb_client needs pub
 aligndb_reader needs $(COMPRESS_LIBS)
@@ -77,55 +73,52 @@ alndb_query needs $(SEQ_LIBS)
 alndb_query needs pub
 alndbaccess needs alndb_query
 alndbaccess needs generic_db_core
+an_core needs $(GPIPE_COMMON_LIBS)
 an_core needs 16S_common
 an_core needs gc_util_sdbapi
 an_core needs gpinit_bag_util
 an_core needs gpipe_an_base
 an_core needs gpipe_kmer
-an_core needs gpipe_xmlutil
-an_core needs ncbi_xcache_netcache
 an_core needs pathogen_connection
 an_core needs reftrack_access
 an_euk_pipeline needs $(GPIPE_COMMON_LIBS)
 an_euk_pipeline needs bag_access
 an_euk_pipeline needs gpipe_an_base
 an_euk_pipeline needs gpipe_val
-an_euk_pipeline needs reftrack_admin
+an_euk_pipeline needs reftrack_access
 an_euk_pipeline needs3party $(BOOST_FILESYSTEM_LIBS)
 an_euk_pipeline needs3party $(BOOST_SYSTEM_LIBS)
-an_prok_pipeline needs $(GPIPE_COMMON_LIBS)
 an_prok_pipeline needs gpipe_an_base
 an_prok_pipeline needs gpipe_asn_proc
 an_prok_pipeline needs pathogen_connection
 an_prok_pipeline needs tax_xml
 an_prok_pipeline needs xobjwrite
 an_worker_nodes needs gpipe_an_base
-asn_cache includes id_dump
+asn_cache needs $(COMPRESS_LIBS)
+asn_cache needs bdb
+asn_cache needs seqset
 asn_config needs build_config_base
 asn_config needs config_access
 asn_config needs gpipe_objutil
-asn_config needs reftrack_access
 asn_sample_lib needs xser
 asngendefs needs xser
 asnmuxdblb needs dbloadb_asn
 asnmuxdblb needs generic_db_asn
 asnmuxdblb needs mux
+attr_cd needs3party $(ORIG_LIBS)
 auxcomm_g needs muxex-C_g
 auxcomm_g needs splitdbasncpp_g
 auxcomm_g needs tea_crypt
 auxcommcpp_g needs muxex_g
 auxnet_g needs generic_db_utils
-backendcommon needs $(SDBAPI_LIB)
-backendcommon needs txxmldoc
-backendcommon needs xconnect
+bacterial_pipeline_proc needs attr_cd
 bacterial_pipeline_proc needs gencoll_client
-bacterial_pipeline_proc needs gpipe_objutil
-bacterial_pipeline_proc needs prok_align_monomer
+bacterial_pipeline_proc needs gpipe_alnutil
 bacterial_pipeline_proc needs xalgoalignutil
 bag_access needs $(SEQ_LIBS)
 bag_access needs gpipe_common
 bag_access needs pub
-bamread needs $(VDB_LIB)
+bamread needs $(COMPRESS_LIBS)
 bamread needs seqset
 bamread needs3party $(VDB_LIBS)
 basic_sample_lib needs xncbi
@@ -136,7 +129,6 @@ bdbasncli needs bdb2ez
 bdbasncli needs xconnect
 biblio needs general
 biosample needs $(SDBAPI_LIB)
-biosample needs xconnect
 biosample needs xmlwrapp
 biosample needs xregexp
 biosample needs xutil
@@ -150,6 +142,9 @@ blast needs tables
 blast_app_util needs $(BLAST_INPUT_LIBS)
 blast_app_util needs $(BLAST_LIBS)
 blast_services needs xnetblastcli
+blast_sra_input needs $(BLAST_INPUT_LIBS)
+blast_sra_input needs $(BLAST_LIBS)
+blast_sra_input needs $(SRAREAD_LIBS)
 blast_unit_test_util needs $(BLAST_LIBS)
 blast_unit_test_util needs $(OBJMGR_LIBS)
 blast_unit_test_util needs3party $(BOOST_TEST_LIBS)
@@ -171,27 +166,24 @@ blastxml needs xser
 blastxml2 needs xser
 bob_g needs splitdbasn_g
 bob_g needs3party netblast
-boost_filesystem-gcc44-mt-d-64 needs3party $(BOOST_SYSTEM_LIBS)
-boost_filesystem-gcc44-mt-d-64 needs3party $(ORIG_LIBS)
-boost_system-gcc44-mt-d-64 needs3party $(ORIG_LIBS)
-boost_unit_test_framework-gcc44-mt-d-64 needs3party $(ORIG_LIBS)
-build_config needs $(GPIPE_COMMON_LIBS)
+boost_filesystem-gcc48-mt-d-64 needs3party $(BOOST_SYSTEM_LIBS)
+boost_filesystem-gcc48-mt-d-64 needs3party $(ORIG_LIBS)
+boost_system-gcc48-mt-d-64 needs3party $(ORIG_LIBS)
+boost_unit_test_framework-gcc48-mt-d-64 needs3party $(ORIG_LIBS)
 build_config needs $(GPIPE_GENCOLL_LIBS)
 build_config needs bacterial_pipeline_proc
 build_config needs build_config_base
 build_config needs gpipe_xmlutil
 build_config needs reftrack_access
+build_config needs simple_asm
 build_config_base needs gencoll_client
 build_config_base needs gpinit_bag_util
 build_config_base needs gpinit_register
 bz2 needs3party $(ORIG_LIBS)
-cache_blob needs $(COMPRESS_LIBS)
-cache_blob needs xser
 cache_g needs generic_db_utils
 cdd needs cn3d
 cdd needs scoremat
 clog needs3party $(ORIG_LIBS)
-cluster needs3party $(ORIG_LIBS)
 cluster_assignment needs xser
 cluster_utils needs gpipe_objutil
 clustering needs cobalt
@@ -206,13 +198,10 @@ com_err needs3party $(ORIG_LIBS)
 composition_adjustment needs3party $(ORIG_LIBS)
 config_access needs gpinit_obj
 config_access needs gpipe_common
-configure_ctl needs gpipe_common
 connect needs3party $(NETWORK_LIBS)
 connect needs3party $(ORIG_LIBS)
 connext needs connect
 connssl needs connect
-connssl needs3party $(GCRYPT_LIBS)
-connssl needs3party $(GNUTLS_LIBS)
 creaders needs3party $(ORIG_LIBS)
 crypto needs $(Z_LIB)
 crypto needs3party $(ORIG_LIBS)
@@ -220,13 +209,19 @@ crypto needs3party $(Z_LIBS)
 ct_ftds64 needs tds_ftds64
 ct_ftds95 needs tds_ftds95
 ctransition needs xncbi
-ctutils needs $(VDB_LIB)
 ctutils needs3party $(SYBASE_DLLS)
 ctutils needs3party $(SYBASE_LIBS)
 ctutils needs3party $(VDB_LIBS)
 ctutils needs3party ncbiobj
-ctutils needs3party sybunic64
 curl needs3party $(ORIG_LIBS)
+data_loaders_util needs $(OBJMGR_LIBS)
+data_loaders_util needs $(ncbi_xreader_pubseqos2)
+data_loaders_util needs ncbi_xdbapi_ftds
+data_loaders_util needs ncbi_xloader_asn_cache
+data_loaders_util needs ncbi_xloader_blastdb
+data_loaders_util needs ncbi_xloader_csra
+data_loaders_util needs ncbi_xloader_lds2
+data_loaders_util needs ncbi_xloader_wgs
 db needs3party $(ORIG_LIBS)
 dbapi needs dbapi_driver
 dbapi_driver needs xncbi
@@ -260,9 +255,10 @@ docsum needs xser
 drmaa needs3party $(ORIG_LIBS)
 dtd_sample_lib needs xser
 dummy_gpipe needs3party $(ORIG_LIBS)
+ec_hmm_relation_cd needs3party $(ORIG_LIBS)
 edirect needs eueid
 edirect needs ncqhst
-edirect needs txservbase
+edirect needs txserv
 egenedb needs $(COMPRESS_LIBS)
 egenedb needs $(CONNEXT)
 egenedb needs dbapi_driver_wrap_s
@@ -295,7 +291,6 @@ eutils needs espell
 eutils needs esummary
 eutils needs uilist
 eutils needs xconnect
-eutils_client needs xconnect
 eutils_client needs xmlwrapp
 eutilsapp includes eueid
 eutilsapp needs ncqhst
@@ -310,6 +305,10 @@ fbsdstd_g needs3party $(ORIG_LIBS)
 fcgi needs3party $(ORIG_LIBS)
 featdef needs xser
 filter_snps needs xalnmgr
+flatfile needs $(OBJMGR_LIBS)
+flatfile needs ncbi_xcache_netcache
+flatfile needs ncbi_xloader_wgs
+flatfile needs xobjwrite
 freetype needs3party $(ORIG_LIBS)
 fscreen needs agp_lookup
 fscreen needs dbapi_util_blobstore
@@ -319,7 +318,10 @@ ftgl needs3party $(ORIG_LIBS)
 gbproj needs submit
 gbproj needs xconnect
 gbseq needs xser
+gc_assm_rpt needs gcaccess_utils
+gc_common needs xser
 gc_load_utils needs $(GPIPE_COMMON_LIBS)
+gc_load_utils needs gc_common
 gc_load_utils needs gc_organism
 gc_load_utils needs gc_utils
 gc_organism needs gpipe_attr
@@ -329,10 +331,10 @@ gc_util_sdbapi needs gencoll_client
 gc_util_sdbapi needs gpipe_common
 gc_utils needs gpipe_objutil
 gcaccess_utils needs $(GPIPE_GENCOLL_LIBS)
+gcaccess_utils needs simple_asm
 gcedit needs agp_lookup
 gcedit needs gc_load_utils
 gcrypt needs3party $(ORIG_LIBS)
-gdsutil needs xncbi
 gencoll_client needs $(COMPRESS_LIBS)
 gencoll_client needs genome_collection
 gencoll_client needs xconnect
@@ -344,7 +346,6 @@ gene_info needs xncbi
 gene_info_writer needs gene_info
 gene_info_writer needs seqdb
 genemark_proc needs bacterial_pipeline_proc
-genemark_proc needs genomic_repeat_region
 general needs xser
 generic_db_asn needs xser
 generic_db_core needs $(CONNEXT)
@@ -360,45 +361,22 @@ genome_collection needs pub
 genome_size needs $(COMPRESS_LIBS)
 genome_size needs xconnect
 genome_size needs xutil
-genomic_repeat_region needs $(SOBJMGR_LIBS)
 gensvc_g needs xser
-geoauth needs GMA
-geobrowse needs xser
-geocgi needs $(SDBAPI_LIB)
-geocgi needs xcgi
-geocgi needs xconnect
-geocgi needs xmlwrapp
-geocgi2 needs geomyncbi
-geocgi2 needs xcgi
 geodataset needs biblio
-geoindex needs $(COMPRESS_LIBS)
-geoindex needs xmlwrapp
-geoindex needs xutil
-geometa needs GMA
-geometa needs xmlwrapp
-geometa needs xser
-geomyncbi includes geoauth
-geomyncbi needs connssl
-geomyncbi needs xmlwrapp
-geostat needs xncbi
 gif needs3party $(ORIG_LIBS)
 gif needs3party X11
 gmap needs xmlwrapp
-gmap needs xncbi
 gmp needs3party $(ORIG_LIBS)
 gnomon_access needs sqlitewrapp
 gnomon_access needs xalgognomon
 gnomon_access needs xqueryparse
 gnomon_asn_proc needs xobjutil
-gnutls needs $(Z_LIB)
 gnutls needs3party $(GMP_LIBS)
 gnutls needs3party $(NETTLE_LIBS)
 gnutls needs3party $(ORIG_LIBS)
-gnutls needs3party $(Z_LIBS)
 gpcgi needs $(SDBAPI_LIB)
-gpcgi needs gpipe_xmlutil
 gpcgi needs xcgi
-gpcgi needs xconnect
+gpcgi needs xmlwrapp
 gpcgi needs xregexp
 gpexec_query needs gpipe_common
 gpexec_query needs monitor_buildrun
@@ -408,15 +386,15 @@ gpinit needs entrez2cli
 gpinit needs gc_organism
 gpinit needs gpinit_access
 gpinit needs gpipe_objutil
-gpinit_access needs gpipe_common
+gpinit_access needs $(SDBAPI_LIB)
+gpinit_access needs xconnect
+gpinit_access needs xutil
 gpinit_bag_util needs bag_access
 gpinit_bag_util needs gpinit_access
 gpinit_obj needs general
 gpinit_register needs gc_organism
-gpinit_register needs gpinit_access
 gpinit_reports needs xmlwrapp
 gpinit_reports needs xregexp
-gpinit_stats_report needs gpipe_attr
 gpipe_align_format needs $(BLAST_FORMATTER_MINIMAL_LIBS)
 gpipe_align_format needs gpipe_objutil
 gpipe_align_format needs prosplign
@@ -439,51 +417,51 @@ gpipe_attr needs gpipe_property
 gpipe_best_placement needs gpipe_alnutil
 gpipe_best_placement needs xalgoalignutil
 gpipe_blast needs $(BLAST_INPUT_LIBS)
+gpipe_blast needs $(BLAST_LIBS)
 gpipe_blast needs gpipe_alnutil
-gpipe_clean_prot_names needs $(SDBAPI_LIB)
+gpipe_clean_prot_names needs gpipe_attr
 gpipe_clean_prot_names needs xdiscrepancy_report
 gpipe_common needs $(SDBAPI_LIB)
 gpipe_common needs eutils_client
 gpipe_common needs xcgi
 gpipe_common needs xregexp
+gpipe_curl needs xncbi
+gpipe_curl needs3party $(CURL_LIBS)
 gpipe_dateutil needs xregexp
-gpipe_ftp needs gc_utils
 gpipe_ftp needs gcaccess_utils
 gpipe_ftp needs gpinit
 gpipe_ftp needs gpipe_alnutil
 gpipe_ftp needs xalgoalignutil
 gpipe_ftp needs xobjwrite
 gpipe_ftp needs xrepeatdb
-gpipe_ftp_new needs $(GPIPE_COMMON_LIBS)
-gpipe_ftp_new needs gc_utils
 gpipe_ftp_new needs gcaccess_utils
 gpipe_ftp_new needs gpinit
 gpipe_ftp_new needs gpipe_alnutil
 gpipe_ftp_new needs xalgoalignutil
 gpipe_ftp_new needs xobjwrite
 gpipe_ftp_new needs xrepeatdb
-gpipe_jira needs connssl
 gpipe_jira needs gpinit_access
 gpipe_jira needs gpipe_attr
-gpipe_jira needs3party $(CURL_LIBS)
+gpipe_jira needs gpipe_curl
 gpipe_jira needs3party $(GSOAP_LIBS)
 gpipe_kmer needs gpipe_objutil
 gpipe_kmer needs sampling
 gpipe_kpi needs xmlwrapp
-gpipe_kpi needs xncbi
-gpipe_meta_access needs gpipe_common
+gpipe_meta_access needs $(SDBAPI_LIB)
+gpipe_meta_access needs xconnect
+gpipe_meta_access needs xutil
 gpipe_object_edit needs xalgoalignutil
-gpipe_objutil needs $(GPIPE_LOADER_LIBS)
+gpipe_objutil needs $(DATA_LOADERS_UTIL_LIB)
+gpipe_objutil needs $(DATA_LOADERS_UTIL_LIBS)
 gpipe_objutil needs $(OBJEDIT_LIBS)
 gpipe_objutil needs $(OBJMGR_LIBS)
 gpipe_objutil needs $(XFORMAT_LIBS)
 gpipe_objutil needs gpipe_attr
 gpipe_objutil needs taxon1
 gpipe_objutil needs writedb
-gpipe_objutil needs3party $(GPIPE_LOADER_THIRDPARTY_LIBS)
+gpipe_objutil needs xalnmgr
 gpipe_objutil needs3party $(UUID_LIBS)
-gpipe_prok_clean_prot_names needs gpipe_attr
-gpipe_prok_clean_prot_names needs gpipe_clean_prot_names
+gpipe_prodigal needs bacterial_pipeline_proc
 gpipe_property needs gpipe_common
 gpipe_remap needs xobjreadex
 gpipe_resource_req needs xncbi
@@ -498,7 +476,9 @@ gpipe_sqlite needs sqlitewrapp
 gpipe_sqlite needs xconnect
 gpipe_sqlite needs xregexp
 gpipe_standalone needs gpipe_an_base
-gpipe_tree needs gpipe_property
+gpipe_teamcity needs gpipe_common
+gpipe_teamcity needs gpipe_curl
+gpipe_tree needs gpipe_common
 gpipe_tree needs xalgophytree
 gpipe_type_verifier needs gpipe_asn_cleanup
 gpipe_type_verifier needs xalgognomon
@@ -508,12 +488,12 @@ gpipe_val needs pub
 gpipe_val needs valerr
 gpipe_val needs xmlwrapp
 gpipe_xml needs $(SEQ_LIBS)
-gpipe_xml needs connssl
 gpipe_xml needs gpipe_attr
 gpipe_xml needs gpipe_dateutil
 gpipe_xml needs pub
-gpipe_xmlutil needs xmlwrapp
 gpipe_xmlutil needs xutil
+gpipe_xmlutil needs3party $(LIBXML_LIBS)
+gpipe_xmlutil needs3party $(LIBXSLT_LIBS)
 gpxapi needs general
 gpxapi needs xconnect
 gpxlib needs $(COMPRESS_LIBS)
@@ -554,10 +534,10 @@ gui_objutils needs eutils_client
 gui_objutils needs gbproj
 gui_objutils needs gencoll_client
 gui_objutils needs gui_utils
-gui_objutils needs macro
 gui_objutils needs snputil
 gui_objutils needs xalgoalignutil
 gui_objutils needs xcgi
+gui_objutils needs xdiscrepancy
 gui_objutils needs xobjwrite
 gui_objutils needs xvalidate
 gui_opengl needs gui_utils
@@ -583,14 +563,15 @@ hgvs needs xregexp
 hgvs_name needs $(OBJMGR_LIBS)
 hgvs_name needs gui_objutils
 hgvs_name needs sv_objects
-hmm_file needs xregexp
-hmm_hit_handle needs xobjutil
 hogweed needs3party $(GMP_LIBS)
 hogweed needs3party $(ORIG_LIBS)
 homologene needs $(SEQ_LIBS)
 homologene needs pub
-htbcli needs txserv
-htbcon needs txserv
+htbbase needs txxmldoc
+htbcli includes htbcon
+htbcon needs htbbase
+htbcon needs txclient
+hydra_client needs xmlwrapp
 icudata needs3party $(ORIG_LIBS)
 icui18n needs3party $(ORIG_LIBS)
 icuuc needs3party $(ORIG_LIBS)
@@ -602,9 +583,6 @@ id2_split needs $(COMPRESS_LIBS)
 id2_split needs $(SOBJMGR_LIBS)
 id2cli needs id2
 id2cli needs xconnect
-id_dump needs bdb
-id_dump needs cache_blob
-id_dump needs seqset
 ideo needs xmvdatacache
 ideochr needs3party vibrant
 ideocli needs ideo
@@ -615,33 +593,7 @@ idload needs3party ctutils
 idload_utils needs gpipe_common
 idload_utils needs xid_utils
 idload_utils needs xobjutil
-idx needs $(CONNEXT)
-idx needs dbapi_driver
-idx needs spellsrvbase
-idx needs xutil
-idxgenome2 needs idxnucleotide2
-idxlinkout needs $(CONNEXT)
-idxlinkout needs $(IDX_COMMON_LIB)
-idxlinkout needs dbapi_driver
-idxlinkout needs spellsrvbase
-idxlinkout needs xutil
-idxlinkout2 needs $(CONNEXT)
-idxlinkout2 needs $(IDX_COMMON_LIB)
-idxlinkout2 needs dbapi_driver
-idxlinkout2 needs spellsrvbase
-idxlinkout2 needs txxmldoc
-idxnucleotide2 needs idxseq2base
-idxpopset2 needs idxseq2base
-idxprotein2 needs idxseq2base
-idxseq2base needs $(IDX_COMMON_LIB)
-idxseq2base needs spellsrvbase
-idxseq2base needs xid_utils
-idxumbrella needs idxnucleotide2
 igblast needs $(BLAST_LIBS)
-ilink needs $(CONNEXT)
-ilink needs dbapi_driver
-ilink needs spellsrvbase
-ilink needs xutil
 insdseq needs xser
 jiracli needs jirasvc
 jiracli needs xconnect
@@ -656,6 +608,9 @@ krb5 needs3party $(NETWORK_LIBS)
 krb5 needs3party $(ORIG_LIBS)
 krb5 needs3party com_err
 krb5 needs3party k5crypto
+lapack needs3party $(ORIG_LIBS)
+lapackwrapp needs3party $(LAPACK_LIBS)
+lapackwrapp needs3party $(ORIG_LIBS)
 lbsmdapi needs connect
 lds2 needs $(COMPRESS_LIBS)
 lds2 needs $(OBJREAD_LIBS)
@@ -763,12 +718,12 @@ ncbi_xdbapi_dblib needs3party $(SYBASE_LIBS)
 ncbi_xdbapi_ftds needs $(FTDS_LIB)
 ncbi_xdbapi_ftds needs dbapi_driver
 ncbi_xdbapi_ftds needs3party $(FTDS_LIBS)
-ncbi_xdbapi_ftds64 needs $(FTDS_LIB)
+ncbi_xdbapi_ftds64 needs $(FTDS64_LIB)
 ncbi_xdbapi_ftds64 needs dbapi_driver
-ncbi_xdbapi_ftds64 needs3party $(FTDS_LIBS)
-ncbi_xdbapi_ftds95 needs $(FTDS95_LIB)
+ncbi_xdbapi_ftds64 needs3party $(FTDS64_LIBS)
+ncbi_xdbapi_ftds95 needs $(FTDS_LIB)
 ncbi_xdbapi_ftds95 needs dbapi_driver
-ncbi_xdbapi_ftds95 needs3party $(FTDS95_LIBS)
+ncbi_xdbapi_ftds95 needs3party $(FTDS_LIBS)
 ncbi_xdbapi_mysql needs dbapi_driver
 ncbi_xdbapi_mysql needs3party $(MYSQL_LIBS)
 ncbi_xdbapi_mysql needs3party $(NETWORK_LIBS)
@@ -780,8 +735,6 @@ ncbi_xloader_bam needs xobjreadex
 ncbi_xloader_blastdb needs seqdb
 ncbi_xloader_blastdb_rmt needs blast_services
 ncbi_xloader_blastdb_rmt needs ncbi_xloader_blastdb
-ncbi_xloader_cdd needs $(SOBJMGR_LIBS)
-ncbi_xloader_cdd needs xconnect
 ncbi_xloader_csra needs $(SOBJMGR_LIBS)
 ncbi_xloader_csra needs $(SRAREAD_LIBS)
 ncbi_xloader_genbank needs ncbi_xreader_cache
@@ -790,10 +743,10 @@ ncbi_xloader_genbank needs ncbi_xreader_id2
 ncbi_xloader_lds2 needs $(SOBJMGR_LIBS)
 ncbi_xloader_lds2 needs lds2
 ncbi_xloader_patcher needs $(SOBJMGR_LIBS)
+ncbi_xloader_snp needs $(SOBJMGR_LIBS)
+ncbi_xloader_snp needs $(SRAREAD_LIBS)
 ncbi_xloader_sra needs $(SOBJMGR_LIBS)
 ncbi_xloader_sra needs $(SRAREAD_LIBS)
-ncbi_xloader_trace needs $(SOBJMGR_LIBS)
-ncbi_xloader_trace needs id1cli
 ncbi_xloader_vdbgraph needs $(SOBJMGR_LIBS)
 ncbi_xloader_vdbgraph needs $(SRAREAD_LIBS)
 ncbi_xloader_wgs needs $(SOBJMGR_LIBS)
@@ -872,7 +825,6 @@ netblast needs3party netcli
 netcli needs3party $(NCBI_C_ncbi)
 netentr needs3party ncbiacc
 netentr needs3party netcli
-netstorage needs connssl
 netstorage needs ncbi_xcache_netcache
 nettle needs3party $(ORIG_LIBS)
 nlmzip needs3party $(NCBI_C_ncbi)
@@ -890,16 +842,12 @@ osutils needs3party ctutils
 pathogen_cluster_loader needs $(SDBAPI_LIB)
 pathogen_cluster_loader needs xasmcompare
 pathogen_cluster_loader needs xconnect
-pathogen_cluster_loader needs xutil
-pathogen_connection needs connssl
 pathogen_connection needs gpipe_common
 pathogen_connection needs gpipe_dateutil
 pathogen_ctl needs $(GPIPE_COMMON_LIBS)
-pathogen_ctl needs $(SRAREAD_LIBS)
 pathogen_ctl needs bag_access
-pathogen_ctl needs gencoll_client
+pathogen_ctl needs gpipe_kmer
 pathogen_ctl needs pathogen_connection
-pathogen_ctl needs taxon1
 pathogen_ctl needs xvalidate
 pathogen_fill_taxa needs gpipe_common
 pathogen_target_loader needs gpinit_register
@@ -912,27 +860,29 @@ pepXML needs xser
 phytree_format needs taxon1
 phytree_format needs xalgophytree
 pn_ctl needs $(GPIPE_GENCOLL_LIBS)
-pn_ctl needs gpipe_prok_clean_prot_names
-pn_ctl needs hmm_file
-pn_ctl needs hmm_hit_handle
+pn_ctl needs bacterial_pipeline_proc
+pn_ctl needs ec_hmm_relation_cd
+pn_ctl needs gpipe_clean_prot_names
+pn_ctl needs gpipe_jira
 pn_ctl needs idload_utils
-pn_ctl needs third_party
+pn_ctl needs simple_asm
 png needs $(Z_LIB)
 png needs3party $(ORIG_LIBS)
 png needs3party $(Z_LIBS)
+process_annotation_stats needs xser
 proj needs pubmed
 proj needs seqset
-prok_align_monomer needs $(SOBJMGR_LIBS)
-prok_align_monomer needs align_part_ci
 prosplign needs xalgoalignutil
 proxsort needs taxoscli
 pstub needs3party $(ORIG_LIBS)
 pub needs medline
 pubmed needs medline
-python2.5 needs3party $(ORIG_LIBS)
-python_ncbi_dbapi needs connect
+python2.7 needs3party $(ORIG_LIBS)
+python_ncbi_dbapi needs $(Z_LIB)
+python_ncbi_dbapi needs connssl
 python_ncbi_dbapi needs dbapi
 python_ncbi_dbapi needs3party $(PYTHON_LIBS)
+python_ncbi_dbapi needs3party $(Z_LIBS)
 rcobaltasn_g needs xser
 refseq_aln_source needs $(COMPRESS_LIBS)
 refseq_aln_source needs dbapi
@@ -941,9 +891,14 @@ refseq_aln_source needs xalgoalignsplign
 refseq_ctl needs bacterial_pipeline_proc
 refseq_ctl needs bag_access
 refseq_ctl needs gpinit_access
+refseq_ctl needs process_annotation_stats
 refseq_ctl needs xid_utils
-reftrack_access needs gpipe_common
-reftrack_admin needs reftrack_access
+reftrack_access needs $(SDBAPI_LIB)
+reftrack_access needs xconnect
+reftrack_access needs xutil
+reftrack_admin needs $(SDBAPI_LIB)
+reftrack_admin needs xconnect
+reftrack_admin needs xutil
 remap needs $(SEQ_LIBS)
 remap needs pub
 remapcli needs remap
@@ -956,9 +911,10 @@ scoremat needs seqset
 sdbapi needs $(XCONNEXT)
 sdbapi needs dbapi
 sdbapi needs ncbi_xdbapi_ftds
+sdbapi needs ncbi_xdbapi_ftds64
+sdbapi needs ncbi_xdbapi_ftds95
 sdbapi needs xconnect
 sdbapi needs xutil
-sdncbiauth needs auxcomm_g
 sdncbiauth needs generic_db_core
 sdncbiauth needs muxex_g
 sdncbiauth needs xmyncbi
@@ -971,6 +927,7 @@ seqcode needs xser
 seqdb needs $(SOBJMGR_LIBS)
 seqdb needs blastdb
 seqedit needs seqset
+seqentry_comparator needs xobjwrite
 seqgapscan needs $(SDBAPI_LIB)
 seqgapscan needs xconnect
 seqgapscan needs xobjutil
@@ -983,21 +940,21 @@ seqsplit needs seqset
 seqtest needs $(SEQ_LIBS)
 seqtest needs pub
 sequtil needs xncbi
+simple_asm needs gc_load_utils
 smartasn_g needs submit
 smartnet needs3party vibrant
 smartnetclient needs xconnect
-snphgvs needs $(GPIPE_LOADER_LIBS)
-snphgvs needs $(SDBAPI_LIB)
-snphgvs needs hgvs
-snphgvs needs ncbi_xcache_netcache
-snphgvs needs refseq_aln_source
-snphgvs needs3party $(GPIPE_LOADER_THIRDPARTY_LIBS)
 snputil needs $(SOBJMGR_LIBS)
 snputil needs variation
 soap_dataobj needs xser
-spcgi needs geomyncbi
+softparse needs $(COMPRESS_LIBS)
+softparse needs affy
+softparse needs taxon1
+softparse needs xmlwrapp
+spcgi needs $(CONNEXT)
+spcgi needs softparse
 spcgi needs xgridcgi
-spellsrvbase needs txservbase
+spellsrvbase needs txserv
 splitdbasn_g needs gendefasn_g
 splitdbasn_g needs3party ncbiobj
 splitdbasncpp_g needs asngendefs
@@ -1006,13 +963,7 @@ sqlite3 needs3party $(ORIG_LIBS)
 sqlitewrapp needs xncbi
 sqlitewrapp needs3party $(SQLITE3_LIBS)
 sraread needs $(SOBJMGR_LIBS)
-sraread needs $(VDB_LIB)
 sraread needs3party $(VDB_LIBS)
-srprism needs srprism_seq
-srprism_common needs $(COMPRESS_LIBS)
-srprism_common needs xutil
-srprism_seq needs srprism_common
-srprism_setup needs xncbi
 ssl needs $(Z_LIB)
 ssl needs3party $(KRB5_LIBS)
 ssl needs3party $(NETWORK_LIBS)
@@ -1067,8 +1018,8 @@ sybtcl64 needs3party sybintl64
 sybtcl64 needs3party sybunic64
 sybunic64 needs3party $(ORIG_LIBS)
 tables needs3party $(ORIG_LIBS)
-tax_assignment_region needs gpipe_objutil
-tax_xml needs gpipe_objutil
+tax_xml needs $(GPIPE_GENCOLL_LIBS)
+tax_xml needs simple_asm
 taxon needs xser
 taxon1 needs $(SEQ_LIBS)
 taxon1 needs pub
@@ -1098,8 +1049,6 @@ test_stat_ext needs dbapi
 test_stat_ext needs ncbi_xdbapi_ftds
 test_stat_ext needs xconnect
 test_stat_ext needs xutil
-third_party needs xmlwrapp
-third_party needs xregexp
 tiff needs $(Z_LIB)
 tiff needs3party $(JPEG_LIBS)
 tiff needs3party $(ORIG_LIBS)
@@ -1111,6 +1060,11 @@ tiol needs3party $(Z_LIBS)
 tracking_utils needs gpipe_attr
 trackmgr needs $(SEQ_LIBS)
 trackmgr needs pub
+trackmgr_objtools needs $(OBJMGR_LIBS)
+trackmgr_objtools needs gencoll_client
+trackmgr_objtools needs trackmgrgridcli
+trackmgr_objtools needs uudutil
+trackmgr_objtools needs xid_mapper
 trackmgrcli needs trackmgr
 trackmgrcli needs xconnect
 trackmgrgridcli needs $(COMPRESS_LIBS)
@@ -1123,18 +1077,15 @@ tvlib needs tv_objects
 tvlib needs uudutil
 tvlib needs w_phylo_tree
 txclient needs xconnect
-txserv includes txservbase
-txserv needs txxmldoc
+txserv needs xmlwrapp
+txserv needs3party $(RT_LIBS)
 txserv14 needs txxmldoc
 txserv14 needs xconnect
 txserv14 needs3party $(RT_LIBS)
-txservbase needs xconnect
-txservbase needs3party $(RT_LIBS)
 txxmldoc needs $(COMPRESS_LIBS)
 txxmldoc needs xutil
 txxmldoc needs3party $(LIBXML_LIBS)
 txxmldoc needs3party $(LIBXSLT_LIBS)
-txxmltrans needs3party $(ORIG_LIBS)
 u2tl needs $(Z_LIB)
 u2tl needs3party $(NETWORK_LIBS)
 u2tl needs3party $(ORIG_LIBS)
@@ -1144,6 +1095,8 @@ u2tl needs3party $(SYBASE_LIBS)
 u2tl needs3party $(Z_LIBS)
 uilist needs xser
 unicoll_dump_access needs gpipe_sqlite
+univ_prot_access needs gpipe_common
+univ_prot_access needs xser
 uudutil needs $(COMPRESS_LIBS)
 uudutil needs gbproj
 uudutil needs xconnserv
@@ -1152,12 +1105,13 @@ valerr needs xser
 valid needs general
 valid needs xregexp
 validate_regions needs $(GPIPE_GENCOLL_LIBS)
+validate_regions needs simple_asm
 variation needs $(SEQ_LIBS)
 variation needs pub
 variation_utils needs variation
 variation_utils needs xobjutil
+varrep needs xser
 vdb2blast needs $(BLAST_LIBS)
-vdb2blast needs $(VDB_LIB)
 vdb2blast needs3party $(VDB_LIBS)
 vibgif needs3party $(NCBI_C_ncbi)
 vibnet needs3party ncbiacc
@@ -1171,15 +1125,15 @@ vibrantOGL includes3party vibrant
 vibrantOGL needs3party $(OPENGL_LIBS)
 vibrantOGL needs3party ncbiobj
 w_aln_crossaln needs w_hit_matrix
-w_aln_multi needs w_aln_score
-w_aln_multi needs w_data
-w_aln_multi needs w_gl
+w_aln_multi needs w_seq_graphic
 w_aln_score needs w_wx
 w_aln_table needs w_wx
 w_data needs w_wx
 w_edit needs align_format
+w_edit needs hydra_client
 w_edit needs prosplign
 w_edit needs w_loaders
+w_edit needs w_seq
 w_feat_table needs w_wx
 w_gl needs w_wx
 w_grid_widget needs w_data
@@ -1207,6 +1161,7 @@ w_seq_graphic needs gui_graph
 w_seq_graphic needs gui_objects
 w_seq_graphic needs hgvs
 w_seq_graphic needs ncbi_xcache_netcache
+w_seq_graphic needs trackmgr
 w_seq_graphic needs w_aln_score
 w_seq_graphic needs w_gl
 w_seq_graphic needs w_seq
@@ -1229,54 +1184,54 @@ w_wx needs3party $(WXWIDGETS_LIBS)
 we_cpp needs xser
 writedb needs $(OBJREAD_LIBS)
 writedb needs seqdb
-wx_base-2.9 needs $(Z_LIB)
-wx_base-2.9 needs3party $(ORIG_LIBS)
-wx_base-2.9 needs3party $(Z_LIBS)
-wx_base_net-2.9 needs $(Z_LIB)
-wx_base_net-2.9 needs3party $(ORIG_LIBS)
-wx_base_net-2.9 needs3party $(Z_LIBS)
-wx_base_xml-2.9 needs $(Z_LIB)
-wx_base_xml-2.9 needs3party $(EXPAT_LIBS)
-wx_base_xml-2.9 needs3party $(ORIG_LIBS)
-wx_base_xml-2.9 needs3party $(Z_LIBS)
-wx_gtk2_adv-2.9 needs3party $(ORIG_LIBS)
-wx_gtk2_adv-2.9 needs3party $(PNG_LIBS)
-wx_gtk2_adv-2.9 needs3party $(TIFF_LIBS)
-wx_gtk2_adv-2.9 needs3party X11
-wx_gtk2_aui-2.9 needs3party $(ORIG_LIBS)
-wx_gtk2_aui-2.9 needs3party $(PNG_LIBS)
-wx_gtk2_aui-2.9 needs3party $(TIFF_LIBS)
-wx_gtk2_aui-2.9 needs3party X11
-wx_gtk2_core-2.9 needs3party $(ORIG_LIBS)
-wx_gtk2_core-2.9 needs3party $(PNG_LIBS)
-wx_gtk2_core-2.9 needs3party $(TIFF_LIBS)
-wx_gtk2_core-2.9 needs3party X11
-wx_gtk2_gl-2.9 needs3party $(OPENGL_LIBS)
-wx_gtk2_gl-2.9 needs3party $(ORIG_LIBS)
-wx_gtk2_gl-2.9 needs3party $(WXWIDGETS_LIBS)
-wx_gtk2_html-2.9 needs3party $(ORIG_LIBS)
-wx_gtk2_html-2.9 needs3party $(PNG_LIBS)
-wx_gtk2_html-2.9 needs3party $(TIFF_LIBS)
-wx_gtk2_html-2.9 needs3party X11
-wx_gtk2_propgrid-2.9 needs3party $(ORIG_LIBS)
-wx_gtk2_propgrid-2.9 needs3party $(PNG_LIBS)
-wx_gtk2_propgrid-2.9 needs3party $(TIFF_LIBS)
-wx_gtk2_propgrid-2.9 needs3party X11
-wx_gtk2_qa-2.9 needs3party $(EXPAT_LIBS)
-wx_gtk2_qa-2.9 needs3party $(ORIG_LIBS)
-wx_gtk2_qa-2.9 needs3party $(PNG_LIBS)
-wx_gtk2_qa-2.9 needs3party $(TIFF_LIBS)
-wx_gtk2_qa-2.9 needs3party X11
-wx_gtk2_richtext-2.9 needs3party $(EXPAT_LIBS)
-wx_gtk2_richtext-2.9 needs3party $(ORIG_LIBS)
-wx_gtk2_richtext-2.9 needs3party $(PNG_LIBS)
-wx_gtk2_richtext-2.9 needs3party $(TIFF_LIBS)
-wx_gtk2_richtext-2.9 needs3party X11
-wx_gtk2_xrc-2.9 needs3party $(EXPAT_LIBS)
-wx_gtk2_xrc-2.9 needs3party $(ORIG_LIBS)
-wx_gtk2_xrc-2.9 needs3party $(PNG_LIBS)
-wx_gtk2_xrc-2.9 needs3party $(TIFF_LIBS)
-wx_gtk2_xrc-2.9 needs3party X11
+wx_base-3.0 needs $(Z_LIB)
+wx_base-3.0 needs3party $(ORIG_LIBS)
+wx_base-3.0 needs3party $(Z_LIBS)
+wx_base_net-3.0 needs $(Z_LIB)
+wx_base_net-3.0 needs3party $(ORIG_LIBS)
+wx_base_net-3.0 needs3party $(Z_LIBS)
+wx_base_xml-3.0 needs $(Z_LIB)
+wx_base_xml-3.0 needs3party $(EXPAT_LIBS)
+wx_base_xml-3.0 needs3party $(ORIG_LIBS)
+wx_base_xml-3.0 needs3party $(Z_LIBS)
+wx_gtk2_adv-3.0 needs3party $(ORIG_LIBS)
+wx_gtk2_adv-3.0 needs3party $(PNG_LIBS)
+wx_gtk2_adv-3.0 needs3party $(TIFF_LIBS)
+wx_gtk2_adv-3.0 needs3party X11
+wx_gtk2_aui-3.0 needs3party $(ORIG_LIBS)
+wx_gtk2_aui-3.0 needs3party $(PNG_LIBS)
+wx_gtk2_aui-3.0 needs3party $(TIFF_LIBS)
+wx_gtk2_aui-3.0 needs3party X11
+wx_gtk2_core-3.0 needs3party $(ORIG_LIBS)
+wx_gtk2_core-3.0 needs3party $(PNG_LIBS)
+wx_gtk2_core-3.0 needs3party $(TIFF_LIBS)
+wx_gtk2_core-3.0 needs3party X11
+wx_gtk2_gl-3.0 needs3party $(OPENGL_LIBS)
+wx_gtk2_gl-3.0 needs3party $(ORIG_LIBS)
+wx_gtk2_gl-3.0 needs3party $(WXWIDGETS_LIBS)
+wx_gtk2_html-3.0 needs3party $(ORIG_LIBS)
+wx_gtk2_html-3.0 needs3party $(PNG_LIBS)
+wx_gtk2_html-3.0 needs3party $(TIFF_LIBS)
+wx_gtk2_html-3.0 needs3party X11
+wx_gtk2_propgrid-3.0 needs3party $(ORIG_LIBS)
+wx_gtk2_propgrid-3.0 needs3party $(PNG_LIBS)
+wx_gtk2_propgrid-3.0 needs3party $(TIFF_LIBS)
+wx_gtk2_propgrid-3.0 needs3party X11
+wx_gtk2_qa-3.0 needs3party $(EXPAT_LIBS)
+wx_gtk2_qa-3.0 needs3party $(ORIG_LIBS)
+wx_gtk2_qa-3.0 needs3party $(PNG_LIBS)
+wx_gtk2_qa-3.0 needs3party $(TIFF_LIBS)
+wx_gtk2_qa-3.0 needs3party X11
+wx_gtk2_richtext-3.0 needs3party $(EXPAT_LIBS)
+wx_gtk2_richtext-3.0 needs3party $(ORIG_LIBS)
+wx_gtk2_richtext-3.0 needs3party $(PNG_LIBS)
+wx_gtk2_richtext-3.0 needs3party $(TIFF_LIBS)
+wx_gtk2_richtext-3.0 needs3party X11
+wx_gtk2_xrc-3.0 needs3party $(EXPAT_LIBS)
+wx_gtk2_xrc-3.0 needs3party $(ORIG_LIBS)
+wx_gtk2_xrc-3.0 needs3party $(PNG_LIBS)
+wx_gtk2_xrc-3.0 needs3party $(TIFF_LIBS)
+wx_gtk2_xrc-3.0 needs3party X11
 wx_tools needs xncbi
 wx_tools needs3party $(WXWIDGETS_LIBS)
 xalan-c needs3party $(CURL_LIBS)
@@ -1322,7 +1277,8 @@ xalnmgr needs xobjutil
 xalntool needs xhtml
 xalntool needs xobjutil
 xannot_builder needs gpipe_asn_proc
-xasmcompare needs xncbi
+xasmcompare needs $(SEQ_LIBS)
+xasmcompare needs pub
 xasn needs xhtml
 xasn needs3party $(NCBI_C_ncbi)
 xassembly_svc needs gcaccess_utils
@@ -1361,7 +1317,7 @@ xcleanup needs xobjutil
 xcompress needs $(CMPRS_LIB)
 xcompress needs xutil
 xcompress needs3party $(CMPRS_LIBS)
-xconnect includes connect
+xconnect includes connssl
 xconnect needs xncbi
 xconnext includes $(CONNEXT)
 xconnext needs xconnect
@@ -1372,8 +1328,10 @@ xctools needs xncbi
 xctools needs3party $(NCBI_C_ncbi)
 xdb needs xncbi
 xdiff needs xncbi
+xdiscrepancy needs $(OBJEDIT_LIBS)
+xdiscrepancy needs $(XFORMAT_LIBS)
 xdiscrepancy needs macro
-xdiscrepancy needs xvalidate
+xdiscrepancy needs xalnmgr
 xdiscrepancy_report needs $(OBJMGR_LIBS)
 xdiscrepancy_report needs macro
 xdiscrepancy_report needs xmlwrapp
@@ -1386,28 +1344,17 @@ xformat needs gbseq
 xformat needs mlacli
 xformat needs xalnmgr
 xformat needs xcleanup
-xgdsapi needs $(CONNEXT)
-xgdsapi needs connect
-xgdsapi needs dbapi
-xgdsapi needs ncbi_xdbapi_ftds
-xgdsdata needs $(CONNEXT)
-xgdsdata needs $(EUTILS_LIBS)
-xgdsdata needs $(SEQ_LIBS)
-xgdsdata needs dbapi
-xgdsdata needs geodataset
-xgdsdata needs ncbi_xdbapi_ftds
-xgdsdata needs pub
-xgdsdata needs txxmldoc
-xgdsdata needs xconnect
-xgdsdata_misc needs xncbi
 xgencoll needs aligndb_reader
 xgencoll needs gencoll_client
-xgencoll needs gpipe_objutil
+xgencoll needs ncbi_xcache_netcache
+xgencoll needs simple_asm
 xgencollstats needs $(GPIPE_GENCOLL_LIBS)
 xgencollstats needs gencoll_stats
+xgencollstats needs simple_asm
 xgp_manifest needs xser
 xgpgcreport needs $(GPIPE_GENCOLL_LIBS)
 xgpgcreport needs gencoll_release_report
+xgpgcreport needs simple_asm
 xgpp_console needs dbapi
 xgpp_console_access needs xgpp_console_commands
 xgpp_console_commands needs gpipe_common
@@ -1416,8 +1363,9 @@ xgpsubmit needs gc_load_utils
 xgpsubmit needs gpinit_access
 xgpsubmit needs gpipe_asn_cleanup
 xgpsubmit needs grid_wrapper
+xgpsubmit needs idload_utils
+xgpsubmit needs seqgapscan
 xgpsubmit needs xasmcompare
-xgpsubmit needs xid_utils
 xgraphiccgi needs gui_glmesa
 xgraphiccgi needs gui_opengl
 xgraphiccgi needs xsvcgi
@@ -1431,24 +1379,23 @@ xid_estsub needs xregexp
 xid_mapper needs $(SOBJMGR_LIBS)
 xid_utils needs $(CONNEXT)
 xid_utils needs $(SEQ_LIBS)
-xid_utils needs connssl
 xid_utils needs dbapi_driver
 xid_utils needs pub
 xid_utils needs xcgi
-xid_utils needs xconnect
 xid_utils needs xmlwrapp
 xid_utils_noncorelib needs txclient
 xid_utils_noncorelib needs xid_utils
+xid_wgs needs xncbi
+xid_wgs needs3party $(VDB_LIBS)
 xid_wgsdb needs xid_utils
 ximage needs xncbi
 ximage needs3party $(IMAGE_LIBS)
 xmergetree needs $(SOBJMGR_LIBS)
 xml2 needs3party $(ORIG_LIBS)
 xmlreaders needs xmlwrapp
-xmlreaders needs xncbi
+xmlwrapp needs xconnect
 xmlwrapp needs3party $(LIBXML_LIBS)
 xmlwrapp needs3party $(LIBXSLT_LIBS)
-xmlwrapp needs3party $(ORIG_LIBS)
 xmvdatacache needs mapview
 xmyncbi needs txclient
 xmyncbi needs txxmldoc
@@ -1477,6 +1424,7 @@ xobjreadex needs xobjutil
 xobjsimple needs $(OBJMGR_LIBS)
 xobjutil needs $(SOBJMGR_LIBS)
 xobjwrite needs $(OBJREAD_LIBS)
+xobjwrite needs $(XFORMAT_LIBS)
 xobjwrite needs variation_utils
 xobjwrite needs xalnmgr
 xomssa needs $(COMPRESS_LIBS)
@@ -1519,11 +1467,14 @@ xstruct_dp needs xncbi
 xstruct_thread needs xutil
 xstruct_util needs $(BLAST_LIBS)
 xstruct_util needs xstruct_dp
+xsubmit2id needs sqlitewrapp
+xsubmit2id needs xid_utils
 xsvcgi needs $(DBAPI_CTLIB)
 xsvcgi needs $(OBJMGR_LIBS)
 xsvcgi needs $(ncbi_xreader_pubseqos2)
-xsvcgi needs gui_objutils
+xsvcgi needs gui_objects
 xsvcgi needs ncbi_xcache_netcache
+xsvcgi needs ncbi_xloader_bam
 xsvcgi needs ncbi_xloader_csra
 xsvcgi needs ncbi_xloader_vdbgraph
 xsvcgi needs ncbi_xloader_wgs
@@ -1531,18 +1482,11 @@ xsvcgi needs uudutil
 xsvcgi needs3party $(SYBASE_DLLS)
 xsvcgi needs3party $(SYBASE_LIBS)
 xsvdata needs $(BLAST_INPUT_LIBS)
-xsvdata needs $(DBAPI_CTLIB)
-xsvdata needs $(ncbi_xreader_pubseqos2)
-xsvdata needs gui_objects
 xsvdata needs hgvs
-xsvdata needs ncbi_xcache_netcache
 xsvdata needs sv_objects
 xsvdata needs trackmgr
-xsvdata needs uudutil
 xsvdata needs xalgophytree
-xsvdata needs xobjreadex
-xsvdata needs3party $(SYBASE_DLLS)
-xsvdata needs3party $(SYBASE_LIBS)
+xsvdata needs xsvcgi
 xsvlink needs gui_objutils
 xsvlink needs sv_objects
 xsvnaa needs xutil
@@ -1557,6 +1501,7 @@ xvalidate needs $(OBJEDIT_LIBS)
 xvalidate needs $(XFORMAT_LIBS)
 xvalidate needs valerr
 xvalidate needs xalnmgr
+xxconnect includes connssl
 xxconnect needs xncbi
 xxconnect needs3party $(NCBI_C_ncbi)
 z needs3party $(ORIG_LIBS)
diff --git a/c++/src/build-system/ncbi_package_version b/c++/src/build-system/ncbi_package_version
index 9183195..914ec96 100644
--- a/c++/src/build-system/ncbi_package_version
+++ b/c++/src/build-system/ncbi_package_version
@@ -1 +1 @@
-2.4.0
\ No newline at end of file
+2.6.0
\ No newline at end of file
diff --git a/c++/src/build-system/project_tree_builder.ini b/c++/src/build-system/project_tree_builder.ini
index 0077005..bf6c052 100644
--- a/c++/src/build-system/project_tree_builder.ini
+++ b/c++/src/build-system/project_tree_builder.ini
@@ -1,4 +1,4 @@
-#  $Id: project_tree_builder.ini 498370 2016-04-15 17:19:18Z ivanov $
+#  $Id: project_tree_builder.ini 520070 2016-11-22 14:36:17Z ivanov $
 ###############################################################################
 
 
@@ -68,7 +68,12 @@ NotProvidedRequests = unix       \
 
 # Whether the following requirements are met or not is up to user
 # One must use GUI tool to enable them
-UserRequests = Ncbi-JNI Ncbi-Unicode
+UserRequests = Ncbi-int8-gi Ncbi-JNI Ncbi-Unicode
+
+#----------------------------------------------------------------------------
+# This file will be generated during the configuration process
+ExtraDefines = ncbi_random_macro.h
+RandomValueCount = 10
 
 #----------------------------------------------------------------------------
 # This file will be generated during the configuration process
@@ -93,6 +98,7 @@ Defines     = HAVE_BERKELEY_DB \
               HAVE_LIBGNUTLS   \
               HAVE_LIBJPEG     \
               HAVE_LIBLZO      \
+              HAVE_LIBLMDB     \
               HAVE_LIBMIMETIC  \
               HAVE_LIBMUPARSER \
               HAVE_LIBOPENSSL  \
@@ -105,6 +111,7 @@ Defines     = HAVE_BERKELEY_DB \
               HAVE_LIBEXSLT    \
               HAVE_LIBMONGODB  \
               HAVE_LOCAL_LBSM  \
+              HAVE_NCBI_VDB    \
               HAVE_ODBC        \
               HAVE_ODBCSS_H    \
               HAVE_OPENGL      \
@@ -118,7 +125,8 @@ Defines     = HAVE_BERKELEY_DB \
               USE_LOCAL_PCRE   \
               HAVE_SQLITE3ASYNC_H \
               HAVE_SQLITE3_UNLOCK_NOTIFY \
-              NCBI_JNI
+              NCBI_JNI         \
+              NCBI_INT8_GI
 
 
 #----------------------------------------------------------------------------
@@ -128,7 +136,10 @@ Defines     = HAVE_BERKELEY_DB \
 Macros = BDB_LIB BDB_CACHE_LIB NCBI_CRYPT CONNEXT XCONNEXT \
          ncbi_xreader_pubseqos ncbi_xreader_pubseqos2 UNLESS_PUBSEQOS \
          FASTCGI_OBJS DBAPI_DRIVER DBAPI_CTLIB DBAPI_DBLIB \
-         DBAPI_ODBC LOCAL_LBSM ncbi_java VDB_REQ
+         DBAPI_ODBC LOCAL_LBSM ncbi_java VDB_REQ bamread sraread \
+         ncbi_id2proc_snp ncbi_id2proc_wgs ncbi_xloader_bam \
+         ncbi_xloader_csra ncbi_xloader_snp ncbi_xloader_sra \
+         ncbi_xloader_vdbgraph ncbi_xloader_wgs
 
 #----------------------------------------------------------------------------
 # Some 3rd party libraries have analog in the toolkit.
@@ -183,10 +194,11 @@ ThirdParty_FreeType     = $(ThirdPartyBasePath)\\freetype\\$(msvc_3rd)\\2.4.10
 ThirdParty_FTGL         = $(ThirdPartyBasePath)\\ftgl\\$(msvc_3rd)\\2.1.3-rc5
 ThirdParty_GIF          = $(ThirdPartyBasePath)\\gif\\$(msvc_3rd)\\4.1.3
 ThirdParty_GLEW         = $(ThirdPartyBasePath)\\glew\\$(msvc_3rd)\\1.5.8
-ThirdParty_GNUTLS       = $(ThirdPartyBasePath)\\gnutls\\$(msvc_3rd)\\3.1.6
+ThirdParty_GNUTLS       = $(ThirdPartyBasePath)\\gnutls\\$(msvc_3rd)\\3.4.9
 ThirdParty_ICU          = $(ThirdPartyBasePath)\\icu\\$(msvc_3rd)\\3.2
 ThirdParty_JPEG         = $(ThirdPartyBasePath)\\jpeg\\$(msvc_3rd)\\6b
 ThirdParty_LZO          = $(ThirdPartyBasePath)\\lzo\\$(msvc_3rd)\\2.05
+ThirdParty_LMDB         = $(ThirdPartyBasePath)\\lmdb\\$(msvc_3rd)\\0.9.18
 ThirdParty_Mimetic      = $(ThirdPartyBasePath)\\mimetic\\$(msvc_3rd)\\0.9.7
 ThirdParty_MongoDB      = $(ThirdPartyBasePath)\\mongodb\\$(msvc_3rd)\\legacy_1.0.0-rc0
 ThirdParty_MSSQL        = $(ThirdPartyBasePath)\\MSSQL\\$(msvc_3rd)\\8.0.1.94
@@ -197,14 +209,14 @@ ThirdParty_PNG          = $(ThirdPartyBasePath)\\png\\$(msvc_3rd)\\1.2.7
 ThirdParty_SQLITE3      = $(ThirdPartyBasePath)\\sqlite\\$(msvc_3rd)\\3.6.14.2
 ThirdParty_Sybase       = $(ThirdPartyBasePath)\\sybase\\$(msvc_3rd)\\15.5
 ThirdParty_TIFF         = $(ThirdPartyBasePath)\\tiff\\$(msvc_3rd)\\3.6.1
-ThirdParty_wxWidgets    = $(ThirdPartyBasePath)\\wxwidgets\\$(msvc_3rd)\\3.0.1
+ThirdParty_wxWidgets    = $(ThirdPartyBasePath)\\wxwidgets\\$(msvc_3rd)\\3.1.0_no28
 ThirdParty_Xalan        = $(ThirdPartyBasePath)\\xalan\\$(msvc_3rd)\\1.10.0-20080814
 ThirdParty_Xerces       = $(ThirdPartyBasePath)\\xerces\\$(msvc_3rd)\\2.8.0
 ThirdParty_XML          = $(ThirdPartyBasePath)\\xml\\$(msvc_3rd)\\2.7.8
 ThirdParty_XSLT         = $(ThirdPartyBasePath)\\xslt\\$(msvc_3rd)\\1.1.26
 ThirdParty_Z            = $(ThirdPartyBasePath)\\z\\$(msvc_3rd)\\1.2.8
 ThirdParty_JDK          = $(ThirdPartyBasePath)\\jdk\\1.6.0_25
-ThirdParty_VDB          = $(ThirdPartyVDBBasePath)\\vdb\\vdb-versions\\2.6.1
+ThirdParty_VDB          = $(ThirdPartyVDBBasePath)\\vdb\\vdb-versions\\2.8.0
 
 PYTHON_PATH = $(ThirdPartyAppsBasePath)\\Python252\\$(msvc_3rd)
 
@@ -275,6 +287,7 @@ msvc_prj       = msvc900_prj
 # Macro
 msvc_3rd       = msvc9
 vdb_arch       = i386
+vdb_arch_inc   = i386
 
 #----------------------------------------------------------------------------
 # Settings for MSVC 2008 (v.9.00, x64)
@@ -290,6 +303,7 @@ msvc_prj       = msvc900_prj
 # Macro
 msvc_3rd       = msvc9.64
 vdb_arch       = x86_64
+vdb_arch_inc   = x86_64
 
 #----------------------------------------------------------------------------
 # Settings for MSVC 2010 (v.10.00, Win32)
@@ -305,6 +319,7 @@ msvc_prj       = msvc1000_prj
 # Macro
 msvc_3rd       = msvc10
 vdb_arch       = i386
+vdb_arch_inc   = i386
 
 #----------------------------------------------------------------------------
 # Settings for MSVC 2010 (v.10.00, x64)
@@ -320,6 +335,7 @@ msvc_prj       = msvc1000_prj
 # Macro
 msvc_3rd       = msvc10.64
 vdb_arch       = x86_64
+vdb_arch_inc   = x86_64
 
 #----------------------------------------------------------------------------
 # Settings for MSVC 2012 (v.11, Win32)
@@ -335,6 +351,7 @@ msvc_prj       = vs2012
 # Macro
 msvc_3rd       = vs2012
 vdb_arch       = i386
+vdb_arch_inc   = i386
 
 
 #----------------------------------------------------------------------------
@@ -351,6 +368,7 @@ msvc_prj       = vs2012
 # Macro
 msvc_3rd       = vs2012.64
 vdb_arch       = x86_64
+vdb_arch_inc   = x86_64
 
 
 #----------------------------------------------------------------------------
@@ -367,6 +385,7 @@ msvc_prj       = vs2013
 # Macro
 msvc_3rd       = vs2013
 vdb_arch       = i386/vs2013.32
+vdb_arch_inc   = i386
 
 
 #----------------------------------------------------------------------------
@@ -383,6 +402,7 @@ msvc_prj       = vs2013
 # Macro
 msvc_3rd       = vs2013.64
 vdb_arch       = x86_64/vs2013.64
+vdb_arch_inc   = x86_64
 
 
 #----------------------------------------------------------------------------
@@ -399,6 +419,7 @@ msvc_prj       = vs2015
 # Macro
 msvc_3rd       = vs2015
 vdb_arch       = i386/vs2013.32
+vdb_arch_inc   = i386
 
 
 #----------------------------------------------------------------------------
@@ -415,6 +436,7 @@ msvc_prj       = vs2015
 # Macro
 msvc_3rd       = vs2015.64
 vdb_arch       = x86_64/vs2013.64
+vdb_arch_inc   = x86_64
 
 
 #============================================================================
@@ -447,7 +469,7 @@ Projects       = build
 # XCODE specific metadata
 # It describes default settings of compiler, linker etc
 MetaMakefile   = build-system/Makefile.mk.in.xcode
-StandardFeatures = unix Darwin XCODE GCC LFS DBLib algo app dbapi gui objects serial FreeTDS
+StandardFeatures = unix Darwin XCODE GCC LFS algo app dbapi gui objects serial FreeTDS LAPACK
 NotProvidedRequests = MSWin MSVC KCC ICC VisualAge CompaqCompiler WorkShop MIPSpro -LimitedLinker MaxDebug LocalSSS SSSUTILS MESA GEO SSSDB SP ODBC LIBMAGIC GIF
 DefinesPath = common/config/ncbiconf_xcode_site.h
 
@@ -462,13 +484,14 @@ ThirdParty_SQLITE3    = $(XCode_ThirdPartyBasePath)/sqlite-3.6.14.2-ncbi1
 ThirdParty_XML        = $(XCode_ThirdPartyBasePath)/libxml-2.7.8
 ThirdParty_XSLT       = $(XCode_ThirdPartyBasePath)/libxml-2.7.8
 ThirdParty_GLEW       = $(XCode_ThirdPartyBasePath)/glew-1.5.8
-ThirdParty_wxWidgets  = $(XCode_ThirdPartyBasePath)/wxWidgets-3.0.2-ncbi1
+ThirdParty_wxWidgets  = $(XCode_ThirdPartyBasePath)/wxWidgets-3.1.0-ncbi2
 ThirdParty_FreeType   = /opt/X11
 ThirdParty_FTGL       = $(XCode_ThirdPartyBasePath)/ftgl-2.1.3-rc5
-ThirdParty_VDB        = $(XCode_ThirdPartyVDBBasePath)/vdb/vdb-versions/2.6.1
+ThirdParty_VDB        = $(XCode_ThirdPartyVDBBasePath)/vdb/vdb-versions/2.8.0
 ThirdParty_GMP        = $(Xcode_ThirdPartyBasePath)/gmp-6.0.0a
 ThirdParty_Nettle     = $(Xcode_ThirdPartyBasePath)/nettle-3.1.1
 ThirdParty_GNUTLS     = $(Xcode_ThirdPartyBasePath)/gnutls-3.4.0
+ThirdParty_LMDB       = $(Xcode_ThirdPartyBasePath)/lmdb-0.9.18
 
 LIBXML_INCLUDE   = $(ThirdParty_XML)/include/libxml2
 LIBXSLT_INCLUDE  = $(ThirdParty_XSLT)/include
@@ -483,6 +506,7 @@ DllBuildDefine    = NCBI_DLL_BUILD
 msvc_prj       = xcode30_prj
 # vdb_arch       = i386
 vdb_arch       = fat86
+vdb_arch_inc   = fat86
 
 [xcode30.x86_64]
 Version=44
@@ -492,6 +516,7 @@ DllBuildDefine    = NCBI_DLL_BUILD
 msvc_prj       = xcode30_prj
 sfx64 = 64
 vdb_arch       = x86_64
+vdb_arch_inc   = x86_64
 
 [xcode30.i386_x86_64]
 Version=44
@@ -500,6 +525,7 @@ DllConfigurations = DebugDLL ReleaseDLL
 DllBuildDefine    = NCBI_DLL_BUILD
 msvc_prj       = xcode30_prj
 vdb_arch       = fat86
+vdb_arch_inc   = fat86
 
 
 #============================================================================
@@ -535,7 +561,6 @@ BZ2_LIB          = bz2
 Z_LIB            = z
 LZO_LIB          = lzo
 PCRE_LIB         = regexp
-VDB_LIB          = ncbi-vdb-read
 
 FTDS64_INCLUDE   = dbapi/driver/ftds64/ dbapi/driver/ftds64/freetds/
 FTDS64_LIB       = ct_ftds64 tds_ftds64
@@ -545,11 +570,12 @@ FTDS95_INCLUDE   = dbapi/driver/ftds95/ dbapi/driver/ftds95/freetds/
 FTDS95_LIB       = ct_ftds95 tds_ftds95
 FTDS95_CTLIB_LIB = ct_ftds95 tds_ftds95
 
-FTDS_INCLUDE     = dbapi/driver/ftds64/ dbapi/driver/ftds64/freetds/
-FTDS_LIB         = ct_ftds64 tds_ftds64
+FTDS_INCLUDE     = dbapi/driver/ftds95/ dbapi/driver/ftds95/freetds/
+FTDS_LIB         = ct_ftds95 tds_ftds95
 FTDS_LIBS        =
 
 TLS_INCLUDE      = $(ThirdParty_OpenSSL)/include
+GNUTLS_INCLUDE   = $(ThirdParty_GNUTLS)/include
 
 LIBXML_INCLUDE   = $(ThirdParty_XML)/include
 LIBXSLT_INCLUDE  = $(ThirdParty_XSLT)/include
@@ -629,6 +655,9 @@ Component=LZO
 [HAVE_LIBGNUTLS]
 Component=GNUTLS
 
+[NETWORK_LIBS]
+Component=GNUTLS
+
 [LIBS]
 Component=
 
@@ -800,24 +829,24 @@ Component=Sybase
 Component=SQLITE3
 
 [FTDS64_CTLIB_LIBS]
-Component=Iconv, KRB5
+Component=Iconv, KRB5, GNUTLS
 [ICONV_LIBS]
 Component=Iconv
 [FTDS64_LIBS]
-Component=Iconv, KRB5
+Component=Iconv, KRB5, GNUTLS
 
 [FTDS95_CTLIB_LIBS]
-Component=Iconv, KRB5
+Component=Iconv, KRB5, GNUTLS
 [FTDS95_LIBS]
-Component=Iconv, KRB5
+Component=Iconv, KRB5, GNUTLS
 
 [FTDS_CTLIB_LIBS]
-Component=Iconv, KRB5
+Component=Iconv, KRB5, GNUTLS
 [FTDS_LIBS]
-Component=Iconv, KRB5
+Component=Iconv, KRB5, GNUTLS
 
 [TLS_LIBS]
-Component=OpenSSL
+Component=GNUTLS
 
 [KRB5_LIBS]
 Component=KRB5
@@ -848,7 +877,8 @@ Component = gbench
 FILES = src\\app\\gbench\\gbench\\Makefile.in
 CONFS = DebugMT DebugDLL ReleaseMT ReleaseDLL
 
-
+[NCBI_INT8_GI]
+Component = Ncbi-int8-gi
 
 #============================================================================
 # Description of Components (non-toolkit libraries)
@@ -1001,7 +1031,7 @@ Component=GLEW
 #----------------------------------------------------------------------------
 [GNUTLS]
 INCLUDE = $(ThirdParty_GNUTLS)\\include
-LIB     = libgnutls-28.lib
+LIB     = libgnutls-30.lib
 CONFS   = DebugDLL ReleaseDLL
 [GNUTLS.debug.DebugDLL]
 LIBPATH = $(ThirdParty_GNUTLS)\\lib_dll\\debugdll
@@ -1138,6 +1168,32 @@ Component=LZO
 
 
 #----------------------------------------------------------------------------
+[LMDB]
+INCLUDE = $(ThirdParty_LMDB)\\include
+CONFS   = DebugMT DebugDLL ReleaseMT ReleaseDLL
+LIB     = liblmdb.lib
+[LMDB.debug.DebugMT]
+LIBPATH = $(ThirdParty_LMDB)\\lib_static\\debugmt
+[LMDB.debug.DebugDLL]
+LIBPATH = $(ThirdParty_LMDB)\\lib_static\\debugdll
+[LMDB.release.ReleaseMT]
+LIBPATH = $(ThirdParty_LMDB)\\lib_static\\releasemt
+[LMDB.release.ReleaseDLL]
+LIBPATH = $(ThirdParty_LMDB)\\lib_static\\releasedll
+
+[LMDB.xcode]
+INCLUDE = $(ThirdParty_LMDB)/include
+LIB     = -llmdb
+LIBPATH = $(ThirdParty_LMDB)/lib$(sfx64)
+
+[HAVE_LIBLMDB]
+Component=LMDB
+
+[LMDB_LIBS]
+Component=LMDB
+
+
+#----------------------------------------------------------------------------
 [Mimetic]
 INCLUDE = $(ThirdParty_Mimetic)\\include
 CONFS   = DebugMT DebugDLL ReleaseMT ReleaseDLL
@@ -1155,6 +1211,7 @@ LIBPATH = $(ThirdParty_Mimetic)\\lib_static\\releasedll
 
 [HAVE_LIBMIMETIC]
 Component=Mimetic
+
 [MIMETIC_LIBS]
 Component=Mimetic
 
@@ -1178,6 +1235,7 @@ LIBPATH = $(ThirdParty_MongoDB)\\lib_static\\releasedll
 
 [HAVE_LIBMONGODB]
 Component=MongoDB
+
 [MONGODB_LIBS]
 Component=MongoDB
 
@@ -1203,6 +1261,7 @@ LIBPATH = $(ThirdParty_muParser)/lib
 
 [HAVE_LIBMUPARSER]
 Component=muParser
+
 [MUPARSER_LIBS]
 Component=muParser
 
@@ -1787,7 +1846,7 @@ LIB     =
 
 [VDB]
 #MACRO   = VDB_INCLUDE VDB_LIBS VDB_STATIC_LIBS
-INCLUDE = $(ThirdParty_VDB)\\interfaces
+INCLUDE = $(ThirdParty_VDB)\\interfaces $(ThirdParty_VDB)\\interfaces\\cc\\vc++\\$(vdb_arch_inc) $(ThirdParty_VDB)\\interfaces\\cc\\vc++ $(ThirdParty_VDB)\\interfaces\\os\\win
 LIB     = ncbi-vdb-md.lib
 CONFS   = DebugMT DebugDLL ReleaseMT ReleaseDLL
 BINPATH = .
@@ -1798,13 +1857,16 @@ LIBPATH = $(ThirdParty_VDB)\\win\\release\\$(vdb_arch)\\bin
 LIBPATH = $(ThirdParty_VDB)\\win\\release\\$(vdb_arch)\\bin
 
 [VDB.xcode]
-INCLUDE = $(ThirdParty_VDB)/interfaces
+INCLUDE = $(ThirdParty_VDB)/interfaces $(ThirdParty_VDB)/interfaces/cc/gcc/$(vdb_arch) $(ThirdParty_VDB)/interfaces/cc/gcc $(ThirdParty_VDB)/interfaces/os/mac $(ThirdParty_VDB)/interfaces/os/unix
 LIB     = -lncbi-vdb
 [VDB.xcode.debug]
 LIBPATH = $(ThirdParty_VDB)/mac/debug/$(vdb_arch)/lib
 [VDB.xcode.release]
 LIBPATH = $(ThirdParty_VDB)/mac/release/$(vdb_arch)/lib
 
+[HAVE_NCBI_VDB]
+Component=VDB
+
 #[VDB_INCLUDE]
 #Component=VDB
 #[VDB_LIB]
@@ -1816,7 +1878,42 @@ Component=VDB,LIBXML,BZ2,Z
 [VDB_REQ]
 Component=VDB
 Value=VDB
-#DefValue=LocalVDBReq
+[bamread]
+Component=VDB
+Value=bamread
+[sraread]
+Component=VDB
+Value=sraread
+[ncbi_id2proc_snp]
+Component=VDB
+Value=ncbi_id2proc_snp
+[ncbi_id2proc_wgs]
+Component=VDB
+Value=ncbi_id2proc_wgs
+[ncbi_xloader_bam]
+Component=VDB
+Value=ncbi_xloader_bam
+[ncbi_xloader_csra]
+Component=VDB
+Value=ncbi_xloader_csra
+[ncbi_xloader_snp]
+Component=VDB
+Value=ncbi_xloader_snp
+[ncbi_xloader_sra]
+Component=VDB
+Value=ncbi_xloader_sra
+[ncbi_xloader_vdbgraph]
+Component=VDB
+Value=ncbi_xloader_vdbgraph
+[ncbi_xloader_wgs]
+Component=VDB
+Value=ncbi_xloader_wgs
+
+# LAPACK (Xcode-only)
+[LAPACK_LIBS]
+Component = LAPACK
+[LAPACK.xcode]
+LIB = -llapack
 
 # CURL
 
diff --git a/c++/src/build-system/project_tree_builder/msvc_prj_generator.cpp b/c++/src/build-system/project_tree_builder/msvc_prj_generator.cpp
index a42efab..79019a2 100644
--- a/c++/src/build-system/project_tree_builder/msvc_prj_generator.cpp
+++ b/c++/src/build-system/project_tree_builder/msvc_prj_generator.cpp
@@ -1316,7 +1316,7 @@ void CMsvcProjectGenerator::GenerateMsbuild(
         // File version
         CRef<msbuild::CProject::C_ProjectLevelTagType::C_E> t(new msbuild::CProject::C_ProjectLevelTagType::C_E);
         project.SetProjectLevelTagType().SetProjectLevelTagType().push_back(t);
-        {
+        if (CMsvc7RegSettings::GetMsvcVersion() < CMsvc7RegSettings::eMsvc1400) {
             string prj_ver(GetApp().GetRegSettings().GetProjectFileFormatVersion());
             if (!prj_ver.empty()) {
                 __SET_PROPGROUP_ELEMENT(t, "_ProjectFileVersion", prj_ver);
diff --git a/c++/src/build-system/project_tree_builder/msvc_prj_utils.cpp b/c++/src/build-system/project_tree_builder/msvc_prj_utils.cpp
index 43e2f58..bcc9ab8 100644
--- a/c++/src/build-system/project_tree_builder/msvc_prj_utils.cpp
+++ b/c++/src/build-system/project_tree_builder/msvc_prj_utils.cpp
@@ -1,4 +1,4 @@
-/* $Id: msvc_prj_utils.cpp 485908 2015-11-30 14:28:08Z gouriano $
+/* $Id: msvc_prj_utils.cpp 493103 2016-02-24 13:52:12Z gouriano $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -576,7 +576,11 @@ string CMsvc7RegSettings::sm_MsvcPlatformName = "i386";
 
 #elif defined(NCBI_COMPILER_MSVC)
 
-#if _MSC_VER >= 1800
+#if _MSC_VER >= 1900
+CMsvc7RegSettings::EMsvcVersion CMsvc7RegSettings::sm_MsvcVersion =
+CMsvc7RegSettings::eMsvc1400;
+string CMsvc7RegSettings::sm_MsvcVersionName = "1400";
+#elif _MSC_VER >= 1800
 CMsvc7RegSettings::EMsvcVersion CMsvc7RegSettings::sm_MsvcVersion =
 CMsvc7RegSettings::eMsvc1200;
 string CMsvc7RegSettings::sm_MsvcVersionName = "1200";
@@ -687,6 +691,10 @@ void CMsvc7RegSettings::IdentifyPlatform()
             sm_MsvcVersion = eMsvc1200;
             sm_MsvcVersionName = "1200";
             break;
+        case 1400:
+            sm_MsvcVersion = eMsvc1400;
+            sm_MsvcVersionName = NStr::NumericToString(ide);
+            break;
         default:
             NCBI_THROW(CProjBulderAppException, eBuildConfiguration, "Unsupported IDE version");
             break;
@@ -775,6 +783,8 @@ string CMsvc7RegSettings::GetSolutionFileFormatVersion(void)
         return "12.00\n# Visual Studio 2012";
     } else if (GetMsvcVersion() == eMsvc1200) {
         return "12.00\n# Visual Studio 2013";
+    } else if (GetMsvcVersion() == eMsvc1400) {
+        return GetApp().GetRegSettings().m_Version;
     }
     return "";
 }
diff --git a/c++/src/build-system/project_tree_builder/msvc_prj_utils.hpp b/c++/src/build-system/project_tree_builder/msvc_prj_utils.hpp
index ef833d5..17f9e31 100644
--- a/c++/src/build-system/project_tree_builder/msvc_prj_utils.hpp
+++ b/c++/src/build-system/project_tree_builder/msvc_prj_utils.hpp
@@ -1,7 +1,7 @@
 #ifndef PROJECT_TREE_BUILDER__MSVC_PRJ_UTILS__HPP
 #define PROJECT_TREE_BUILDER__MSVC_PRJ_UTILS__HPP
 
-/* $Id: msvc_prj_utils.hpp 430659 2014-03-27 18:13:30Z gouriano $
+/* $Id: msvc_prj_utils.hpp 493103 2016-02-24 13:52:12Z gouriano $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -256,6 +256,7 @@ public:
         eMsvc1000,
         eMsvc1100,      // vs2012
         eMsvc1200,      // vs2013
+        eMsvc1400,      // vs2015
         eXCode30,
         eMsvcNone
     };
diff --git a/c++/src/build-system/project_tree_builder/proj_builder_app.cpp b/c++/src/build-system/project_tree_builder/proj_builder_app.cpp
index 536ed60..6e64ebe 100644
--- a/c++/src/build-system/project_tree_builder/proj_builder_app.cpp
+++ b/c++/src/build-system/project_tree_builder/proj_builder_app.cpp
@@ -1,4 +1,4 @@
-/* $Id: proj_builder_app.cpp 485908 2015-11-30 14:28:08Z gouriano $
+/* $Id: proj_builder_app.cpp 509504 2016-08-05 19:09:50Z fukanchi $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -405,7 +405,7 @@ struct PIsExcludedByDisuse
 //-----------------------------------------------------------------------------
 CProjBulderApp::CProjBulderApp(void)
 {
-    SetVersion( CVersionInfo(4,2,0) );
+    SetVersion( CVersionInfo(4,1,5) );
     m_ScanningWholeTree = false;
     m_Dll = false;
     m_AddMissingLibs = false;
@@ -507,7 +507,7 @@ void CProjBulderApp::Init(void)
                              CArgDescriptions::eString);
 #elif defined(NCBI_COMPILER_MSVC)
     arg_desc->AddOptionalKey("ide", "msvc_version",
-                             "Target version of MS Visual Studio, for example: 1000, 1100, 1200",
+                             "Target version of MS Visual Studio, for example: 1100, 1200, 1400",
                              CArgDescriptions::eInteger);
     arg_desc->AddOptionalKey("arch", "platform",
                              "Target platform, for example: Win32, x64",
@@ -1540,6 +1540,9 @@ void CProjBulderApp::GenerateUnixProjects(CProjectItemsTree& projects_tree)
                     if (!lib3order.empty()) {
                         ofs << "GENERATED_LIB3PARTY_ORDER =";
                         ITERATE( list<string>, l3, lib3order) {
+                            if (l3->empty()) {
+                                continue;
+                            }
                             ofs << " ";
                             if (m_Frameworks.find(*l3) != m_Frameworks.end()) {
                                 ofs << "-framework ";
@@ -2267,8 +2270,9 @@ const CMsvc7RegSettings& CProjBulderApp::GetRegSettings(void)
         m_MsvcRegSettings->m_DllInfo = 
             GetConfig().Get(section, "DllInfo");
     
-        m_MsvcRegSettings->m_Version = 
-            GetConfig().Get(CMsvc7RegSettings::GetMsvcSection(), "Version");
+        m_MsvcRegSettings->m_Version = NStr::Replace(
+            GetConfig().Get(CMsvc7RegSettings::GetMsvcSection(), "Version"),
+            "\\n", "\n");
 
         m_MsvcRegSettings->m_CompilersSubdir  = 
             GetConfig().Get(CMsvc7RegSettings::GetMsvcSection(), "msvc_prj");
@@ -2748,6 +2752,9 @@ void CProjBulderApp::UpdateDepGraph( CProjectTreeBuilder::TFiles& files)
             ITERATE(list<string>, l, libdep) {
                 list<string> dep_list;
                 string dep(*l);
+                if (dep.at(0) == '#') {
+                    break;
+                }
                 if (CSymResolver::IsDefine(dep)) {
                     string resolved;
                     if (CMsvc7RegSettings::GetMsvcPlatform() != CMsvc7RegSettings::eUnix) {
@@ -2813,7 +2820,7 @@ bool  CProjBulderApp::InsertDep(vector< set<string> >& graph, const string& dep,
             PTB_ERROR_EX(m_Root, ePTB_ConfigurationError,
                     "Library dependency cycle found: " << NStr::Join(done, " - "));
             done.pop_back();
-            m_GraphDepPrecedes.erase(*d);
+            //m_GraphDepPrecedes.erase(*d);
             return false;
         }
         done.push_back(*d);
diff --git a/c++/src/build-system/project_tree_builder/proj_tree_builder.cpp b/c++/src/build-system/project_tree_builder/proj_tree_builder.cpp
index fa816c3..8088418 100644
--- a/c++/src/build-system/project_tree_builder/proj_tree_builder.cpp
+++ b/c++/src/build-system/project_tree_builder/proj_tree_builder.cpp
@@ -1,4 +1,4 @@
-/* $Id: proj_tree_builder.cpp 485908 2015-11-30 14:28:08Z gouriano $
+/* $Id: proj_tree_builder.cpp 500658 2016-05-06 12:34:22Z gouriano $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -890,7 +890,11 @@ void  SMakeProjectT::VerifyLibDepends(
             }
             if (!wrong.empty()) {
                 fix=true;
-                warnings.push_back("wrong library order: " + p->Id() + " should precede " + NStr::Join(wrong,","));
+#if 0
+                if (find(missing.begin(), missing.end(), p->Id()) == missing.end()) {
+                    warnings.push_back("wrong library order: " + p->Id() + " should precede " + NStr::Join(wrong,","));
+                }
+#endif
             }
             libsofar.insert(p->Id());
             if (!obsolete) {
@@ -930,9 +934,10 @@ void  SMakeProjectT::VerifyLibDepends(
             for (size_t a= recommend.size(); a!= 0; --a) {
                 advice.insert(advice.end(), recommend[a-1].begin(), recommend[a-1].end());
             }
+#if 0
             warnings.push_back("present     library order: " + NStr::Join(original,","));
             warnings.push_back("recommended library order: " + NStr::Join(advice,","));
-
+#endif
             list<string> advice_full;
             ITERATE( list<string>, a, advice) {
                 for(list<CProjKey>::const_iterator p = depends_ids.begin();
@@ -946,6 +951,7 @@ void  SMakeProjectT::VerifyLibDepends(
             liborder = advice_full;
         }
     }
+#if 0
     if (!warnings.empty() && expected_3party != nullptr) {
         if (libs_3party == nullptr) {
             warnings.push_front("====== Library order warnings (3rd party libs) ======");
@@ -955,6 +961,7 @@ void  SMakeProjectT::VerifyLibDepends(
         PTB_WARNING_EX(mkname,ePTB_InvalidMakefile,
             NStr::Join(warnings,"\n"));
     }
+#endif
 #else
 /*
     this compares dependency rank,
@@ -2395,6 +2402,281 @@ CProjKey SMsvcProjectT::DoCreate(const string&      source_base_dir,
     return proj_key;
 }
 //-----------------------------------------------------------------------------
+
+void s_AnalyzeLibraryOrder( CSymResolver& resolver, const CProjectItemsTree&  tree)
+{
+    CProjBulderApp& app(GetApp());
+    CProjectItemsTree::TProjects::const_iterator p;
+    for (p = tree.m_Projects.begin(); p != tree.m_Projects.end(); ++p) {
+        if (p->first.Type() != CProjKey::eApp) {
+            continue;
+        }
+        const CProjItem& project = p->second;
+
+        list<string> list_lib;
+        if (!project.m_DataSource.GetValue("LIB", list_lib)) {
+            continue;
+        }
+        list<string> lib_list_in, lib_list_in0;
+        for( const string& lib : list_lib) {
+            if (lib.at(0) == '#') {
+                break;
+            }
+            else if (!CSymResolver::IsDefine(lib) && CSymResolver::HasDefine(lib)) {
+                string def = FilterDefine(lib);
+                string val = CSymResolver::StripDefine(def);
+                list<string> tmp;
+                if (project.m_DataSource.GetValue(val, tmp)) {
+                    copy(tmp.begin(), tmp.end(), back_inserter(lib_list_in));
+                } else {
+                    lib_list_in.push_back(def);
+                }
+            } else {
+                lib_list_in.push_back(lib);
+            }
+        }
+        if (lib_list_in.empty()) {
+            continue;
+        }
+        lib_list_in0 = lib_list_in;
+
+        map< string,  set<string> > lib_contents;
+        map< string,  set<string> > lib_dependencies;
+
+        list<string> lib_list_out[2];
+        size_t pass=0;
+        for (pass=0; pass<4; ++pass) {
+
+            if (pass > 1) {
+                lib_list_out[0] = lib_list_out[1];
+                lib_list_out[1].clear();
+            }
+            list<string>& list_in  = pass == 0 ? lib_list_in     : lib_list_out[0];
+            list<string>& list_out = pass == 0 ? lib_list_out[0] : lib_list_out[1];
+
+            bool failed = false;
+            for (list<string>::const_iterator l = list_in.begin(); ; ++l) {
+
+// list_in may change (grow) during the cycle
+                if (l == list_in.end()) {
+                    break;
+                }
+                const string& lib = *l;
+                if (failed) {
+                    list_out.push_back(lib);
+                    continue;
+                }
+
+// this item contents
+                list<string> resolved;
+                if (!CSymResolver::IsDefine(lib) ||
+                    !project.m_DataSource.GetValue(CSymResolver::StripDefine(lib), resolved)) {
+                    resolver.Resolve(lib, &resolved);
+                }
+                for_each(resolved.begin(), resolved.end(), [&lib_contents, &lib](const string& ce) {
+                    string e(ce);
+                    CSymResolver::StripSuffix(e);
+                    if (!e.empty() && e.at(0) != '@') {
+                        lib_contents[lib].insert(e);
+                    }});
+
+// this item dependencies
+                set<string> alldepends;
+                set<string> allflags;
+                for( const string& lib_item : lib_contents[lib]) {
+                    s_CollectAllLeaves( app.m_GraphDepPrecedes, app.m_GraphDepFlags, lib_item, alldepends, allflags);
+                }
+                for_each(alldepends.begin(), alldepends.end(), [&lib_dependencies, &lib](const string& ce){
+                    string e(ce);
+                    CSymResolver::StripSuffix(e);
+                    if (!e.empty() && e.at(0) != '@') {
+                        lib_dependencies[lib].insert(e);
+                    }});
+
+                list<string>::iterator iout = list_out.begin();
+                bool do_append = true;
+
+// check that this item dependencies do not contain items in 'out' list
+                for (; iout != list_out.end(); ++iout) {
+                    for( const string& lib_dep : lib_dependencies[lib]) {
+                        if (lib_contents[*iout].find(lib_dep) != lib_contents[*iout].end()) {
+                            do_append = false;
+                            break;
+                        }
+                    }
+                    if (!do_append) {
+                        break;
+                    }
+                }
+
+                // good to append
+                if (do_append) {
+                    list_out.push_back(lib);
+                    continue;
+                }
+
+                list<string>::const_iterator i = iout;
+                set<string> already_there;
+                bool do_replace = false;
+
+// maybe we could drop item at iout, because new one includes it
+// compare lib_contents[*iout] with the contents of the new item
+                already_there.clear();
+                for( const string& lib_item : lib_contents[*iout]) {
+                    if (lib_contents[lib].find(lib_item) != lib_contents[lib].end()) {
+                        already_there.insert(lib_item);
+                    }
+                }
+                if (already_there.size() == lib_contents[*iout].size() &&
+                    already_there.size() != lib_contents[lib].size()) {
+                    // it seems that the new item can replace old one
+                    // make a note to check that it indeed may be inserted here
+                    do_replace = true;
+                }
+
+// is there a need to add this item?
+// compare this item contents with what is already there
+                already_there.clear();
+                for (i = iout; i != list_out.end(); ++i) {
+                    for( const string& lib_item : lib_contents[lib]) {
+                        if (lib_contents[*i].find(lib_item) != lib_contents[*i].end()) {
+                            already_there.insert(lib_item);
+                        }
+                    }
+                }
+                if (already_there.size() == lib_contents[lib].size()) {
+                    // this is a duplicate which is already included
+                    continue;
+                }
+                // if this item adds only few new libraries, maybe we would better
+                // add them expicitely instead
+                if (//!do_replace &&
+                    already_there.size() != 0 &&
+                    already_there.size() >= (lib_contents[lib].size() * 3)/4) {
+                    for( const string& lib_item : lib_contents[lib]) {
+                        if (already_there.find(lib_item) == already_there.end()) {
+                            list_in.push_back(lib_item);
+                        }
+                    }
+                    continue;
+                }
+
+// if we insert it at iout, check that items that follow do not depend on it
+                do_append = false;
+                bool do_insert = true;
+                i = iout;
+                if (do_replace) {
+                    ++i;
+                }
+                for (; i != list_out.end(); ++i) {
+                    for( const string& lib_dep : lib_dependencies[*i]) {
+                        if (lib_contents[lib].find(lib_dep) != lib_contents[lib].end()) {
+// maybe both include the same library.
+// if so, that is acceptable
+                            if (lib_contents[*i].find(lib_dep) != lib_contents[*i].end()) {
+                                do_append = true;
+                                continue;
+                            }
+                            do_insert = false;
+                            break;
+                        }
+                    }
+                    if (!do_insert) {
+                        break;
+                    }
+                }
+
+// good to insert
+                if (do_insert) {
+                    i = iout;
+                    if (do_append && ++i == list_out.end()) {
+                        list_out.push_back(lib);
+                    } else {
+                        if (do_replace) {
+                            iout = list_out.erase(iout);
+                        }
+                        list_out.insert(iout, lib);
+                    }
+                    continue;
+                }
+
+// once again, try to append, allowing identical libraries in both
+                do_append = true;
+// check that this item dependencies do not contain items in 'out' list
+                for (i=iout; i != list_out.end(); ++i) {
+                    for( const string& lib_dep : lib_dependencies[lib]) {
+                        if (lib_contents[*i].find(lib_dep) != lib_contents[*i].end()) {
+                            if (lib_contents[lib].find(lib_dep) != lib_contents[lib].end()) {
+                                continue;
+                            }
+                            do_append = false;
+                            break;
+                        }
+                    }
+                    if (!do_append) {
+                        break;
+                    }
+                }
+
+                // not sure about this one
+                if (do_replace) {
+                    list_out.erase(iout);
+                    for( const string& lib_item : already_there) {
+                        list_out.remove(lib_item);
+                    }
+                }
+                // good to append
+                if (do_append) {
+                    list_out.push_back(lib);
+                    continue;
+                }
+// Do not know what to do
+// keep it as is, in a hope that it will work
+//                failed = true;
+                list_out.push_back(lib);
+            }
+            
+            if (list_in.size() == list_out.size() &&
+                equal(list_in.begin(), list_in.end(), list_out.begin())) {
+                break;
+            }
+        }
+        if (pass != 0) {
+            list<string> warnings;
+            warnings.push_back("====== Library order warnings (toolkit libs) ======");
+            warnings.push_back("present     library order: " + NStr::Join(lib_list_in0," "));
+            if (lib_list_out[0].size() == lib_list_out[1].size() &&
+                equal(lib_list_out[0].begin(), lib_list_out[0].end(), lib_list_out[1].begin())) {
+                warnings.push_back("recommended library order: " + NStr::Join(lib_list_out[0]," "));
+
+                set<string> all_libs, all_deps;
+                for(const string& lib_item: lib_list_out[0]) {
+                    all_libs.insert( lib_contents[lib_item].begin(),lib_contents[lib_item].end());
+                    all_deps.insert( lib_dependencies[lib_item].begin(),lib_dependencies[lib_item].end());
+                }
+                set<string> all_missing;
+                for(const string& lib_item: all_deps) {
+                    if (all_libs.find(lib_item) == all_libs.end()) {
+                        all_missing.insert(lib_item);
+                    }
+                }
+                if (!all_missing.empty()) {
+                    warnings.push_back("missing libraries: " + NStr::Join(all_missing," "));
+                }
+            } else {
+                warnings.push_back("Failed to identify recommended library order");
+                if (pass >= 2) {
+                    warnings.push_back("candidate1: " + NStr::Join(lib_list_out[0]," "));
+                    warnings.push_back("candidate2: " + NStr::Join(lib_list_out[1]," "));
+                }
+            }
+            PTB_WARNING_EX(project.m_DataSource.GetFileName(),ePTB_InvalidMakefile, NStr::Join(warnings,"\n"));
+        }
+    }
+}
+//-----------------------------------------------------------------------------
+
+
 void 
 CProjectTreeBuilder::BuildOneProjectTree(const IProjectFilter* filter,
                                          const string&         root_src_path,
@@ -2446,6 +2728,10 @@ CProjectTreeBuilder::BuildOneProjectTree(const IProjectFilter* filter,
                                   subtree_makefiles.m_Dll, 
                                   subtree_makefiles.m_App,
                                   subtree_makefiles.m_User, tree);
+
+    if (!GetApp().IsScanningWholeTree()) {
+        s_AnalyzeLibraryOrder(resolver, *tree);
+    }
 }
 
 
diff --git a/c++/src/build-system/ptb_version.txt b/c++/src/build-system/ptb_version.txt
index 4d0dcda..b1cbc1f 100644
--- a/c++/src/build-system/ptb_version.txt
+++ b/c++/src/build-system/ptb_version.txt
@@ -1 +1 @@
-4.1.2
+4.1.5
diff --git a/c++/src/build-system/relocate.sh.in b/c++/src/build-system/relocate.sh.in
index a1039bb..18fe936 100644
--- a/c++/src/build-system/relocate.sh.in
+++ b/c++/src/build-system/relocate.sh.in
@@ -1,6 +1,6 @@
 @script_shell@
 
-# $Id: relocate.sh.in 500620 2016-05-05 19:16:05Z blastadm $
+# $Id: relocate.sh.in 521320 2016-12-07 19:38:29Z blastadm $
 # Author:  Denis Vakatov, NCBI 
 # 
 #  Adjust paths to this build tree and the relevant source tree
diff --git a/c++/src/cgi/cgiapp.cpp b/c++/src/cgi/cgiapp.cpp
index cd6cff4..2f5e1ae 100644
--- a/c++/src/cgi/cgiapp.cpp
+++ b/c++/src/cgi/cgiapp.cpp
@@ -1,4 +1,4 @@
-/*  $Id: cgiapp.cpp 492273 2016-02-16 15:26:05Z ivanov $
+/*  $Id: cgiapp.cpp 510827 2016-08-16 15:21:28Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -115,7 +115,7 @@ public:
     virtual ERW_Result Read(void*   buf,
                             size_t  count,
                             size_t* bytes_read = 0);
-    virtual ERW_Result PendingCount(size_t* count)
+    virtual ERW_Result PendingCount(size_t* /*count*/)
     { return eRW_NotImplemented; }
 
 protected:
@@ -714,9 +714,11 @@ void CCgiApplication::LogRequest(void) const
         // Add target url
         string target_url = ctx.GetRequest().GetProperty(eCgi_ScriptName);
         if ( !target_url.empty() ) {
-            string host = "http://" + GetDiagContext().GetHost();
+            bool secure = AStrEquiv(ctx.GetRequest().GetRandomProperty("HTTPS",
+                false), "on", PNocase());
+            string host = (secure ? "https://" : "http://") + GetDiagContext().GetHost();
             string port = ctx.GetRequest().GetProperty(eCgi_ServerPort);
-            if (!port.empty()  &&  port != "80") {
+            if (!port.empty()  &&  port != (secure ? "443" : "80")) {
                 host += ":" + port;
             }
             target_url = host + target_url;
@@ -1003,7 +1005,7 @@ int CCgiApplication::OnException(exception& e, CNcbiOstream& os)
 
         // Message
         os << "ERROR:  " << status_str << " " HTTP_EOL HTTP_EOL;
-        os << message;
+        os << NStr::HtmlEncode(message);
 
         if ( dynamic_cast<CArgException*> (&e) ) {
             string ustr;
@@ -1020,8 +1022,8 @@ int CCgiApplication::OnException(exception& e, CNcbiOstream& os)
             return -1;
         }
     }
-    catch (exception& e) {
-        NCBI_REPORT_EXCEPTION_X(14, "(CGI) CCgiApplication::Run", e);
+    catch (exception& ex) {
+        NCBI_REPORT_EXCEPTION_X(14, "(CGI) CCgiApplication::Run", ex);
     }
     return 0;
 }
@@ -1370,7 +1372,7 @@ CCgiApplication::GetSessionStorage(CCgiSessionParameters&) const
 }
 
 
-bool CCgiApplication::IsCachingNeeded(const CCgiRequest& request) const
+bool CCgiApplication::IsCachingNeeded(const CCgiRequest& /*request*/) const
 {
     return true;
 }
diff --git a/c++/src/cgi/cgictx.cpp b/c++/src/cgi/cgictx.cpp
index 306cfc9..577ec2f 100644
--- a/c++/src/cgi/cgictx.cpp
+++ b/c++/src/cgi/cgictx.cpp
@@ -1,4 +1,4 @@
-/*  $Id: cgictx.cpp 492269 2016-02-16 15:24:58Z ivanov $
+/*  $Id: cgictx.cpp 509509 2016-08-05 19:12:20Z fukanchi $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -308,8 +308,13 @@ const string& CCgiContext::GetSelfURL(void) const
         return kEmptyStr;
     }
 
-    bool secure = AStrEquiv(GetRequest().GetRandomProperty("HTTPS",
-        false), "on", PNocase());
+    bool secure
+        =   AStrEquiv
+        (GetRequest().GetRandomProperty("HTTPS", false), "on",
+         PNocase())
+        ||  AStrEquiv
+        (GetRequest().GetRandomProperty("X_FORWARDED_PROTO"), "https",
+         PNocase());
     m_SecureMode = secure ? eSecure_On : eSecure_Off;
     m_SelfURL = secure ? "https://" : "http://";
     m_SelfURL += server;
@@ -345,7 +350,13 @@ const string& CCgiContext::GetSelfURL(void) const
 bool CCgiContext::IsSecure(void) const
 {
     if (m_SecureMode == eSecure_NotSet) {
-        m_SecureMode = NStr::EqualNocase(CTempStringEx(GetSelfURL(), 5), "https")
+        m_SecureMode
+            =   NStr::EqualNocase
+            (CTempStringEx(GetSelfURL(), 0, 8), "https://")
+            ||  NStr::EqualNocase
+            (GetRequest().GetRandomProperty("HTTPS", false), "on")
+            ||  NStr::EqualNocase
+            (GetRequest().GetRandomProperty("X_FORWARDED_PROTO"), "https")
             ? eSecure_On : eSecure_Off;
     }
     return m_SecureMode == eSecure_On;
@@ -750,11 +761,11 @@ bool CCgiContext::ProcessCORSRequest(const CCgiRequest& request,
 
     // Is this a preflight CORS request?
     if (method == CCgiRequest::eMethod_OPTIONS) {
-        const string& method = request.GetRandomProperty
+        const string& method_str = request.GetRandomProperty
             (s_HeaderToHttp(kAC_RequestMethod));
         const string& headers = request.GetRandomProperty
             (s_HeaderToHttp(kAC_RequestHeaders));
-        if (!s_IsAllowedMethod(method)  ||  !s_IsAllowedHeaderList(headers)) {
+        if (!s_IsAllowedMethod(method_str)  ||  !s_IsAllowedHeaderList(headers)) {
             // This is CORS request, but the method or headers are not allowed.
             response.DisableTrackingCookie();
             response.SetStatus(CRequestStatus::e403_Forbidden);
diff --git a/c++/src/cgi/fcgi_run.cpp b/c++/src/cgi/fcgi_run.cpp
index 7eeaad3..9597d7f 100644
--- a/c++/src/cgi/fcgi_run.cpp
+++ b/c++/src/cgi/fcgi_run.cpp
@@ -1,4 +1,4 @@
-/*  $Id: fcgi_run.cpp 497377 2016-04-06 13:21:42Z ivanov $
+/*  $Id: fcgi_run.cpp 500790 2016-05-09 11:30:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -652,9 +652,9 @@ bool CCgiApplication::x_RunFastCGI(int* result, unsigned int def_iter)
                                 if(caching_needed)
                                     SaveResultToCache(m_Context->GetRequest(), result_copy);
                                 else {
-                                    unique_ptr<CCgiRequest> request(GetSavedRequest(m_RID));
-                                    if (request.get())
-                                        SaveResultToCache(*request, result_copy);
+                                    unique_ptr<CCgiRequest> saved_request(GetSavedRequest(m_RID));
+                                    if (saved_request.get())
+                                        SaveResultToCache(*saved_request, result_copy);
                                 }
                             } else if (caching_needed) {
                                 SaveRequest(m_RID, m_Context->GetRequest());
diff --git a/c++/src/cgi/ncbicgi.cpp b/c++/src/cgi/ncbicgi.cpp
index bbe0271..8682c3a 100644
--- a/c++/src/cgi/ncbicgi.cpp
+++ b/c++/src/cgi/ncbicgi.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbicgi.cpp 497377 2016-04-06 13:21:42Z ivanov $
+/*  $Id: ncbicgi.cpp 497034 2016-04-04 12:46:26Z dicuccio $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/cgi/ncbicgir.cpp b/c++/src/cgi/ncbicgir.cpp
index f6ce191..d2d6a1a 100644
--- a/c++/src/cgi/ncbicgir.cpp
+++ b/c++/src/cgi/ncbicgir.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbicgir.cpp 492273 2016-02-16 15:26:05Z ivanov $
+/*  $Id: ncbicgir.cpp 506589 2016-07-08 18:45:26Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -220,12 +220,12 @@ void CCgiResponse::x_RestoreOutputExceptions(void)
 }
 
 
-void CCgiResponse::SetOutput(CNcbiOstream* out, int fd)
+void CCgiResponse::SetOutput(CNcbiOstream* output, int fd)
 {
     x_RestoreOutputExceptions();
 
     m_HeaderWritten = false;
-    m_Output        = out;
+    m_Output        = output;
     m_OutputFD      = fd;
 
     // Make the output stream to throw on write if it's in a bad state
@@ -341,8 +341,8 @@ CNcbiOstream& CCgiResponse::WriteHeader(CNcbiOstream& os) const
         self->m_Cookies.Add(*m_TrackingCookie);
         self->SetHeaderValue(TCGI_TrackingTagName::GetDefault(),
             m_TrackingCookie->GetValue());
-        self->SetHeaderValue("NCBI-PHID",
-            GetDiagContext().GetRequestContext().GetHitID());
+        CRequestContext& rctx = GetDiagContext().GetRequestContext();
+        self->SetHeaderValue("NCBI-PHID", rctx.GetNextSubHitID("m_"));
         // Prevent storing the page in public caches.
         string cc = GetHeaderValue(sm_CacheControl);
         if ( cc.empty() ) {
diff --git a/c++/src/cgi/user_agent.cpp b/c++/src/cgi/user_agent.cpp
index f5c4af9..e98b637 100644
--- a/c++/src/cgi/user_agent.cpp
+++ b/c++/src/cgi/user_agent.cpp
@@ -1,4 +1,4 @@
-/*  $Id: user_agent.cpp 485509 2015-11-23 14:51:37Z ivanov $
+/*  $Id: user_agent.cpp 514811 2016-09-26 15:28:21Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -123,6 +123,7 @@ bool CCgiUserAgent::IsBrowser(void) const
         case eiCab:
         case eKonqueror:
         case eLynx:
+        case ePapers:
         case eOregano:
         case eOpera:
         case eW3m:
@@ -512,6 +513,8 @@ const SBrowser s_Browsers[] = {
     { CCgiUserAgent::eCrawler,      "BDFetch",                  "BDFetch",                  CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fAppProduct },
     { CCgiUserAgent::eCrawler,      "BecomeBot",                "www.become.com",           CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fAppComment },
     { CCgiUserAgent::eCrawler,      "Bimbot",                   "Bimbot",                   CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fApp },
+    { CCgiUserAgent::eCrawler,      "Bingbot",                  "www.bing.com",             CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fAny },
+    { CCgiUserAgent::eCrawler,      "BingPreview",              "BingPreview",              CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fVendor },
     { CCgiUserAgent::eCrawler,      "BlitzBOT",                 "B-l-i-t-z-B-O-T",          CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fAny },
     { CCgiUserAgent::eCrawler,      "BlitzBOT",                 "BlitzBot",                 CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fAny },
     { CCgiUserAgent::eCrawler,      "BlitzBOT",                 "BlitzBOT",                 CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fAny },
@@ -577,6 +580,7 @@ const SBrowser s_Browsers[] = {
     { CCgiUserAgent::eCrawler,      "MojeekBot",                "www.mojeek.com",           CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fAppComment },
     { CCgiUserAgent::eCrawler,      "Morning Paper",            "Morning Paper",            CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fAppProduct },
     { CCgiUserAgent::eCrawler,      "MSNBot",                   "msnbot",                   CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fApp },
+    { CCgiUserAgent::eCrawler,      "MSNBot-Media",             "msnbot-media",             CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fApp },
     { CCgiUserAgent::eCrawler,      "MS Sharepoint Portal Server","MS Search",              CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fApp },
     { CCgiUserAgent::eCrawler,      "MSIECrawler",              "MSIECrawler",              CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fAppComment },
     { CCgiUserAgent::eCrawler,      "MSRBOT",                   "MSRBOT",                   CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fAppProduct },
@@ -796,12 +800,15 @@ const SBrowser s_Browsers[] = {
     // Other                                                    
 
     { CCgiUserAgent::eiCab,         "iCab",                     "iCab",                     CCgiUserAgent::eEngine_Unknown, CCgiUserAgent::ePlatform_Unknown,      fApp },
+    { CCgiUserAgent::ePapers,       "Papers",                   "Papers",                   CCgiUserAgent::eEngine_Unknown, CCgiUserAgent::ePlatform_Unknown,      fAppProduct },
     { CCgiUserAgent::eKonqueror,    "Konqueror",                "Konqueror",                CCgiUserAgent::eEngine_Unknown, CCgiUserAgent::ePlatform_Unknown,      fAny },
     { CCgiUserAgent::eLynx,         "Lynx",                     "Lynx",                     CCgiUserAgent::eEngine_Unknown, CCgiUserAgent::ePlatform_Unknown,      fAppProduct },
     { CCgiUserAgent::eLynx,         "ELynx", /* Linx based */   "ELynx",                    CCgiUserAgent::eEngine_Unknown, CCgiUserAgent::ePlatform_Unknown,      fAppProduct },
     { CCgiUserAgent::eOregano,      "Oregano",                  "Oregano2",                 CCgiUserAgent::eEngine_Unknown, CCgiUserAgent::ePlatform_Unknown,      fAppComment },
     { CCgiUserAgent::eOregano,      "Oregano",                  "Oregano",                  CCgiUserAgent::eEngine_Unknown, CCgiUserAgent::ePlatform_Unknown,      fAppComment },
     { CCgiUserAgent::eOpera,        "Opera",                    "Opera",                    CCgiUserAgent::eEngine_Unknown, CCgiUserAgent::ePlatform_Unknown,      fAny },
+    { CCgiUserAgent::eUCBrowser,    "UC Browser",               "UCBrowser",                CCgiUserAgent::eEngine_Unknown, CCgiUserAgent::ePlatform_Unknown,      fVendorProduct },
+    { CCgiUserAgent::eUCBrowser,    "UC Browser",               "UCWEB",                    CCgiUserAgent::eEngine_Unknown, CCgiUserAgent::ePlatform_Unknown,      fApp },
     { CCgiUserAgent::eW3m,          "w3m",                      "w3m",                      CCgiUserAgent::eEngine_Unknown, CCgiUserAgent::ePlatform_Unknown,      fAppProduct },
     { CCgiUserAgent::eNagios,       "check_http (nagios-plugins)","check_http",             CCgiUserAgent::eEngine_Bot,     CCgiUserAgent::ePlatform_Unknown,      fAppProduct }
 
@@ -1166,6 +1173,8 @@ void CCgiUserAgent::x_Parse(const string& user_agent)
             m_UserAgent.find(USTR("NetBSD"))       != NPOS  ||
             m_UserAgent.find(USTR("OpenBSD"))      != NPOS  ||
             m_UserAgent.find(USTR("IRIX"))         != NPOS  ||
+            // ??? could be iOS as well
+            //m_UserAgent.find(USTR("Darwin"))       != NPOS  ||
             m_UserAgent.find(USTR("nagios-plugins")) != NPOS) {
             m_Platform = ePlatform_Unix;
         } else
diff --git a/c++/src/connect/Makefile.connect.lib b/c++/src/connect/Makefile.connect.lib
index f943b2e..c703d3d 100644
--- a/c++/src/connect/Makefile.connect.lib
+++ b/c++/src/connect/Makefile.connect.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.connect.lib 472369 2015-07-09 14:09:43Z elisovdn $
+# $Id: Makefile.connect.lib 503166 2016-06-01 19:40:51Z lavr $
 
 SRC_C    = ncbi_ansi_ext ncbi_buffer ncbi_types ncbi_priv ncbi_core ncbi_util \
            ncbi_socket ncbi_connutil ncbi_connection ncbi_connector           \
@@ -6,7 +6,7 @@ SRC_C    = ncbi_ansi_ext ncbi_buffer ncbi_types ncbi_priv ncbi_core ncbi_util \
            ncbi_memory_connector ncbi_heapmgr ncbi_server_info ncbi_service   \
            ncbi_host_info ncbi_dispd ncbi_service_connector ncbi_sendmail     \
            ncbi_ftp_connector ncbi_lb ncbi_local ncbi_base64 ncbi_version     \
-           ncbi_lbos
+           ncbi_lbos parson
 
 SRC      = $(SRC_C)
 UNIX_SRC = $(LOCAL_LBSM)
@@ -16,6 +16,4 @@ PROJ_TAG = core mod_loadinfo
 
 LIBS     = $(NETWORK_LIBS) $(ORIG_C_LIBS)
 
-USES_LIBRARIES = $(NETWORK_LIBS) $(ORIG_LIBS)
-
 WATCHERS = lavr elisovdn
diff --git a/c++/src/connect/Makefile.connect.lib.unix b/c++/src/connect/Makefile.connect.lib.unix
index 5183a51..add7ef6 100644
--- a/c++/src/connect/Makefile.connect.lib.unix
+++ b/c++/src/connect/Makefile.connect.lib.unix
@@ -1,4 +1,4 @@
-# $Id: Makefile.connect.lib.unix 486618 2015-12-08 03:51:15Z ucko $
+# $Id: Makefile.connect.lib.unix 503212 2016-06-01 21:36:53Z ucko $
 
 # Adjust ICC flags to avoid problematic references to
 # __intel_sse2_str* functions (as of ICC [20]13)
@@ -26,4 +26,5 @@ ifeq "$(COMPILER)-$(DEBUG_SFX)$(DLL)" "icc-Release"
   ncbi_util.o:           CFLAGS += -fno-builtin-strncmp
   ncbi_version.o:        CFLAGS += -fno-builtin-strcpy -fno-builtin-strcspn \
                                    -fno-builtin-strspn
+  parson.o:              CFLAGS += -fno-builtin-strncmp
 endif
diff --git a/c++/src/connect/Makefile.connssl.lib b/c++/src/connect/Makefile.connssl.lib
index 54128cd..1491b41 100644
--- a/c++/src/connect/Makefile.connssl.lib
+++ b/c++/src/connect/Makefile.connssl.lib
@@ -1,12 +1,8 @@
-# $Id: Makefile.connssl.lib 466059 2015-04-28 18:03:44Z lavr $
-
-SRC      = ncbi_gnutls
-LIB      = connssl
+# $Id: Makefile.connssl.lib 503166 2016-06-01 19:40:51Z lavr $
 
 CPPFLAGS = $(GNUTLS_INCLUDE) $(ORIG_CPPFLAGS)
 
-LIBS     = $(GNUTLS_LIBS) $(ORIG_LIBS)
-
-USES_LIBRARIES = $(GCRYPT_LIBS) $(GNUTLS_LIBS) connect
+SRC      = ncbi_gnutls
+LIB      = connssl
 
 WATCHERS = lavr
diff --git a/c++/src/connect/Makefile.xconnect.lib b/c++/src/connect/Makefile.xconnect.lib
index 07f6f97..1d6a440 100644
--- a/c++/src/connect/Makefile.xconnect.lib
+++ b/c++/src/connect/Makefile.xconnect.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.xconnect.lib 472369 2015-07-09 14:09:43Z elisovdn $
+# $Id: Makefile.xconnect.lib 503166 2016-06-01 19:40:51Z lavr $
 #
 # XCONNECT -- includes:
 #    CONNECT API (C-only, sources shared with the C Toolkit), plus
@@ -17,7 +17,3 @@ PROJ_TAG = core
 LIBS = $(NETWORK_LIBS) $(ORIG_LIBS)
 
 WATCHERS = lavr elisovdn
-
-
-USES_LIBRARIES =  \
-    $(NETWORK_LIBS) $(ORIG_LIBS) xncbi
diff --git a/c++/src/connect/Makefile.xthrserv.lib b/c++/src/connect/Makefile.xthrserv.lib
index fb432e8..34524ca 100644
--- a/c++/src/connect/Makefile.xthrserv.lib
+++ b/c++/src/connect/Makefile.xthrserv.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.xthrserv.lib 427428 2014-02-20 13:41:02Z gouriano $
+# $Id: Makefile.xthrserv.lib 503166 2016-06-01 19:40:51Z lavr $
 
 SRC      = threaded_server server server_monitor connection_pool
 LIB      = xthrserv
@@ -7,7 +7,3 @@ LIBS     = $(NETWORK_LIBS)
 DLL_LIB  = xutil xconnect
 
 WATCHERS = vakatov
-
-
-USES_LIBRARIES =  \
-    xconnect xutil
diff --git a/c++/src/connect/Makefile.xxconnect.lib b/c++/src/connect/Makefile.xxconnect.lib
index 372ee84..220ccc3 100644
--- a/c++/src/connect/Makefile.xxconnect.lib
+++ b/c++/src/connect/Makefile.xxconnect.lib
@@ -1,12 +1,15 @@
-# $Id: Makefile.xxconnect.lib 478813 2015-09-14 15:54:56Z elisovdn $
+# $Id: Makefile.xxconnect.lib 503166 2016-06-01 19:40:51Z lavr $
 #
 # XXCONNECT -- includes C++-only part of connection library
 
+CPPFLAGS = $(GNUTLS_INCLUDE) $(ORIG_CPPFLAGS)
+
 SRC_CXX = ncbi_socket_cxx ncbi_core_cxx email_diag_handler \
           ncbi_conn_streambuf ncbi_conn_stream ncbi_conn_test \
           ncbi_misc ncbi_namedpipe ncbi_namedpipe_connector \
           ncbi_pipe ncbi_pipe_connector ncbi_conn_reader_writer \
-          ncbi_userhost ncbi_http_session ncbi_lbos_cxx
+          ncbi_userhost ncbi_http_session ncbi_lbos_cxx ncbi_monkey \
+	      ncbi_gnutls
 
 SRC      = $(SRC_CXX)
 
@@ -16,7 +19,3 @@ PROJ_TAG = core
 LIBS     = $(NETWORK_LIBS) $(ORIG_LIBS)
 
 WATCHERS = lavr elisovdn
-
-
-USES_LIBRARIES =  \
-    $(NCBI_C_ncbi) xncbi
diff --git a/c++/src/connect/connection_pool.cpp b/c++/src/connect/connection_pool.cpp
index cbec6e1..4d1a77a 100644
--- a/c++/src/connect/connection_pool.cpp
+++ b/c++/src/connect/connection_pool.cpp
@@ -1,4 +1,4 @@
-/* $Id: connection_pool.cpp 462064 2015-03-16 14:27:31Z satskyse $
+/* $Id: connection_pool.cpp 506707 2016-07-11 15:26:50Z satskyse $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -56,43 +56,9 @@ std::string g_ServerConnTypeToString(enum EServerConnType  conn_type)
 }
 
 
-// CServer_ControlConnection
-CStdRequest* CServer_ControlConnection::CreateRequest(
-                                            EServIO_Event event,
-                                            CServer_ConnectionPool& connPool,
-                                            const STimeout* timeout)
-{
-    char buf[4096];
-    Read(buf, sizeof(buf));
-    return NULL;
-}
-
-static void CheckIOStatus(EIO_Status io_status, const char* step)
-{
-    if (io_status != eIO_Success) {
-        NCBI_THROW_FMT(CConnException, eConn,
-                       "Cannot create signaling socket for internal use: " <<
-                       step << ": " << IO_StatusStr(io_status));
-    }
-}
-
 CServer_ConnectionPool::CServer_ConnectionPool(unsigned max_connections) :
-        m_MaxConnections(max_connections)
-{
-    // Create internal signaling connection from m_ControlSocket to
-    // m_ControlSocketForPoll
-    CListeningSocket listener;
-    static const STimeout kTimeout = { 10, 500000 }; // 10.5s // DEBUG
-    CheckIOStatus(listener.Listen(0, 5, fSOCK_BindLocal), "Listen/Bind");
-    CheckIOStatus(m_ControlSocket.Connect("127.0.0.1",
-        listener.GetPort(eNH_HostByteOrder)), "Connect");
-    m_ControlSocket.DisableOSSendDelay();
-    // Set a (modest) timeout to prevent SetConnType from blocking forever
-    // with m_Mutex held, which could deadlock the whole server.
-    CheckIOStatus(m_ControlSocket.SetTimeout(eIO_Write,
-        &kTimeout), "SetTimeout");
-    CheckIOStatus(listener.Accept(m_ControlSocketForPoll), "Accept");
-}
+    m_MaxConnections(max_connections), m_ListeningStarted(false)
+{}
 
 CServer_ConnectionPool::~CServer_ConnectionPool()
 {
@@ -148,6 +114,13 @@ bool CServer_ConnectionPool::Add(TConnBase* conn, EServerConnType type)
         m_Data.insert(conn);
     }}
 
+    if (type == eListener)
+        if (m_ListeningStarted)
+            // That's a new listener which should be activated right away
+            // because the StartListening() had already been called earlier
+            // (e.g. in CServer::Run())
+            conn->Activate();
+
     PingControlConnection();
     return true;
 }
@@ -159,6 +132,50 @@ void CServer_ConnectionPool::Remove(TConnBase* conn)
 }
 
 
+bool CServer_ConnectionPool::RemoveListener(unsigned short  port)
+{
+    bool        found = false;
+
+    {{
+        CMutexGuard     guard(m_Mutex);
+
+        if (std::find(m_ListenerPortsToStop.begin(),
+                      m_ListenerPortsToStop.end(), port) !=
+                                                m_ListenerPortsToStop.end()) {
+            ERR_POST(Warning << "Removing listener on port " << port <<
+                     " which has already been requested for removal");
+            return false;
+        }
+
+        ITERATE (TData, it, m_Data) {
+            TConnBase *         conn_base = *it;
+
+            conn_base->type_lock.Lock();    // To be on the safe side
+            if (conn_base->type == eListener) {
+                CServer_Listener *  listener = dynamic_cast<CServer_Listener *>(
+                                                                    conn_base);
+                if (listener) {
+                    if (listener->GetPort() == port) {
+                        m_ListenerPortsToStop.push_back(port);
+                        conn_base->type_lock.Unlock();
+
+                        found = true;
+                        break;
+                    }
+                }
+            }
+            conn_base->type_lock.Unlock();
+        }
+    }}
+
+    if (found)
+        PingControlConnection();
+    else
+        ERR_POST(Warning << "No listener on port " << port << " found");
+    return found;
+}
+
+
 void CServer_ConnectionPool::SetConnType(TConnBase* conn, EServerConnType type)
 {
     conn->type_lock.Lock();
@@ -184,11 +201,10 @@ void CServer_ConnectionPool::SetConnType(TConnBase* conn, EServerConnType type)
 
 void CServer_ConnectionPool::PingControlConnection(void)
 {
-    CFastMutexGuard guard(m_ControlMutex);
-    EIO_Status status = m_ControlSocket.Write("", 1, NULL, eIO_WritePlain);
+    EIO_Status status = m_ControlTrigger.Set();
     if (status != eIO_Success) {
         ERR_POST_X(4, Warning
-                   << "PingControlConnection: failed to write to control socket: "
+                   << "PingControlConnection: failed to set control trigger: "
                    << IO_StatusStr(status));
     }
 }
@@ -228,15 +244,16 @@ bool CServer_ConnectionPool::GetPollAndTimerVec(
     to_close_conns.clear();
     to_delete_conns.clear();
 
-    CMutexGuard guard(m_Mutex);
-    // Control socket goes here as well
-    polls.reserve(m_Data.size()+1);
-    polls.push_back(CSocketAPI::SPoll(
-                    dynamic_cast<CPollable*>(&m_ControlSocketForPoll), eIO_Read));
-    CTime current_time(CTime::eEmpty);
-    const CTime* alarm_time = NULL;
-    const CTime* min_alarm_time = NULL;
-    bool alarm_time_defined = false;
+    const CTime *   alarm_time = NULL;
+    const CTime *   min_alarm_time = NULL;
+    bool            alarm_time_defined = false;
+    CTime           current_time(CTime::eEmpty);
+
+    CMutexGuard     guard(m_Mutex);
+
+    // Control trigger goes here as well
+    polls.push_back(CSocketAPI::SPoll(&m_ControlTrigger, eIO_Read));
+
     ERASE_ITERATE(TData, it, m_Data) {
         // Check that socket is not processing packet - safeguards against
         // out-of-order packet processing by effectively pulling socket from
@@ -246,6 +263,28 @@ bool CServer_ConnectionPool::GetPollAndTimerVec(
         TConnBase* conn_base = *it;
         conn_base->type_lock.Lock();
         EServerConnType conn_type = conn_base->type;
+
+        // There might be a request to delete a listener
+        if (conn_type == eListener) {
+            CServer_Listener *  listener = dynamic_cast<CServer_Listener *>(
+                                                                    conn_base);
+            if (listener) {
+                unsigned short  port = listener->GetPort();
+
+                vector<unsigned short>::iterator    port_it = 
+                        std::find(m_ListenerPortsToStop.begin(),
+                                  m_ListenerPortsToStop.end(), port);
+                if (port_it != m_ListenerPortsToStop.end()) {
+                    conn_base->type_lock.Unlock();
+                    m_ListenerPortsToStop.erase(port_it);
+                    delete conn_base;
+                    m_Data.erase(it);
+                    continue;
+                }
+            }
+        }
+
+
         if (conn_type == eClosedSocket
             ||  (conn_type == eInactiveSocket  &&  !conn_base->IsOpen()))
         {
@@ -322,11 +361,15 @@ bool CServer_ConnectionPool::GetPollAndTimerVec(
 void CServer_ConnectionPool::SetAllActive(const vector<CSocketAPI::SPoll>& polls)
 {
     ITERATE(vector<CSocketAPI::SPoll>, it, polls) {
-        if (!it->m_REvent) continue;
+        if (!it->m_REvent)
+            continue;
+
+        CTrigger *      trigger = dynamic_cast<CTrigger *>(it->m_Pollable);
+        if (trigger)
+            continue;
+
         IServer_ConnectionBase* conn_base =
                         dynamic_cast<IServer_ConnectionBase*>(it->m_Pollable);
-        if (conn_base == &m_ControlSocketForPoll)
-            continue;
 
         conn_base->type_lock.Lock();
         if (conn_base->type == eInactiveSocket)
@@ -356,6 +399,7 @@ void CServer_ConnectionPool::StartListening(void)
     ITERATE (TData, it, m_Data) {
         (*it)->Activate();
     }
+    m_ListeningStarted = true;
 }
 
 
@@ -367,4 +411,32 @@ void CServer_ConnectionPool::StopListening(void)
     }
 }
 
+
+vector<unsigned short>  CServer_ConnectionPool::GetListenerPorts(void)
+{
+    vector<unsigned short>      ports;
+
+    CMutexGuard guard(m_Mutex);
+    ITERATE (TData, it, m_Data) {
+        TConnBase *         conn_base = *it;
+
+        conn_base->type_lock.Lock();    // To be on the safe side
+        if (conn_base->type == eListener) {
+            CServer_Listener *  listener = dynamic_cast<CServer_Listener *>(
+                                                                    conn_base);
+            if (listener) {
+                unsigned short  port = listener->GetPort();
+
+                if (std::find(m_ListenerPortsToStop.begin(),
+                              m_ListenerPortsToStop.end(), port) ==
+                                                m_ListenerPortsToStop.end())
+                    ports.push_back(listener->GetPort());
+            }
+        }
+        conn_base->type_lock.Unlock();
+    }
+
+    return ports;
+}
+
 END_NCBI_SCOPE
diff --git a/c++/src/connect/connection_pool.hpp b/c++/src/connect/connection_pool.hpp
index cba97cd..a320046 100644
--- a/c++/src/connect/connection_pool.hpp
+++ b/c++/src/connect/connection_pool.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT___CONNECTION_POOL__HPP
 #define CONNECT___CONNECTION_POOL__HPP
 
-/* $Id: connection_pool.hpp 354749 2012-02-29 17:24:19Z ivanovp $
+/* $Id: connection_pool.hpp 506707 2016-07-11 15:26:50Z satskyse $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -46,16 +46,6 @@
 BEGIN_NCBI_SCOPE
 
 
-class CServer_ControlConnection : public CSocket,
-                                  public IServer_ConnectionBase
-{
-public:
-    virtual CStdRequest* CreateRequest(EServIO_Event event,
-                                       CServer_ConnectionPool& connPool,
-                                       const STimeout* timeout);
-};
-
-
 class CServer_ConnectionPool
 {
 public:
@@ -72,6 +62,7 @@ public:
 
     bool Add(TConnBase* conn, EServerConnType type);
     void Remove(TConnBase* conn);
+    bool RemoveListener(unsigned short  port);
     void PingControlConnection(void);
 
     /// Guard connection from out-of-order packet processing by
@@ -97,18 +88,30 @@ public:
     void StartListening(void);
     void StopListening(void);
 
+    /// Provides a list of ports on which the server is listening
+    /// @return
+    ///  currently listened ports
+    vector<unsigned short>  GetListenerPorts(void);
+
 private:
     void x_UpdateExpiration(TConnBase* conn);
 
 
     typedef set<TConnBase*> TData;
 
-    TData           m_Data;
-    mutable CMutex  m_Mutex;
-    unsigned int    m_MaxConnections;
-    CSocket         m_ControlSocket;
-    mutable CServer_ControlConnection m_ControlSocketForPoll;
-    CFastMutex      m_ControlMutex;
+    TData               m_Data;
+    mutable CMutex      m_Mutex;
+    unsigned int        m_MaxConnections;
+    mutable CTrigger    m_ControlTrigger;
+
+private:
+    // A list of ports on which the listeners should be stopped.
+    // A storage for the ports is needed because the listener deletion could
+    // not be done synchronously - the listener needs to be taken out of a poll
+    // vector.
+    // The access to the container is protected with m_Mutex
+    vector<unsigned short>  m_ListenerPortsToStop;
+    bool                    m_ListeningStarted;
 };
 
 
diff --git a/c++/src/connect/ncbi_buffer.c b/c++/src/connect/ncbi_buffer.c
index 4c7161d..eaa6b74 100644
--- a/c++/src/connect/ncbi_buffer.c
+++ b/c++/src/connect/ncbi_buffer.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_buffer.c 471594 2015-06-29 17:51:13Z lavr $
+/* $Id: ncbi_buffer.c 494167 2016-03-04 01:39:52Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -89,11 +89,13 @@ extern size_t BUF_Size(BUF buf)
 
     if (!buf)
         return 0;
+    assert(!buf->size == !(buf->list  ||  buf->last));
 
     for (size = 0, chunk = buf->list;  chunk;  chunk = chunk->next) {
         /* NB: no empty chunks allowed within the list */
         assert(chunk->size > chunk->skip);
         size += chunk->size - chunk->skip;
+        assert(chunk != buf->last  ||  !chunk->next);
     }
     assert(size == buf->size);
     return size;
@@ -336,8 +338,11 @@ extern size_t BUF_PeekAtCB(BUF      buf,
     size_t     todo;
     SBufChunk* chunk;
 
-    if (!size  ||  !buf  ||  !buf->size  ||  !buf->list)
+    assert(!buf  ||  !buf->size == !(buf->list  ||  buf->last));
+
+    if (!size  ||  !buf  ||  !buf->size)
         return 0;
+    assert(buf->list  &&  buf->last);
 
     /* special treatment for NULL callback */
     if (!callback) {
@@ -347,26 +352,31 @@ extern size_t BUF_PeekAtCB(BUF      buf,
         return todo < size ? todo : size;
     }
 
-    /* skip "pos" bytes */
-    for (chunk = buf->list;  chunk;  chunk = chunk->next) {
-        size_t avail = chunk->size - chunk->skip;
-        assert(chunk->size > chunk->skip);
-        if (avail > pos)
-            break;
-        pos -= avail;
-    }
+    /* skip "pos" bytes, first fast tracking for last chunk if possible */
+    chunk = buf->last; 
+    assert(chunk->size > chunk->skip /*i.e. chunk->size > 0*/);
+    if (pos + (todo = chunk->size - chunk->skip) < buf->size) {
+        for (chunk = buf->list;  chunk;  chunk = chunk->next) {
+            todo = chunk->size - chunk->skip;
+            assert(chunk->size > chunk->skip /*i.e. chunk->size > 0*/);
+            if (todo > pos)
+                break;
+            pos -= todo;
+        }
+        assert(chunk != buf->last);
+    } else
+        pos -= buf->size - todo;
 
     /* process the peeked data */
     for (todo = size;  todo  &&  chunk;  chunk = chunk->next, pos = 0) {
         size_t skip = chunk->skip + pos;
         size_t copy = chunk->size - skip;
-        assert(chunk->size > skip);
+        assert(chunk->size > skip /*i.e. chunk->size > 0*/);
         if (copy > todo)
             copy = todo;
-
+        assert(copy);
         skip  = callback(cbdata, (const char*) chunk->data + skip, copy);
-        if (skip > copy)
-            skip = copy;
+        assert(skip <= copy);
         todo -= skip;
         if (skip < copy)
             break;
@@ -403,16 +413,19 @@ extern size_t BUF_Read(BUF buf, void* dst, size_t size)
 {
     size_t todo;
 
+    assert(!buf  ||  !buf->size == !(buf->list  ||  buf->last));
+
     /* peek to the callers data buffer, if non-NULL */
     if (dst)
         size = BUF_Peek(buf, dst, size);
-    else if (!buf  ||  !buf->size  ||  !buf->list)
+    else if (!buf  ||  !buf->size)
         return 0;
     if (!size)
         return 0;
 
     /* remove the read data from the buffer */ 
     todo = size;
+
     do {
         SBufChunk* head  = buf->list;
         size_t     avail = head->size - head->skip;
@@ -433,6 +446,7 @@ extern size_t BUF_Read(BUF buf, void* dst, size_t size)
         todo      -= avail;
     } while (todo  &&  buf->list);
 
+    assert(!buf->size == !(buf->list  ||  buf->last));
     assert(size >= todo);
     return size - todo;
 }
diff --git a/c++/src/connect/ncbi_comm.h b/c++/src/connect/ncbi_comm.h
index 2b0bd97..ba4db43 100644
--- a/c++/src/connect/ncbi_comm.h
+++ b/c++/src/connect/ncbi_comm.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_COMM__H
 #define CONNECT___NCBI_COMM__H
 
-/* $Id: ncbi_comm.h 436802 2014-05-30 18:49:16Z lavr $
+/* $Id: ncbi_comm.h 516330 2016-10-12 17:20:46Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -34,22 +34,28 @@
  *
  */
 
-#define NCBID_WEBPATH          "/Service/ncbid.cgi"
-#define NCBI_DISP_VERSION      "1.2"
-#define HTTP_CONNECTION_INFO   "Connection-Info:"
-#define HTTP_DISP_FAILURES     "Dispatcher-Failures:"
-#define HTTP_DISP_MESSAGES     "Dispatcher-Messages:"
-#define HTTP_NCBI_MESSAGE      "NCBI-Message:"
-#define HTTP_NCBI_SID          "NCBI-SID:"
-#define HTTP_NCBI_PHID         "NCBI-PHID:"
-#define LBSM_DEFAULT_TIME      30     /* Default expiration time, in seconds */
-#define LBSM_DEFAULT_RATE      1000.0 /* For SLBSM_Service::info::rate       */
-#define LBSM_STANDBY_THRESHOLD 0.01
-#define DISPATCHER_CFGPATH     "/etc/lbsmd/"
-#define DISPATCHER_CFGFILE     "servrc.cfg"
-#define DISPATCHER_MSGFILE     ".dispd.msg"
-#define CONN_FWD_PORT_MIN      5860
-#define CONN_FWD_PORT_MAX      5870
+#define NCBID_WEBPATH           "/Service/ncbid.cgi"
+#define NCBI_DISP_VERSION       "1.2"
+#define HTTP_CONNECTION_INFO    "Connection-Info:"
+#define HTTP_DISP_FAILURES      "Dispatcher-Failures:"
+#define HTTP_DISP_MESSAGES      "Dispatcher-Messages:"
+#define HTTP_NCBI_MESSAGE       "NCBI-Message:"
+#define HTTP_NCBI_SID           "NCBI-SID:"
+#define HTTP_NCBI_PHID          "NCBI-PHID:"
+#define LBSM_DEFAULT_TIME       30      /* Default expiration time, seconds */
+#define LBSM_DEFAULT_RATE       1000.0  /* For SLBSM_Service::info::rate    */
+#define LBSM_STANDBY_THRESHOLD  0.01
+#define DISPATCHER_CFGPATH      "/etc/lbsmd/"
+#define DISPATCHER_CFGFILE      "servrc.cfg"
+#define DISPATCHER_MSGFILE      ".dispd.msg"
+#define CONN_FWD_PORT_MIN       5860
+#define CONN_FWD_PORT_MAX       5870
+#define CONN_FWD_BASE                                   \
+    "https://www.ncbi.nlm.nih.gov/IEB/ToolBox/NETWORK"
+#define CONN_FWD_LINK           CONN_FWD_BASE "/dispatcher.html#Firewalling"
+#define CONN_FWD_URL            CONN_FWD_BASE "/firewall.html#Settings"
+#define NCBI_EXTERNAL           "NCBI-External"
+
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/c++/src/connect/ncbi_conn_stream.cpp b/c++/src/connect/ncbi_conn_stream.cpp
index 428b6fe..93319bb 100644
--- a/c++/src/connect/ncbi_conn_stream.cpp
+++ b/c++/src/connect/ncbi_conn_stream.cpp
@@ -1,4 +1,4 @@
-/* $Id: ncbi_conn_stream.cpp 500356 2016-05-04 09:48:20Z ivanov $
+/* $Id: ncbi_conn_stream.cpp 507385 2016-07-18 22:38:48Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -186,10 +186,10 @@ EIO_Status CConn_IOStream::SetCanceledCallback(const ICanceled* canceled)
         CONN_SetCallback(conn, eCONN_OnWrite, &cb,      isset ? 0 : &m_CB[2]);
         CONN_SetCallback(conn, eCONN_OnFlush, &cb,      isset ? 0 : &m_CB[3]);
     } else if (isset) {
-        CONN_SetCallback(conn, eCONN_OnFlush, &m_CB[3], 0);
-        CONN_SetCallback(conn, eCONN_OnWrite, &m_CB[2], 0);
-        CONN_SetCallback(conn, eCONN_OnRead,  &m_CB[1], 0);
-        CONN_SetCallback(conn, eCONN_OnOpen,  &m_CB[0], 0);
+        CONN_SetCallback(conn, eCONN_OnFlush, &m_CB[3],         0);
+        CONN_SetCallback(conn, eCONN_OnWrite, &m_CB[2],         0);
+        CONN_SetCallback(conn, eCONN_OnRead,  &m_CB[1],         0);
+        CONN_SetCallback(conn, eCONN_OnOpen,  &m_CB[0],         0);
         m_Canceled = 0;
     }
 
@@ -427,7 +427,7 @@ s_HttpConnectorBuilder(const SConnNetInfo* net_info,
                        const STimeout*     timeout)
 {
     size_t len;
-    AutoPtr<SConnNetInfo, CDeleter<SConnNetInfo> >
+    AutoPtr<SConnNetInfo>
         x_net_info(net_info
                    ? ConnNetInfo_Clone(net_info) : ConnNetInfo_Create(0));
     if (!x_net_info.get()) {
@@ -710,7 +710,7 @@ s_ServiceConnectorBuilder(const char*                           service,
                           FSERVICE_GetNextInfo                  get_next_info,
                           const STimeout*                       timeout)
 {
-    AutoPtr<SConnNetInfo, CDeleter<SConnNetInfo> >
+    AutoPtr<SConnNetInfo>
         x_net_info(net_info ?
                    ConnNetInfo_Clone(net_info) : ConnNetInfo_Create(service));
     if (!x_net_info.get()) {
@@ -1269,7 +1269,7 @@ CConn_IOStream* NcbiOpenURL(const string& url, size_t buf_size)
     }
     bool svc = s_IsIdentifier(url);
 
-    AutoPtr<SConnNetInfo, CDeleter<SConnNetInfo> > net_info
+    AutoPtr<SConnNetInfo> net_info
         (ConnNetInfo_Create(svc ? url.c_str() : 0));
 
     if (svc)
diff --git a/c++/src/connect/ncbi_conn_test.cpp b/c++/src/connect/ncbi_conn_test.cpp
index 6f0131b..df065c7 100644
--- a/c++/src/connect/ncbi_conn_test.cpp
+++ b/c++/src/connect/ncbi_conn_test.cpp
@@ -1,4 +1,4 @@
-/* $Id: ncbi_conn_test.cpp 484889 2015-11-16 21:56:43Z lavr $
+/* $Id: ncbi_conn_test.cpp 516329 2016-10-12 17:20:25Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -47,8 +47,6 @@
 #define HELP_EMAIL    (m_Email.empty()                                  \
                        ? string("NCBI Help Desk info at ncbi.nlm.nih.gov") \
                        : m_Email)
-#define NCBI_FWDOC_URL                                                  \
-    "http://www.ncbi.nlm.nih.gov/IEB/ToolBox/NETWORK/firewall.html#Settings"
 
 #define NCBI_FWD_BEMD  "130.14.29.112"
 #define NCBI_FWD_STVA  "165.112.7.12"
@@ -266,20 +264,28 @@ EIO_Status CConnTest::ExtraCheckOnFailure(void)
     static const STimeout kTimeout   = { 5,      0 };
     static const STimeout kTimeSlice = { 0, 100000 };
     static const struct {
+        EURLScheme scheme;
         const char*  host;
         const char* vhost;
     } kTests[] = {
         // 0. NCBI default
-        { "",                           0                      }, // NCBI
+        { eURL_Http,
+          "",                           0                      }, // NCBI
         // 1. External server(s)
-        { "www.google.com",             0                      },
-        //    NB: Google's public DNS (also @8.8.8.8), responds at :80 as well
-        { "8.8.4.4",                    "www.google.com"       },
+        { eURL_Https,
+          "www.google.com",             0                      },
+        //    NB: Google's public DNS (@8.8.4.4/8.8), responds at :80 as well
+        { eURL_Http,
+          0,                            "www.google.com"       },
         // 2. NCBI servers, explicitly
-        { "www.be-md.ncbi.nlm.nih.gov", "www.ncbi.nlm.nih.gov" }, // NCBI main
-        { "www.st-va.ncbi.nlm.nih.gov", "www.ncbi.nlm.nih.gov" }, // NCBI colo
-        { "130.14.29.110",              "www.ncbi.nlm.nih.gov" }, // NCBI main
-        { "165.112.7.20",               "www.ncbi.nlm.nih.gov" }  // NCBI colo
+        { eURL_Https,
+          "www.be-md.ncbi.nlm.nih.gov", "www.ncbi.nlm.nih.gov" }, // NCBI main
+        { eURL_Https,
+          "www.st-va.ncbi.nlm.nih.gov", "www.ncbi.nlm.nih.gov" }, // NCBI colo
+        { eURL_Https,
+          "130.14.29.110",              "www.ncbi.nlm.nih.gov" }, // NCBI main
+        { eURL_Https,
+          "165.112.7.20",               "www.ncbi.nlm.nih.gov" }  // NCBI colo
     };
 
     m_CheckPoint.clear();
@@ -307,19 +313,26 @@ EIO_Status CConnTest::ExtraCheckOnFailure(void)
     vector< AutoPtr<CConn_HttpStream> > http;
     for (size_t n = 0;  n < sizeof(kTests) / sizeof(kTests[0]);  ++n) {
         char user_header[80];
-        _ASSERT(::strlen(kTests[n].host) < sizeof(net_info->host) - 1);
-        if (kTests[n].host[0])
-            ::strcpy(net_info->host, kTests[n].host);
+        net_info->scheme = kTests[n].scheme;
+        const char* host = kTests[n].host;
+        if (!host)
+            host = rand() & 1 ? "8.8.4.4" : "8.8.8.8";
+        if (*host) {
+            _ASSERT(::strlen(host) < sizeof(net_info->host) - 1);
+            ::strcpy(net_info->host, host);
+        }
         if (kTests[n].vhost) {
             _ASSERT(::strlen(kTests[n].vhost) + 6 < sizeof(user_header) - 1);
             ::sprintf(user_header, "Host: %s", kTests[n].vhost);
         } else
             *user_header = '\0';
         SAuxData* auxdata = new SAuxData(m_Canceled, 0);
-        http.push_back(new CConn_HttpStream(net_info, user_header, s_AnyHeader,
+        http.push_back(new CConn_HttpStream(net_info, 
+                                            user_header, s_AnyHeader,
                                             auxdata, s_Adjust, s_Cleanup));
         http.back()->SetCanceledCallback(m_Canceled);
     }
+    ConnNetInfo_Destroy(net_info);
 
     EIO_Status status = eIO_Success;
     do {
@@ -360,6 +373,7 @@ EIO_Status CConnTest::HttpOkay(string* reason)
 {
     SConnNetInfo* net_info = ConnNetInfo_Create(0, m_DebugPrintout);
     if (net_info) {
+        net_info->scheme = eURL_Https;
         if (net_info->http_proxy_host[0]  &&  net_info->http_proxy_port)
             m_HttpProxy = true;
         // Make sure there are no extras
@@ -368,7 +382,7 @@ EIO_Status CConnTest::HttpOkay(string* reason)
     }
 
     PreCheck(eHttp, 0/*main*/,
-             "Checking whether NCBI is HTTP accessible");
+             "Checking whether NCBI is HTTP(S) accessible");
 
     string host(net_info ? net_info->host : DEF_CONN_HOST);
     string port(net_info  &&  net_info->port
@@ -443,6 +457,8 @@ EIO_Status CConnTest::HttpOkay(string* reason)
                 " appear in your configuration -- NCBI services neither"
                 " require nor use them\n";
         }
+        if (net_info  &&  status == eIO_NotSupported)
+            temp += "Your application may also need to have SSL support on\n";
     }
 
     PostCheck(eHttp, 0/*main*/, status, temp);
@@ -457,7 +473,8 @@ EIO_Status CConnTest::HttpOkay(string* reason)
 EIO_Status CConnTest::DispatcherOkay(string* reason)
 {
     SConnNetInfo* net_info = ConnNetInfo_Create(0, m_DebugPrintout);
-    ConnNetInfo_SetupStandardArgs(net_info, kTest);
+    if (ConnNetInfo_SetupStandardArgs(net_info, kTest))
+        net_info->scheme = eURL_Https;
 
     PreCheck(eDispatcher, 0/*main*/,
              "Checking whether NCBI dispatcher is okay");
@@ -496,6 +513,8 @@ EIO_Status CConnTest::DispatcherOkay(string* reason)
             temp += "Check with your network administrator that your network"
                 " neither filters out nor blocks non-standard HTTP headers\n";
         }
+        if (net_info  &&  status == eIO_NotSupported)
+            temp += "NCBI network dispatcher must be accessed via HTTPS\n";
     }
 
     PostCheck(eDispatcher, 0/*main*/, status, temp);
@@ -653,8 +672,9 @@ EIO_Status CConnTest::x_GetFirewallConfiguration(const SConnNetInfo* net_info)
 EIO_Status CConnTest::GetFWConnections(string* reason)
 {
     SConnNetInfo* net_info = ConnNetInfo_Create(0, m_DebugPrintout);
-    if (net_info) {
+    if (ConnNetInfo_SetupStandardArgs(net_info, 0/*w/o service*/)) {
         const char* user_header;
+        net_info->scheme     = eURL_Https;
         net_info->req_method = eReqMethod_Post;
         if (net_info->firewall) {
             user_header = "NCBI-RELAY: FALSE";
@@ -664,7 +684,6 @@ EIO_Status CConnTest::GetFWConnections(string* reason)
         if (net_info->stateless)
             m_Stateless = true;
         ConnNetInfo_OverrideUserHeader(net_info, user_header);
-        ConnNetInfo_SetupStandardArgs(net_info, 0/*w/o service*/);
     }
 
     string temp(m_Firewall ? "FIREWALL" : "RELAY (legacy)");
@@ -677,7 +696,7 @@ EIO_Status CConnTest::GetFWConnections(string* reason)
             NCBI_FWD_BEMD " and " NCBI_FWD_STVA ".\n"
             "To set that up correctly, please have your network administrator"
             " read the following (if they have not already done so):"
-            " " NCBI_FWDOC_URL "\n";
+            " " CONN_FWD_URL "\n";
     } else {
         temp += "This is an obsolescent mode that requires keeping a wide port"
             " range [4444..4544] (inclusive) open to let through connections"
@@ -1038,7 +1057,7 @@ EIO_Status CConnTest::CheckFWConnections(string* reason)
                     temp += n ? "fallback" : "non-conventional";
                     temp += " ports; please see your network administrator";
                     if (!url) {
-                        temp += " and let them read: " NCBI_FWDOC_URL;
+                        temp += " and let them read: " CONN_FWD_URL;
                         url = true;
                     }
                     temp += '\n';
@@ -1049,7 +1068,7 @@ EIO_Status CConnTest::CheckFWConnections(string* reason)
                     temp += " please see your network administrator";
                     if (!url) {
                         temp += " and have them read the following: "
-                            NCBI_FWDOC_URL;
+                            CONN_FWD_URL;
                         url = true;
                     }
                     temp += '\n';
@@ -1058,7 +1077,7 @@ EIO_Status CConnTest::CheckFWConnections(string* reason)
                         " configuration to use a more narrow"
                         " port range";
                     if (!url) {
-                        temp += " per: " NCBI_FWDOC_URL;
+                        temp += " per: " CONN_FWD_URL;
                         url = true;
                     }
                     temp += '\n';
@@ -1103,7 +1122,7 @@ EIO_Status CConnTest::CheckFWConnections(string* reason)
         }
         if (note  &&  status != eIO_Interrupt) {
             temp += "\nYou may want to read this link for more information: "
-                NCBI_FWDOC_URL;
+                CONN_FWD_URL;
         }
     } else {
         temp = "All " + string(m_Firewall
diff --git a/c++/src/connect/ncbi_connection.c b/c++/src/connect/ncbi_connection.c
index 3c1a31e..a81caf2 100644
--- a/c++/src/connect/ncbi_connection.c
+++ b/c++/src/connect/ncbi_connection.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_connection.c 480536 2015-10-01 15:22:53Z lavr $
+/* $Id: ncbi_connection.c 513293 2016-09-09 11:36:15Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -235,6 +235,7 @@ static EIO_Status x_Flush(CONN conn, const STimeout* timeout)
     if (conn->meta.flush) {
         if (timeout == kDefaultTimeout)
             timeout  = conn->meta.default_timeout;
+        assert(timeout != kDefaultTimeout);
         for (;;) {
             status = conn->meta.flush(conn->meta.c_flush, timeout);
             if (status == eIO_Success)
@@ -288,10 +289,11 @@ static EIO_Status x_ReInit(CONN conn, CONNECTOR connector, int/*bool*/ close)
             /* call current connector's "CLOSE" method */
             if (conn->meta.close) {
                 EIO_Status closed;
-                closed = conn->meta.close(conn->meta.c_close,
-                                          conn->c_timeout == kDefaultTimeout
-                                          ? conn->meta.default_timeout
-                                          : conn->c_timeout);
+                const STimeout* timeout = (conn->c_timeout == kDefaultTimeout
+                                           ? conn->meta.default_timeout
+                                           : conn->c_timeout);
+                assert(timeout != kDefaultTimeout);
+                closed = conn->meta.close(conn->meta.c_close, timeout);
                 if (closed != eIO_Success)
                     status  = closed;
             }
@@ -325,7 +327,7 @@ static EIO_Status x_ReInit(CONN conn, CONNECTOR connector, int/*bool*/ close)
     if (!x_conn  &&  connector) {
         assert(conn->state == eCONN_Unusable);
         /* setup the new connector */
-        if ((status = METACONN_Add(&conn->meta, connector)) != eIO_Success)
+        if ((status = METACONN_Insert(&conn->meta, connector)) != eIO_Success)
             return status;
         assert(conn->meta.list);
         conn->state = eCONN_Closed;
@@ -362,6 +364,7 @@ static EIO_Status s_Open(CONN conn)
             timeout = (conn->o_timeout == kDefaultTimeout
                        ? conn->meta.default_timeout
                        : conn->o_timeout);
+            assert(timeout != kDefaultTimeout);
             status = conn->meta.open(conn->meta.c_open, timeout);
             /* OnTimeout gets called only if OnOpen was there */
             if (status == eIO_Timeout  &&  !nocb) {
@@ -423,6 +426,7 @@ extern EIO_Status CONN_CreateEx
         CONN_LOG(2, Create, eLOG_Error, "NULL connector");
     }
 
+    assert(!conn == (status != eIO_Success));
     CONN_CALLTRACE(Create);
     *connection = conn;
     return status;
@@ -670,8 +674,10 @@ static EIO_Status s_CONN_Write
         timeout = (conn->w_timeout == kDefaultTimeout
                    ? conn->meta.default_timeout
                    : conn->w_timeout);
+        assert(timeout != kDefaultTimeout);
         status = conn->meta.write(conn->meta.c_write, buf, size,
                                   n_written, timeout);
+        assert(status != eIO_Success  ||  *n_written  ||  !size);
         assert(*n_written <= size);
 
         if (*n_written) {
@@ -809,6 +815,7 @@ extern EIO_Status CONN_Flush
             : (conn->w_timeout == kDefaultTimeout
                ? conn->meta.default_timeout
                : conn->w_timeout);
+        assert(timeout != kDefaultTimeout);
         CONN_LOG(21, Flush, eLOG_Warning, "Failed to flush");
     }
     if (conn->meta.flush)
@@ -864,8 +871,10 @@ static EIO_Status s_CONN_Read
         timeout = (conn->r_timeout == kDefaultTimeout
                    ? conn->meta.default_timeout
                    : conn->r_timeout);
+        assert(timeout != kDefaultTimeout);
         status = conn->meta.read(conn->meta.c_read, buf, size - *n_read,
                                  &x_read, timeout);
+        assert(status != eIO_Success  ||  x_read  ||  !size);
         assert(x_read <= size - *n_read);
 
         if (x_read) {
diff --git a/c++/src/connect/ncbi_connector.c b/c++/src/connect/ncbi_connector.c
index 3552838..166fbab 100644
--- a/c++/src/connect/ncbi_connector.c
+++ b/c++/src/connect/ncbi_connector.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_connector.c 362029 2012-05-07 15:36:34Z lavr $
+/* $Id: ncbi_connector.c 513293 2016-09-09 11:36:15Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -36,25 +36,24 @@
 
 #define NCBI_USE_ERRCODE_X   Connect_Conn
 
-/* Standard logging message
- */
-#define METACONN_LOG(subcode, level, message)                   \
-  CORE_LOGF_X(subcode, level,                                   \
-              ("%s (connector \"%s\", error \"%s\")", message,  \
-               meta->get_type                                   \
-               ? meta->get_type(meta->c_get_type)               \
-               : "UNDEF", IO_StatusStr(status)))
+/* Standardized logging message */
+#define METACONN_LOG(subcode, level, message)                       \
+    CORE_LOGF_X(subcode, level,                                     \
+                ("%s (connector \"%s\", error \"%s\")", message,    \
+                 meta->get_type                                     \
+                 ? meta->get_type(meta->c_get_type)                 \
+                 : "UNDEF", IO_StatusStr(status)))
 
 
 extern EIO_Status METACONN_Remove
 (SMetaConnector* meta,
  CONNECTOR       connector)
 {
+    CONNECTOR x_conn;
+
     assert(meta);
 
     if (connector) {
-        CONNECTOR x_conn;
-        
         for (x_conn = meta->list;  x_conn;  x_conn = x_conn->next) {
             if (x_conn == connector)
                 break;
@@ -68,20 +67,21 @@ extern EIO_Status METACONN_Remove
     }
 
     while (meta->list) {
-        CONNECTOR victim = meta->list;
-        meta->list       = victim->next;
-        victim->meta     = 0;
-        victim->next     = 0;
-        if (victim->destroy)
-            victim->destroy(victim);
-        if (victim == connector)
+        x_conn       = meta->list;
+        meta->list   = x_conn->next;
+        x_conn->meta = 0;
+        x_conn->next = 0;
+        if (x_conn->destroy)
+            x_conn->destroy(x_conn);
+        if (x_conn == connector)
             break;
     }
+
     return eIO_Success;
 }
 
 
-extern EIO_Status METACONN_Add
+extern EIO_Status METACONN_Insert
 (SMetaConnector* meta,
  CONNECTOR       connector)
 {
@@ -90,7 +90,7 @@ extern EIO_Status METACONN_Add
     if (connector->next  ||  !connector->setup) {
         EIO_Status status = eIO_Unknown;
         METACONN_LOG(33, eLOG_Error,
-                     "[METACONN_Add]  Connector is in use/uninitable");
+                     "[METACONN_Insert]  Connector is in use/uninitable");
         return status;
     }
 
@@ -98,5 +98,6 @@ extern EIO_Status METACONN_Add
     connector->setup(connector);
     connector->next = meta->list;
     meta->list = connector;
+
     return eIO_Success;
 }
diff --git a/c++/src/connect/ncbi_connutil.c b/c++/src/connect/ncbi_connutil.c
index 17875b1..e0f3516 100644
--- a/c++/src/connect/ncbi_connutil.c
+++ b/c++/src/connect/ncbi_connutil.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_connutil.c 488578 2016-01-01 00:35:35Z lavr $
+/* $Id: ncbi_connutil.c 513930 2016-09-16 15:08:47Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -43,6 +43,8 @@
 #define NCBI_USE_ERRCODE_X   Connect_Util
 
 
+#define CONN_NET_INFO_MAGIC  0x600DF00D
+
 #define SizeOf(arr)  (sizeof(arr) / sizeof((arr)[0]))
 
 
@@ -283,6 +285,13 @@ static EFWMode x_ParseFirewall(const char* str, int/*bool*/ generic)
 }
 
 
+static int/*bool*/ s_InfoIsValid(const SConnNetInfo* info)
+{
+    assert(info->magic == CONN_NET_INFO_MAGIC);
+    return info->magic == CONN_NET_INFO_MAGIC ? 1/*true*/ : 0/*false*/;
+}
+
+
 /****************************************************************************
  * ConnNetInfo API
  */
@@ -304,11 +313,14 @@ extern SConnNetInfo* ConnNetInfo_Create(const char* service)
 
     len = service ? strlen(service) : 0;
 
-    /* NB: *NOT* cleared up with all 0s */
+    /* NB: created *NOT* cleared up with all 0s */
     if (!(info = (SConnNetInfo*) malloc(sizeof(*info) + len)))
         return 0/*failure*/;
     info->reserved = 0/*MBZ*/;
 
+    /* store the service name, which this structure has been created for */
+    memcpy((char*) info->svc, service ? service : "", ++len);
+
     /* client host: default */
     info->client_host[0] = '\0';
 
@@ -328,6 +340,10 @@ extern SConnNetInfo* ConnNetInfo_Create(const char* service)
     /* compatibility */
     info->version = 0;
 
+    /* external mode */
+    REG_VALUE(REG_CONN_EXTERNAL, str, DEF_CONN_EXTERNAL);
+    info->external = ConnNetInfo_Boolean(str);
+    
     /* firewall mode */
     REG_VALUE(REG_CONN_FIREWALL, str, DEF_CONN_FIREWALL);
     info->firewall = x_ParseFirewall(str, generic);
@@ -437,8 +453,8 @@ extern SConnNetInfo* ConnNetInfo_Create(const char* service)
     /* credentials */
     info->credentials = 0;
 
-    /* store the service name, which this structure has been created for */
-    strcpy((char*) info->svc, service ? service : "");
+    /* magic */
+    info->magic = CONN_NET_INFO_MAGIC;
 
     /* done */
     return info;
@@ -451,14 +467,15 @@ extern int/*bool*/ ConnNetInfo_ParseURL(SConnNetInfo* info, const char* url)
     /* URL elements and their parsed lengths as passed */
     const char *user,   *pass,   *host,   *path,   *args;
     size_t     userlen, passlen, hostlen, pathlen, argslen;
-    unsigned short port;
     EURLScheme scheme;
     const char* s;
     size_t len;
+    long port;
     char* p;
 
-    if (!url)
+    if (!s_InfoIsValid(info)  ||  !url)
         return 0/*failure*/;
+
     if (!*url)
         return 1/*success*/;
 
@@ -470,12 +487,13 @@ extern int/*bool*/ ConnNetInfo_ParseURL(SConnNetInfo* info, const char* url)
         if (len >= sizeof(info->host))
             return 0/*failure*/;
         if (s) {
-            long i;
             errno = 0;
-            i = strtol(++s, &p, 10);
-            if (errno  ||  s == p  ||  !i  ||  i ^ (i & 0xFFFF)  ||  *p)
+            port = strtol(++s, &p, 10);
+            if (errno  ||  s == p  ||  *p)
+                return 0/*failure*/;
+            if (!port  ||  port ^ (port & 0xFFFF))
                 return 0/*failure*/;
-            info->port = (unsigned short) i;
+            info->port = port;
         }
         if (len) {
             memcpy(info->host, url, len);
@@ -484,9 +502,10 @@ extern int/*bool*/ ConnNetInfo_ParseURL(SConnNetInfo* info, const char* url)
         return 1/*success*/;
     }
 
-    /* "user:pass at host:port" first [any optional] */
+    port = -1/*unassigned*/;
+
+    /* "scheme://user:pass@host:port" first [any optional] */
     if ((s = strstr(url, "//")) != 0) {
-        /* scheme is now optional, too */
         if (s > url) {
             if (s[-1] != ':')
                 return 0/*failure*/;
@@ -501,11 +520,8 @@ extern int/*bool*/ ConnNetInfo_ParseURL(SConnNetInfo* info, const char* url)
 
         /* username:password */
         if (!hostlen) {
-            if (scheme != eURL_File)
-                return 0/*failure*/;
-            user = pass = host = "";
+            user    = pass    = host = scheme == eURL_File ? "" : 0;
             userlen = passlen = 0;
-            port = 0/*none*/;
         } else {
             if (!(s = (const char*) memrchr(host, '@', hostlen))) {
                 user    = pass    = "";
@@ -515,6 +531,8 @@ extern int/*bool*/ ConnNetInfo_ParseURL(SConnNetInfo* info, const char* url)
                 userlen = (size_t)(s - user);
                 host    = ++s;
                 hostlen = (size_t)(path - s);
+                if (!hostlen)
+                    return 0/*failure*/;
                 if (!(s = (const char*) memchr(user, ':', userlen))) {
                     pass    = "";
                     passlen = 0;
@@ -527,13 +545,14 @@ extern int/*bool*/ ConnNetInfo_ParseURL(SConnNetInfo* info, const char* url)
 
             /* port, if any */
             if ((s = (const char*) memchr(host, ':', hostlen)) != 0) {
-                long i;
-                hostlen = (size_t)(s - host);
+                if (!(hostlen = (size_t)(s - host)))
+                    return 0/*failure*/;
                 errno = 0;
-                i = strtol(++s, &p, 10);
-                if (errno  ||  s == p  || !i || i ^ (i & 0xFFFF) ||  p != path)
+                port = strtol(++s, &p, 10);
+                if (errno  ||  s == p  ||  p != path)
+                    return 0/*failure*/;
+                if (!port  ||  port ^ (port & 0xFFFF))
                     return 0/*failure*/;
-                port = (unsigned short) i;
             } else
                 port = 0/*default*/;
 
@@ -548,7 +567,6 @@ extern int/*bool*/ ConnNetInfo_ParseURL(SConnNetInfo* info, const char* url)
         user    = pass    = host    = 0;
         userlen = passlen = hostlen = 0;
         path    = url;
-        port    = 0;
     }
 
     pathlen = (scheme == eURL_Https  ||  scheme == eURL_Http
@@ -625,10 +643,11 @@ extern int/*bool*/ ConnNetInfo_ParseURL(SConnNetInfo* info, const char* url)
         memcpy(info->pass, pass, passlen);
         info->pass[passlen] = '\0';
     }
+    if (port >= 0  ||  scheme == eURL_File)
+        info->port = port < 0 ? 0 : port;
     if (host) {
         memcpy(info->host, host, hostlen);
         info->host[hostlen] = '\0';
-        info->port = port;
     }
     info->scheme = scheme;
     return 1/*success*/;
@@ -638,6 +657,9 @@ extern int/*bool*/ ConnNetInfo_ParseURL(SConnNetInfo* info, const char* url)
 extern int/*bool*/ ConnNetInfo_SetUserHeader(SConnNetInfo* info,
                                              const char*   user_header)
 {
+    if (!s_InfoIsValid(info))
+        return 0/*failure*/;
+
     if (info->http_user_header)
         free((void*) info->http_user_header);
     if (!user_header  ||  !*user_header)
@@ -653,6 +675,9 @@ extern int/*bool*/ ConnNetInfo_AppendUserHeader(SConnNetInfo* info,
 {
     char* new_header;
 
+    if (!s_InfoIsValid(info))
+        return 0/*failure*/;
+
     if (!info->http_user_header  ||  !*info->http_user_header)
         return ConnNetInfo_SetUserHeader(info, user_header);
 
@@ -712,6 +737,9 @@ static int/*bool*/ s_ModifyUserHeader(SConnNetInfo*      info,
     size_t hdrlen;
     char*  hdr;
 
+    if (!s_InfoIsValid(info))
+        return 0/*failure*/;
+
     if (!user_header || !(newhdrlen = strlen(user_header)))
         return 1/*success*/;
 
@@ -899,7 +927,10 @@ extern int/*bool*/ ConnNetInfo_AppendArg(SConnNetInfo* info,
 {
     size_t len, used;
 
-    if (!arg || !*arg)
+    if (!s_InfoIsValid(info))
+        return 0/*failure*/;
+
+    if (!arg  ||  !*arg)
         return 1/*success*/;
 
     used = strlen(info->args);
@@ -913,7 +944,7 @@ extern int/*bool*/ ConnNetInfo_AppendArg(SConnNetInfo* info,
     if (used)
         info->args[used++] = '&';
     strcpy(info->args + used, arg);
-    if (val && *val) {
+    if (val  &&  *val) {
         used += len;
         info->args[used++] = '=';
         strcpy(info->args + used, val);
@@ -928,7 +959,10 @@ extern int/*bool*/ ConnNetInfo_PrependArg(SConnNetInfo* info,
 {
     size_t len, off, used;
 
-    if (!arg || !*arg)
+    if (!s_InfoIsValid(info))
+        return 0/*failure*/;
+
+    if (!arg  ||  !*arg)
         return 1/*success*/;
 
     used = strlen(info->args);
@@ -959,8 +993,9 @@ extern int/*bool*/ ConnNetInfo_DeleteArg(SConnNetInfo* info,
     size_t arglen;
     char*  a;
 
-    if (!arg || !(argnamelen = strcspn(arg, "=&")))
+    if (!s_InfoIsValid(info)  ||  !arg  ||  !(argnamelen = strcspn(arg, "=&")))
         return 0/*false*/;
+    
     deleted = 0/*false*/;
     for (a = info->args; *a; a += arglen) {
         if (*a == '&')
@@ -989,8 +1024,9 @@ extern int/*bool*/ ConnNetInfo_DeleteArg(SConnNetInfo* info,
 extern void ConnNetInfo_DeleteAllArgs(SConnNetInfo* info,
                                       const char*   args)
 {
-    if (!args)
+    if (!s_InfoIsValid(info)  ||  !args)
         return;
+
     while (*args) {
         const char* a = strchr(args, '&');
         if (!a)
@@ -1007,8 +1043,12 @@ extern int/*bool*/ ConnNetInfo_PreOverrideArg(SConnNetInfo* info,
                                               const char*   arg,
                                               const char*   val)
 {
-    if (!arg || !*arg)
+    if (!s_InfoIsValid(info))
+        return 0/*failure*/;
+
+    if (!arg  ||  !*arg)
         return 1/*success*/;
+
     ConnNetInfo_DeleteAllArgs(info, arg);
     return ConnNetInfo_PrependArg(info, arg, val);
 }
@@ -1018,8 +1058,12 @@ extern int/*bool*/ ConnNetInfo_PostOverrideArg(SConnNetInfo* info,
                                                const char*   arg,
                                                const char*   val)
 {
-    if (!arg || !*arg)
+    if (!s_InfoIsValid(info))
+        return 0/*failure*/;
+
+    if (!arg  ||  !*arg)
         return 1/*success*/;
+
     ConnNetInfo_DeleteAllArgs(info, arg);
     return ConnNetInfo_AppendArg(info, arg, val);
 }
@@ -1060,8 +1104,7 @@ static const char* x_ClientAddress(const char* client_host,
     sprintf(s, "%s(%s)", client_host, addr);
     if (client_host != c)
         free((void*) client_host);
-    client_host = s;
-    for (;  *s;  ++s) {
+    for (client_host = s;  *s;  ++s) {
         if (*s == ' ')
             *s  = '+';
     }
@@ -1078,7 +1121,7 @@ extern int/*bool*/ ConnNetInfo_SetupStandardArgs(SConnNetInfo* info,
     int/*bool*/ local_host;
     const char* s;
 
-    if (!info)
+    if (!info  ||  !s_InfoIsValid(info))
         return 0/*failed*/;
 
     s = CORE_GetAppName();
@@ -1122,20 +1165,39 @@ extern SConnNetInfo* ConnNetInfo_Clone(const SConnNetInfo* info)
 {
     SConnNetInfo* x_info;
 
-    if (!info)
+    if (!info  ||  !s_InfoIsValid(info))
         return 0;
 
     if (!(x_info = (SConnNetInfo*) malloc(sizeof(*info) + strlen(info->svc))))
         return 0;
 
-    memcpy(x_info, info, sizeof(*x_info));
-    x_info->http_user_header = 0;
-    x_info->http_referer = 0;
+    strcpy(x_info->client_host,     info->client_host);
+    x_info->scheme                = info->scheme;
+    x_info->req_method            = info->req_method;
+    x_info->version               = info->version;
+    x_info->external              = info->external;
+    x_info->firewall              = info->firewall;
+    x_info->stateless             = info->stateless;
+    x_info->lb_disable            = info->lb_disable;
+    x_info->debug_printout        = info->debug_printout;
+    x_info->http_push_auth        = info->http_push_auth;
+    x_info->http_proxy_leak       = info->http_proxy_leak;
+    x_info->reserved              = info->reserved;
+    strcpy(x_info->user,            info->user);
+    strcpy(x_info->pass,            info->pass);
+    strcpy(x_info->host,            info->host);
+    x_info->port                  = info->port;
+    strcpy(x_info->path,            info->path);
+    strcpy(x_info->args,            info->args);
+    strcpy(x_info->http_proxy_host, info->http_proxy_host);
+    x_info->http_proxy_port       = info->http_proxy_port;
+    strcpy(x_info->http_proxy_user, info->http_proxy_user);
+    strcpy(x_info->http_proxy_pass, info->http_proxy_pass);
+    x_info->max_try               = info->max_try;
+    x_info->http_user_header      = 0;
+    x_info->http_referer          = 0;
+    x_info->credentials           = info->credentials;
 
-    if (info->timeout) {
-        x_info->tmo     = *info->timeout;
-        x_info->timeout = &x_info->tmo;
-    }
     if (info->http_user_header  &&  *info->http_user_header
         &&  !(x_info->http_user_header = strdup(info->http_user_header))) {
         ConnNetInfo_Destroy(x_info);
@@ -1146,11 +1208,24 @@ extern SConnNetInfo* ConnNetInfo_Clone(const SConnNetInfo* info)
         ConnNetInfo_Destroy(x_info);
         return 0;
     }
-    strcpy((char*) x_info->svc, info->svc);
+
+    x_info->tmo                   = info->timeout ? *info->timeout : info->tmo;
+    x_info->timeout               = info->timeout ? &x_info->tmo   : 0;
+    strcpy((char*) x_info->svc,     info->svc);
+
+    x_info->magic                 = CONN_NET_INFO_MAGIC;
     return x_info;
 }
 
 
+static const char* x_BadMagic(unsigned int magic, char buf[])
+{
+    sprintf(buf, "0x%08lX (INVALID != 0x%08lX)",
+            (unsigned long) magic, (unsigned long) CONN_NET_INFO_MAGIC);
+    return buf;
+}
+
+
 static const char* x_Port(unsigned short port, char buf[])
 {
     assert(port);
@@ -1273,6 +1348,7 @@ static void s_SaveUserHeader(char* s, const char* name,
         memcpy(s, "NULL\n", 6);
 }
 
+
 extern void ConnNetInfo_Log(const SConnNetInfo* info, ELOG_Level sev, LOG lg)
 {
     char   buf[80];
@@ -1282,7 +1358,7 @@ extern void ConnNetInfo_Log(const SConnNetInfo* info, ELOG_Level sev, LOG lg)
 
     if (!info) {
         LOG_Write(lg, NCBI_C_ERRCODE_X, 10, sev, 0, 0, 0, 0,
-                  "ConnNetInfo_Log: NULL info", 0, 0);
+                  "ConnNetInfo_Log: NULL", 0, 0);
         return;
     }
 
@@ -1302,6 +1378,8 @@ extern void ConnNetInfo_Log(const SConnNetInfo* info, ELOG_Level sev, LOG lg)
 
     strcpy(s, "ConnNetInfo_Log\n"
            "#################### [BEGIN] SConnNetInfo:\n");
+    if (!s_InfoIsValid(info))
+        s_SaveKeyval(s, "magic",           x_BadMagic(info->magic, buf));
     if (*info->svc)
         s_SaveString(s, "service",         info->svc);
     else
@@ -1357,6 +1435,7 @@ extern void ConnNetInfo_Log(const SConnNetInfo* info, ELOG_Level sev, LOG lg)
         s_SaveULong (s, "timeout(usec)",   info->timeout->usec);
     } else
         s_SaveKeyval(s, "timeout",         "INFINITE");
+    s_SaveBool      (s, "external",        info->external);
     s_SaveKeyval    (s, "firewall",        x_Firewall(info->firewall));
     s_SaveBool      (s, "stateless",       info->stateless);
     s_SaveBool      (s, "lb_disable",      info->lb_disable);
@@ -1394,7 +1473,7 @@ extern char* ConnNetInfo_URL(const SConnNetInfo* info)
     char*       url;
     char        buf[40];
 
-    if (!info)
+    if (!info  ||  !s_InfoIsValid(info))
         return 0/*failed*/;
 
     req_method = info->req_method & ~eReqMethod_v1;
@@ -1440,7 +1519,7 @@ extern char* ConnNetInfo_URL(const SConnNetInfo* info)
 extern int/*bool*/ ConnNetInfo_SetTimeout(SConnNetInfo*   info,
                                           const STimeout* timeout)
 {
-    if (!info  ||  timeout == kDefaultTimeout)
+    if (!s_InfoIsValid(info)  ||  timeout == kDefaultTimeout)
         return 0/*failed*/;
     if (timeout) {
         info->tmo     = *timeout;
@@ -1551,8 +1630,8 @@ extern EIO_Status URL_ConnectEx
     /* select request method and its verbal representation */
     if (x_req_meth == eReqMethod_Any)
         x_req_meth  = content_length ? eReqMethod_Post : eReqMethod_Get;
-    else if (content_length  &&  (x_req_meth == eReqMethod_Get   ||
-                                  x_req_meth == eReqMethod_Head)) {
+    else if (content_length  &&  (x_req_meth == eReqMethod_Head  ||
+                                  x_req_meth == eReqMethod_Get)) {
         CORE_LOGF_X(3, eLOG_Warning,
                     ("[URL_Connect; http%s://%s:%hu%s%s] "
                      " Content-Length (%lu) is ignored with request method %s",
diff --git a/c++/src/connect/ncbi_core.c b/c++/src/connect/ncbi_core.c
index 05697a5..a530101 100644
--- a/c++/src/connect/ncbi_core.c
+++ b/c++/src/connect/ncbi_core.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_core.c 491622 2016-02-08 14:51:50Z ivanov $
+/* $Id: ncbi_core.c 507875 2016-07-21 21:24:44Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -96,7 +96,7 @@ struct MT_LOCK_tag {
   FMT_LOCK_Cleanup cleanup;      /* cleanup function */
   unsigned int     magic_number; /* used internally to make sure it's init'd */
 };
-#define kMT_LOCK_magic_number 0x7A96283F
+#define kMT_LOCK_magic_number  0x7A96283F
 
 
 #ifndef NCBI_NO_THREADS
@@ -132,7 +132,7 @@ static int/*bool*/ s_CORE_MT_Lock_default_handler(void*    unused,
         InitializeCriticalSection(&sx_Crit);
         sx_Inited = 1; /*go*/
     } else while (!sx_Inited)
-        Sleep(10/*ms*/); /*spin*/
+        Sleep(1/*ms*/); /*spin*/
 
     switch (action) {
     case eMT_Lock:
@@ -255,7 +255,7 @@ struct LOG_tag {
     MT_LOCK      mt_lock;
     unsigned int magic_number;  /* used internally, to make sure it's init'd */
 };
-#define kLOG_magic_number 0x3FB97156
+#define kLOG_magic_number  0x3FB97156
 
 
 extern const char* LOG_LevelStr(ELOG_Level level)
@@ -445,7 +445,7 @@ struct REG_tag {
     MT_LOCK      mt_lock;
     unsigned int magic_number;  /* used internally, to make sure it's init'd */
 };
-#define kREG_magic_number 0xA921BC08
+#define kREG_magic_number  0xA921BC08
 
 
 extern REG REG_Create
diff --git a/c++/src/connect/ncbi_core_cxx.cpp b/c++/src/connect/ncbi_core_cxx.cpp
index 0022b90..bb1cb32 100644
--- a/c++/src/connect/ncbi_core_cxx.cpp
+++ b/c++/src/connect/ncbi_core_cxx.cpp
@@ -1,4 +1,4 @@
-/* $Id: ncbi_core_cxx.cpp 488838 2016-01-06 13:45:11Z elisovdn $
+/* $Id: ncbi_core_cxx.cpp 507875 2016-07-21 21:24:44Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -34,12 +34,14 @@
  */
 
 #include <ncbi_pch.hpp>
-#include "ncbi_ansi_ext.h"
-#include "ncbi_priv.h"
 #include <corelib/ncbiapp.hpp>
 #include <corelib/request_ctx.hpp>
 #include <connect/error_codes.hpp>
 #include <connect/ncbi_core_cxx.hpp>
+#include <connect/ncbi_gnutls.h>
+#include <connect/ncbi_monkey.hpp>
+#include "ncbi_ansi_ext.h"
+#include "ncbi_priv.h"
 #include <stdlib.h>
 
 #define NCBI_USE_ERRCODE_X   Connect_Core
@@ -48,6 +50,9 @@
 BEGIN_NCBI_SCOPE
 
 
+static TCORE_Set s_CORE_Set = 0;
+
+
 /***********************************************************************
  *                              Registry                               *
  ***********************************************************************/
@@ -150,8 +155,9 @@ static void s_LOG_Handler(void*       /*user_data*/,
             level = eDiag_Fatal;
             break;
         }
-        if (!IsVisibleDiagPostLevel(level))
+        if (!IsVisibleDiagPostLevel(level)) {
             return;
+        }
 
         CDiagCompileInfo info(call_data->file,
                               call_data->line,
@@ -245,20 +251,6 @@ extern MT_LOCK MT_LOCK_cxx2c(CRWLock* lock, bool pass_ownership)
 
 
 /***********************************************************************
- *                                 Fini                                *
- ***********************************************************************/
-
-extern "C" {
-static void s_Fini(void) THROWS_NONE
-{
-    CORE_SetREG(0);
-    CORE_SetLOG(0);
-    CORE_SetLOCK(0);
-}
-}
-
-
-/***********************************************************************
  *                               App Name                              *
  ***********************************************************************/
 extern "C" {
@@ -311,67 +303,182 @@ static const char* s_GetRequestDTab(void)
 
 
 /***********************************************************************
- *                                 Init                                *
+ *                         CRAZY MONKEY CALLS                          *
  ***********************************************************************/
 
-DEFINE_STATIC_FAST_MUTEX(s_ConnectInitMutex);
+#ifdef NCBI_MONKEY
+extern "C" {
+    static MONKEY_RETTYPE 
+        MONKEY_STDCALL s_MonkeySend(MONKEY_SOCKTYPE        sock,
+                                    const MONKEY_DATATYPE  data,
+                                    MONKEY_LENTYPE         size,
+                                    int                    flags,
+                                    void* /* SOCK* */      sock_ptr)
+    {
+        return CMonkey::Instance()->Send(sock, data, size, flags, 
+                                         (SOCK*)sock_ptr);
+    }
+    
+    static MONKEY_RETTYPE 
+        MONKEY_STDCALL s_MonkeyRecv(MONKEY_SOCKTYPE   sock,
+                                    MONKEY_DATATYPE   buf,
+                                    MONKEY_LENTYPE    size,
+                                    int               flags,
+                                    void* /* SOCK* */ sock_ptr)
+    {
+        return CMonkey::Instance()->Recv(sock, buf, size, flags, 
+                                         (SOCK*) sock_ptr);
+    }
+
+    
+    static int MONKEY_STDCALL s_MonkeyConnect(MONKEY_SOCKTYPE        sock,
+                                              const struct sockaddr* name,
+                                              MONKEY_SOCKLENTYPE     namelen)
+    {
+        return CMonkey::Instance()->Connect(sock, name, namelen);
+    }
+
+    
+    static int /*bool*/ s_MonkeyPoll(size_t*                  n,
+                                     void* /* SSOCK_Poll** */ polls,
+                                     EIO_Status*              return_status)
+    {
+        return CMonkey::Instance()->
+            Poll(n, (SSOCK_Poll**) polls, return_status) ? 1 : 0;
+    }
+
+
+    static void s_MonkeyClose(SOCKET  sock)
+    {
+        CMonkey::Instance()->Close(sock);
+    }
+}
+
+
+static int s_MONKEY_Poll_dummy(size_t*     n,
+                               void*       polls,
+                               EIO_Status* return_status)
+{
+    return 0; /* call was not intercepted by Monkey*/
+}
+
+
+static void s_MONKEY_Close_dummy(SOCKET sock)
+{
+    return; /* call was not intercepted by Monkey*/
+}
+
+
+/* Chaos Monkey hooks for Connect library*/
+static void s_SetMonkeyHooks(EMonkeyHookSwitch hook_switch)
+{
+    switch (hook_switch)
+    {
+    case eMonkeyHookSwitch_Disabled:
+        g_MONKEY_Send    = 0;
+        g_MONKEY_Recv    = 0;
+        g_MONKEY_Connect = 0;
+        g_MONKEY_Poll    = 0;
+        g_MONKEY_Close   = 0;
+        break;
+    case eMonkeyHookSwitch_Enabled:
+        g_MONKEY_Send    = s_MonkeySend;
+        g_MONKEY_Recv    = s_MonkeyRecv;
+        g_MONKEY_Connect = s_MonkeyConnect;
+        g_MONKEY_Poll    = s_MonkeyPoll;
+        g_MONKEY_Close   = s_MonkeyClose;
+        break;
+    default:
+        break;
+    }
+}
+#endif //NCBI_MONKEY
+
 
 static enum EConnectInit {
-    eConnectInit_Weak = -1,
-    eConnectInit_Intact = 0,
-    eConnectInit_Explicit = 1
+    eConnectInit_Weak     = -1,  ///< CConn_Initer
+    eConnectInit_Intact   =  0,  ///< Not yet visited
+    eConnectInit_Strong   =  1,  ///< User init detected
+    eConnectInit_Explicit =  2   ///< CONNECT_Init() called
 } s_ConnectInit = eConnectInit_Intact;
 
 
+
+/***********************************************************************
+ *                                 Fini                                *
+ ***********************************************************************/
+
+extern "C" {
+static void s_Fini(void) THROWS_NONE
+{
+    s_CORE_Set &= ~g_CORE_Set;
+    if (s_CORE_Set & eCORE_SetSSL)
+        SOCK_SetupSSL(0);
+    if (s_CORE_Set & eCORE_SetREG)
+        CORE_SetREG(0);
+    if (s_CORE_Set & eCORE_SetLOG)
+        CORE_SetLOG(0);
+    if (s_CORE_Set & eCORE_SetLOCK)
+        CORE_SetLOCK(0);
+    g_CORE_Set &= ~s_CORE_Set;
+    s_CORE_Set  =  0;
+}
+}
+
+
+/***********************************************************************
+ *                                 Init                                *
+ ***********************************************************************/
+
+DEFINE_STATIC_FAST_MUTEX(s_ConnectInitMutex);
+
 /* NB: gets called under a lock */
 static void s_Init(IRWRegistry*      reg  = 0,
+                   FSSLSetup         ssl  = 0,
                    CRWLock*          lock = 0,
                    TConnectInitFlags flag = 0,
                    EConnectInit      how  = eConnectInit_Weak)
 {
     _ASSERT(how != eConnectInit_Intact);
-    if (g_NCBI_ConnectRandomSeed == 0) {
-        g_NCBI_ConnectRandomSeed  = (int) time(0) ^ NCBI_CONNECT_SRAND_ADDEND;
-        srand(g_NCBI_ConnectRandomSeed);
+
+    TCORE_Set set = 0;
+    if (!(g_CORE_Set & eCORE_SetLOCK)) {
+        CORE_SetLOCK(MT_LOCK_cxx2c(lock, flag & eConnectInit_OwnLock));
+        set |= eCORE_SetLOCK;
+    }
+    if (!(g_CORE_Set & eCORE_SetLOG)) {
+        CORE_SetLOG(LOG_cxx2c());
+        set |= eCORE_SetLOG;
+    }
+    if (!(g_CORE_Set & eCORE_SetREG)) {
+        CORE_SetREG(REG_cxx2c(reg, flag & eConnectInit_OwnRegistry));
+        set |= eCORE_SetREG;
     }
-    CORE_SetLOCK(MT_LOCK_cxx2c(lock,
-                               flag & eConnectInit_OwnLock ? true : false));
-    CORE_SetLOG(LOG_cxx2c());
-    CORE_SetREG(REG_cxx2c(reg, flag & eConnectInit_OwnRegistry));
+    if (!(g_CORE_Set & eCORE_SetSSL)) {
+        SOCK_SetupSSL(ssl);
+        set |= ssl ? eCORE_SetSSL : 0;
+    }
+    g_CORE_Set &= ~set;
+    s_CORE_Set |=  set;
+
     if (s_ConnectInit == eConnectInit_Intact) {
+        g_NCBI_ConnectRandomSeed  = (int) time(0) ^ NCBI_CONNECT_SRAND_ADDEND;
+        srand(g_NCBI_ConnectRandomSeed);
         atexit(s_Fini);
     }
 
-    /* setup request ID retrieval callback */
-    g_CORE_GetRequestID = s_GetRequestID;
-
-    /* setup app name retrieval callback */
-    g_CORE_GetAppName = s_GetAppName;
-
-    /* setup DTab-Local retrieval */
+    g_CORE_GetAppName     = s_GetAppName;
+    g_CORE_GetRequestID   = s_GetRequestID;
     g_CORE_GetRequestDtab = s_GetRequestDTab;
-    
-    /* done! */
-    s_ConnectInit = how;
-}
 
+#ifdef NCBI_MONKEY
+    /* Allow CMonkey to switch hooks to Connect library */
+    CMonkey::MonkeyHookSwitchSet(s_SetMonkeyHooks);
+    /* Create CMonkey instance. It loads config and sets hooks */
+    CMonkey::Instance();
+#endif //NCBI_MONKEY
 
-static void s_InitInternal(void)
-{
-    CFastMutexGuard guard(s_ConnectInitMutex);
-    if (!g_CORE_Registry  &&  !g_CORE_Log
-        &&  g_CORE_MT_Lock == &g_CORE_MT_Lock_default) {
-        try {
-            if (s_ConnectInit == eConnectInit_Intact) {
-                CMutexGuard guard(CNcbiApplication::GetInstanceMutex());
-                CNcbiApplication* app = CNcbiApplication::Instance();
-                s_Init(app ? &app->GetConfig() : 0);
-            }
-        }
-        NCBI_CATCH_ALL_X(7, "CONNECT_InitInternal() failed");
-    } else {
-        s_ConnectInit = eConnectInit_Explicit;
-    }
+    s_ConnectInit = g_CORE_Set ? how : eConnectInit_Strong;
 }
 
 
@@ -382,7 +489,9 @@ extern void CONNECT_Init(IRWRegistry*      reg,
 {
     CFastMutexGuard guard(s_ConnectInitMutex);
     try {
-        s_Init(reg, lock, flag, eConnectInit_Explicit);
+        g_CORE_Set = 0;
+        s_Init(reg, flag & eConnectInit_NoSSL ? 0 : NcbiSetupGnuTls,
+               lock, flag, eConnectInit_Explicit);
     }
     NCBI_CATCH_ALL_X(8, "CONNECT_Init() failed");
 }
@@ -390,9 +499,17 @@ extern void CONNECT_Init(IRWRegistry*      reg,
 
 CConnIniter::CConnIniter(void)
 {
-    if (s_ConnectInit == eConnectInit_Intact) {
-        s_InitInternal();
+    if (s_ConnectInit != eConnectInit_Intact)
+        return;
+    CFastMutexGuard guard(s_ConnectInitMutex);
+    try {
+        if (s_ConnectInit == eConnectInit_Intact) {
+            CMutexGuard appguard(CNcbiApplication::GetInstanceMutex());
+            CNcbiApplication* app = CNcbiApplication::Instance();
+            s_Init(app ? &app->GetConfig() : 0, NcbiSetupGnuTls);
+        }
     }
+    NCBI_CATCH_ALL_X(7, "CConn_Initer::CConn_Initer() failed");
 }
 
 
diff --git a/c++/src/connect/ncbi_dispd.c b/c++/src/connect/ncbi_dispd.c
index f8c01fe..fa059b1 100644
--- a/c++/src/connect/ncbi_dispd.c
+++ b/c++/src/connect/ncbi_dispd.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_dispd.c 482179 2015-10-21 15:02:35Z lavr $
+/* $Id: ncbi_dispd.c 516325 2016-10-12 17:18:28Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -26,8 +26,8 @@
  * Author:  Anton Lavrentiev
  *
  * File Description:
- *   Low-level API to resolve NCBI service name to the server meta-address
- *   with the use of NCBI network dispatcher (DISPD).
+ *   Low-level API to resolve an NCBI service name to server meta-addresses
+ *   with the use of the NCBI network dispatcher (DISPD).
  *
  */
 
@@ -407,7 +407,7 @@ const SSERV_VTable* SERV_DISPD_Open(SERV_ITER iter,
         srand(g_NCBI_ConnectRandomSeed);
     }
 
-    /* Reset request method to be GET ('cause there's no HTTP body to send) */
+    data->net_info->scheme = eURL_Https;
     data->net_info->req_method = eReqMethod_Get;
     if (iter->stateless)
         data->net_info->stateless = 1/*true*/;
diff --git a/c++/src/connect/ncbi_ftp_connector.c b/c++/src/connect/ncbi_ftp_connector.c
index a9ff991..6eb688a 100644
--- a/c++/src/connect/ncbi_ftp_connector.c
+++ b/c++/src/connect/ncbi_ftp_connector.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_ftp_connector.c 451703 2014-11-10 18:32:44Z lavr $
+/* $Id: ncbi_ftp_connector.c 503173 2016-06-01 19:44:56Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -110,64 +110,8 @@ static const STimeout kZeroTimeout     = {  0, 0 };
 static const char     kDigits[] = "0123456789";
 
 
-typedef EIO_Status (*FFTPReplyParser)(SFTPConnector* xxx, int code,
-                                      size_t lineno, const char* line);
-
-
-static EIO_Status x_FTPParseReply(SFTPConnector* xxx, int* code,
-                                  char* line, size_t maxlinelen,
-                                  FFTPReplyParser parser)
-{
-    EIO_Status status = eIO_Success;
-    size_t     lineno;
-    size_t     len;
-
-    assert(xxx->cntl);
-
-    for (lineno = 0; ; lineno++) {
-        EIO_Status rdstat;
-        const char* msg;
-        char buf[1024];
-        int c, m;
-
-        /* all FTP replies are at least '\n'-terminated, no ending with EOF */
-        rdstat = SOCK_ReadLine(xxx->cntl, buf, sizeof(buf), &len);
-        if (rdstat != eIO_Success) {
-            status  = rdstat;
-            break;
-        }
-        if (len == sizeof(buf)) {
-            status = eIO_Unknown/*line too long*/;
-            break;
-        }
-        msg = buf;
-        if (!lineno  ||  isdigit((unsigned char)(*buf))) {
-            if (sscanf(buf, "%d%n", &c, &m) < 1  ||  m != 3  ||  !c
-                ||  (buf[m]  &&  buf[m] != ' '  &&  buf[m] != '-')
-                ||  (lineno  &&  c != *code)) {
-                status = eIO_Unknown;
-                break;
-            }
-            msg += m + 1;
-            if (buf[m] == '-')
-                m = 0;
-        } else {
-            c = *code;
-            m = 0;
-        }
-        msg += strspn(msg, " \t");
-        if (status == eIO_Success  &&  parser)
-            status  = parser(xxx, lineno  &&  m ? 0 : c, lineno, msg);
-        if (!lineno) {
-            *code = c;
-            if (line)
-                strncpy0(line, msg, maxlinelen);
-        }
-        if (m)
-            break;
-    }
-    return status;
-}
+typedef EIO_Status (*FFTPReplyCB)(SFTPConnector* xxx,  int   code,
+                                  size_t lineno, const char* line);
 
 
 /* Close data connection w/error messages
@@ -252,16 +196,72 @@ static EIO_Status x_FTPCloseData(SFTPConnector* xxx,
 }
 
 
+static EIO_Status x_FTPParseReply(SFTPConnector* xxx, int* code,
+                                  char* line, size_t maxlinelen,
+                                  FFTPReplyCB replycb)
+{
+    EIO_Status status = eIO_Success;
+    size_t     lineno;
+    size_t     len;
+
+    assert(xxx->cntl);
+
+    for (lineno = 0 ; ; lineno++) {
+        EIO_Status rdstat;
+        const char* msg;
+        char buf[1024];
+        int c, m;
+
+        /* all FTP replies are at least '\n'-terminated, no ending with EOF */
+        rdstat = SOCK_ReadLine(xxx->cntl, buf, sizeof(buf), &len);
+        if (rdstat != eIO_Success) {
+            status  = rdstat;
+            break;
+        }
+        if (len == sizeof(buf)) {
+            status = eIO_Unknown/*line too long*/;
+            break;
+        }
+        msg = buf;
+        if (!lineno  ||  isdigit((unsigned char)(*buf))) {
+            if (sscanf(buf, "%d%n", &c, &m) < 1  ||  m != 3  ||  !c
+                ||  (buf[m]  &&  buf[m] != ' '  &&  buf[m] != '-')
+                ||  (lineno  &&  c != *code)) {
+                status = eIO_Unknown;
+                break;
+            }
+            msg += m + 1;
+            if (buf[m] == '-')
+                m = 0;
+        } else {
+            c = *code;
+            m = 0;
+        }
+        msg += strspn(msg, " \t");
+        if (status == eIO_Success  &&  replycb)
+            status  = replycb(xxx, lineno  &&  m ? 0 : c, lineno, msg);
+        if (!lineno) {
+            *code = c;
+            if (line)
+                strncpy0(line, msg, maxlinelen);
+        }
+        if (m)
+            break;
+    }
+    return status;
+}
+
+
 static EIO_Status s_FTPReply(SFTPConnector* xxx, int* code,
                              char* line, size_t maxlinelen,
-                             FFTPReplyParser parser)
+                             FFTPReplyCB replycb)
 {
     EIO_Status status;
     int        c = 0;
 
     if (xxx->cntl) {
         char reason[40];
-        status = x_FTPParseReply(xxx, &c, line, maxlinelen, parser);
+        status = x_FTPParseReply(xxx, &c, line, maxlinelen, replycb);
         if (status != eIO_Timeout)
             xxx->sync = 1/*true*/;
         if (status == eIO_Success) {
@@ -281,7 +281,7 @@ static EIO_Status s_FTPReply(SFTPConnector* xxx, int* code,
             xxx->cntl = 0;
             if (status == eIO_Closed) {
                 CORE_LOGF_X(10, eLOG_Error,
-                            ("[FTP%s%s]  Lost connection @ %s:%hu (%s)",
+                            ("[FTP%s%s]  Lost connection to %s:%hu (%s)",
                              xxx->what ? "; " : "", xxx->what ? xxx->what : "",
                              xxx->info->host, xxx->info->port, reason));
             }
@@ -379,8 +379,8 @@ static const char* x_4Word(const char* line, const char word[4+1])
 }
 
 
-static EIO_Status x_FTPParseHelp(SFTPConnector* xxx, int code,
-                                 size_t lineno, const char* line)
+static EIO_Status x_FTPHelpCB(SFTPConnector* xxx, int code,
+                              size_t lineno, const char* line)
 {
     if (!lineno)
         return code == 211  ||  code == 214 ? eIO_Success : eIO_NotSupported;
@@ -466,7 +466,7 @@ static EIO_Status x_FTPHelp(SFTPConnector* xxx)
     if (status != eIO_Success)
         return status;
     feat = xxx->feat;
-    status = s_FTPReply(xxx, &code, 0, 0, x_FTPParseHelp);
+    status = s_FTPReply(xxx, &code, 0, 0, x_FTPHelpCB);
     if (status != eIO_Success  ||  (code != 211  &&  code != 214)) {
         xxx->feat = feat;
         return status != eIO_Success ? status : eIO_NotSupported;
@@ -475,8 +475,8 @@ static EIO_Status x_FTPHelp(SFTPConnector* xxx)
 }
 
 
-static EIO_Status x_FTPParseFeat(SFTPConnector* xxx, int code,
-                                 size_t lineno, const char* line)
+static EIO_Status x_FTPFeatCB(SFTPConnector* xxx, int code,
+                              size_t lineno, const char* line)
 {
     if (!lineno)
         return code == 211 ? eIO_Success : eIO_NotSupported;
@@ -511,7 +511,7 @@ static EIO_Status x_FTPFeat(SFTPConnector* xxx)
     if (status != eIO_Success)
         return status;
     feat = xxx->feat;
-    status = s_FTPReply(xxx, &code, 0, 0, x_FTPParseFeat);
+    status = s_FTPReply(xxx, &code, 0, 0, x_FTPFeatCB);
     if (status != eIO_Success  ||  code != 211) {
         xxx->feat = feat;
         return status != eIO_Success ? status : eIO_NotSupported;
@@ -1077,7 +1077,7 @@ static EIO_Status x_FTPOpenData(SFTPConnector*  xxx,
 static EIO_Status x_FTPXfer(SFTPConnector*  xxx,
                             const char*     cmd,
                             const STimeout* timeout,
-                            FFTPReplyParser parser)
+                            FFTPReplyCB     replycb)
 {
     int code;
     LSOCK lsock;
@@ -1097,7 +1097,7 @@ static EIO_Status x_FTPXfer(SFTPConnector*  xxx,
     if (status == eIO_Success)
         status  = s_FTPCommand(xxx, cmd, 0);
     if (status == eIO_Success)
-        status  = s_FTPReply(xxx, &code, 0, 0, parser);
+        status  = s_FTPReply(xxx, &code, 0, 0, replycb);
     if (status == eIO_Success) {
         if (code == 125  ||  code == 150) {
             if (lsock) {
@@ -1109,7 +1109,7 @@ static EIO_Status x_FTPXfer(SFTPConnector*  xxx,
                     assert(!xxx->data);
                     CORE_LOGF_X(5, eLOG_Error,
                                 ("[FTP; %s]  Cannot accept data connection"
-                                 " @ :%hu (%s)", xxx->what,
+                                 " at :%hu (%s)", xxx->what,
                                  LSOCK_GetPort(lsock, eNH_HostByteOrder),
                                  IO_StatusStr(status)));
                     /* NB: data conn may have started at the server end */
@@ -1220,6 +1220,7 @@ static EIO_Status s_FTPRename(SFTPConnector* xxx,
 }
 
 
+/* [X]CWD, [X]PWD, [X]MKD, [X]RMD, CDUP, XCUP */
 static EIO_Status s_FTPDir(SFTPConnector* xxx,
                            const char*    cmd,
                            const char*    arg)
@@ -1247,8 +1248,8 @@ static EIO_Status s_FTPSyst(SFTPConnector* xxx,
 }
 
 
-static EIO_Status x_FTPParseStat(SFTPConnector* xxx, int code,
-                                 size_t lineno, const char* line)
+static EIO_Status x_FTPStatCB(SFTPConnector* xxx, int code,
+                              size_t lineno, const char* line)
 {
     if (!lineno  &&  code != 211  &&  code != 212  &&  code != 213)
         return code == 450 ? eIO_Closed : eIO_NotSupported;
@@ -1269,7 +1270,7 @@ static EIO_Status s_FTPStat(SFTPConnector* xxx,
     EIO_Status status = s_FTPCommand(xxx, cmd, 0);
     if (status != eIO_Success)
         return status;
-    return s_FTPReply(xxx, 0, 0, 0, x_FTPParseStat);
+    return s_FTPReply(xxx, 0, 0, 0, x_FTPStatCB);
 }
 
 
@@ -1337,10 +1338,10 @@ static EIO_Status x_FTPParseMdtm(SFTPConnector* xxx, char* timestamp)
     } else if (len != 14)
         return eIO_Unknown;
     /* Can't use strptime() here, per the following reasons:
-     * 1. Only GNU implementation is documented not to require spaces
-     *    between input format specifiers in the format string (%-based);
-     * 2. None to any spaces are allowed to match a space in the format,
-     *    whilst an MDTM response must not contain even a single space. */
+     * 1. Only GNU implementation is documented not to require spaces between
+     *    input format specifiers in the format string (%-based);
+     * 2. None to any spaces are allowed to match a space in the format, whilst
+     *    an MDTM response must not contain even a single space. */
     for (n = 0;  n < 6;  n++) {
         size_t len = n ? 2 : 4/*year*/;
         if (len != strlen(strncpy0(buf, timestamp, len))  ||
@@ -1454,8 +1455,8 @@ static EIO_Status s_FTPRestart(SFTPConnector* xxx,
 }
 
 
-static EIO_Status x_FTPSzcb(SFTPConnector* xxx, int code,
-                            size_t lineno, const char* line)
+static EIO_Status x_FTPRetrieveCB(SFTPConnector* xxx, int code,
+                                  size_t lineno, const char* line)
 {
     EIO_Status status = eIO_Success;
     if (!lineno  &&  (code == 125  ||  code == 150)) {
@@ -1495,7 +1496,7 @@ static EIO_Status s_FTPRetrieve(SFTPConnector*  xxx,
                                 const STimeout* timeout)
 {
     xxx->size = 0;
-    return x_FTPXfer(xxx, cmd, timeout, x_FTPSzcb);
+    return x_FTPXfer(xxx, cmd, timeout, x_FTPRetrieveCB);
 }
 
 
@@ -1527,8 +1528,8 @@ static EIO_Status s_FTPDele(SFTPConnector* xxx,
 }
 
 
-static EIO_Status x_FTPMlsd(SFTPConnector* xxx, int code,
-                            size_t lineno, const char* line)
+static EIO_Status x_FTPMlsdCB(SFTPConnector* xxx, int code,
+                              size_t lineno, const char* line)
 {
     if (!lineno  ||  code != 501)
         return eIO_Success;
@@ -1536,8 +1537,8 @@ static EIO_Status x_FTPMlsd(SFTPConnector* xxx, int code,
 }
 
 
-static EIO_Status x_FTPMlst(SFTPConnector* xxx, int code,
-                            size_t lineno, const char* line)
+static EIO_Status x_FTPMlstCB(SFTPConnector* xxx, int code,
+                              size_t lineno, const char* line)
 {
     if (!lineno) {
         return code == 250 ? eIO_Success :
@@ -1556,26 +1557,27 @@ static EIO_Status x_FTPMlst(SFTPConnector* xxx, int code,
 
 
 /* MLST, MLSD */
-static EIO_Status s_FTPMlsx(SFTPConnector*  xxx,
+static EIO_Status s_FTPMlsX(SFTPConnector*  xxx,
                             const char*     cmd,
                             const STimeout* timeout)
 {
-    if (cmd[3] == 'T') { /*MLST*/
+    if (cmd[3] == 'T') { /* MLST */
         EIO_Status status = s_FTPCommand(xxx, cmd, 0);
         if (status != eIO_Success)
             return status;
-        status = s_FTPReply(xxx, 0/*code checked by cb*/, 0, 0, x_FTPMlst);
+        status = s_FTPReply(xxx, 0/*code checked by cb*/, 0, 0, x_FTPMlstCB);
         if (status != eIO_Success)
             BUF_Erase(xxx->rbuf);
         return status;
     }
+    /* MLSD */
     xxx->size = 0;  /* cf. s_FTPRetrieve() */
-    return x_FTPXfer(xxx, cmd, timeout, x_FTPMlsd);
+    return x_FTPXfer(xxx, cmd, timeout, x_FTPMlsdCB);
 }
 
 
-static EIO_Status x_FTPNgcb(SFTPConnector* xxx, int code,
-                            size_t lineno, const char* line)
+static EIO_Status x_FTPNegotiateCB(SFTPConnector* xxx, int code,
+                                   size_t lineno, const char* line)
 {
     if (lineno  &&  code / 100 == 2) {
         if (*line &&/*NB: RFC2389 3.2 & 4, the leading space has been skipped*/
@@ -1597,12 +1599,12 @@ static EIO_Status s_FTPNegotiate(SFTPConnector* xxx,
     EIO_Status status = s_FTPCommand(xxx, cmd, 0);
     if (status != eIO_Success)
         return status;
-    status = s_FTPReply(xxx, &code, 0, 0, x_FTPNgcb);
+    status = s_FTPReply(xxx, &code, 0, 0, x_FTPNegotiateCB);
     if (status == eIO_Success) {
-        if (*cmd == 'F') {
+        if (*cmd == 'F') {  /* FEAT */
             if (code != 211)
                 status = eIO_Closed;
-        } else {
+        } else {            /* OPTS */
             if (code == 451)
                 status = eIO_Unknown;
             else if (code != 200)
@@ -1630,7 +1632,7 @@ static EIO_Status s_FTPPollCntl(SFTPConnector* xxx, const STimeout* timeout)
         status = s_FTPReply(xxx, &code, buf, sizeof(buf) - 1, 0);
         if (status == eIO_Success) {
             assert(!xxx->data  ||  xxx->send);
-            CORE_LOGF_X(12, eLOG_Error,
+            CORE_LOGF_X(12, xxx->data ? eLOG_Error : eLOG_Warning,
                         ("[FTP%s%s]  %spurious response %d from server%s%s",
                          xxx->what ? "; " : "", xxx->what ? xxx->what : "",
                          xxx->data ? "Aborting upload due to a s" : "S", code,
@@ -1706,7 +1708,7 @@ static EIO_Status s_FTPExecute(SFTPConnector* xxx, const STimeout* timeout)
         if (size == 3  ||  size == 4) {
             SOCK_SetTimeout(xxx->cntl, eIO_ReadWrite, timeout);
             if         (size == 3  &&   strncasecmp(s, "REN",  3) == 0) {
-                /* a special-case, non-standard command */
+                /* special-case, non-standard command */
                 status = s_FTPRename(xxx, c + strspn(c, " \t"));
             } else if ((size == 3  ||  toupper((unsigned char) c[-4]) == 'X')
                        &&          (strncasecmp(c - 3, "CWD",  3) == 0  ||
@@ -1738,7 +1740,7 @@ static EIO_Status s_FTPExecute(SFTPConnector* xxx, const STimeout* timeout)
                 status = s_FTPStore   (xxx, s, timeout);
             } else if  (size == 4  &&  (strncasecmp(s, "MLSD", 4) == 0  ||
                                         strncasecmp(s, "MLST", 4) == 0)) {
-                status = s_FTPMlsx    (xxx, s, timeout);
+                status = s_FTPMlsX    (xxx, s, timeout);
             } else if  (size == 4  &&  (strncasecmp(s, "FEAT", 4) == 0  ||
                                         strncasecmp(s, "OPTS", 4) == 0)) {
                 status = s_FTPNegotiate(xxx, s);
diff --git a/c++/src/connect/ncbi_gnutls.c b/c++/src/connect/ncbi_gnutls.c
index 2d32bbf..f1e5a01 100644
--- a/c++/src/connect/ncbi_gnutls.c
+++ b/c++/src/connect/ncbi_gnutls.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_gnutls.c 500354 2016-05-04 09:47:08Z ivanov $
+/* $Id: ncbi_gnutls.c 517037 2016-10-20 11:20:25Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -602,7 +602,7 @@ static EIO_Status s_GnuTlsInit(FSSLPull pull, FSSLPush push)
         CORE_UNLOCK;
         if (s_GnuTlsLogLevel) {
             gnutls_global_set_log_function(x_GnuTlsLogger);
-            if (val != buf)
+            if (val == buf)
                 gnutls_global_set_log_level(s_GnuTlsLogLevel);
             CORE_LOGF(eLOG_Note, ("GNUTLS V%s (Loglevel=%d)",
                                   version, s_GnuTlsLogLevel));
@@ -681,28 +681,39 @@ static const char* s_GnuTlsError(void* session/*unused*/, int error)
 }
 
 
+#else
+
+
+/*ARGSUSED*/
+static EIO_Status s_GnuTlsInit(FSSLPull unused_pull, FSSLPush unused_push)
+{
+    CORE_LOG(eLOG_Critical, "Unavailable feature GNUTLS");
+    return eIO_NotSupported;
+}
+
+
 #endif /*HAVE_LIBGNUTLS*/
 
 
 extern SOCKSSL NcbiSetupGnuTls(void)
 {
-#ifdef HAVE_LIBGNUTLS
     static const struct SOCKSSL_struct kGnuTlsOps = {
-        s_GnuTlsInit,
-        s_GnuTlsCreate,
-        s_GnuTlsOpen,
-        s_GnuTlsRead,
-        s_GnuTlsWrite,
-        s_GnuTlsClose,
-        s_GnuTlsDelete,
-        s_GnuTlsExit,
-        s_GnuTlsError
+        s_GnuTlsInit
+#ifdef HAVE_LIBGNUTLS
+        , s_GnuTlsCreate
+        , s_GnuTlsOpen
+        , s_GnuTlsRead
+        , s_GnuTlsWrite
+        , s_GnuTlsClose
+        , s_GnuTlsDelete
+        , s_GnuTlsExit
+        , s_GnuTlsError
+#endif /*HAVE_LIBGNUTLS*/
     };
+#ifndef HAVE_LIBGNUTLS
+    CORE_LOG(eLOG_Warning, "Unavailable feature GNUTLS");
+#endif /*!HAVE_LIBGNUTLS*/
     return &kGnuTlsOps;
-#else
-    CORE_LOG(eLOG_Critical, "Unavailable feature GNUTLS");
-    return 0;
-#endif /*HAVE_LIBGNUTLS*/
 }
 
 
diff --git a/c++/src/connect/ncbi_http_connector.c b/c++/src/connect/ncbi_http_connector.c
index 69af0b7..b93f2d2 100644
--- a/c++/src/connect/ncbi_http_connector.c
+++ b/c++/src/connect/ncbi_http_connector.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_http_connector.c 500357 2016-05-04 09:48:45Z ivanov $
+/* $Id: ncbi_http_connector.c 505576 2016-06-27 16:34:25Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1220,7 +1220,7 @@ static EIO_Status s_ReadHeader(SHttpConnector* uuu,
             }
             verify(BUF_Peek(uuu->http, hdr, size) == size);
             if (memcmp(&hdr[size - 4], "\r\n\r\n", 4) == 0) {
-                /*full header captured*/
+                /* full header captured */
                 hdr[size] = '\0';
                 break;
             }
@@ -1580,15 +1580,12 @@ static EIO_Status s_ReadHeader(SHttpConnector* uuu,
     if (!retry->data)
         free(hdr);
 
-    if (!http_code) {
-        if (header_parse != eHTTP_HeaderError) {
-            if (url)
-                free(url);
-            return eIO_Success;
-        }
-        http_code = -1;
+    if (http_code == 0) {
+        if (url)
+            free(url);
+        return header_parse == eHTTP_HeaderError ? eIO_Unknown : eIO_Success;
     }
-    /*NB: http_code != 0*/
+    assert(header_parse != eHTTP_HeaderComplete);
 
     if (uuu->net_info->debug_printout
         ||  header_parse == eHTTP_HeaderContinue) {
@@ -1733,7 +1730,7 @@ static EIO_Status s_PreRead(SHttpConnector* uuu,
             assert((uuu->conn_state & eCS_ReadBody)  &&  !retry.mode);
             /* pending output data no longer needed */
             BUF_Erase(uuu->w_buf);
-            return eIO_Success;
+            break;
         }
 
         assert(status != eIO_Timeout  ||  !retry.mode);
@@ -1758,9 +1755,9 @@ static EIO_Status s_PreRead(SHttpConnector* uuu,
         }
     }
 
-    assert(status != eIO_Success);
     if (BUF_Size(uuu->http)  &&  !BUF_Splice(&uuu->r_buf, uuu->http))
         BUF_Erase(uuu->http);
+    assert(!BUF_Size(uuu->http));
     return status;
 }
 
@@ -1852,7 +1849,6 @@ static EIO_Status s_Read(SHttpConnector* uuu, void* buf,
         const char* how = 0;
         if (uuu->received < uuu->expected) {
             if (status == eIO_Closed) {
-                assert(uuu->conn_state == eCS_ReadBody);
                 status  = eIO_Unknown;
                 how = "premature EOM in";
             }
@@ -2092,7 +2088,7 @@ static EIO_Status s_VT_Write
     } else
         uuu->w_timeout  = kInfiniteTimeout;
 
-    /* if trying to write after a request then close the socket,
+    /* if trying to write after a request then close the socket first,
      * and so return to "IDLE" */
     if (uuu->sock  &&  uuu->conn_state > eCS_WriteRequest) {
         status = s_Disconnect(uuu, timeout,
@@ -2118,8 +2114,8 @@ static EIO_Status s_VT_Write
             if (status != eIO_Success)
                 return status;
         }
-        assert((!uuu->sock  ||  uuu->conn_state == eCS_WriteRequest)
-               &&  !uuu->w_len);
+        assert(!uuu->sock  ||  (uuu->conn_state == eCS_WriteRequest
+                                &&  !uuu->w_len));
         if (size) {
             char prefix[80];
             int  n = sprintf(prefix, "%" NCBI_BIGCOUNT_FORMAT_SPEC_HEX "\r\n",
@@ -2186,7 +2182,7 @@ static EIO_Status s_VT_Flush
     }
     status = x_IsWriteThru(uuu)
         ? s_ConnectAndSend(uuu, timeout, eEM_Flush)
-        : s_PreRead       (uuu, timeout, eEM_Flush); 
+        : s_PreRead       (uuu, timeout, eEM_Flush);
     return BUF_Size(uuu->r_buf) ? eIO_Success : status;
 }
 
@@ -2424,6 +2420,7 @@ static EIO_Status s_CreateHttpConnector
     uuu->http         = 0;
     uuu->r_buf        = 0;
     uuu->w_buf        = 0;
+    uuu->w_len        = 0;
 
     if (tunnel)
         s_OpenHttpConnector(uuu, xxx->timeout);
diff --git a/c++/src/connect/ncbi_http_session.cpp b/c++/src/connect/ncbi_http_session.cpp
index dd3525b..2e14f09 100644
--- a/c++/src/connect/ncbi_http_session.cpp
+++ b/c++/src/connect/ncbi_http_session.cpp
@@ -1,4 +1,4 @@
-/* $Id: ncbi_http_session.cpp 493038 2016-02-23 19:24:35Z ivanov $
+/* $Id: ncbi_http_session.cpp 519414 2016-11-15 18:23:40Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -195,8 +195,7 @@ void CHttpHeaders::Merge(const CHttpHeaders& headers)
 bool CHttpHeaders::x_IsReservedHeader(CTempString name) const
 {
     for (size_t i = 0; i < sizeof(kReservedHeaders)/sizeof(kReservedHeaders[0]); ++i) {
-        THeaders::const_iterator it = m_Headers.find(kReservedHeaders[i]);
-        if (it != m_Headers.end()) {
+        if (!NStr::CompareNocase(name, kReservedHeaders[i])) {
             ERR_POST(kReservedHeaders[i] << " must be set through CRequestContext");
             return true;
         }
@@ -552,31 +551,160 @@ CHttpRequest::CHttpRequest(CHttpSession& session,
       m_Url(url),
       m_Method(method),
       m_Headers(new CHttpHeaders),
-      m_Timeout(CTimeout::eDefault)
+      m_Timeout(CTimeout::eDefault),
+      m_Deadline(CTimeout::eDefault),
+      m_RetryProcessing(ESwitch::eDefault)
 {
 }
 
 
+// Processing logic for 'retry later' response in CHttpRequest::Execute()
+struct SRetryProcessing
+{
+    SRetryProcessing(ESwitch on_off, const CTimeout& deadline, CUrl& url,
+            EReqMethod& method, CRef<CHttpHeaders>& headers,
+            CRef<CHttpFormData>& form_data);
+
+    bool operator()(const CHttpHeaders& headers);
+
+private:
+    // This class is used to restore CHttpRequest members to their original state
+    template <class TMember, class TValue = TMember>
+    struct SValueRestorer
+    {
+        TMember& value;
+
+        SValueRestorer(TMember& v) : value(v) { Assign(original, value); }
+        ~SValueRestorer() { Restore(); }
+        void Restore() { Assign(value, original); }
+
+    private:
+        TValue original;
+    };
+
+    template <class TTo, class TFrom> static void Assign(TTo&, const TFrom&);
+
+    const bool m_Enabled;
+    CDeadline m_Deadline;
+    SValueRestorer<CUrl> m_Url;
+    SValueRestorer<EReqMethod> m_Method;
+    SValueRestorer<CRef<CHttpHeaders>, CHttpHeaders> m_Headers;
+    SValueRestorer<CRef<CHttpFormData>> m_FormData;
+};
+
+
+SRetryProcessing::SRetryProcessing(ESwitch on_off, const CTimeout& deadline, CUrl& url,
+        EReqMethod& method, CRef<CHttpHeaders>& headers,
+        CRef<CHttpFormData>& form_data) :
+    m_Enabled(on_off == eOn),
+    m_Deadline(deadline.IsDefault() ? CTimeout::eInfinite : deadline),
+    m_Url(url),
+    m_Method(method),
+    m_Headers(headers),
+    m_FormData(form_data)
+{
+}
+
+
+bool SRetryProcessing::operator()(const CHttpHeaders& headers)
+{
+    // Must correspond to CHttpRetryContext (e.g. CCgi2RCgiApp) values
+    const unsigned long kExecuteDefaultRefreshDelay = 5;
+    const string        kExecuteHeaderRetryURL      = "X-NCBI-Retry-URL";
+    const string        kExecuteHeaderRetryDelay    = "X-NCBI-Retry-Delay";
+
+    if (!m_Enabled) return false;
+    if (m_Deadline.IsExpired()) return false;
+
+    const auto& retry_url = headers.GetValue(kExecuteHeaderRetryURL);
+
+    // Not a 'retry later' response (e.g. remote CGI has already finished)
+    if (retry_url.empty()) return false;
+
+    const auto& retry_delay = headers.GetValue(kExecuteHeaderRetryDelay);
+    unsigned long sleep_ms = kExecuteDefaultRefreshDelay;
+
+    // HTTP header has delay
+    if (!retry_delay.empty()) {
+        try {
+            sleep_ms = NStr::StringToULong(retry_delay) * kMilliSecondsPerSecond;
+        }
+        catch (CStringException& ex) {
+            if (ex.GetErrCode() != CStringException::eConvert) throw;
+        }
+    }
+
+    // If the deadline is less than the retry delay,
+    // sleep for the remaining and check once again
+    try {
+        auto remaining = m_Deadline.GetRemainingTime().GetAsMilliSeconds();
+        if (remaining < sleep_ms) sleep_ms = remaining;
+    }
+    catch (CTimeException& ex) {
+        if (ex.GetErrCode() != CTimeException::eConvert) throw;
+    }
+
+    SleepMilliSec(sleep_ms);
+
+    // Make subsequent requests appropriate
+    m_Url.value = retry_url;
+    m_Method.value = eReqMethod_Get;
+    m_Headers.Restore();
+    m_FormData.value.Reset();
+
+    return true;
+}
+
+
+template <class TTo, class TFrom>
+void SRetryProcessing::Assign(TTo& to, const TFrom& from)
+{
+    to = from;
+}
+
+
+template <>
+void SRetryProcessing::Assign(CHttpHeaders& to, const CRef<CHttpHeaders>& from)
+{
+    to.Assign(*from);
+}
+
+
+template <>
+void SRetryProcessing::Assign(CRef<CHttpHeaders>& to, const CHttpHeaders& from)
+{
+    to->Assign(from);
+}
+
+
 CHttpResponse CHttpRequest::Execute(void)
 {
-    // Connection not open yet.
-    // Only POST and PUT support sending form data.
-    bool have_data = m_FormData  &&  !m_FormData.Empty();
-    if ( !m_Response ) {
-        x_InitConnection(have_data);
+    SRetryProcessing retry_processing(m_RetryProcessing, m_Deadline, m_Url,
+            m_Method, m_Headers, m_FormData);
+    CRef<CHttpResponse> ret;
+
+    do {
+        // Connection not open yet.
+        // Only POST and PUT support sending form data.
+        bool have_data = m_FormData  &&  !m_FormData.Empty();
+        if ( !m_Response ) {
+            x_InitConnection(have_data);
+        }
+        _ASSERT(m_Response);
+        _ASSERT(m_Stream  &&  m_Stream->IsInitialized());
+        CConn_IOStream& out = m_Stream->GetConnStream();
+        if ( have_data ) {
+            m_FormData->WriteFormData(out);
+        }
+        // Send data to the server and close output stream.
+        out.peek();
+        m_Stream.Reset();
+        ret = m_Response;
+        m_Response.Reset();
     }
-    _ASSERT(m_Response);
-    _ASSERT(m_Stream  &&  m_Stream->IsInitialized());
-    CConn_IOStream& out = m_Stream->GetConnStream();
-    if ( have_data ) {
-        m_FormData->WriteFormData(out);
-    }
-    // Send data to the server and close output stream.
-    out.peek();
-    m_Stream.Reset();
-    CHttpResponse ret = *m_Response;
-    m_Response.Reset();
-    return ret;
+    while (retry_processing(ret->Headers()));
+
+    return *ret;
 }
 
 
@@ -771,6 +899,20 @@ CHttpRequest& CHttpRequest::SetTimeout(unsigned int sec,
 }
 
 
+CHttpRequest& CHttpRequest::SetDeadline(const CTimeout& deadline)
+{
+    m_Deadline = deadline;
+    return *this;
+}
+
+
+CHttpRequest& CHttpRequest::SetRetryProcessing(ESwitch on_off)
+{
+    m_RetryProcessing = on_off;
+    return *this;
+}
+
+
 ///////////////////////////////////////////////////////
 //  CHttpSession::
 //
diff --git a/c++/src/connect/ncbi_lbos.c b/c++/src/connect/ncbi_lbos.c
index feb646f..5de9259 100644
--- a/c++/src/connect/ncbi_lbos.c
+++ b/c++/src/connect/ncbi_lbos.c
@@ -24,6 +24,7 @@
  * ===========================================================================
  *
  * Authors:  Dmitriy Elisov
+ * Credits:  Denis Vakatov
  * @file
  * File Description:
  *   A client for service discovery API based on LBOS.
@@ -38,7 +39,7 @@
 #include "ncbi_priv.h"
 #include <stdlib.h> /* free, realloc, calloc, malloc */
 #include <ctype.h> /* isdigit */
-
+#include "parson.h"
 #define            kHostportStringLength     (16+1+5)/**<
                                                      strlen("255.255.255.255")+
                                                      strlen(":") +
@@ -49,20 +50,24 @@
 #define            NCBI_USE_ERRCODE_X        Connect_LBSM /**< Used in
                                                                CORE_LOG*_X  */
 
+#ifdef NCBI_COMPILER_MSVC
+#   define LBOS_STRTOK strtok_s
+#else
+#   define LBOS_STRTOK strtok_r
+#endif 
 /*/////////////////////////////////////////////////////////////////////////////
 //                         STATIC VARIABLES                                  //
 /////////////////////////////////////////////////////////////////////////////*/
 
-static const char* kRoleFile                  = "/etc/ncbi/role";
-static const char* kDomainFile                = "/etc/ncbi/domain";
 #ifdef NCBI_OS_MSWIN
     static const char* kLbosresolverFile      = "C:\\Apps\\Admin_Installs\\etc"
                                                 "\\ncbi\\lbosresolver";
 #else 
     static const char* kLbosresolverFile      = "/etc/ncbi/lbosresolver";
 #endif
-static const char* kLBOSQuery                 = "/lbos/text/mlresolve?name=";
 
+static const char* kLBOSQuery                 = "/lbos/v3/services/"
+                                                "?format=json&show=all&q=";
 
 /*
  * LBOS registry section for announcement
@@ -73,13 +78,11 @@ static const char* kLBOSVersionVariable        = "VERSION";
 static const char* kLBOSServerHostVariable     = "HOST";
 static const char* kLBOSPortVariable           = "PORT";
 static const char* kLBOSHealthcheckUrlVariable = "HEALTHCHECK";
-static const char* kLBOSDomainVariable         = "lbos_domain";
+static const char* kLBOSMetaVariable           = "meta";
 
 
-static SConnNetInfo* s_EmptyNetInfo         = NULL; /* Do..                  */
-static       char*   s_LBOS_CurrentDomain   = NULL; /*  ..not..              */
-static       char*   s_LBOS_Lbosresolver    = NULL; /*      ..change..       */
-static       char*   s_LBOS_CurrentRole     = NULL; /*          ..after init */
+static SConnNetInfo* s_EmptyNetInfo         = NULL; /* Do not change..       */
+static       char*   s_LBOS_Lbosresolver    = NULL; /*          ..after init */
 static const int     kInitialCandidatesCount = 1;   /* For initial memory
                                                        allocation            */
 static       int     s_LBOS_TurnedOn         = 1;   /* If LBOS cannot 
@@ -121,9 +124,9 @@ static void           s_LBOS_Reset         (SERV_ITER     iter);
 static int/*bool*/    s_LBOS_Update        (SERV_ITER     iter,
                                             const char*   text,
                                             int           code);
-static const char*    s_LBOS_ReadDomain    (void);
-static const char*    s_LBOS_ReadRole      (void);
+#if defined NCBI_OS_LINUX || defined NCBI_OS_MSWIN
 static const char*    s_LBOS_ReadLbosresolver(void);
+#endif /* defined NCBI_OS_LINUX || defined NCBI_OS_MSWIN */
 static 
 EHTTP_HeaderParse     s_LBOS_ParseHeader   (const char*   header,
                                             void*         /* SLBOS_UserData* */
@@ -140,6 +143,7 @@ unsigned short s_LBOS_Announce(const char*             service,
                                const char*             host,
                                unsigned short          port,
                                const char*             healthcheck_url,
+                               const char*             meta,
                                char**                  lbos_answer,
                                char**                  http_status_message);
 
@@ -150,7 +154,6 @@ unsigned short s_LBOS_Announce(const char*             service,
 static SLBOS_Functions s_LBOS_funcs = {
                 s_LBOS_ResolveIPPort
                 ,CONN_Read
-                ,g_LBOS_ComposeLBOSAddress
                 ,s_LBOS_FillCandidates
                 ,s_LBOS_DestroyData
                 ,s_LBOS_GetNextInfo
@@ -347,7 +350,7 @@ static const SSERV_VTable s_lbos_op =  {
 //                    GLOBAL CONVENIENCE FUNCTIONS                           //
 /////////////////////////////////////////////////////////////////////////////*/
 /** Check C-string if it is not NULL and contains at least one symbol        */
-int/*bool*/ g_LBOS_StringIsNullOrEmpty(const char* const str)
+int/*bool*/ g_LBOS_StringIsNullOrEmpty(const char* str)
 {
     if ((str == NULL) || (strlen(str) == 0)) {
         return 1;
@@ -402,7 +405,8 @@ const char* g_LBOS_strcasestr(const char* dest, const char* lookup)
  *   g_LBOS_StringConcat(g_LBOS_StringConcat(str,to_app1,&len), to_app2,&len).
  *   Value of data_length on first call should be 0.
  *  @return 
- *   1 if success, 0 if error happened and dest was not changed              */
+ *   reallocated dest on success, NULL if error happened and dest was 
+ *   not changed         */
 char*   g_LBOS_StringConcat(char*       dest, 
                             const char* to_append,
                             size_t*     dest_length)
@@ -426,7 +430,8 @@ char*   g_LBOS_StringConcat(char*       dest,
     }
     realloc_result = (char*)realloc(dest, dest_length_local + append_len + 1);
     if (realloc_result == NULL) {
-        CORE_LOG(eLOG_Critical, "g_LBOS_StringConcat: No RAM. Returning NULL.");
+        CORE_LOG_X(eLBOS_MemAlloc, eLOG_Critical, 
+                    "g_LBOS_StringConcat: No RAM. Returning NULL.");
         free(dest);
         return NULL;
     }
@@ -439,72 +444,8 @@ char*   g_LBOS_StringConcat(char*       dest,
     }
     return dest;
 }
-#if 0
-/* Get "tag: value" pair from HTTP header */
-char* s_LBOS_GetHTTPHeader(const char* tag, const char* headers)
-{
-    char* tag_lwr = strlwr(strdup(tag));
-    char* header_lwr = strlwr(strdup(headers));
-    char* tag_start = header_lwr, *tag_end;
-    while (tag_start != NULL)
-    {
-        /* We move bit by bit */
-        tag_start = strstr(tag_start, tag_lwr);
-        /* We want to be sure that found tag is the tag itself,
-         * not a value as if in "Some-Tag: tag: 2". So we check for
-         * either \n before tag, or it should be positioned at the very
-         * beginning of the string
-         */
-        if  (
-                tag_start != NULL
-                &&
-                (
-                    (*(tag_start - 1) == '\n')
-                    ||
-                    (tag_start == header_lwr)
-                )
-            ) 
-            {
-                /* Look for the end of tag: value */
-                while ()
-            }
-        else {
-            tag_start = 
-
-        if (d)
-    }
-}
 
 
-char* g_LBOS_CombineDTabs(const char* primary_dtab, const char* secondary_dtab)
-{
-    char* primary_dtab, *primary_dtab_end, *new_dtab;
-    int length, primary_dtab_length;
-    primary_dtab += strlen("DTab-Local:");
-    if (primary_dtab[1] == ' ') {
-        primary_dtab++;
-    }
-    /* Find end of line */
-    primary_dtab_end = strchr(primary_dtab, '\n');
-    if (primary_dtab_end[-1] == '\r')  {
-        primary_dtab_end--;
-    }
-    /* Create new string that includes first DTabs from registry and then
-    * DTabs from HTTP requests */
-    length = 0;
-    primary_dtab_length = primary_dtab_end - primary_dtab;
-    new_dtab = NULL;
-    new_dtab = g_LBOS_StringNConcat(g_LBOS_StringConcat(
-               g_LBOS_StringConcat(g_LBOS_StringConcat(
-                 /*dest*/   /*to append*/     /*length*/  /*count*/
-                 new_dtab,  "DTab-local: ",   &length),
-                            secondary_dtab,   &length),
-                            ";",              &length),
-                            primary_dtab,     &length,    primary_dtab_length);
-    return new_dtab;
-}
-#endif
-
 char*   g_LBOS_StringNConcat(char*       dest,
                              const char* to_append,
                              size_t*     dest_length,
@@ -514,7 +455,7 @@ char*   g_LBOS_StringNConcat(char*       dest,
     char* result;
 
     if (buf == NULL) {
-        CORE_LOG(eLOG_Critical, 
+        CORE_LOG_X(eLBOS_MemAlloc, eLOG_Critical, 
                  "g_LBOS_StringConcat: No RAM. Returning NULL.");
         free(buf);
         free(dest);
@@ -539,7 +480,8 @@ char*   g_LBOS_RegGet(const char* section,
     char*     buf              = (char*)malloc(totalBufSize * sizeof(char));
 
     if (buf == NULL) {
-        CORE_LOG(eLOG_Critical, "g_LBOS_RegGet: No RAM. Returning NULL.");
+        CORE_LOG_X(eLBOS_MemAlloc, eLOG_Critical, 
+                   "g_LBOS_RegGet: No RAM. Returning NULL.");
         return buf;
     }
     for (;;) {
@@ -552,10 +494,9 @@ char*   g_LBOS_RegGet(const char* section,
            then add space to buffer  */
         realloc_result = (char*)realloc(buf, sizeof(char)*(totalBufSize * 2));
         if (realloc_result == NULL) {
-            CORE_LOG(eLOG_Warning, "g_LBOS_RegGet: Buffer "
-                                    "overflow while reading from "
-                                    "registry. Returning string at its "
-                                    "maximum size");
+            CORE_LOG_X(eLBOS_MemAlloc, eLOG_Warning, 
+                       "g_LBOS_RegGet: Buffer overflow while reading from "
+                       "registry. Returning string at its maximum size");
             return buf;
         } else {
             buf = realloc_result;
@@ -566,33 +507,6 @@ char*   g_LBOS_RegGet(const char* section,
 }
 
 
-/**  We compose LBOS hostname based on /etc/ncbi/domain and /etc/ncbi/role.  */
-char* g_LBOS_ComposeLBOSAddress(void)
-{
-    char* site = NULL;
-    size_t length = 0;
-    const char *role   = s_LBOS_ReadRole(), 
-               *domain = s_LBOS_ReadDomain();
-
-    if (role == NULL || domain == NULL) {
-        return NULL;
-    }
-    site = g_LBOS_StringConcat(g_LBOS_StringConcat(
-                g_LBOS_StringConcat(g_LBOS_StringConcat(
-                /* dest */    /* to append */        /* length */
-                site,          "lbos.",              &length),
-                               role,                 &length),
-                               ".",                  &length),
-                               domain,               &length);
-    if (site == NULL) {
-        CORE_LOG(eLOG_Warning, "s_LBOS_ComposeLBOSAddress: "
-                                 "memory allocation failed");
-        return NULL;
-    }
-    return site;
-}
-
-
 /** Checks iterator, fact that iterator belongs to this mapper, iterator data.
  * Only debug function.                                                      */
 int/*bool*/ g_LBOS_CheckIterator(SERV_ITER              iter,
@@ -619,53 +533,6 @@ int/*bool*/ g_LBOS_CheckIterator(SERV_ITER              iter,
 }
 
 
-/** Given address to LBOS instance, check if it resides in the same domain
- * (be-md, st-va, ac-va, or-wa) as current machine                           */
-int/*bool*/ g_LBOS_CheckDomain(const char* lbos_address)
-{
-    return 1; /* we do not check domain */
-    /* Though we cannot be 100% sure that sequence of numbers and dots is IP, 
-     * it is what we hope for */
-    int/*bool*/ is_ip = 1;
-    unsigned short int i;
-    for (i = 0; i < strlen(lbos_address); i++) {
-        if (!isdigit(lbos_address[i]) && lbos_address[i] != '.') {
-            is_ip = 0;
-        }
-    }
-    /*  The check now is really simple - it searches for known domains in the
-     * provided address. If domain is omitted in address - then we deny such 
-     * address, just in case. If address contains 
-     * non-standard domain - check will not work. */
-    if ( !is_ip
-         /* &&
-         (
-            (strstr(lbos_address, ".be-md.") != NULL) 
-             || 
-            (strstr(lbos_address, ".st-va.") != NULL)
-             ||
-            (strstr(lbos_address, ".or-wa.") != NULL)
-             ||
-            (strstr(lbos_address, ".ac-va.") != NULL)
-         ) */
-         &&
-         (
-            !g_LBOS_StringIsNullOrEmpty(s_LBOS_ReadDomain())
-         )
-         &&
-         (
-             strcmp(s_LBOS_ReadDomain(), "*") != 0
-         )
-       )
-    {
-        /* If we can perform check, we return result of check */
-        return (strstr(lbos_address, s_LBOS_ReadDomain()) != NULL);
-    }
-    /* If we cannot perform check, we allow any domain */
-    return 1;
-}
-
-
 /**  This function is needed to get LBOS hostname in different situations.
  *  @param priority_find_method[in]
  *   The first method to try to find LBOS. If it fails, default order of
@@ -676,24 +543,26 @@ int/*bool*/ g_LBOS_CheckDomain(const char* lbos_address)
  *   3) LBOS for current /etc/ncbi/{role, domain}.
  *   To not specify default method, use eLBOSFindMethod_None.
  *  @param lbos_addr[in]
- *   If priority_find_method is eLBOSFindMethod_CustomHost, then LBOS is
+ *   If priority_find_method is eLBOS_FindMethod_CustomHost, then LBOS is
  *   first looked for at hostname:port specified in this variable.           */
 char* g_LBOS_GetLBOSAddressEx (ELBOSFindMethod priority_find_method,
                                 const char* lbos_addr)
 {
+#if defined NCBI_OS_LINUX || defined NCBI_OS_MSWIN
     const char* lbosaddress = NULL; /* for const strings */
+#endif /* defined NCBI_OS_LINUX || defined NCBI_OS_MSWIN */
     char* lbosaddress_temp = NULL;  /* for non-const strings */
     char* address = NULL;
     /* List of methods used, in their order */
     ELBOSFindMethod find_method_order[] = {
                priority_find_method /* eLBOSFindMethod_None, if not specified*/
-               , eLBOSFindMethod_Registry
-               , eLBOSFindMethod_Lbosresolve
+               , eLBOS_FindMethod_Registry
+               , eLBOS_FindMethod_Lbosresolve
     };
     size_t find_method_iter;
     size_t find_method_count = 
         sizeof(find_method_order) / sizeof(ELBOSFindMethod);
-    CORE_LOG_X(1, eLOG_Trace, "Getting LBOS addresses...");
+    CORE_LOG(eLOG_Trace, "Getting LBOS addresses...");
     /* Iterate through methods of finding LBOS address */
     for (find_method_iter = 0;  
          find_method_iter < find_method_count;
@@ -705,7 +574,7 @@ char* g_LBOS_GetLBOSAddressEx (ELBOSFindMethod priority_find_method,
         switch (find_method_order[find_method_iter]) {
         case eLBOSFindMethod_None :
             break;
-        case eLBOSFindMethod_CustomHost :
+        case eLBOS_FindMethod_CustomHost :
             if (g_LBOS_StringIsNullOrEmpty(lbos_addr)) {
                 CORE_LOG_X(1, eLOG_Warning, "Use of custom LBOS address was "
                            "asked for, but no custom address was supplied. "
@@ -718,7 +587,7 @@ char* g_LBOS_GetLBOSAddressEx (ELBOSFindMethod priority_find_method,
                            "LBOS address. Probably insufficient RAM.");
             }
             break;
-        case eLBOSFindMethod_Lbosresolve :
+        case eLBOS_FindMethod_Lbosresolve :
 #if defined NCBI_OS_LINUX || defined NCBI_OS_MSWIN
             lbosaddress = s_LBOS_ReadLbosresolver();
             if (g_LBOS_StringIsNullOrEmpty(lbosaddress)) {
@@ -727,9 +596,9 @@ char* g_LBOS_GetLBOSAddressEx (ELBOSFindMethod priority_find_method,
             } else {
                 address = strdup(lbosaddress);
             }
-#endif
+#endif /* defined NCBI_OS_LINUX || defined NCBI_OS_MSWIN */
             break;
-        case eLBOSFindMethod_Registry:
+        case eLBOS_FindMethod_Registry:
             lbosaddress_temp = g_LBOS_RegGet("CONN", "lbos", NULL);
             if (g_LBOS_StringIsNullOrEmpty(lbosaddress_temp)) {
                 CORE_LOG_X(1, eLOG_Warning, "Trying to find LBOS in "
@@ -758,6 +627,7 @@ char* g_LBOS_GetLBOSAddress(void)
 /*/////////////////////////////////////////////////////////////////////////////
 //                    STATIC CONVENIENCE FUNCTIONS                           //
 /////////////////////////////////////////////////////////////////////////////*/
+#if 0 /* deprecated, remove on or after July 9 2016 */
 /** Get role of current host. Returned string is read-only, may reside in 
  * 'data' memory area                                                        */
 static const char* s_LBOS_ReadRole()
@@ -829,155 +699,114 @@ static const char* s_LBOS_ReadRole()
     return s_LBOS_CurrentRole;
 }
 
+#endif /* 0 */
 
-/** Get domain of current host. Do not modify or clear the returned string!
- * Returned string is read-only, may reside in 'data' memory area            */
-static const char* s_LBOS_ReadDomain()
-{
-    /*
-     * If no domain has been previously read, fill it
-     */
-    if (s_LBOS_CurrentDomain == NULL) {
-        char* registry_domain = NULL; /* if registry has domain specified
-                                       * for LBOS First, we check registry
-                                       * and then if nothing there, we check
-                                       * /etc/ncbi/domain                    */
-        registry_domain = g_LBOS_RegGet("CONN", kLBOSDomainVariable, NULL);
-        CORE_LOCK_WRITE;
-        if (!g_LBOS_StringIsNullOrEmpty(registry_domain)
-                && s_LBOS_CurrentDomain == NULL)
-        {
-            s_LBOS_CurrentDomain = registry_domain;
-        } else {
-            free(registry_domain);
-        }
-        CORE_UNLOCK;
-        if (s_LBOS_CurrentDomain != NULL)
-            return s_LBOS_CurrentDomain;
-
-#ifdef NCBI_OS_LINUX
-        else { /* If nothing found in registry, check /etc/ncbi/domain */
-            FILE* domain_file;
-            size_t len;
-            char str[kMaxLineSize];
-            char* read_result; /* during function will become equal either NULL 
-                               or str, do not free() */
-            if ((domain_file = fopen(kDomainFile, "r")) == NULL) {
-                CORE_LOGF(eLOG_Warning, ("s_LBOS_ReadDomain: "
-                                         "could not open domain file %s",
-                                         kDomainFile));
-                return NULL;
-            }
-            read_result = fgets(str, sizeof(str), domain_file);
-            fclose(domain_file);
-            if (read_result == NULL) {
-                CORE_LOG(eLOG_Warning, "s_LBOS_ReadDomain: "
-                                       "memory allocation failed");
-                return NULL;
-            }
-            len = strlen(str);
-            assert(len);
-            /*We remove unnecessary '/n' and probably '/r'   */
-            if (str[len - 1] == '\n') {
-                if (--len && str[len - 1] == '\r')
-                    --len;
-                str[len] = '\0';
-            }
-            if (g_LBOS_StringIsNullOrEmpty(str)) {
-                /* No domain recognized */
-                CORE_LOGF(eLOG_Warning,
-                          ("s_LBOS_ComposeLBOSAddress: domain file"
-                          "%s is empty, skipping this method",
-                          kDomainFile));
-                free(read_result);
-                return NULL;
-            }
-            CORE_LOCK_WRITE;
-            /* Check one more time that no other thread managed to fill
-                * static variable ahead of this thread. If this happened,
-                * release memory */
-            if (s_LBOS_CurrentDomain == NULL)
-                s_LBOS_CurrentDomain = strdup(str);
-            CORE_UNLOCK;
-        }
-#endif /* #ifdef NCBI_OS_LINUX */
-    }
-    return s_LBOS_CurrentDomain;
-}
-
-
-/** Get domain of current host. Do not modify or clear the returned string!
- * Returned string is read-only, may reside in 'data' memory area            */
+#if defined NCBI_OS_LINUX || defined NCBI_OS_MSWIN
+/**  Read contents of lbosresolver
+ *
+ *  @warning 
+ *   Do not modify or clear the returned string! Returned string is 
+ *   read-only  
+ */
 static const char* s_LBOS_ReadLbosresolver(void)
 {
-#ifdef NCBI_OS_LINUX
-    if (s_LBOS_Lbosresolver == NULL) {
-        FILE* lbosresolver_file;
-        size_t len;
-        char str[kMaxLineSize];
-        char* read_result; /* during function will become equal either NULL
-                           or str, do not free() */
-        if ((lbosresolver_file = fopen(kLbosresolverFile, "r")) == NULL) {
-            CORE_LOGF(eLOG_Warning, ("LBOS mapper: "
-                                     "could not open lbosresolve file %s",
-                                     kLbosresolverFile));
-            return NULL;
-        }
-        read_result = fgets(str, sizeof(str), lbosresolver_file);
-        fclose(lbosresolver_file);
-        if (read_result == NULL) {
-            CORE_LOG(eLOG_Warning, "s_LBOS_ReadLBOSResolve: "
-                                   "memory allocation failed");
-            return NULL;
-        }
-        len = strlen(str);
-        assert(len);
-        /*We remove unnecessary '/n' and probably '/r'   */
-        if (str[len - 1] == '\n') {
-            if (--len && str[len - 1] == '\r')
-                --len;
-            str[len] = '\0';
-        }
-        if (g_LBOS_StringIsNullOrEmpty(str)) {
-            /* No domain recognized */
-            CORE_LOGF(eLOG_Warning,
-                      ("LBOS mapper: /etc/ncbi/lbosresolve file"
-                      "%s is empty, no LBOS address available",
-                      kLbosresolverFile));
-            free(read_result);
-            return NULL;
+    if (s_LBOS_Lbosresolver != NULL) {
+        return s_LBOS_Lbosresolver;
+    }
+
+    FILE* lbosresolver_file;
+    size_t len;
+    char str[kMaxLineSize];
+    char* read_result; /* during function will become equal either NULL
+                        or str, do not free() */
+    if ((lbosresolver_file = fopen(kLbosresolverFile, "r")) == NULL) {
+        CORE_LOGF(eLOG_Warning, ("LBOS mapper: "
+                                 "could not open file %s",
+                                 kLbosresolverFile));
+        return NULL;
+    }
+    read_result = fgets(str, sizeof(str), lbosresolver_file);
+    fclose(lbosresolver_file);
+    if (read_result == NULL) {
+        CORE_LOG(eLOG_Warning, "s_LBOS_ReadLBOSResolve: "
+                               "memory allocation failed");
+        return NULL;
+    }
+    len = strlen(str);
+    assert(len);
+    if (g_LBOS_StringIsNullOrEmpty(str)) {
+        /* No domain recognized */
+        CORE_LOGF(eLOG_Warning,
+                  ("LBOS mapper: file %s is empty, no LBOS address available",
+                   kLbosresolverFile));
+        free(read_result);
+        return NULL;
+    }
+    /*We remove unnecessary '/n' and probably '/r'   */
+    if (str[len - 1] == '\n') {
+        if (--len && str[len - 1] == '\r') {
+            --len;
         }
-        CORE_LOCK_WRITE;
-        /* Check one more time that no other thread managed to fill
-            * static variable ahead of this thread. If this happened,
-            * release memory */
-        if (s_LBOS_Lbosresolver == NULL)
-            /* We skip "http://" and "/lbos" */
-            str[strlen(str) - strlen("/lbos")] = '\0';
-            s_LBOS_Lbosresolver = strdup(str + 7);
-        CORE_UNLOCK;
+        str[len] = '\0';
     }
-#endif /* #ifdef NCBI_OS_LINUX */
+    CORE_LOCK_WRITE;
+    /* Check one more time that no other thread managed to fill
+        * static variable ahead of this thread. If this happened,
+        * release memory */
+    if (s_LBOS_Lbosresolver == NULL)
+        /* We skip "http://" and "/lbos" */
+        str[strlen(str) - strlen("/lbos")] = '\0';
+        s_LBOS_Lbosresolver = strdup(str + 7);
+    CORE_UNLOCK;
+    
     return s_LBOS_Lbosresolver;
 }
+#endif  /* defined NCBI_OS_LINUX || defined NCBI_OS_MSWIN */
 
 
-/**   Takes original string and returns URL-encoded string. Original string
- *  is untouched.
+/**  Take original string and return URL-encoded string.
+ *  @attention
+ *   Original string is untouched. Caller is responsible for freeing
+ *   allocated space.
  */
-char* s_LBOS_URLEncode (const char* to_encode)
+static char* s_LBOS_URLEncode (const char* to_encode)
 {
     /* If all symbols are escape, our string will take triple space */
     size_t encoded_string_buf_size = strlen(to_encode)*3 + 1;
     char* encoded_string = (char*)calloc(encoded_string_buf_size, 
                                          sizeof(char));
-    size_t src_read, dst_written; /*strange things needed by URL_Encode*/
+    size_t src_read, dst_written; /* strange things needed by URL_Encode */
     URL_Encode(to_encode, strlen(to_encode), &src_read,
                encoded_string, encoded_string_buf_size, &dst_written);
     return encoded_string;
 }
 
 
+/**  Function to convert legacy service names for LBOS.
+ *   Takes service name and if it does not start with '/', prepends "/Legacy"
+ *   to it. 
+ *  @attention 
+ *   Original string is untouched. Caller is responsible for freeing
+ *   allocated space.
+ *  @warning
+ *   to_modify MUST be a valid non-empty C-string 
+ */
+char* s_LBOS_ModifyServiceName (const char* to_modify)
+{
+    /* If all symbols are escape, our string will take triple space */
+    static const char* prefix = "/Legacy/";
+    if (to_modify[0] == '/')
+        return strdup(to_modify);
+    /* We deal with legacy service name. First, get "/Legacy/" prefix, then
+     * change to_modify to lower register, concatenate them and return */
+    char* modified_str = strdup(prefix);
+    char* service_lwr = strlwr(strdup(to_modify));
+    modified_str = g_LBOS_StringConcat(modified_str, service_lwr, NULL);
+    free(service_lwr);
+    return modified_str;
+}
+
+
 /** @brief Just connect and return connection
  *
  *  Internal function to create connection, which simplifies process
@@ -1045,8 +874,9 @@ static char * s_LBOS_UrlReadAll(SConnNetInfo*   net_info,
     size_t        totalBufSize;
     char*         realloc_result;
 
-    /* Not to handle case when status_code is NULL, we use internal variable,
-       and only try to set status_code in the end of this function */
+    /* Not to handle case when 'status_code' is NULL, we use internal variable,
+     * and only try to set 'status_code' in the end of this function (and if it 
+     * is NULL, we do not set it) */
     user_data.http_response_code = 0;
     /* The same for status_message */
     user_data.http_status_mesage = NULL;
@@ -1098,24 +928,7 @@ static char * s_LBOS_UrlReadAll(SConnNetInfo*   net_info,
         totalRead += bytesRead;
 
         buf[totalRead] = 0; /* force end of string */
-#if 0
-        /* If we have read enough and use PUT or DELETE methods,
-         * exit this loop */
-        if (
-                totalRead >= user_data.content_length
-                /*&&
-                (   net_info->req_method == eReqMethod_Put
-                    ||
-                    net_info->req_method == eReqMethod_Delete
-                )*/
-            )
-        {
-            CONN_Flush(conn);
-            CONN_SetTimeout(conn, eIO_Close, &kLBOSZeroTimeout);
-            SOCK_CloseEx(sock, 0/*retain SOCK*/);
-            break;
-        }
-#endif
+
         /* IF we still have to read - then add space to buffer, if needed  */
         if ( status == eIO_Success && totalBufSize < totalRead * 2 )
         {
@@ -1150,7 +963,7 @@ static char * s_LBOS_UrlReadAll(SConnNetInfo*   net_info,
  *   Uses LBZK at specified IP and port.
  */
 static SSERV_Info** s_LBOS_ResolveIPPort(const char* lbos_address,
-                                         const char* serviceName,
+                                         const char* service_name,
                                          SConnNetInfo* net_info)
 { 
     SSERV_Info** infos;
@@ -1165,10 +978,6 @@ static SSERV_Info** s_LBOS_ResolveIPPort(const char* lbos_address,
     size_t user_dtab_length;
     char* new_dtab = NULL;
     char* user_dtab_end;
-    char* token = NULL, *saveptr = NULL, *str = NULL, *opt_param = NULL;
-#ifdef _DEBUG
-    char hostport[kHostportStringLength]; //just for debug
-#endif
     /* Allocate space for answer (will be expanded later, if needed) */
     infos = (SSERV_Info**)calloc(2, sizeof(SSERV_Info*));
     if (infos == NULL) {
@@ -1183,8 +992,7 @@ static SSERV_Info** s_LBOS_ResolveIPPort(const char* lbos_address,
     /* First, we look if there is DTab-Local already in header*/
     char* old_header = net_info->http_user_header ?
             strdup(net_info->http_user_header) : NULL;
-    user_dtab = g_LBOS_strcasestr(net_info->http_user_header, 
-                                              "DTab-local:");
+    user_dtab = g_LBOS_strcasestr(net_info->http_user_header, "DTab-local:");
     /* If there is an already defined local DTab, we mix it with one from 
      * registry */
     if (user_dtab != NULL) 
@@ -1224,10 +1032,10 @@ static SSERV_Info** s_LBOS_ResolveIPPort(const char* lbos_address,
         ConnNetInfo_OverrideUserHeader(net_info, new_dtab);
         free(new_dtab);
     }
-    servicename_url_encoded = s_LBOS_URLEncode(serviceName);
-  /*encode service name to url encoding (change ' ' to %20, '/' to %2f, etc.)*/
-    url_length = strlen("http://") + strlen(lbos_address) +
-            strlen(kLBOSQuery) + strlen(servicename_url_encoded);
+    servicename_url_encoded = s_LBOS_ModifyServiceName(service_name);
+   /*encode service name to url encoding (change ' ' to %20, '/' to %2f, etc.)*/
+    url_length = strlen("http://")  + strlen(lbos_address) +
+                 strlen(kLBOSQuery) + strlen(servicename_url_encoded);
     url = (char*)malloc(sizeof(char) * url_length + 1); /** to make up
                                                    LBOS query URI to connect*/
     if (url == NULL)
@@ -1252,53 +1060,90 @@ static SSERV_Info** s_LBOS_ResolveIPPort(const char* lbos_address,
         free(infos);
         return NULL;
     }
-    /*
-     * We read all the answer, find host:port in the answer and fill
-     * 'hostports', occasionally reallocating array, if needed
-     */
-    for (str = lbos_answer  ;  ;  str = NULL) {
-        SSERV_Info * info;
-#ifdef NCBI_COMPILER_MSVC
-        token = strtok_s(str, "\n", &saveptr);
-#else
-        token = strtok_r(str, "\n", &saveptr);
-#endif
-        if (token == NULL) {
-            break;
-        }
-        if ((opt_param = strstr(token, " | ")) != NULL) {
-            *opt_param = 0;
+    x_JSON_Value  *root_value;
+    x_JSON_Object *root_obj;
+    x_JSON_Object *services;
+    x_JSON_Array  *serviceEndpoints;
+    x_JSON_Object *serviceEndpoint;
+    unsigned int j = 0;
+    root_value = x_json_parse_string(lbos_answer);
+    if (x_json_value_get_type(root_value) != JSONObject) {
+        goto clean_and_exit;
+    }
+    root_obj = x_json_value_get_object(root_value);
+    services = x_json_object_get_object(root_obj, "services");
+    /* Get endpoints for the first service name. 
+     * Note: Multiple service resolution is not supported intentionally 
+     * (yet). */
+    serviceEndpoints = 
+        x_json_object_get_array(services, x_json_object_get_name(services, 0));
+    /* Iterate through endpoints */
+    for (j = 0;  j < x_json_array_get_count(serviceEndpoints);  j++) {
+        const char *host, *rate, *extra, *type;
+        char* server_description;
+        const char* descr_format = "%s %s:%u %s Regular R=%s L=no T=25";
+        int port;
+        serviceEndpoint = x_json_array_get_object(serviceEndpoints, j);
+        host = x_json_object_dotget_string(serviceEndpoint,
+                                         "serviceEndpoint.host");
+        if (host == NULL) {
+            continue;
         }
-        info = SERV_ReadInfoEx(token, serviceName, 0);
-        /* Occasionally, the info returned by LBOS can be invalid. */
+        port = (int)x_json_object_dotget_number(serviceEndpoint,
+                                              "serviceEndpoint.port");
+        /* -------------rate------------- */
+        rate = x_json_object_dotget_string(serviceEndpoint,
+                                         "meta.rate");
+        rate = !g_LBOS_StringIsNullOrEmpty(rate) ? rate : "1";
+        /* -------------type------------- */
+        type = x_json_object_dotget_string(serviceEndpoint,
+                                         "meta.type");
+        type = !g_LBOS_StringIsNullOrEmpty(type) ? type : "STANDALONE";
+        /* -------------extra------------- */
+        extra = x_json_object_dotget_string(serviceEndpoint,
+                                         "meta.extra");
+        extra = !g_LBOS_StringIsNullOrEmpty(extra) ? extra : "";
+
+        /* Examples: 
+           HTTP - accn2gi
+           DNS  - alndbasn_lb
+           STANDALONE - aligndb_dbldd 
+           HTTP_POST - taxservice3test
+           NCBID - taxservice/mapviewaugust2011*/
+        size_t length; /* used to count size to allocate for server_description,
+                          and then for g_LBOS_StringConcat*/
+        /* Occasionally, we are not able to allocate memory */
+        length = strlen(descr_format) + strlen(type) + strlen(host) + 
+                 5 /*length of port*/ + strlen(extra) + strlen(rate);
+        server_description = malloc(sizeof(char) * length);
+        sprintf(server_description, descr_format, type, host, 
+                port, extra, rate);
+        SSERV_Info * info = SERV_ReadInfoEx(server_description,service_name, 0);
+        free(server_description);
         if (info == NULL) {
             continue;
         }
-        /* We check if we have at least two more places: one for current
-            * info and one for finalizing NULL
-            */
         if (infos_capacity <= infos_count + 1) {
-            SSERV_Info** realloc_result = (SSERV_Info**)realloc(infos,
-                    sizeof(SSERV_Info*) * (infos_capacity*2 + 1));
+            SSERV_Info** realloc_result = 
+                (SSERV_Info**)realloc(infos, sizeof(SSERV_Info*) * 
+                                             (infos_capacity*2 + 1));
             if (realloc_result == NULL) {
-                /* If error with realloc, return as much as could allocate
-                    * for*/
-                infos_count--; /*Will just rewrite last info with NULL to
-                                    mark end of array*/
+                /* If error with realloc, return as much as could 
+                 * allocate for */
+                infos_count--; /* Will just rewrite last info with NULL 
+                                * to mark end of array*/
+                free(info);
                 break;
-            } else { /*If realloc successful */
+            } else { /* If realloc successful */
                 infos = realloc_result;
                 infos_capacity = infos_capacity*2 + 1;
             }
         }
         infos[infos_count++] = info;
-#ifdef _DEBUG
-        SOCK_HostPortToString(info->host, info->port, hostport,
-                kHostportStringLength);
-        /*Copy IP from stream to the result char array*/
-        CORE_LOGF(eLOG_Note, ("Resolved [%s] to [%s]", serviceName, hostport));
-#endif
     }
+
+clean_and_exit:
+    x_json_value_free(root_value);
     free(lbos_answer);
     /* Shuffle list with Durstenfeld's shuffle algorithm 
      * (also credits go to Fisher and Yates, and Knuth) */
@@ -1406,6 +1251,11 @@ static int s_LBOS_CheckAnnounceArgs(const char* service,
     if (!g_LBOS_StringIsNullOrEmpty(host)) {
         for (i = 0;  i < strlen(host);  i++) {
             if (!isalnum(host[i]) && (host[i] != '.')) {
+                CORE_LOG(eLOG_Critical, "Error with announcement, " 
+                                        "ip has incorrect format "
+                                        "(only digits and dots are allowed). "
+                                        "Please provide resolved IP to "
+                                        "avoid this error");
                 return 0;
             }
         }
@@ -1433,9 +1283,9 @@ static int s_LBOS_CheckAnnounceArgs(const char* service,
 }
 
 
-static int s_LBOS_CheckDeannounceArgs(const char* service,
-                                      const char* version,
-                                      const char* host,
+static int s_LBOS_CheckDeannounceArgs(const char*    service,
+                                      const char*    version,
+                                      const char*    host,
                                       unsigned short port)
 {
     if (!g_LBOS_StringIsNullOrEmpty(host) && strstr(host, ":") != NULL) {
@@ -1485,30 +1335,18 @@ static unsigned short s_LBOS_PerformRequest(const char* request,
      * return error code. If we receive nothing (LBOS is not present), then
      * we save nothing.
      */
-    net_info                = ConnNetInfo_Clone(s_EmptyNetInfo);
-    net_info->req_method    = req_method;
-    buf                     = NULL;
-    status_code             = 0;
-    lbos_address            = s_LBOS_Instance;
-    /* We deny foreign de-announcement*/
-    /* Compare local domain and LBOS domain */
-    if (!g_LBOS_CheckDomain(lbos_address)) {
-        CORE_LOGF_X(1, eLOG_Error,
-                    ("Could not verify that [%s] is in local domain [%s]. "
-                    "Announcement in foreign domain is not allowed. "
-                    "If you omitted [%s] in the LBOS address - please, "
-                    "provide it.",
-                    lbos_address, s_LBOS_ReadDomain(), s_LBOS_ReadDomain()));
-    }
-    else { /* domain is good */
-        query = g_LBOS_StringConcat(g_LBOS_StringConcat(
-                                    strdup("http://"), lbos_address, &length),
-                                    request, &length);
-        length = strlen(query);
-        buf = s_LBOS_UrlReadAll(net_info, query, &status_code, 
-                                &status_message);
-        free(query);
-    }
+    net_info             = ConnNetInfo_Clone(s_EmptyNetInfo);
+    net_info->req_method = req_method;
+    buf                  = NULL;
+    status_code          = 0;
+    lbos_address         = s_LBOS_Instance;
+    query                = g_LBOS_StringConcat(g_LBOS_StringConcat(
+                                strdup("http://"), lbos_address, &length),
+                                request, &length);
+    length               = strlen(query);
+    buf                  = s_LBOS_UrlReadAll(net_info, query, &status_code, 
+                                             &status_message);
+    free(query);
     if (lbos_answer != NULL && !g_LBOS_StringIsNullOrEmpty(buf)) {
         *lbos_answer = strdup(buf);
     }
@@ -1519,14 +1357,18 @@ static unsigned short s_LBOS_PerformRequest(const char* request,
     free(status_message);
 
     if (status_code == 0) {
-        status_code = kLBOSNoLBOS;
+        status_code = eLBOS_LbosNotFound;
     }
     /* Cleanup */
     ConnNetInfo_Destroy(net_info);
     return status_code;
 }
 
-
+/**  Find "0.0.0.0" in healthcheck_url and replace it with IP of current host
+ *  @attention
+ *   Original string is untouched. Caller is responsible for freeing
+ *   allocated space.
+ */
 static char* s_LBOS_Replace0000WithIP(const char* healthcheck_url)
 {
     size_t          chars_to_copy;
@@ -1535,6 +1377,7 @@ static char* s_LBOS_Replace0000WithIP(const char* healthcheck_url)
     size_t          length;
     /* new url with replaced "0.0.0.0" (if needed) */
     char*           my_healthcheck_url; 
+    unsigned int    local_host_ip;
     const char*     replace_pos; /* to check if there is 0.0.0.0 */
     if (healthcheck_url == NULL)
         return NULL;
@@ -1553,8 +1396,7 @@ static char* s_LBOS_Replace0000WithIP(const char* healthcheck_url)
     }
     chars_to_copy   = replace_pos - healthcheck_url;
     query           = replace_pos + strlen("0.0.0.0");
-    unsigned int local_host_ip =
-            g_LBOS_UnitTesting_GetLBOSFuncs()->LocalHostAddr(eDefault);
+    local_host_ip = g_LBOS_UnitTesting_GetLBOSFuncs()->LocalHostAddr(eDefault);
     if (local_host_ip == 0) {
         CORE_LOG(eLOG_Warning,
                  "Error with announcement, cannot find local IP.");
@@ -1562,7 +1404,7 @@ static char* s_LBOS_Replace0000WithIP(const char* healthcheck_url)
         return NULL;
     }
     SOCK_HostPortToString(local_host_ip, 0, hostname, kMaxLineSize - 1);
-    if (hostname == NULL) {
+    if (strlen(hostname) == 0) {
         CORE_LOG(eLOG_Warning,
                  "Error with announcement, cannot find local IP.");
         free(my_healthcheck_url);
@@ -1579,6 +1421,17 @@ static char* s_LBOS_Replace0000WithIP(const char* healthcheck_url)
 }
 
 
+static int s_TurnOn()
+{
+    if (s_LBOS_Init == 0) {
+        s_LBOS_funcs.Initialize();
+    }
+    if (s_LBOS_TurnedOn == 0) {
+        return 0;
+    }
+    return 1;
+}
+
 /*/////////////////////////////////////////////////////////////////////////////
 //                             UNIT TESTING                                  //
 /////////////////////////////////////////////////////////////////////////////*/
@@ -1620,26 +1473,6 @@ char** g_LBOS_UnitTesting_Instance(void)
 }
 
 
-/**  Pointer to s_LBOS_CurrentDomain
- *  @return
- *   address of static variable s_LBOS_CurrentDomain.
- *  @see                                                                     */
-char** g_LBOS_UnitTesting_CurrentDomain(void)
-{
-    return &s_LBOS_CurrentDomain;
-}
-
-
-/**  Pointer to s_LBOS_CurrentRole
- *  @return
- *   address of static variable s_LBOS_CurrentRole.
- *  @see                                                                     */
-char** g_LBOS_UnitTesting_CurrentRole(void)
-{
-    return &s_LBOS_CurrentRole;
-}
-
-
 /**  Pointer to s_LBOS_CurrentRole
  *  @return
  *   address of static variable s_LBOS_CurrentRole.
@@ -1661,29 +1494,20 @@ int/*bool*/ g_LBOS_UnitTesting_SetLBOSFindMethod (SERV_ITER       iter,
 }
 
 
-int/*bool*/ g_LBOS_UnitTesting_SetLBOSRoleDomainResolverFile
-                                                 (const char* roleFile,
-                                                  const char* domainFile,
-                                                  const char* lbosresolverfile)
+int/*bool*/ g_LBOS_UnitTesting_SetLBOSResolverFile(const char* resolverfile)
 {
-    if (roleFile != NULL) {
-        kRoleFile = roleFile;
-    }
-    if (domainFile != NULL) {
-        kDomainFile = domainFile;
-    }
-    if (lbosresolverfile != NULL) {
-        kLbosresolverFile = lbosresolverfile;
+    if (resolverfile != NULL) {
+        kLbosresolverFile = resolverfile;
+        return 1;
     }
-    return 1;
+    return 0;
 }
 
 
-/* UNIT TESTING*/
-/**  Set custom address for LBOS. Can be both hostname:port and IP:port.
- *  Intended mostly for testing.
- * @param[in] iter
- *  Where to set address for LBOS. The settings is made for only one iterator*/
+/**  Set custom address for LBOS. Can be either hostname:port or IP:port.
+ *   Intended mostly for testing.
+ *  @param[in] iter
+ *   Where to set address for LBOS. Change is made only for this iterator */
 int/*bool*/ g_LBOS_UnitTesting_SetLBOSaddress (SERV_ITER iter, char* address) {
     SLBOS_Data* data;
     assert(g_LBOS_CheckIterator(iter, ELBOSIteratorCheckType_MustHaveData));
@@ -2052,10 +1876,7 @@ const SSERV_VTable* SERV_LBOS_Open( SERV_ITER            iter,
     SLBOS_Data* data;
     char* new_name = NULL; /* if we need to add dbaf */
     const char* orig_serv_name = iter->name; /* we may modify name with dbaf */
-    if (s_LBOS_Init == 0) {
-        s_LBOS_funcs.Initialize();
-    }
-    if (s_LBOS_TurnedOn == 0) {
+    if (!s_TurnOn()) {
         return NULL;
     }
     /*
@@ -2169,6 +1990,9 @@ unsigned short s_LBOS_Announce(const char*             service,
                                const char*             host,
                                unsigned short          port,
                                const char*             healthcheck_url,
+#ifdef LBOS_METADATA
+                               const char*             meta_args,
+#endif /* LBOS_METADATA */
                                /* lbos_answer is never NULL  */
                                char**                  lbos_answer,
                                char**                  http_status_message)
@@ -2182,122 +2006,116 @@ unsigned short s_LBOS_Announce(const char*             service,
     const char*     query_format        = NULL;
     char*           buf                 = NULL; /* for answer from LBOS */
     int             parsed_symbols = 0;
-    size_t length;
+    assert(!g_LBOS_StringIsNullOrEmpty(host));
+
+    if (!s_TurnOn())
+        return eLBOS_Disabled;
 
-    if (s_LBOS_Init == 0) {
-        s_LBOS_funcs.Initialize();
-    }
-    if (s_LBOS_TurnedOn == 0) {
-        return kLBOSOff;
-    }
     lbos_address         = s_LBOS_Instance;
     status_code          = 0;
     status_message       = NULL;
     net_info             = ConnNetInfo_Clone(s_EmptyNetInfo);
-    net_info->req_method = eReqMethod_Post;
-    query_format         = "http://%s/lbos/json/announce?name=%s&"
-                           "version=%s&port=%hu&check=%s";
+    net_info->req_method = eReqMethod_Put;
+    /* Format for announcement request. "ip" parameter is optional and  
+     * will be added separately, if provided */
+    query_format         = "http://%s/lbos/v3/services%s?version=%s&"
+                                                        "port=%hu&"
+                                                        "check=%s&"
+                                                        "ip=%s&"
+                                                        "format=json";
     /*
      * Let's try announce 
      */
     char* query;
-    /* We deny foreign announcement*/
-    /* Compare local domain and LBOS domain */
-    if (!g_LBOS_CheckDomain(lbos_address)) {
-        CORE_LOGF_X(1, eLOG_Warning, 
-                    ("[%s] is not from local domain [%s]. "
-                    "Announcement in foreign domain is not allowed.",
-                    lbos_address, s_LBOS_ReadDomain()));    
-    } else {
-        query = (char*)calloc(strlen(query_format) + 
-                              strlen(lbos_address) + 
-                              strlen(service) + strlen(version) +
-                              5/* port */ + strlen(healthcheck_url),
-                              sizeof(char));
-        sprintf(query,
-                query_format,
-                lbos_address, service, version, port, healthcheck_url);
-        length = strlen(query);
-        /* If host was provided, we append it to query */
-        if (!g_LBOS_StringIsNullOrEmpty(host)) {
-            query = g_LBOS_StringConcat(g_LBOS_StringConcat(
-                                                    query,  "&ip=", &length),
-                                                            host,   &length);
-        }
-        buf = s_LBOS_UrlReadAll(net_info, query, &status_code, 
-                                &status_message);
-        free(query);      
+    /* We do not count extra 1 byte for \0 because we still have extra 
+     * bytes because of %s placeholders in query_format */
+    query = (char*)calloc(strlen(query_format) + 
+                          strlen(lbos_address) + 
+                          strlen(service) + strlen(version) +
+                          5/* port */ + strlen(healthcheck_url) +
+                          strlen(host),
+                          sizeof(char));
+    sprintf(query, query_format,
+            lbos_address, service, version, port, healthcheck_url, host);
+    if (!g_LBOS_StringIsNullOrEmpty(meta_args)) {
+        query = g_LBOS_StringConcat(g_LBOS_StringConcat(
+            query, "&",       NULL), 
+                   meta_args, NULL);
     }
+    buf = s_LBOS_UrlReadAll(net_info, query, &status_code, &status_message);
+    free(query);
     if (!g_LBOS_StringIsNullOrEmpty(buf)) {
+        /* If this function is not able to parse LBOS output, original LBOS
+         * response will be available to the caller. Otherwise, content of 
+         * lbos_answer will be replaced with parsed IP address of LBOS watcher 
+         * a bit later */
         *lbos_answer = strdup(buf);
     }
     if (http_status_message != NULL && status_message != NULL) {
         *http_status_message = strdup(status_message);
     }
     free(status_message);
-    /* If no LBOS found */
-    if (status_code == 0) {
+    switch (status_code) {
+    case 0:
+        /* If no LBOS found */
         CORE_LOG(eLOG_Warning, "Announce failed. No LBOS found.");
-        status_code = kLBOSNoLBOS;
-        goto clear_and_exit;
-    }
-    /* If announced server has broken healthcheck */
-    if (status_code == kLBOSNotFound || status_code == kLBOSBadRequest  
-        || status_code == kLBOSServerError) 
-    {
+        status_code = eLBOS_LbosNotFound;
+        break;
+    case eLBOS_NotFound: case eLBOS_BadRequest: case eLBOS_Server:
+        /* If announced server has a broken healthcheck */
         CORE_LOGF(eLOG_Warning, ("Announce failed. "
                                  "LBOS returned error code %d.", status_code));
-        goto clear_and_exit;
-    }
-    /* If we could not announce, it is really bad */
-    if (status_code != 200) {
+        break;
+    case eLBOS_Success:
+        /* If we announced successfully and status_code is 200,
+         * let's extract LBOS address */
+        lbos_addr = (char*)calloc(kMaxLineSize, sizeof(char)); /* will not be 
+                                                                * free()'d */
+        if (lbos_addr == NULL) {
+            CORE_LOG(eLOG_Warning, "Failed memory allocation. Most likely, "
+                                   "not enough RAM.");
+            status_code = eLBOS_MemAlloc; 
+            break;
+        }
+        if (buf != NULL) {
+            parsed_symbols = sscanf(buf, "{\"watcher\":\"%[^\"]\"}", 
+                                    lbos_addr);
+        }
+        if (parsed_symbols != 1) {
+            CORE_LOG(eLOG_Warning, "g_LBOS_Announce: LBOS answered 200 OK, but "
+                                   "output could not be parsed");
+            free(lbos_addr);
+            status_code = eLBOS_Protocol; 
+            break;
+        } 
+        /* If announce finished with success, we parsed it to extract LBOS 
+         * ip:port. We free() original output and replace it with ip:port */
+        free(*lbos_answer);
+        *lbos_answer = lbos_addr;
+        /* If we could not announce, it is really bad */
+        break;
+    default:
         CORE_LOGF(eLOG_Warning, ("Announce failed. "
                                  "LBOS returned error code %d. "
                                  "LBOS answer: %s.", status_code, buf));
-        goto clear_and_exit;
-    }
-    /* If we announced successfully and status_code is 200,
-     * let's extract LBOS address */
-    lbos_addr = (char*)calloc(kMaxLineSize, sizeof(char)); /* will not be 
-                                                            * free()'d */
-    if (lbos_addr == NULL) {
-        CORE_LOG(eLOG_Warning, "Failed memory allocation. Most likely, "
-                               "not enough RAM.");
-        status_code = kLBOSMemAllocError;
-        goto clear_and_exit;
-    }
-    if (buf != NULL) {
-        parsed_symbols = sscanf(buf, "{\"watcher\":\"%[^\"]\"}", 
-                                lbos_addr);
-    }
-    if (parsed_symbols != 1) {
-        CORE_LOG(eLOG_Warning, "g_LBOS_Announce: LBOS answered 200 OK, but "
-                               "output could not be parsed");
-        free(lbos_addr);
-        status_code = kLBOSCorruptOutput;
-        goto clear_and_exit;
-    } else {
-    /* If announce finished with success, we parsed it to extract LBOS ip:port.
-     * We free() original output and replace it with ip:port                 */
-        free(*lbos_answer);
-        *lbos_answer = lbos_addr;
     }
-
     /* Cleanup */
-    clear_and_exit:
-        free(buf);
-        ConnNetInfo_Destroy(net_info);
+    free(buf);
+    ConnNetInfo_Destroy(net_info);
     return status_code;
 }
 
 
-unsigned short LBOS_Announce(const char*             service,
-                             const char*             version,
-                             const char*             host,
-                             unsigned short          port,
-                             const char*             healthcheck_url,
-                             char**                  lbos_answer,
-                             char**                  http_status_message)
+unsigned short LBOS_Announce(const char*    service,
+                             const char*    version,
+                             const char*    host,
+                             unsigned short port,
+                             const char*    healthcheck_url,
+#ifdef LBOS_METADATA
+                             const char*    meta_args,
+#endif /* LBOS_METADATA */
+                             char**         lbos_answer,
+                             char**         http_status_message)
 {
     char*           my_healthcheck_url      = NULL;
     char*           healthcheck_encoded     = NULL;
@@ -2312,7 +2130,7 @@ unsigned short LBOS_Announce(const char*             service,
     if (s_LBOS_CheckAnnounceArgs(service, version, host, port, healthcheck_url,
                                  lbos_answer) == 0)
     {
-        return kLBOSInvalidArgs;
+        return eLBOS_InvalidArgs;
     }
     /*
      * Pre-assign variables
@@ -2323,15 +2141,37 @@ unsigned short LBOS_Announce(const char*             service,
 
 	/*my_healthcheck_url = strdup(healthcheck_url); */
     if (my_healthcheck_url == NULL) {
-        result = kLBOSDNSResolveError;
+        result = eLBOS_DNSResolve;
         goto clean_and_exit;
     }
     /* If host provided separately from healthcheck URL, check if we need to
      * replace 0.0.0.0 with local IP, and do it if needed                    */
-    my_host = s_LBOS_Replace0000WithIP(host);
+    if (!g_LBOS_StringIsNullOrEmpty(host)) {
+        my_host = s_LBOS_Replace0000WithIP(host);
+    }
+    else { /* If host was NOT provided, we append local IP to query,
+           * just in case */
+        SConnNetInfo * healthcheck_info;
+        healthcheck_info = ConnNetInfo_Clone(s_EmptyNetInfo);
+        healthcheck_info->host[0] = '\0'; /* to be sure that it will be
+                                          * overridden                      */
+        /* Save info about host */
+        ConnNetInfo_ParseURL(healthcheck_info, my_healthcheck_url);
+        my_host = strdup(healthcheck_info->host);
+        /* If we could not parse healthcheck URL, throw "Invalid Arguments" */
+        if (g_LBOS_StringIsNullOrEmpty(my_host)) {
+            ConnNetInfo_Destroy(healthcheck_info);
+            CORE_LOG_X(eLBOS_InvalidArgs, eLOG_Critical, 
+                       "Could not parse host from healthcheck URL. Please set "
+                       "ip of the announced server explicitly.");
+            result = eLBOS_InvalidArgs;
+            goto clean_and_exit;
+        }
+        ConnNetInfo_Destroy(healthcheck_info);
+    }
 
     healthcheck_encoded  = s_LBOS_URLEncode(my_healthcheck_url);
-    service_encoded      = s_LBOS_URLEncode(service);
+    service_encoded      = s_LBOS_ModifyServiceName(service);
     version_encoded      = s_LBOS_URLEncode(version);
 
     /* Announce */
@@ -2341,9 +2181,10 @@ unsigned short LBOS_Announce(const char*             service,
                                                           my_host,
                                                           port,
                                                           healthcheck_encoded, 
+                                                          meta_args,
                                                           lbos_answer,
                                                           http_status_message);     
-    if (result == kLBOSSuccess) {
+    if (result == eLBOS_Success) {
         CORE_LOCK_WRITE;
         s_LBOS_AddAnnouncedServer(service, version, port, healthcheck_url);
         CORE_UNLOCK;
@@ -2364,7 +2205,7 @@ unsigned short LBOS_AnnounceFromRegistry(const char*  registry_section,
                                          char**       lbos_answer,
                                          char**       http_status_message)
 {
-    unsigned short  result      = kLBOSSuccess;
+    unsigned short  result      = eLBOS_Success;
     size_t          i           = 0;
     unsigned int    port;
     char*           srvc;
@@ -2372,6 +2213,7 @@ unsigned short LBOS_AnnounceFromRegistry(const char*  registry_section,
     char*           port_str;
     char*           hlth;
     char*           host;
+    char*           meta;
 
     if (g_LBOS_StringIsNullOrEmpty(registry_section)) {
         registry_section = kLBOSAnnouncementSection;
@@ -2382,25 +2224,30 @@ unsigned short LBOS_AnnounceFromRegistry(const char*  registry_section,
     host      = g_LBOS_RegGet(registry_section, kLBOSServerHostVariable, NULL);
     hlth      = g_LBOS_RegGet(registry_section, kLBOSHealthcheckUrlVariable, 
                               NULL);
+    meta      = g_LBOS_RegGet(registry_section, kLBOSMetaVariable, 
+                              NULL);
     
     /* Check port that it is a number of max 5 digits and no other symbols   */
     for (i = 0;  i < strlen(port_str);  i++) {
         if (!isdigit(port_str[i])) {
-            result = kLBOSInvalidArgs;
+            CORE_LOGF_X(eLBOS_InvalidArgs, eLOG_Warning, 
+                        ("Port \"%s\" in section %s is invalid", port_str, 
+                        registry_section));
+            result = eLBOS_InvalidArgs;
             goto clean_and_exit;
         }
     }
     if (strlen(port_str) > 5 || (sscanf(port_str, "%d", &port) != 1) ||
         port < 1 || port > 65535) 
     {
-        result = kLBOSInvalidArgs;
+        result = eLBOS_InvalidArgs;
         goto clean_and_exit;
     }    
 
     /* Announce */    
-    result = LBOS_Announce(srvc, vers, host, (unsigned short)port, hlth,
+    result = LBOS_Announce(srvc, vers, host, (unsigned short)port, hlth, meta,
                            lbos_answer, http_status_message);    
-    if (result == kLBOSSuccess) {
+    if (result == eLBOS_Success) {
         CORE_LOCK_WRITE;
         s_LBOS_AddAnnouncedServer(srvc, vers, port, hlth);
         CORE_UNLOCK;
@@ -2413,10 +2260,12 @@ clean_and_exit:
     free(port_str);
     free(hlth);
     free(host);
+    free(meta);
     return result;
 }
 
-
+/* Separated from LBOS_Deannounce to easier control memory allocated for 
+ * variables */
 unsigned short s_LBOS_Deannounce(const char*      service,
                                const char*        version,
                                const char*        host,
@@ -2433,45 +2282,26 @@ unsigned short s_LBOS_Deannounce(const char*      service,
     lbos_address = s_LBOS_Instance;
     status_code = 0;
     buf = NULL;
-    query_format = "http://%s/lbos/json/conceal?name=%s&version=%s&port=%hu";
+    /* ip */
+    query_format = "http://%s/lbos/v3/services%s?version=%s&"
+                                                 "port=%hu&"
+                                                 "ip=%s";
     /*
     * Try deannounce
     */
     char* query;
-    size_t length;
-    /* We deny foreign de-announcement*/
-    /* Compare local domain and LBOS domain */
-    if (!g_LBOS_CheckDomain(lbos_address)) {
-        CORE_LOGF_X(1, eLOG_Warning,
-            ("[%s] is not from local domain [%s]. "
-            "Announcement in foreign domain is not allowed.",
-            lbos_address, s_LBOS_ReadDomain()));
-    }
-    else {
-        query = (char*)calloc(strlen(query_format) +
-                       strlen(lbos_address) + strlen(service) +
-                       strlen(version) + 5/*port*/,
-                       sizeof(char));
-        sprintf(query, query_format, lbos_address, service, version, port);
-        length = strlen(query);
-        /* If host was provided, we append it to query */
-        if (!g_LBOS_StringIsNullOrEmpty(host)) {
-            query = g_LBOS_StringConcat(g_LBOS_StringConcat(
-                                                query,    "&ip=",    &length),
-                                                          host,      &length);
-        }
-        else { /* If host was NOT provided, we append local IP to query,
-                * just in case */
-            char* local_ip = s_LBOS_Replace0000WithIP("0.0.0.0");
-            query = g_LBOS_StringConcat(g_LBOS_StringConcat(
-                                        query,   "&ip=",         &length),
-                                                  local_ip,      &length);
-            free(local_ip);
-        }
-        buf = s_LBOS_UrlReadAll(net_info, query, &status_code, 
-                                &status_message);
-        free(query);
-    }
+    assert(!g_LBOS_StringIsNullOrEmpty(host));
+    /* We do not count extra 1 byte for \0 because we still have extra 
+        * bytes because of %s placeholders */
+    query = (char*)calloc(strlen(query_format) +
+                          strlen(lbos_address) + strlen(service) +
+                          strlen(version) + 5/*port*/ + strlen(host),
+                          sizeof(char));
+    sprintf(query, query_format, 
+            lbos_address, service, version, port, host);
+    buf = s_LBOS_UrlReadAll(net_info, query, &status_code, 
+                            &status_message);
+    free(query);
     if (lbos_answer != NULL && !g_LBOS_StringIsNullOrEmpty(buf)) {
         *lbos_answer = strdup(buf);
     }
@@ -2482,7 +2312,7 @@ unsigned short s_LBOS_Deannounce(const char*      service,
     free(status_message);
 
     if (status_code == 0) {
-        status_code = kLBOSNoLBOS;
+        status_code = eLBOS_LbosNotFound;
     }
     return status_code;
 }
@@ -2504,16 +2334,13 @@ unsigned short LBOS_Deannounce(const char*        service,
      * First we check input arguments
      */
     if (s_LBOS_CheckDeannounceArgs(service, version, host, port) == 0) {
-        return kLBOSInvalidArgs;
+        return eLBOS_InvalidArgs;
     }
     /*
      * Check if LBOS is ON
      */
-    if (s_LBOS_Init == 0) {
-        s_LBOS_funcs.Initialize();
-    }
-    if (s_LBOS_TurnedOn == 0) {
-        return kLBOSOff;
+    if (!s_TurnOn()) {
+        return eLBOS_Disabled;
     }
     /*
      * If we are here, arguments are good!
@@ -2524,19 +2351,25 @@ unsigned short LBOS_Deannounce(const char*        service,
     else { /* If host was NOT provided, we append local IP to query,
            * just in case */
         my_host = s_LBOS_Replace0000WithIP("0.0.0.0");
+        if (g_LBOS_StringIsNullOrEmpty(my_host)){
+            CORE_LOG_X(eLBOS_DNSResolve, eLOG_Critical,
+                       "Did not manage to get local IP address.");
+            free(my_host);
+            return eLBOS_DNSResolve;
+        }
     }
     net_info             = ConnNetInfo_Clone(s_EmptyNetInfo);
-    net_info->req_method = eReqMethod_Post;
-    service_encoded      = s_LBOS_URLEncode(service);
+    net_info->req_method = eReqMethod_Delete;
+    service_encoded      = s_LBOS_ModifyServiceName(service);
     version_encoded      = s_LBOS_URLEncode(version);
     
     retval = s_LBOS_Deannounce(service_encoded, version_encoded, 
                                my_host, port, lbos_answer, 
                                http_status_message, net_info);
 
-    /* If kLBOSNotFound or kLBOSSuccess - we delete server from local storage
+    /* If eLBOS_NotFound or eLBOS_Success - we delete server from local storage
     * as no longer existing */
-    if (retval == kLBOSNotFound || retval == kLBOSSuccess) {
+    if (retval == eLBOS_NotFound || retval == eLBOS_Success) {
         CORE_LOCK_WRITE;
         s_LBOS_RemoveAnnouncedServer(service, version, port, host);
         CORE_UNLOCK;
@@ -2577,7 +2410,8 @@ void LBOS_DeannounceAll()
     local_arr = 
               (struct SLBOS_AnnounceHandle_Tag*)calloc(servers, sizeof(**arr)); 
     if (local_arr == NULL) {
-        CORE_LOG_X(1, eLOG_Warning, "RAM error. Cancelling deannounce all.");
+        CORE_LOG_X(eLBOS_MemAlloc, eLOG_Warning, 
+                   "RAM error. Cancelling deannounce all.");
         CORE_UNLOCK;
         return;
     }
@@ -2624,6 +2458,27 @@ void LBOS_DeannounceAll()
 /*/////////////////////////////////////////////////////////////////////////////
 //                             LBOS CONFIGURATION                            //
 /////////////////////////////////////////////////////////////////////////////*/
+static int s_LBOS_CheckConfArgs(const char* service, const char** lbos_answer)
+{
+    unsigned int i;
+    if (g_LBOS_StringIsNullOrEmpty(service)  ||  lbos_answer == NULL) {
+        CORE_LOG_X(eLBOS_InvalidArgs, eLOG_Warning, 
+                    "s_LBOS_CheckConfArgs: service is NULL or lbos_answer "
+                    "is NULL");
+        return 0;
+    }
+    for (i = 0;  i < strlen(service);  i++) {
+        if (isspace(service[i])) {
+            CORE_LOGF_X(eLBOS_InvalidArgs, eLOG_Warning, 
+                        ("s_LBOS_CheckConfArgs: service "
+                        "\"%s\" contains invalid character", service));
+            return 0;
+        }
+    }
+    return 1;
+}
+
+
 /** This request will show currently used version for a requested service.
  * Current and previous version will be the same.
  * @param service[in]
@@ -2646,23 +2501,21 @@ unsigned short LBOS_ServiceVersionGet(const char*  service,
     /*
      * First we check input arguments
      */
-    if (g_LBOS_StringIsNullOrEmpty(service) || lbos_answer == NULL) {
-        return kLBOSInvalidArgs;
+    if (!s_LBOS_CheckConfArgs(service, (const char**)lbos_answer)) {
+        return eLBOS_InvalidArgs;
     }
     /*
      * Check if LBOS is ON
      */
-    if (s_LBOS_Init == 0) {
-        s_LBOS_funcs.Initialize();
-    }
-    if (s_LBOS_TurnedOn == 0) {
-        return kLBOSOff;
+    if (!s_TurnOn()) {
+        return eLBOS_Disabled;
     }
+    
     /*
      * Arguments are good! Let's do the request
      */
-    service_encoded = s_LBOS_URLEncode(service);
-    query_format = "/lbos/xml/configuration?name=%s";
+    service_encoded = s_LBOS_ModifyServiceName(service);
+    query_format = "/lbos/v3/conf%s?format=xml";
     query = (char*)calloc(strlen(query_format) +
                           strlen(service_encoded),
                           sizeof(char));
@@ -2704,24 +2557,27 @@ unsigned short LBOS_ServiceVersionSet(const char*  service,
     /*
      * First we check input arguments
      */
-    if (g_LBOS_StringIsNullOrEmpty(service) || lbos_answer == NULL
-            || g_LBOS_StringIsNullOrEmpty(new_version)) {
-        return kLBOSInvalidArgs;
+    if (!s_LBOS_CheckConfArgs(service, (const char**)lbos_answer)) {
+        return eLBOS_InvalidArgs;
+    }
+    if (g_LBOS_StringIsNullOrEmpty(new_version)) {
+        CORE_LOG_X(eLBOS_InvalidArgs, eLOG_Warning, 
+                   "LBOS_ServiceVersionSet: new_version is empty. "
+                   "If you want to delete service config, use "
+                   "LBOS_ServiceVersionDelete");
+        return eLBOS_InvalidArgs;
     }
     /*
      * Check if LBOS is ON
      */
-    if (s_LBOS_Init == 0) {
-        s_LBOS_funcs.Initialize();
-    }
-    if (s_LBOS_TurnedOn == 0) {
-        return kLBOSOff;
+    if (!s_TurnOn()) {
+        return eLBOS_Disabled;
     }
     /*
      * Arguments are good! Let's do the request
      */
-    service_encoded = s_LBOS_URLEncode(service);
-    query_format = "/lbos/xml/configuration?name=%s&version=%s";
+    service_encoded = s_LBOS_ModifyServiceName(service);
+    query_format = "/lbos/v3/conf%s?version=%s&format=xml";
     query = (char*)calloc(strlen(query_format) +
                           strlen(service_encoded) +
                           strlen(new_version),
@@ -2754,23 +2610,20 @@ unsigned short LBOS_ServiceVersionDelete(const char*  service,
     /*
      * First we check input arguments
      */
-    if (g_LBOS_StringIsNullOrEmpty(service) || lbos_answer == NULL) {
-        return kLBOSInvalidArgs;
+    if (!s_LBOS_CheckConfArgs(service, (const char**)lbos_answer)) {
+        return eLBOS_InvalidArgs;
     }
     /*
      * Check if LBOS is ON
      */
-    if (s_LBOS_Init == 0) {
-        s_LBOS_funcs.Initialize();
-    }
-    if (s_LBOS_TurnedOn == 0) {
-        return kLBOSOff;
+    if (!s_TurnOn()) {
+        return eLBOS_Disabled;
     }
     /*
      * Arguments are good! Let's do the request
      */
-    service_encoded = s_LBOS_URLEncode(service);
-    query_format = "/lbos/xml/configuration?name=%s";
+    service_encoded = s_LBOS_ModifyServiceName(service);
+    query_format = "/lbos/v3/conf%s?format=xml";
     query = (char*)calloc(strlen(query_format) +
                           strlen(service_encoded),
                           sizeof(char));
diff --git a/c++/src/connect/ncbi_lbos.h b/c++/src/connect/ncbi_lbos.h
old mode 100755
new mode 100644
index a3c512f..05bd4de
--- a/c++/src/connect/ncbi_lbos.h
+++ b/c++/src/connect/ncbi_lbos.h
@@ -26,6 +26,7 @@
 * ===========================================================================
 *
 * Authors:  Dmitriy Elisov
+* Credits:  Denis Vakatov
 * @file
 * File Description:
 *   Possibly public interface to LBOS client if someone ever needs a C version
@@ -40,7 +41,10 @@
 extern "C" {
 #endif /*__cplusplus*/
 
-    
+
+#define LBOS_METADATA
+
+
 /** Announce server.
 *
 * @attention
@@ -66,6 +70,8 @@ extern "C" {
 *  announces it (i.e., if server announces itself), you can write
 *  "0.0.0.0" for IP (this is convention with lbos). You still have to
 *  provide port, even if you write "0.0.0.0".
+* @param [out] meta_args
+*  Array of meta arguments in form { "name1", "val1", "name2", "val2", NULL }
 * @param [out] lbos_answer
 *  This variable will be assigned a pointer to C-string with exact body of
 *  lbos' response (or NULL, if no lbos was reached).
@@ -89,6 +95,9 @@ unsigned short LBOS_Announce(const char*             service,
                              const char*             host,
                              unsigned short          port,
                              const char*             healthcheck_url,
+#ifdef LBOS_METADATA
+                             const char*             meta_args,
+#endif /* LBOS_METADATA */
                              char**                  lbos_answer,
                              char**                  http_status_message);
 
diff --git a/c++/src/connect/ncbi_lbos_cxx.cpp b/c++/src/connect/ncbi_lbos_cxx.cpp
old mode 100755
new mode 100644
index b3537b4..836e593
--- a/c++/src/connect/ncbi_lbos_cxx.cpp
+++ b/c++/src/connect/ncbi_lbos_cxx.cpp
@@ -24,6 +24,7 @@
  * ===========================================================================
  *
  * Authors:  Dmitriy Elisov
+ * Credits:  Denis Vakatov
  * @file
  * File Description:
  *   C++ Wrapper for the LBOS mapper written in C
@@ -42,13 +43,14 @@
 
 BEGIN_NCBI_SCOPE
 
-DEFINE_STATIC_FAST_MUTEX(s_GlobalLock);
-static const char* kLBOSAnnounceRegistrySection("LBOS_ANNOUNCEMENT");
-static const char* kLBOSServiceVariable("SERVICE");
-static const char* kLBOSVersionVariable("VERSION");
-static const char* kLBOSServerHostVariable("HOST");
-static const char* kLBOSPortVariable("PORT");
-static const char* kLBOSHealthcheckUrlVariable("HEALTHCHECK");
+DEFINE_STATIC_FAST_MUTEX(s_IPCacheLock);
+const string kLBOSAnnounceRegistrySection = "LBOS_ANNOUNCEMENT";
+const string kLBOSServiceVariable         = "SERVICE";
+const string kLBOSVersionVariable         = "VERSION";
+const string kLBOSServerHostVariable      = "HOST";
+const string kLBOSPortVariable            = "PORT";
+const string kLBOSHealthcheckUrlVariable  = "HEALTHCHECK";
+const string kLBOSMetaVariable            = "META";
 
 const SConnNetInfo* kEmptyNetInfo = ConnNetInfo_Create(NULL);
 
@@ -73,6 +75,10 @@ struct SLbosConfigure
     string current_version;
 };
 
+
+CSafeStatic< map< CLBOSIpCacheKey, string > > CLBOSIpCache::sm_IpCache;
+
+
 bool CLBOSIpCacheKey::operator==(const CLBOSIpCacheKey& rh) const
 {
     return x_Service == rh.x_Service &&
@@ -82,7 +88,10 @@ bool CLBOSIpCacheKey::operator==(const CLBOSIpCacheKey& rh) const
 }
 
 
-CLBOSIpCacheKey::CLBOSIpCacheKey(string service, string hostname, string version, unsigned short port) :
+CLBOSIpCacheKey::CLBOSIpCacheKey(const string& service,
+                                 const string& hostname,
+                                 const string& version,
+                                 unsigned short port) :
 x_Service(service), x_Hostname(hostname), x_Version(version),
 x_Port(port)
 {
@@ -109,77 +118,94 @@ bool CLBOSIpCacheKey::operator>(const CLBOSIpCacheKey& rh) const
 }
 
 
-std::string CLBOSIpCache::HostnameTryFind(string service, string hostname, 
-                                      string version, unsigned short port)
+std::string CLBOSIpCache::HostnameTryFind(const string& service,
+                                          const string& hostname_in,
+                                          const string& version, 
+                                          unsigned short port)
 {
-    if (hostname == "")
-        hostname = CSocketAPI::GetLocalHostAddress();
+    string hostname = hostname_in;
+    if (hostname.empty())
+        hostname = CSocketAPI::HostPortToString(
+                                          CSocketAPI::GetLocalHostAddress(), 0);
     map<CLBOSIpCacheKey, string>::iterator pos;
     CLBOSIpCacheKey key(service, hostname, version, port);
-    pos = x_IpCache->find(key);
-    if (pos != x_IpCache->end())
-        return pos->second;
-    else return hostname;
+    {{
+        CFastMutexGuard spawn_guard(s_IPCacheLock);
+        pos = sm_IpCache->find(key);
+        if (pos != sm_IpCache->end())
+            return pos->second;
+        else return hostname;
+    }}
 }
 
-std::string CLBOSIpCache::HostnameResolve(string service, string hostname, 
-                                      string version, unsigned short port)
+std::string CLBOSIpCache::HostnameResolve(const string& service,
+                                          const string& hostname,
+                                          const string& version,
+                                          unsigned short port)
 {
-    /* LBOS behavior - if DNS could not resolve hostname, throw 400 Bad Request.
-    * Here we emulate LBOS behavior.
-    * Here we try to resolve hostname before
-    * sending it to LBOS, so we should return the same answer as LBOS would
-    * do.*/
-    if (hostname == "") {
+    /* Hostname should not be empty in any case */
+    if (hostname.empty()) {
         throw CLBOSException(CDiagCompileInfo(__FILE__, __LINE__), NULL,
-            CLBOSException::EErrCode::e_LBOSBadRequest, "400 Bad Request",
-            kLBOSBadRequest);
+            CLBOSException::eUnknown, 
+            "Internal error in LBOS Client IP Cache. Please contact developer",
+            eLBOS_BadRequest);
     }
     map<CLBOSIpCacheKey, string>::iterator pos;
     CLBOSIpCacheKey key(service, hostname, version, port);
-    pos = x_IpCache->find(key);
-    /* If hostname is already in the cache, return previously resolved IP */
-    if (pos != x_IpCache->end())
-        return pos->second;
+    {{
+        CFastMutexGuard spawn_guard(s_IPCacheLock);
+        pos = sm_IpCache->find(key);
+        /* If hostname is already in the cache, return previously resolved IP */
+        if (pos != sm_IpCache->end())
+            return pos->second;
+
+    }}
     /* We did not find IP in the cache. Then we resolve the hostname to IP and
-       save it to the cache. To make sure that our changes do not interfere
-       with changes from another thread, we use 'insert' instead of '[]' (not
-       to rewrite) */
+        save it to the cache. To make sure that our changes do not interfere
+        with changes from another thread, we use 'insert' instead of '[]' (not
+           to rewrite) */
     string host =
         CSocketAPI::HostPortToString(CSocketAPI::gethostbyname(hostname), 0);
     /* If gethostbyname() could not resolve the hostname, it will return ":0".
-       In this case we go back to the original hostname, so that LBOS can try 
-       to resolve it itself. */
+        In this case we go back to the original hostname, so that LBOS can try 
+        to resolve it itself. */
     if (host == ":0") {
         host = hostname; 
     }
-    /* Save pair */
-    std::pair<map<CLBOSIpCacheKey, string>::iterator, bool> res =
-        x_IpCache->insert(std::pair<CLBOSIpCacheKey, string>(key, host));
-    return res.first->second;
+    {{
+        CFastMutexGuard spawn_guard(s_IPCacheLock);
+        /* Save pair */
+        std::pair<map<CLBOSIpCacheKey, string>::iterator, bool> res =
+            sm_IpCache->insert(std::pair<CLBOSIpCacheKey, string>(key, host));
+        return res.first->second;
+    }}
 }
 
-void CLBOSIpCache::HostnameDelete(string service, string hostname, 
-                                  string version, unsigned short port)
+void CLBOSIpCache::HostnameDelete(const string& service,
+                                  const string& hostname_in,
+                                  const string& version,
+                                  unsigned short port)
 {
-    if (hostname == "")
-        hostname = CSocketAPI::GetLocalHostAddress();
+    string hostname = hostname_in;
+    if (hostname.empty())
+        hostname = CSocketAPI::HostPortToString(
+                                          CSocketAPI::GetLocalHostAddress(), 0);
     map<CLBOSIpCacheKey, string>::iterator pos;
     CLBOSIpCacheKey key(service, hostname, version, port);
-    pos = x_IpCache->find(key);
-    if (pos != x_IpCache->end())
-        x_IpCache->erase(pos);
+    {{
+        CFastMutexGuard spawn_guard(s_IPCacheLock);
+        pos = sm_IpCache->find(key);
+        if (pos != sm_IpCache->end())
+            sm_IpCache->erase(pos);
+    }}
 }
 
 
-CSafeStatic< map< CLBOSIpCacheKey, string > > CLBOSIpCache::x_IpCache;
-
-
 static void s_ProcessResult(unsigned short result, 
                             const char* lbos_answer,
                             const char* status_message)
 {
-    if (result == kLBOSSuccess)
+    if (result == eLBOS_Success)
         return;
 
     stringstream message;
@@ -197,9 +223,12 @@ static void s_ProcessResult(unsigned short result,
 }
 
 
-void LBOS::Announce(const string& service, const string& version,
-                    const string& host, unsigned short port,
-                    const string& healthcheck_url)
+void LBOS::Announce(const string&  service, 
+                    const string&  version,
+                    const string&  host, 
+                    unsigned short port,
+                    const string&  healthcheck_url,
+                    const string&  metadata)
 {
     char* body_str = NULL, *status_message_str = NULL;
     AutoPtr< char*, Free<char*> > body_aptr(&body_str),
@@ -207,7 +236,7 @@ void LBOS::Announce(const string& service, const string& version,
     string cur_host = host, ip;
     /* If host is empty, it means that host is the same as in healthcheck 
      * (by convention). We have to parse healthcheck and get host */
-    if (cur_host == "")
+    if (cur_host.empty())
     {
         SConnNetInfo * healthcheck_info;
         healthcheck_info = ConnNetInfo_Clone(kEmptyNetInfo);
@@ -217,46 +246,60 @@ void LBOS::Announce(const string& service, const string& version,
         ConnNetInfo_ParseURL(healthcheck_info, healthcheck_url.c_str());
         cur_host = healthcheck_info->host;
         /* If we could not parse healthcheck URL, throw "Invalid Arguments" */
-        if (cur_host == "") {
+        if (cur_host.empty()) {
             ConnNetInfo_Destroy(healthcheck_info);
             throw CLBOSException(CDiagCompileInfo(__FILE__, __LINE__), NULL,
-                                 CLBOSException::EErrCode::e_LBOSInvalidArgs,
-                                 NStr::IntToString(kLBOSInvalidArgs),
-                                 kLBOSInvalidArgs);
+                                 CLBOSException::eInvalidArgs,
+                                 NStr::IntToString(eLBOS_InvalidArgs),
+                                 eLBOS_InvalidArgs);
         }
         ConnNetInfo_Destroy(healthcheck_info);
     }
     if (cur_host == "0.0.0.0") {
         ip = cur_host;
     } else {
-        /* We make a guard here because CLBOSIpCache saves resolution results 
-           to its static storage */
-        CFastMutexGuard spawn_guard(s_GlobalLock);
         ip = CLBOSIpCache::HostnameResolve(service, cur_host, version, port);
     }
     /* If healthcheck is on the same host as server, we try to replace hostname 
      * with IP in healthcheck URL, too */
     string temp_healthcheck = NStr::Replace(healthcheck_url, cur_host, ip);
-    unsigned short result = LBOS_Announce(service.c_str(), version.c_str(),
-                                          ip.c_str(), port,
+    unsigned short result = LBOS_Announce(service.c_str(), 
+                                          version.c_str(),
+                                          ip.c_str(),
+                                          port,
                                           temp_healthcheck.c_str(),
-                                          &*body_aptr, &*status_message_aptr);
+                                          metadata.c_str(),
+                                          &*body_aptr, 
+                                          &*status_message_aptr);
     s_ProcessResult(result, *body_aptr, *status_message_aptr);
 }
 
 
-void LBOS::AnnounceFromRegistry(string reg_section)
+void LBOS::Announce(const string& service, 
+                    const string& version,
+                    const string& host, 
+                    unsigned short port,
+                    const string& healthcheck_url,
+                    const CMetaData& metadata)
+{
+    Announce(service, version, host, port, healthcheck_url, 
+             metadata.GetMetaString());
+}
+
+
+void LBOS::AnnounceFromRegistry(const string& reg_sec)
 {
+    /* If "reg_section" is empty, we use default section. */
+    const string& reg_section = reg_sec.empty() ? kLBOSAnnounceRegistrySection
+                                                : reg_sec;
+    LOG_POST(Error << "Registry section is " << reg_section);
     CNcbiRegistry& config = CNcbiApplication::Instance()->GetConfig();
-    /* If "registry_section" is empty, we use default section. */
-    if (reg_section == "") {
-        reg_section = kLBOSAnnounceRegistrySection;
-    }
     string host =     config.Get(reg_section, kLBOSServerHostVariable);
     string service =  config.Get(reg_section, kLBOSServiceVariable);
     string version =  config.Get(reg_section, kLBOSVersionVariable);
     string port_str = config.Get(reg_section, kLBOSPortVariable);
     string health =   config.Get(reg_section, kLBOSHealthcheckUrlVariable);
+    string meta   =   config.Get(reg_section, kLBOSMetaVariable);
 
     /* Check that port is a number between 1 and 65535   */
     int port_int = 0;
@@ -265,19 +308,21 @@ void LBOS::AnnounceFromRegistry(string reg_section)
     }
     catch (...) {
         throw CLBOSException(CDiagCompileInfo(__FILE__, __LINE__), NULL,
-                             CLBOSException::EErrCode::e_LBOSInvalidArgs,
-                             NStr::IntToString(kLBOSInvalidArgs),
-                             kLBOSInvalidArgs);
+                             CLBOSException::eInvalidArgs,
+                             "Could not parse port \"" + port_str + 
+                             "\" in section \"" + reg_section + "\"",
+                             eLBOS_InvalidArgs);
     }
     if (port_int < 1 || port_int > 65535)
     {
         throw CLBOSException(CDiagCompileInfo(__FILE__, __LINE__), NULL,
-                             CLBOSException::EErrCode::e_LBOSInvalidArgs, 
-                             NStr::IntToString(kLBOSInvalidArgs),
-                             kLBOSInvalidArgs);
+                             CLBOSException::eInvalidArgs, 
+                             "Invalid server port \"" + port_str + 
+                             "\" in section \"" + reg_section + "\"",
+                             eLBOS_InvalidArgs);
     }
     unsigned short port = static_cast<unsigned short>(port_int);
-    Announce(service, version, host, port, health);
+    Announce(service, version, host, port, health, meta);
 }
 
 
@@ -294,10 +339,9 @@ void LBOS::Deannounce(const string&         service,
 {
     char* body_str = NULL, *status_message_str = NULL;
     string ip;
-    if (host == "" || host == "0.0.0.0") {
+    if (host.empty() || host == "0.0.0.0") {
         ip = host;
     } else {
-        CFastMutexGuard spawn_guard(s_GlobalLock);
         ip = CLBOSIpCache::HostnameTryFind(service, host, version, port);
     }
     AutoPtr< char*, Free<char*> > body_aptr(&body_str),
@@ -310,7 +354,6 @@ void LBOS::Deannounce(const string&         service,
     /* Then remove resolution result from cache */
     if (host != "" /* invalid input */ &&
         host != "0.0.0.0" /* not handled by cache */) {
-        CFastMutexGuard spawn_guard(s_GlobalLock);
         CLBOSIpCache::HostnameDelete(service, host, version, port);
     }
 }
@@ -369,13 +412,14 @@ SLbosConfigure ParseLbosConfigureAnswer(const char* lbos_answer)
 }
 
 
-string LBOS::ServiceVersionGet(const string&  service,
-                               bool* exists) 
+string LBOSPrivate::GetServiceVersion(const string&  service,
+                                      bool*          exists) 
 {
     char* body_str = NULL, *status_message_str = NULL;
     AutoPtr< char*, Free<char*> > body_aptr(&body_str),
                                   status_message_aptr(&status_message_str);
-    unsigned short result = LBOS_ServiceVersionGet(service.c_str(), &*body_aptr,
+    unsigned short result = LBOS_ServiceVersionGet(service.c_str(), 
+                                                   &*body_aptr,
                                                    &*status_message_aptr);
     s_ProcessResult(result, *body_aptr, *status_message_aptr);
     SLbosConfigure res = ParseLbosConfigureAnswer(*body_aptr);
@@ -386,9 +430,9 @@ string LBOS::ServiceVersionGet(const string&  service,
 }
 
 
-string LBOS::ServiceVersionSet(const string&  service,
-                               const string&  new_version,
-                               bool* existed)
+string LBOSPrivate::SetServiceVersion(const string&  service,
+                                      const string&  new_version,
+                                      bool* existed)
 {
     char* body_str = NULL, *status_message_str = NULL;
     AutoPtr< char*, Free<char*> > body_aptr(&body_str),
@@ -406,8 +450,8 @@ string LBOS::ServiceVersionSet(const string&  service,
 }
 
 
-string LBOS::ServiceVersionDelete(const string&  service,
-                                  bool* existed)
+string LBOSPrivate::DeleteServiceVersion(const string&  service,
+                                         bool* existed)
 {
     char* body_str = NULL, *status_message_str = NULL;
     AutoPtr< char*, Free<char*> > body_aptr(&body_str),
@@ -424,30 +468,29 @@ string LBOS::ServiceVersionDelete(const string&  service,
 }
 
 
-CLBOSException::EErrCode 
-    CLBOSException::s_HTTPCodeToEnum(unsigned short http_code) 
-{
-    switch (http_code) {
-    case kLBOSNoLBOS:
-        return EErrCode::e_LBOSNoLBOS;
-    case kLBOSNotFound:
-        return EErrCode::e_LBOSNotFound;
-    case kLBOSBadRequest:
-        return EErrCode::e_LBOSBadRequest;
-    case kLBOSOff:
-        return EErrCode::e_LBOSOff;
-    case kLBOSInvalidArgs:
-        return EErrCode::e_LBOSInvalidArgs;
-    case kLBOSDNSResolveError:
-        return EErrCode::e_LBOSDNSResolveError;
-    case kLBOSMemAllocError:
-        return EErrCode::e_LBOSMemAllocError;
-    case kLBOSCorruptOutput:
-        return EErrCode::e_LBOSCorruptOutput;
-    case kLBOSServerError:
-        return EErrCode::e_LBOSServerError;
+CLBOSException::EErrCode CLBOSException::s_HTTPCodeToEnum(unsigned short code) 
+{
+    switch (code) {
+    case eLBOS_LbosNotFound:
+        return eLbosNotFound;
+    case eLBOS_NotFound:
+        return eNotFound;
+    case eLBOS_BadRequest:
+        return eBadRequest;
+    case eLBOS_Disabled:
+        return eDisabled;
+    case eLBOS_InvalidArgs:
+        return eInvalidArgs;
+    case eLBOS_DNSResolve:
+        return eDNSResolve;
+    case eLBOS_MemAlloc:
+        return eMemAlloc;
+    case eLBOS_Protocol:
+        return eProtocol;
+    case eLBOS_Server:
+        return eServer;
     default:
-        return EErrCode::e_LBOSUnknown;
+        return eUnknown;
     }
 }
 
@@ -461,32 +504,32 @@ const char* CLBOSException::GetErrCodeString(void) const
 {
     switch (GetErrCode()) {
     /* 400 */
-    case EErrCode::e_LBOSBadRequest:
+    case eBadRequest:
         return "";
     /* 404 */
-    case EErrCode::e_LBOSNotFound:
+    case eNotFound:
         return "";
     /* 500 */
-    case EErrCode::e_LBOSServerError:
+    case eServer:
         return "";
     /* 450 */
-    case EErrCode::e_LBOSNoLBOS:
+    case eLbosNotFound:
         return "LBOS was not found";
     /* 451 */
-    case EErrCode::e_LBOSDNSResolveError:
+    case eDNSResolve:
         return "DNS error. Possibly, cannot get IP of current machine or "
                "resolve provided hostname for the server";
     /* 452 */
-    case EErrCode::e_LBOSInvalidArgs:
+    case eInvalidArgs:
         return "Invalid arguments were provided. No request to LBOS was sent";
     /* 453 */
-    case EErrCode::e_LBOSMemAllocError:
+    case eMemAlloc:
         return "Memory allocation error happened while performing request";
     /* 454 */
-    case EErrCode::e_LBOSCorruptOutput:
+    case eProtocol:
         return "Failed to parse LBOS output.";
     /* 550 */
-    case EErrCode::e_LBOSOff:
+    case eDisabled:
         return "LBOS functionality is turned OFF. Check config file or "
                "connection to LBOS.";
     default:
@@ -565,4 +608,306 @@ const CException* CLBOSException::x_Clone(void) const
     return new CLBOSException(*this);
 }
 
+#ifdef LBOS_METADATA
+LBOS::CMetaData::CMetaData()
+{
+}
+
+
+void LBOS::CMetaData::Set(const CTempString name_in, const CTempString val_in)
+{
+    string name = name_in;
+    /* First, transform name to lower register to search it */
+    NStr::ToLower(name);
+    /* Forbidden names for meta parameters */
+    if (name == "version" || name == "ip" || name == "port" || name == "check" 
+        || name == "format" || name == "name") {
+        throw CLBOSException(CDiagCompileInfo(__FILE__, __LINE__), NULL,
+                             CLBOSException::eInvalidArgs, 
+                             "This name cannot be used for metadata", 
+                             eLBOS_InvalidArgs);
+    }
+    /* If val is empty, we delete the value from m_Meta */
+    if (val_in.empty()) {
+        auto iter = m_Meta.find(name);
+        if (iter != m_Meta.end()) {
+            m_Meta.erase(iter);
+        }
+    }
+    else {
+        /* If val is not empty, save it to m_Meta or rewrite previous value */
+        m_Meta[name] = val_in;
+    }
+}
+
+
+string LBOS::CMetaData::Get(const string& name) const
+{
+    auto iter = m_Meta.find(name);
+    if (iter != m_Meta.end()) {
+        return iter->second;
+    }
+    return "";
+}
+
+
+void LBOS::CMetaData::GetNames(list<string>& cont)
+{
+    auto iter = m_Meta.begin();
+    for (; iter != m_Meta.end(); iter++) {
+        cont.push_back(iter->first);
+    }
+}
+
+
+void LBOS::CMetaData::GetNames(vector<string>& cont)
+{
+    auto iter = m_Meta.begin();
+    for (; iter != m_Meta.end(); iter++) {
+        cont.push_back(iter->first);
+    }
+}
+
+
+void LBOS::CMetaData::SetRate(const string& rate)
+{
+    if (rate.empty()) {
+        Set("rate", "");
+    } else {
+        try {
+            SetRate(NStr::StringToInt(rate));
+        } 
+        catch (const CStringException&) {
+            throw CLBOSException(CDiagCompileInfo(__FILE__, __LINE__), NULL,
+                                 CLBOSException::eInvalidArgs,
+                                 "Could not parse string value for SetRate",
+                                 eLBOS_InvalidArgs);
+        }
+    }
+}
+
+
+void LBOS::CMetaData::SetRate(double rate)
+{
+    if (rate == 0)
+        Set("rate", "");
+    else
+        Set("rate", NStr::DoubleToString(rate));
+}
+
+
+double LBOS::CMetaData::GetRate() const
+{
+    string rate = Get("rate");
+    if (rate.empty())
+        return 0;
+    try {
+        return NStr::StringToDouble(rate);
+    }
+    catch (const CStringException&) {
+        throw CLBOSException(CDiagCompileInfo(__FILE__, __LINE__), NULL,
+                             CLBOSException::eInvalidArgs,
+                             "Value in \"rate\" meta parameter cannot "
+                             "be represented as an integer",
+                             eLBOS_InvalidArgs);
+    }
+}
+
+
+void LBOS::CMetaData::SetType(const string& host_type)
+{
+    if (host_type.find_first_of(" \t\n\v\f\r") != string::npos) {
+        throw CLBOSException(CDiagCompileInfo(__FILE__, __LINE__), NULL,
+            CLBOSException::eInvalidArgs,
+            "This convenience function throws on whitespace characters "
+            "in \"type\" meta parameter. If you know what you are doing, "
+            "you can use CMetaData::Set(\"type\", ...)",
+            eLBOS_InvalidArgs);
+    }
+    string type = host_type;
+    type = NStr::ToUpper(type);
+    Set("type", type);
+}
+
+
+void LBOS::CMetaData::SetType(EHostType host_type)
+{
+    switch (host_type) {
+    case eHTTP:
+        SetType("HTTP");
+        break;
+    case eHTTP_POST:
+        SetType("HTTP_POST");
+        break;
+    case eHTTP_GET:
+        SetType("HTTP_GET");
+        break;
+    case eStandalone:
+        SetType("STANDALONE");
+        break;
+    case eNCBID:
+        SetType("NCBID");
+        break;
+    case eDNS:
+        SetType("DNS");
+        break;
+    case eFirewall:
+        SetType("FIREWALL");
+        break;
+    case eNone:
+        SetType("");
+        break;
+    default:
+        throw CLBOSException(CDiagCompileInfo(__FILE__, __LINE__), NULL,
+                             CLBOSException::eInvalidArgs, "Unknown EHostType "
+                             "value. If you are sure that a correct value is "
+                             "used, please tell the developer about this issue", 
+                             eLBOS_InvalidArgs);
+    }
+}
+
+
+void LBOS::CMetaData::SetType(ESERV_Type host_type)
+{
+    switch (host_type) {
+    case fSERV_Http:
+        SetType("HTTP");
+        break;
+    case fSERV_HttpPost:
+        SetType("HTTP_POST");
+        break;
+    case fSERV_HttpGet:
+        SetType("HTTP_GET");
+        break;
+    case fSERV_Standalone:
+        SetType("STANDALONE");
+        break;
+    case fSERV_Ncbid:
+        SetType("NCBID");
+        break;
+    case fSERV_Dns:
+        SetType("DNS");
+        break;
+    case fSERV_Firewall:
+        SetType("FIREWALL");
+        break;
+    default:
+        throw CLBOSException(CDiagCompileInfo(__FILE__, __LINE__), NULL,
+                             CLBOSException::eInvalidArgs, "Unknown ESERV_Type "
+                             "value. If you are sure that a correct value is "
+                             "used, please tell the developer about this issue", 
+                             eLBOS_InvalidArgs);
+    }
+}
+
+
+void LBOS::CMetaData::SetType(int host_type)
+{
+    switch (host_type) {
+    case (int)eHTTP:
+        SetType("HTTP");
+        break;
+    case (int)eHTTP_POST:
+        SetType("HTTP_POST");
+        break;
+    case (int)eStandalone:
+        SetType("STANDALONE");
+        break;
+    case (int)eNCBID:
+        SetType("NCBID");
+        break;
+    case (int)eDNS:
+        SetType("DNS");
+        break;
+    case (int)eNone:
+        SetType("");
+        break;
+    default:
+        throw CLBOSException(CDiagCompileInfo(__FILE__, __LINE__), NULL,
+                             CLBOSException::eInvalidArgs, "Unknown EHostType "
+                             "value. If you are sure that a correct value is "
+                             "used, please tell the developer about this issue",
+                             eLBOS_InvalidArgs);
+    }
+}
+
+
+string LBOS::CMetaData::GetType(bool) const
+{
+    string type = Get("type");
+    return NStr::ToUpper(type);
+}
+
+
+LBOS::CMetaData::EHostType LBOS::CMetaData::GetType() const
+{
+    string type = GetType(true);
+    if (type == "HTTP") {
+        return eHTTP;
+    }
+    else if (type == "HTTP_POST") {
+        return eHTTP_POST;
+    }
+    else if (type == "STANDALONE") {
+        return eStandalone;
+    }
+    else if (type == "NCBID") {
+        return eNCBID;
+    }
+    else if (type == "DNS") {
+        return eDNS;
+    }
+    else if (type.empty()) {
+        return eNone;
+    }
+    else {
+        return eUnknown;
+    }
+}
+
+
+void LBOS::CMetaData::SetExtra(const string& extra)
+{
+    if (extra.find_first_of(" \t\n\v\f\r") != string::npos) {
+        throw CLBOSException(CDiagCompileInfo(__FILE__, __LINE__), NULL,
+            CLBOSException::eInvalidArgs,
+            "This convenience function throws on whitespace characters "
+            "in \"extra\" meta parameter. If you know what you are doing, "
+            "you can use CMetaData::Set(\"extra\", ...)",
+            eLBOS_InvalidArgs);
+    }
+    Set("extra", extra);
+}
+
+
+std::string LBOS::CMetaData::GetExtra() const
+{
+    return Get("extra");
+}
+
+
+string LBOS::CMetaData::GetMetaString() const
+{
+    stringstream meta_stringstream;
+    auto iter = m_Meta.begin();
+    for (  ;  iter != m_Meta.end()  ;  ) {
+        meta_stringstream << NStr::URLEncode(iter->first) << "=" 
+                          << NStr::URLEncode(iter->second);
+        if (++iter != m_Meta.end()) {
+            meta_stringstream << "&";
+        }
+    }
+    return meta_stringstream.str();
+}
+
+
+ostream& operator<<(ostream& os, const LBOS::CMetaData& metadata)
+{
+    os << metadata.GetMetaString();
+    return os;
+}
+
+
+#endif /* LBOS_METADATA */
+
 END_NCBI_SCOPE
diff --git a/c++/src/connect/ncbi_lbosp.h b/c++/src/connect/ncbi_lbosp.h
index 5592d46..5aa6875 100644
--- a/c++/src/connect/ncbi_lbosp.h
+++ b/c++/src/connect/ncbi_lbosp.h
@@ -26,6 +26,7 @@
  * ===========================================================================
  *
  * Authors:  Dmitriy Elisov
+ * Credits:  Denis Vakatov
  * @file
  * File Description:
  *   This header was made only because of unit testing application. Please, 
@@ -42,6 +43,9 @@
 extern "C" {
 #endif /*__cplusplus*/
 
+#ifndef LBOS_METADATA
+#define LBOS_METADATA
+#endif
 
 /*
  * Additional HTTP codes:
@@ -52,17 +56,25 @@ extern "C" {
  *  454 - LBOS output could not be parsed
  *  550 - LBOS client is OFF in the current process
  */
-static const int kLBOSSuccess         = 200;
-static const int kLBOSBadRequest      = 400;
-static const int kLBOSNotFound        = 404;
-static const int kLBOSNoLBOS          = 450;
-static const int kLBOSDNSResolveError = 451;
-static const int kLBOSInvalidArgs     = 452;
-static const int kLBOSMemAllocError   = 453;
-static const int kLBOSCorruptOutput   = 454;
-static const int kLBOSServerError     = 500;
-static const int kLBOSOff             = 550;
-
+enum ELBOSStatusCodes {
+    eLBOS_Success         = 200, /**< HTTP 200 OK */
+    eLBOS_BadRequest      = 400, /**< HTTP 400 Bad Request */
+    eLBOS_NotFound        = 404, /**< HTTP 404 Not Found */
+    eLBOS_LbosNotFound    = 450, /**< Not a HTTP code. LBOS was not found */
+    eLBOS_DNSResolve      = 451, /**< Not a HTTP code. Could not find IP of
+                                      localhost */
+    eLBOS_InvalidArgs     = 452, /**< Not a HTTP code. Some arguments were
+                                      invalid */
+    eLBOS_MemAlloc        = 453, /**< Not a HTTP code. Some memory could not be
+                                      allocated */
+    eLBOS_Protocol        = 454, /**< Not a HTTP code. LBOS response could not
+                                      be parsed */
+    eLBOS_Server          = 500, /**< HTTP 500 Internal Server Error */
+    eLBOS_Disabled        = 550  /**< Not a HTTP code. LBOS Client functionality
+                                      is disabled in registry or during
+                                      initialization (LBOS Client could not
+                                      establish connection with LBOS) */
+};
 
 ///////////////////////////////////////////////////////////////////////////////
 //                             DATA TYPES                                    //
@@ -81,10 +93,10 @@ static const int kLBOSOff             = 550;
 typedef enum {
     eLBOSFindMethod_None,           /**< do not search. Used to skip
                                          "custom host" method                */
-    eLBOSFindMethod_CustomHost,     /**< Use custom address provided by
+    eLBOS_FindMethod_CustomHost,     /**< Use custom address provided by
                                          s_SetLBOSaddress()                  */
-    eLBOSFindMethod_Registry,       /**< Use value from registry (default)   */
-    eLBOSFindMethod_Lbosresolve,    /**< Use value from /etc/ncbi/lbosresolve*/
+    eLBOS_FindMethod_Registry,       /**< Use value from registry (default)   */
+    eLBOS_FindMethod_Lbosresolve,    /**< Use value from /etc/ncbi/lbosresolve*/
 } ELBOSFindMethod;
 
 
@@ -101,7 +113,7 @@ typedef struct {
     SConnNetInfo*       net_info;    /**< Connection point                   */
     const char*         lbos_addr;   /**< LBOS host:port or IP:port. Used if
                                           find_method == 
-                                          eLBOSFindMethod_CustomHost        */
+                                          eLBOS_FindMethod_CustomHost        */
     SLBOS_Candidate*    cand;        /**< Array of found server to iterate   */
     size_t              pos_cand;    /**< Current candidate                  */
     size_t              n_cand;      /**< Used space for candidates          */
@@ -117,8 +129,8 @@ typedef struct {
     int http_response_code;
     char* http_status_mesage;
     const char* header;
-    size_t content_length; /* Value of "Content-length" HTTP header tag. 
-                              -1 (max value) as no limit */
+    size_t content_length; /**< Value of "Content-length" HTTP header tag. 
+                                -1 (max value) as no limit */
 } SLBOS_UserData;
 
 
@@ -191,13 +203,6 @@ EIO_Status FLBOS_ConnReadMethod(CONN           conn,
                                 EIO_ReadMethod how);
 
 
-/**  Compose LBOS address from /etc/ncbi/{role, domain}.
- *  @return             
- *   Constructed host:port or IP:port. Must be free()'d by the caller.       */
-typedef
-char* FLBOS_ComposeLBOSAddressMethod(void);
-
-
 /**  Given just empty data structure and name of service, do all necessary 
  *  operations to fill the structure with servers.
  *  @param data[out]    
@@ -253,6 +258,8 @@ SSERV_Info* FLBOS_GetNextInfoMethod(SERV_ITER  iter,
  * @param healthcheck_url[in]
  *  Full absolute URL starting with "http://" or "https://". Should include
  *  hostname or IP and port, if necessary.
+ * @param metadata[in]
+ *  URL-ready link with additional meta parameters
  * @param LBOS_answer[out]
  *  This variable will be assigned a pointer to char* with exact answer of
  *  LBOS, or NULL. If it is not NULL, must be free()'d by the caller. If
@@ -269,6 +276,9 @@ unsigned short FLBOS_AnnounceMethod(const char*     service,
                                     const char*     host,
                                     unsigned short  port,
                                     const char*     healthcheck_url,
+#ifdef LBOS_METADATA
+                                    const char*     metadata,
+#endif /* LBOS_METADATA */
                                     char**          LBOS_answer,
                                     char**          http_status_message);
 
@@ -327,7 +337,6 @@ typedef unsigned int FLBOS_SOCKGetLocalHostAddressMethod(ESwitch reget);
 typedef struct {
     FLBOS_ResolveIPPortMethod*              ResolveIPPort;
     FLBOS_ConnReadMethod*                   Read;
-    FLBOS_ComposeLBOSAddressMethod*         ComposeLBOSAddress;
     FLBOS_FillCandidatesMethod*             FillCandidates;
     FLBOS_DestroyDataMethod*                DestroyData;
     FLBOS_GetNextInfoMethod*                GetNextInfo;
@@ -357,7 +366,7 @@ char* g_LBOS_GetLBOSAddress(void);
  *  First method to try.
  * @param[in]   lbos_addr
  *  String with "%hostname%:%port%" or "%IP%:%port%". If priority_find_method
- *  is set to eLBOSFindMethod_CustomHost, lbos_addr should be non-NULL
+ *  is set to eLBOS_FindMethod_CustomHost, lbos_addr should be non-NULL
  *  (or else the method will be ignored)
  * @return
  *  LBOS address that needs to be free()'d by the caller.
@@ -392,7 +401,7 @@ const SSERV_VTable*  SERV_LBOS_Open(SERV_ITER           iter,
  *  true - string is NULL or empty;
  *  false - string exists and contains elements.                             */
 NCBI_XCONNECT_EXPORT
-int/*bool*/ g_LBOS_StringIsNullOrEmpty(const char* const str);
+int/*bool*/ g_LBOS_StringIsNullOrEmpty(const char* str);
 
 
 /** Compose LBOS address from /etc/ncbi/{role, domain}.
@@ -402,7 +411,7 @@ NCBI_XCONNECT_EXPORT
 char* g_LBOS_ComposeLBOSAddress(void);
 
 
-/** Set primary method how to find LBOS. Default is eLBOSFindMethod_Registry.
+/** Set primary method how to find LBOS. Default is eLBOS_FindMethod_Registry.
  *  @param[in]  iter
  *   Iterator that represents current request to LBOS.
  *  @param[in]  method
@@ -416,7 +425,7 @@ int/*bool*/ g_LBOS_UnitTesting_SetLBOSFindMethod(SERV_ITER        iter,
 
 
 /**  Set custom host for LBOS. It will be used when method 
- *  eLBOSFindMethod_CustomHost is used.
+ *  eLBOS_FindMethod_CustomHost is used.
  *  @param[in]  iter
  *   Iterator that represents current request to LBOS.
  *  @param[in]  address
@@ -430,22 +439,14 @@ int/*bool*/ g_LBOS_UnitTesting_SetLBOSaddress(SERV_ITER  iter,
 
 
 /**  Set custom files to load role and domain from, respectively.
- *  @param roleFile[in] 
- *   To change role file path, pass it here. To use current role file path, 
- *   pass NULL.
- *  @param domainFile[in]  
- *   To change domain file path, pass it here. To use current domain file path, 
- *   pass NULL.
  *  @param lbosresolverFile[in]
  *   To change lbosresolver file path, pass it here. To use current 
  *   lbosresolver file path, pass NULL.
  *  @return             
- *   false - something went wrong, values not changed;
+ *   false - values not changed;
  *   true  - success.                                                        */
 NCBI_XCONNECT_EXPORT int/*bool*/
-g_LBOS_UnitTesting_SetLBOSRoleDomainResolverFile(const char* roleFile,
-                                                 const char* domainFile,
-                                                 const char* lbosresolverFile);
+g_LBOS_UnitTesting_SetLBOSResolverFile(const char* lbosresolverFile);
 
 
 /**  Checks iterator, fact that iterator belongs to this client, iterator data.
@@ -576,22 +577,6 @@ NCBI_XCONNECT_EXPORT
 int g_LBOS_UnitTesting_GetAnnouncedServersNum(void);
 
 
-/**  Pointer to s_LBOS_CurrentDomain
- *  @return
- *   address of static variable s_LBOS_CurrentDomain.
- *  @see                                                                     */
-NCBI_XCONNECT_EXPORT
-char** g_LBOS_UnitTesting_CurrentDomain(void);
-
-
-/**  Pointer to s_LBOS_CurrentRole
- *  @return
- *   address of static variable s_LBOS_CurrentRole.
- *  @see                                                                     */
-NCBI_XCONNECT_EXPORT
-char** g_LBOS_UnitTesting_CurrentRole(void);
-
-
 /**  Pointer to s_LBOS_Lbosresolver
  *  @return
  *   address of static variable s_LBOS_Lbosresolver.
diff --git a/c++/src/connect/ncbi_lbosp.hpp b/c++/src/connect/ncbi_lbosp.hpp
index 7de44ec..27bd795 100644
--- a/c++/src/connect/ncbi_lbosp.hpp
+++ b/c++/src/connect/ncbi_lbosp.hpp
@@ -41,7 +41,9 @@ BEGIN_NCBI_SCOPE
 class CLBOSIpCacheKey
 {
 public:
-    CLBOSIpCacheKey(string service, string hostname, string version,
+    CLBOSIpCacheKey(const string& service,
+                    const string& hostname,
+                    const string& version,
                     unsigned short port);
 
     bool operator==(const CLBOSIpCacheKey& rh) const;
@@ -63,33 +65,80 @@ public:
     /** Search the cache for previously resolved hostname with a given 
     * service name, version, port. If not found - return the same hostname.
     */
-    static
-    string HostnameTryFind(string service, string hostname, string version,
-    unsigned short port);
+    static string HostnameTryFind(const string& service,
+                                  const string& hostname,
+                                  const string& version,
+                                  unsigned short port);
 
 
     /** Search the cache for previously resolved hostname with a given 
     * service name, version, port. If not found - resolve, cache and return 
     * result.
     */
-    static
-        string HostnameResolve(string service, string hostname,
-        string version, unsigned short port);
+    static string HostnameResolve(const string& service,
+                                  const string& hostname,
+                                  const string& version,
+                                  unsigned short port);
 
 
     /** We do not need to store hostname<->IP record after the server is
     * de-announced. So we just make sure that we delete the record only one 
     * time, in case if many threads are going to delete it at the same 
     * moment */
-    static
-        void HostnameDelete(string service, string hostname, string version,
-        unsigned short port);
+    static void HostnameDelete(const string& service,
+                               const string& hostname,
+                               const string& version,
+                               unsigned short port);
 
 private:
-    static CSafeStatic< map< CLBOSIpCacheKey, string > > x_IpCache;
+    static CSafeStatic< map< CLBOSIpCacheKey, string > > sm_IpCache;
 };
 
 
+/* Private API of LBOS */
+class NCBI_XCONNECT_EXPORT LBOSPrivate
+{
+public:
+   /** Get global config for a service name. 
+    * @note It does not change anything in the global DTab configuration.
+    * @param service[in]
+    *  Name of service for which to get default version.
+    * @return
+    *  Current default version. Can be an empty string
+    * @exception CLBOSException
+    *  Throw on any error.  Note: if the service is present in DTab but it has
+    *  no default version, then "eBadVersion" code will be used.
+    * @note 
+    *  Config can be of 3 types: empty string, path or version
+    */
+    static string GetServiceVersion(const string& service,
+                                    bool* exists = NULL);
+
+
+   /** Set default version for a service in the global DTab configuration.
+    * @param[in] service
+    *  Name of service for which to change the default version.
+    * @param new_version[out]
+    *  Version that will be used by default for specified service.
+    * @return
+    *  Previously set default version.
+    */
+    static string SetServiceVersion(const string& service,
+                                    const string& new_version,
+                                    bool* existed = NULL);
+
+
+   /** Remove service from the global DTab configuration configuration.
+    * @note Its default version will become empty.
+    * @param[in] service
+    *  Name of service to delete from the global DTab configuration.
+    * @return
+    *  Previously set default version.
+    */
+    static string DeleteServiceVersion(const string& service,
+                                       bool* existed = NULL);
+};
+
 
 END_NCBI_SCOPE
 
diff --git a/c++/src/connect/ncbi_monkey.cpp b/c++/src/connect/ncbi_monkey.cpp
new file mode 100644
index 0000000..683015e
--- /dev/null
+++ b/c++/src/connect/ncbi_monkey.cpp
@@ -0,0 +1,1681 @@
+/* $Id: ncbi_monkey.cpp 505633 2016-06-27 19:28:13Z elisovdn $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's official duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* Author:  Dmitriy Elisov
+*
+* File Description:
+*   Chaos Monkey - a library that is hooked with ncbi_socket.c and introduces 
+*   problems in network connectivity - losses, bad data, delays.
+*   difficulties
+*
+*/
+
+#include <ncbi_pch.hpp>
+
+#include "ncbi_priv.h"
+
+#ifdef NCBI_MONKEY
+#   include <connect/ncbi_connutil.h>
+#   include <corelib/ncbi_system.hpp>
+#   include <corelib/ncbireg.hpp>
+#   include <corelib/ncbithr.hpp>
+#   include <corelib/env_reg.hpp>
+#   include <corelib/ncbiapp.hpp>
+#   include <corelib/ncbimisc.hpp>
+#   include "ncbi_monkeyp.hpp"
+#   include <list>
+
+/* OS-dependent way to set socket errors */
+#   ifdef NCBI_OS_MSWIN
+#       define MONKEY_SET_SOCKET_ERROR(error) WSASetLastError(error)
+#       define MONKEY_ENOPROTOOPT WSAENOPROTOOPT 
+#   else
+#       define MONKEY_SET_SOCKET_ERROR(error) errno = error
+#       define MONKEY_ENOPROTOOPT ENOPROTOOPT 
+#   endif /* NCBI_OS_MSWIN */
+
+/* Include OS-specific headers */
+#   ifdef NCBI_OS_MSWIN
+#       include <regex>
+#   else
+#       include <arpa/inet.h>
+#       include <sys/types.h>
+#       include <sys/socket.h>
+#       include <sys/un.h>
+#   endif /* NCBI_OS_MSWIN */
+
+
+BEGIN_NCBI_SCOPE
+
+DEFINE_STATIC_FAST_MUTEX(s_ConfigMutex);
+DEFINE_STATIC_FAST_MUTEX(s_SeedLogConfigMutex);
+DEFINE_STATIC_FAST_MUTEX(s_SingletonMutex);
+DEFINE_STATIC_FAST_MUTEX(s_KnownConnMutex);
+static CSocket*          s_TimeoutingSock = NULL;
+static CSocket*          s_PeerSock = NULL;
+const  int               kRandCount = 100;
+/* Registry names */
+const string             kMonkeyMainSect = "CHAOS_MONKEY";
+const string             kEnablField     = "enabled";
+const string             kSeedField     = "seed";
+
+/*/////////////////////////////////////////////////////////////////////////////
+//                              MOCK DEFINITIONS                             //
+/////////////////////////////////////////////////////////////////////////////*/
+#   ifdef NCBI_MONKEY_TESTS
+#       undef DECLARE_MONKEY_MOCK
+/* Declare a static variable and global getter&setter for it */
+#       define DECLARE_MONKEY_MOCK(ty,name,def_val)                            \
+            static ty s_Monkey_ ## name = def_val;                             \
+            ty g_MonkeyMock_Get ## name() {                                    \
+                return s_Monkey_ ## name;                                      \
+            }                                                                  \
+            void g_MonkeyMock_Set ## name(const ty& val) {                     \
+                s_Monkey_ ## name = val;                                       \
+            }
+
+/* This macro contains the list of variables to be mocked. Needed mocks will
+ * be created with DECLARE_MONKEY_MOCK
+ */
+MONKEY_MOCK_MACRO()
+
+#   endif /* NCBI_MONKEY_TESTS */
+/*/////////////////////////////////////////////////////////////////////////////
+//                    STATIC CONVENIENCE FUNCTIONS                           //
+/////////////////////////////////////////////////////////////////////////////*/
+static vector<string>& s_Monkey_Split(const string   &s, 
+                                      char           delim,
+                                      vector<string> &elems) 
+{
+    g_MonkeyMock_SetInterceptedPoll(false);
+    stringstream ss(s);
+    string item;
+    while (getline(ss, item, delim)) {
+        elems.push_back(item);
+    }
+    return elems;
+}
+
+
+/* Trash collector for Thread Local Storage */
+template<class T>
+static void s_TlsCleanup(T* p_value, void* /* data */)
+{
+    delete p_value;
+}
+
+
+static void s_TimeoutingSocketInit(void)
+{
+    unsigned short i = 8080;
+    CListeningSocket* server_socket;
+
+    for (;  i < 8100;  i++) {
+        /* Initialize a timeouting socket */
+        try {
+            server_socket = new CListeningSocket(i);
+        } catch (CException) {
+            continue;
+        }
+        STimeout         accept_timeout = { 0, 20000 };
+        STimeout         connect_timeout = { 1, 20000 };
+        if (server_socket->GetStatus() != eIO_Success) {
+            server_socket->Close();
+            delete server_socket;
+            continue;
+        }
+        try {
+            s_TimeoutingSock = new CSocket(CSocketAPI::gethostbyaddr(0), i,
+                                           &connect_timeout);
+        } catch (CException) {
+            continue;
+        }
+        s_PeerSock       = new CSocket;
+        if (server_socket->Accept(*s_PeerSock, &accept_timeout) == eIO_Success) {
+            server_socket->Close();
+            delete server_socket;
+            char buf[1024];
+            size_t n_read;
+            s_TimeoutingSock->SetTimeout(eIO_Read, &accept_timeout);
+            s_TimeoutingSock->SetTimeout(eIO_Write, &accept_timeout);
+            s_TimeoutingSock->Read((void*)buf, 1024, &n_read);
+            return;
+        } else {
+            s_TimeoutingSock->Close();
+            delete s_TimeoutingSock;
+            s_PeerSock->Close();
+            delete s_PeerSock;
+            server_socket->Close();
+            delete server_socket;
+            continue;
+        }
+        /* If we got here, everything works fine */
+    }
+    throw CMonkeyException(CDiagCompileInfo(), NULL,
+                            CMonkeyException::e_MonkeyUnknown,
+                            "Could not create a peer socket for the "
+                            "timeouting socket. Tried ports 8080-8100",
+                            ncbi::EDiagSev::eDiagSevMin);
+}
+
+
+static void s_TimeoutingSocketDestroy(void)
+{
+    if (s_TimeoutingSock != NULL) {
+        s_TimeoutingSock->Close();
+        delete s_TimeoutingSock;
+        s_TimeoutingSock = NULL;
+    }
+    if (s_PeerSock != NULL) {
+        s_PeerSock->Close();
+        delete s_PeerSock;
+        s_PeerSock = NULL;
+    }
+}
+
+
+static string s_GetMonkeySection()
+{
+    CNcbiRegistry& config = CNcbiApplication::Instance()->GetConfig();
+    return config.Get(kMonkeyMainSect, "config");
+}
+
+
+static vector<string> s_Monkey_Split(const string &s, char delim) {
+    vector<string> elems;
+    s_Monkey_Split(s, delim, elems);
+    return elems;
+}
+
+
+static void s_MONKEY_GenRandomString(char *s, const size_t len) {
+    static const char alphabet[] =
+        "0123456789"
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+        "abcdefghijklmnopqrstuvwxyz"
+        " !@#$%^&*()-=_+/,.{}[];':`~<>"
+        "\\\n\"";
+
+    for (size_t i = 0; i < len - 1; ++i) {
+        s[i] = alphabet[rand() % (sizeof(alphabet) - 1)];
+    }
+
+    s[len-1] = 0;
+}
+
+
+static void s_GetSocketDestinations(MONKEY_SOCKTYPE sock,
+                                    string*         fqdn,
+                                    string*         IP,
+                                    unsigned short* my_port,
+                                    unsigned short* peer_port)
+{
+    struct sockaddr_in sock_addr;
+#ifdef NCBI_OS_MSWIN
+    int len_inet = sizeof(sock_addr);
+#else
+    socklen_t len_inet = sizeof(sock_addr);
+#endif
+    if (my_port != NULL) {
+        getsockname(sock, (struct sockaddr*)&sock_addr, &len_inet);
+        *my_port = ntohs(sock_addr.sin_port);
+    }
+    /* If we need peer information for at least one value */
+    if (peer_port || fqdn || IP)
+        getpeername(sock, (struct sockaddr*)&sock_addr, &len_inet);
+    if (peer_port != NULL) 
+        *peer_port = ntohs(sock_addr.sin_port);
+#ifndef NCBI_OS_MSWIN
+    uint32_t addr = sock_addr.sin_addr.s_addr;
+#else
+    u_long addr = sock_addr.sin_addr.S_un.S_addr;
+#endif
+    if (fqdn != NULL)
+        *fqdn = CSocketAPI::gethostbyaddr   (addr);
+    if (IP != NULL)
+        *IP   = CSocketAPI::HostPortToString(addr, 0);
+}
+
+
+#if 0
+#   ifdef NCBI_OS_MSWIN
+static
+int s_MONKEY_GetTimeOfDay(struct timeval* tv)
+{
+    FILETIME         systime;
+    unsigned __int64 sysusec;
+
+    if (!tv)
+        return -1;
+
+    GetSystemTimeAsFileTime(&systime);
+
+    sysusec = systime.dwHighDateTime;
+    sysusec <<= 32;
+    sysusec |= systime.dwLowDateTime;
+    sysusec += 5;
+    sysusec /= 10;
+
+    tv->tv_usec = (long)(sysusec % 1000000);
+    tv->tv_sec = (long)(sysusec / 1000000 - 11644473600Ui64);
+
+    return 0;
+}
+
+#   else
+
+#       define s_MONKEY_GetTimeOfDay(tv)  gettimeofday(tv, 0)
+
+#   endif
+
+static
+double s_MONKEY_TimeDiff(const struct timeval* end,
+const struct timeval* beg)
+{
+    if (end->tv_sec < beg->tv_sec)
+        return 0.0;
+    if (end->tv_usec < beg->tv_usec) {
+        if (end->tv_sec == beg->tv_sec)
+            return 0.0;
+        return (end->tv_sec - beg->tv_sec - 1)
+            + (end->tv_usec - beg->tv_usec + 1000000) / 1000000.0;
+    }
+    return (end->tv_sec - beg->tv_sec)
+        + (end->tv_usec - beg->tv_usec) / 1000000.0;
+}
+#endif
+
+
+/*//////////////////////////////////////////////////////////////////////////////
+//                             CMonkeySeedKey                                 //
+//////////////////////////////////////////////////////////////////////////////*/
+const CMonkeySeedKey& CMonkeySeedAccessor::Key()
+{
+    static CMonkeySeedKey key;
+    return key;
+}
+
+
+/*//////////////////////////////////////////////////////////////////////////////
+//                            CMonkeyException                                //
+//////////////////////////////////////////////////////////////////////////////*/
+const char* CMonkeyException::what() const throw()
+{
+    return m_Message.c_str();
+}
+
+
+/*//////////////////////////////////////////////////////////////////////////////
+//                             CMonkeyRuleBase                                //
+//////////////////////////////////////////////////////////////////////////////*/
+CMonkeyRuleBase::CMonkeyRuleBase(EMonkeyActionType     action_type,
+                                 const vector<string>& params)
+    : m_ReturnStatus(-1), m_RepeatType(eMonkey_RepeatNone), m_Delay (0),
+      m_RunsSize(0), m_ActionType(action_type)
+{
+    /** If there are no-interception runs before repeating the cycle,
+    * we know that from m_RunsSize */
+    for (unsigned int i = 0; i < params.size(); i++) {
+        vector<string> name_value = s_Monkey_Split(params[i], '=');
+        string name = name_value[0];
+        string value = name_value[1];
+        if (name == "return_status") {
+            x_ReadEIOStatus(value);
+        } else if (name == "runs") {
+            x_ReadRuns(value);
+        } else if (name == "delay") {
+            m_Delay = NStr::StringToULong(value);
+        }
+    }
+}
+
+
+static string s_PrintActionType(EMonkeyActionType action) {
+    switch (action)
+    {
+    case eMonkey_Recv:
+        return "recv()";
+    case eMonkey_Send:
+        return "send()";
+    case eMonkey_Poll:
+        return "poll()";
+    case eMonkey_Connect:
+        return "connect()";
+    default:
+        throw CMonkeyException(
+            CDiagCompileInfo(__FILE__, __LINE__),
+            NULL, CMonkeyException::e_MonkeyInvalidArgs,
+            string("Unknown EMonkeyActionType value"));
+    }
+}
+
+
+void CMonkeyRuleBase::AddSocket(MONKEY_SOCKTYPE sock)
+{
+    /* Element has to exist */
+    m_RunPos[sock];
+}
+
+/** Check that the rule should trigger on this run */
+bool CMonkeyRuleBase::CheckRun(MONKEY_SOCKTYPE sock, 
+                               unsigned short probability_left) const
+{
+    bool isRun = false;
+    
+    int rand_val = CMonkey::Instance()->GetRand(Key());
+    isRun = (rand_val % 100) < GetProbability(sock) * 100 / probability_left;
+    LOG_POST(Note << "[CMonkeyRuleBase::CheckRun]  Checking if the rule " 
+                  << "for " << s_PrintActionType(m_ActionType) 
+                  << " will be run this time. Random value is " 
+                  << rand_val << ", probability threshold is " 
+                  << m_Runs.at(m_RunPos.at(sock)) * 100);
+    LOG_POST(Note << "[CMonkeyRuleBase::CheckRun]  The rule will be " 
+                  << (isRun ? "" : "NOT ") << "run");
+    return isRun;
+}
+
+
+unsigned short CMonkeyRuleBase::GetProbability(MONKEY_SOCKTYPE sock) const
+{
+    if (m_RunPos.find(sock) == m_RunPos.end()) {
+        throw CMonkeyException(
+            CDiagCompileInfo(__FILE__, __LINE__),
+            NULL, CMonkeyException::e_MonkeyInvalidArgs,
+            "The socket provided has not been registered with current rule");
+    }
+    if (m_RunMode == eMonkey_RunProbability) {
+        return static_cast<unsigned short>(m_Runs.at(m_RunPos.at(sock)) * 100);
+    } else {
+        if ((m_RunPos.at(sock) + 1) > *m_Runs.rbegin()) {
+            switch (m_RepeatType) {
+            case eMonkey_RepeatNone:
+                return 0;
+            case eMonkey_RepeatLast:
+                return 100;
+            }
+        }
+        /* If m_Runs has the exact number of current run, the rule triggers */
+        return std::binary_search(m_Runs.begin(),
+                                  m_Runs.end(),
+                                  m_RunPos.at(sock) + 1) ? 100 : 0;
+    }
+    /* If "runs" is not set, rule always triggers */
+    if (m_Runs.empty()) return 100;
+
+}
+
+void CMonkeyRuleBase::x_ReadEIOStatus(const string& eIOStatus_in)
+{
+    string eIOStatus = eIOStatus_in;
+    NStr::ToLower(eIOStatus);
+    if (eIOStatus == "eio_closed") {
+        m_ReturnStatus = eIO_Closed;
+    } else if (eIOStatus == "eio_invalidarg") {
+        m_ReturnStatus = eIO_InvalidArg;
+    } else if (eIOStatus == "eio_interrupt") {
+        m_ReturnStatus = eIO_Interrupt;
+    } else if (eIOStatus == "eio_success") {
+        m_ReturnStatus = eIO_Success;
+    } else if (eIOStatus == "eio_timeout") {
+        m_ReturnStatus = eIO_Timeout;
+    } else if (eIOStatus == "eio_unknown") {
+        m_ReturnStatus = eIO_Unknown;
+    } else if (eIOStatus == "eio_notsupported") {
+        m_ReturnStatus = eIO_NotSupported;
+    } else {
+        throw CMonkeyException(
+            CDiagCompileInfo(__FILE__, __LINE__),
+            NULL, CMonkeyException::e_MonkeyInvalidArgs,
+            string("Could not parse 'return_status': ") + eIOStatus_in);
+    }
+}
+
+
+void CMonkeyRuleBase::x_ReadRuns(const string& runs)
+{
+    /* We get the string already without whitespaces and only have to
+       split it on commas*/
+    vector<string> runs_list = s_Monkey_Split(runs, ',');
+    if (runs_list.size() == 0)
+        throw CMonkeyException(
+            CDiagCompileInfo(__FILE__, __LINE__),
+            NULL, CMonkeyException::e_MonkeyInvalidArgs,
+            string("\"Runs\" parameter is empty"));
+    if (runs_list.size() == 1)
+        runs_list.push_back("...");
+    m_RunMode = runs_list[0][runs_list[0].length() - 1] == '%'
+                ? eMonkey_RunProbability : eMonkey_RunNumber;
+
+    m_RepeatType = eMonkey_RepeatNone;
+    if ( *runs_list.rbegin() == "repeat" ) {
+        m_RepeatType = eMonkey_RepeatAgain;
+    } else if ( *runs_list.rbegin() == "..." ) {
+        m_RepeatType = eMonkey_RepeatLast;
+    }
+
+    ERunFormat run_format = runs_list[0].find_first_of(':') != string::npos ? 
+                                                          eMonkey_RunRanges : 
+                                                         eMonkey_RunSequence;
+
+    unsigned int end_pos = (m_RepeatType == eMonkey_RepeatNone)
+                                    ? runs_list.size() : runs_list.size() - 1;
+
+    for ( unsigned int i = 0;  i < end_pos;  i++ ) {
+        string& run = runs_list[i];
+        double prob;
+        if (m_RunMode == eMonkey_RunProbability) {
+            if (*run.rbegin() != '%') {
+                throw CMonkeyException(
+                        CDiagCompileInfo(__FILE__, __LINE__),
+                        NULL, CMonkeyException::e_MonkeyInvalidArgs,
+                        "Value is not percentage: " + run +
+                        ", values have to be either only percentages or "
+                               "only numbers of tries, not mixed");
+            }
+            switch (run_format) {
+            default:
+                assert(0);
+                /* In release build - fall through to eMonkey_RunSequence */
+            case eMonkey_RunSequence:
+                prob = NStr::StringToDouble(run.substr(0, run.length() - 1));
+                m_Runs.push_back(prob / 100);
+                break;
+            case eMonkey_RunRanges:
+                size_t prob_start = run.find_first_of(':');
+                size_t step = NStr::StringToSizet(run.substr(0, prob_start));
+                size_t last_step = m_Runs.size();
+                if (last_step == 0 && step != 1) {
+                    throw CMonkeyException(
+                            CDiagCompileInfo(__FILE__, __LINE__),
+                            NULL, CMonkeyException::e_MonkeyInvalidArgs,
+                            "In the string of runs: " + runs + " the first "
+                            "element MUST set value for the first run");
+                }
+                prob = NStr::StringToDouble(run.substr(prob_start+1, run.length() - prob_start - 2));
+                for (size_t j = last_step+1; j > 0 && j < step; j++) {
+                    m_Runs.push_back(*m_Runs.rbegin());
+                }
+                m_Runs.push_back(prob / 100);
+                break;
+            }
+        } else {
+            assert(run_format == eMonkey_RunSequence);
+            if (*run.rbegin() == '%') {
+                throw CMonkeyException(
+                        CDiagCompileInfo(__FILE__, __LINE__),
+                        NULL, CMonkeyException::e_MonkeyInvalidArgs,
+                        string("Value is percentage: ") + run +
+                        string(", values have to be either only percentages or "
+                               "only numbers of tries, not mixed"));
+            }
+            int val = NStr::StringToInt(run);
+            if (m_Runs.size() > 0 && val <= *m_Runs.rbegin()) {
+                throw CMonkeyException(
+                    CDiagCompileInfo(__FILE__, __LINE__),
+                    NULL, CMonkeyException::e_MonkeyInvalidArgs,
+                    string("\"runs\" should contain values in "
+                           "increasing order"));
+            }
+            m_Runs.push_back(val);
+        }
+    }
+}
+
+
+int /* EIO_Status or -1 */ CMonkeyRuleBase::GetReturnStatus() const
+{
+    return m_ReturnStatus;
+}
+
+
+unsigned long CMonkeyRuleBase::GetDelay() const
+{
+    return m_Delay;
+}
+
+
+void CMonkeyRuleBase::IterateRun(MONKEY_SOCKTYPE sock)
+{
+    if (m_Runs.empty()) 
+        return;
+    m_RunPos[sock]++;
+    /* In probability mode each item of m_Runs is a probability of each run */
+    if (m_RunMode == eMonkey_RunProbability) {
+        assert(m_RunPos[sock] <= m_Runs.size());
+        if (m_RunPos[sock] == m_Runs.size()) {
+            switch (m_RepeatType) {
+            case eMonkey_RepeatNone: case eMonkey_RepeatLast:
+                m_RunPos[sock]--;
+            case eMonkey_RepeatAgain:
+                m_RunPos[sock] = 0;
+                break;
+            }
+        }
+        return;
+    }
+    /* In "number of the run" mode each item in m_Runs is a specific number of
+    run when the rule should trigger */
+    else if ((m_RunPos.at(sock) + 1) > *m_Runs.rbegin()) {
+        switch (m_RepeatType) {
+        case eMonkey_RepeatAgain:
+            m_RunPos[sock] = 0;
+            break;
+        }
+    }
+    return;
+}
+
+
+/*//////////////////////////////////////////////////////////////////////////////
+//                              CMonkeyRWRuleBase                             //
+//////////////////////////////////////////////////////////////////////////////*/
+CMonkeyRWRuleBase::CMonkeyRWRuleBase(EMonkeyActionType           action_type, 
+                                     const vector<string>& params)
+    : CMonkeyRuleBase(action_type, params), m_Text(""), m_TextLength(0), 
+      m_Garbage(false), m_FillType(eMonkey_FillRepeat)
+{
+    for ( unsigned int i = 0;  i < params.size();  i++ ) {
+        vector<string> name_value = s_Monkey_Split(params[i], '=');
+        string name = name_value[0];
+        string value = name_value[1];
+        if (name == "text") {
+            if (GetReturnStatus() != eIO_Success && GetReturnStatus() != -1) {
+                throw CMonkeyException(
+                    CDiagCompileInfo(__FILE__, __LINE__),
+                    NULL, CMonkeyException::e_MonkeyInvalidArgs,
+                    string("Return error status is set in Rule, cannot "
+                           "set 'text' parameter"));
+            }
+            if (value == "garbage") {
+                m_Garbage = true;
+            }
+            /*  The text should start and finish with ' or "  */
+            else if ( value[0] == value[value.length() - 1] 
+                  && (value[0] == '\'' || value[0] == '\"') )
+            {
+                m_Garbage = false;
+                m_Text = value.substr(1, value.length() - 2);
+            } else {
+                throw CMonkeyException(
+                    CDiagCompileInfo(__FILE__, __LINE__),
+                    NULL, CMonkeyException::e_MonkeyInvalidArgs,
+                    string("Could not parse 'text' for Rule: ") + value);
+            }
+        } else if (name == "text_length") {
+            m_TextLength = NStr::StringToInt(value);
+        } else if (name == "fill") {
+            if (value == "last_letter") {
+                m_FillType = eMonkey_FillLastLetter;
+            } else if (name == "repeat") {
+                m_FillType = eMonkey_FillRepeat;
+            }
+        } 
+    }
+    /* Checking that everything was set */
+    if (GetReturnStatus() == eIO_Success && m_Text == "") {
+        throw CMonkeyException(
+            CDiagCompileInfo(__FILE__, __LINE__),
+            NULL, CMonkeyException::e_MonkeyInvalidArgs,
+            string("Parameter 'text' not set to a non-empty value for rule, "
+                   "but 'return_status' set to eIO_Success requires 'text' to "
+                   "be set"));
+    }
+    if (GetReturnStatus() == -1 && m_Text == "") {
+        throw CMonkeyException(
+            CDiagCompileInfo(__FILE__, __LINE__),
+            NULL, CMonkeyException::e_MonkeyInvalidArgs,
+            string("Parameter 'text' not set to a non-empty value for rule, "
+                   "but 'return_status' not set requires 'text' to "
+                   "be set"));
+    }
+}
+
+
+void CMonkeyRWRuleBase::x_ReadFill(const string& fill_str)
+{
+    string fill = fill_str;
+    if (NStr::ToLower(fill) == "repeat") {
+        m_FillType = eMonkey_FillRepeat;
+    }
+    if (NStr::ToLower(fill) == "last_letter") {
+        m_FillType = eMonkey_FillLastLetter;
+    }
+}
+
+
+string CMonkeyRWRuleBase::GetText() const
+{
+    return m_Text;
+}
+
+
+size_t CMonkeyRWRuleBase::GetTextLength() const
+{
+    return m_TextLength;
+}
+
+
+bool CMonkeyRWRuleBase::GetGarbage() const
+{
+    return m_Garbage;
+}
+
+
+CMonkeyRWRuleBase::EFillType CMonkeyRWRuleBase::GetFillType() const
+{
+    return m_FillType;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// CMonkeyWriteRule
+//////////////////////////////////////////////////////////////////////////
+CMonkeyWriteRule::CMonkeyWriteRule(const vector<string>& params) 
+    : CMonkeyRWRuleBase(eMonkey_Send, params)
+{
+}
+
+
+MONKEY_RETTYPE CMonkeyWriteRule::Run(MONKEY_SOCKTYPE        sock,
+                                     const MONKEY_DATATYPE  data,
+                                     MONKEY_LENTYPE         size,
+                                     int                    flags,
+                                     SOCK*                  sock_ptr)
+{
+#ifdef NCBI_MONKEY_TESTS
+    g_MonkeyMock_SetInterceptedSend(true);
+#endif /* NCBI_MONKEY_TESTS */
+    LOG_POST(Error << "[CMonkeyWriteRule::Run]  CHAOS MONKEY ENGAGE!!! "
+                      "INTERCEPTED send()");
+    int return_status = GetReturnStatus();
+    if (return_status != eIO_Success && return_status != -1) {
+        switch (return_status) {
+        case eIO_Timeout:
+            *sock_ptr = s_TimeoutingSock->GetSOCK();
+            MONKEY_SET_SOCKET_ERROR(SOCK_EWOULDBLOCK);
+            return -1;
+        case eIO_Closed:
+            MONKEY_SET_SOCKET_ERROR(SOCK_ENOTCONN);
+            return -1;
+        case eIO_Unknown:
+            MONKEY_SET_SOCKET_ERROR(MONKEY_ENOPROTOOPT);
+            return -1; 
+        default:
+            break;
+        }
+    }
+
+    /* We cannot write more than the user asked */
+    size_t max_size;
+    if (GetTextLength() == 0) {
+        max_size = min(GetTextLength(), (size_t)size);
+    }
+    else {
+        max_size = size;
+    }
+    /* Fill data */
+    void* new_data = (char*)malloc(max_size * sizeof(char));
+    if (GetGarbage()) {
+        s_MONKEY_GenRandomString((char*)new_data, max_size);
+    } else {
+        string text = GetText();
+        if (GetFillType() == CMonkeyRWRuleBase::eMonkey_FillRepeat) {
+            text += text;
+            text = text.substr(0, max_size);
+        }
+        if (GetFillType() == CMonkeyRWRuleBase::eMonkey_FillLastLetter)
+            text.insert(text.length() - 1, max_size - text.length(),
+                        text[text.length()-1]);
+        memcpy(new_data, text.c_str(), max_size);
+    }
+    return send(sock, (const char*)new_data, size, flags);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// CMonkeyReadRule
+//////////////////////////////////////////////////////////////////////////
+CMonkeyReadRule::CMonkeyReadRule(const vector<string>& params)
+    : CMonkeyRWRuleBase(eMonkey_Recv, params)
+{
+    STimeout r_timeout = { 1, 0 };
+}
+
+
+MONKEY_RETTYPE CMonkeyReadRule::Run(MONKEY_SOCKTYPE sock,
+                                    MONKEY_DATATYPE buf,
+                                    MONKEY_LENTYPE  size,
+                                    int             flags,
+                                    SOCK*           sock_ptr)
+{
+#ifdef NCBI_MONKEY_TESTS
+    g_MonkeyMock_SetInterceptedRecv(true);
+#endif /* NCBI_MONKEY_TESTS */
+    LOG_POST(Error << "[CMonkeyReadRule::Run]  CHAOS MONKEY ENGAGE!!! "
+                      "INTERCEPTED recv()");
+    int return_status = GetReturnStatus();
+    if (return_status != eIO_Success && return_status != -1) {
+        switch (return_status) {
+        case eIO_Timeout:
+            *sock_ptr = s_TimeoutingSock->GetSOCK();
+            MONKEY_SET_SOCKET_ERROR(SOCK_EWOULDBLOCK);
+            return -1;
+        case eIO_Closed:
+            MONKEY_SET_SOCKET_ERROR(SOCK_ENOTCONN);
+            return -1;
+        case eIO_Unknown:
+            MONKEY_SET_SOCKET_ERROR(MONKEY_ENOPROTOOPT);
+            return -1;
+        default:
+            break;
+        }
+    }
+
+    if (size == 0) 
+        return 0;
+
+    /* So we decided to override */
+    MONKEY_RETTYPE bytes_read = recv(sock, buf, size, flags);
+
+    /* We cannot resize the buffer since it can be a local array, so we have to 
+     * decrease monkey text length instead */
+    size_t max_size = min(GetTextLength() - 1, static_cast<size_t>(size) - 1);
+    /* Replace data */
+    if (GetGarbage()) {
+        s_MONKEY_GenRandomString((char*)buf, max_size);
+    } else {
+        string text = GetText();
+        if (GetFillType() == CMonkeyRWRuleBase::eMonkey_FillRepeat) {
+            text += text;
+            text = text.substr(0, GetTextLength());
+        }
+        if (GetFillType() == CMonkeyRWRuleBase::eMonkey_FillLastLetter)
+            text.insert(text.length()-1, GetTextLength() - text.length(), 
+                        text[text.length()-1]);
+        memcpy(buf, text.c_str(), GetTextLength());
+    }
+
+    return bytes_read;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// CMonkeyConnectRule
+//////////////////////////////////////////////////////////////////////////
+
+CMonkeyConnectRule::CMonkeyConnectRule(const vector<string>& params)
+    : CMonkeyRuleBase(eMonkey_Connect, params)
+{
+    for (unsigned int i = 0; i < params.size(); i++) {
+        vector<string> name_value = s_Monkey_Split(params[i], '=');
+        string name = name_value[0];
+        string value = name_value[1];
+        if (name == "allow") {
+            m_Allow = ConnNetInfo_Boolean(value.c_str()) == 1;
+        }
+    }
+}
+
+
+int CMonkeyConnectRule::Run(MONKEY_SOCKTYPE        sock,
+                            const struct sockaddr* name,
+                            MONKEY_SOCKLENTYPE     namelen)
+{
+#ifdef NCBI_MONKEY_TESTS
+    g_MonkeyMock_SetInterceptedConnect(true);
+#endif /* NCBI_MONKEY_TESTS */
+    LOG_POST(Error << "[CMonkeyConnectRule::Run]  CHAOS MONKEY ENGAGE!!! "
+                      "INTERCEPTED connect()");
+    int return_status = GetReturnStatus();
+    if (return_status != eIO_Success && return_status != -1) {
+        switch (return_status) {
+        case eIO_Timeout:
+            MONKEY_SET_SOCKET_ERROR(SOCK_EWOULDBLOCK);
+            return -1;
+        case eIO_Closed:
+            MONKEY_SET_SOCKET_ERROR(SOCK_ECONNREFUSED);
+            return -1;
+        case eIO_Unknown:
+            MONKEY_SET_SOCKET_ERROR(MONKEY_ENOPROTOOPT);
+            return -1;
+        case eIO_Interrupt:
+            MONKEY_SET_SOCKET_ERROR(SOCK_EINTR);
+            return -1;
+        default:
+            break;
+        }
+    }
+    if (GetDelay() > 0) {
+        SleepMilliSec(GetDelay(), EInterruptOnSignal::eInterruptOnSignal);
+    }
+    if (m_Allow) {
+        return connect(sock, name, namelen);
+    }
+    else {
+        struct sockaddr_in addr;
+        /* Connect to a non-existing host */
+        addr.sin_family = AF_INET;
+        addr.sin_port = 65511;
+        /* 3232235631 is 192.168.0.111 - does not exist at NCBI, which is 
+           enough for the goal of test */
+#ifdef NCBI_OS_MSWIN
+        addr.sin_addr.S_un.S_addr = htonl(3232235631);
+#else
+        addr.sin_addr.s_addr = htonl(3232235631);
+#endif /* NCBI_OS_MSWIN */
+        return connect(sock, (struct sockaddr*)&addr, namelen);
+    }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// CMonkeyPollRule
+//////////////////////////////////////////////////////////////////////////
+CMonkeyPollRule::CMonkeyPollRule(const vector<string>& params) 
+    : CMonkeyRuleBase(eMonkey_Poll, params)
+{
+#ifdef NCBI_MONKEY_TESTS
+    g_MonkeyMock_SetInterceptedPoll(true);
+#endif /* NCBI_MONKEY_TESTS */
+    for ( unsigned int i = 0;  i < params.size();  i++ ) {
+        vector<string> name_value = s_Monkey_Split(params[i], '=');
+        string name  = name_value[0];
+        string value = name_value[1];
+        if (name == "ignore") {
+            m_Ignore = ConnNetInfo_Boolean(value.c_str()) == 1;
+        }
+    }
+}
+
+
+bool CMonkeyPollRule::Run(size_t*     n,
+                          SOCK*       sock,
+                          EIO_Status* return_status)
+{
+    LOG_POST(Error << "[CMonkeyPollRule::Run]  CHAOS MONKEY ENGAGE!!! "
+                      "INTERCEPTED poll()");
+    if (m_Ignore) {
+        return true;
+    }
+    return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// CMonkeyPlan
+//////////////////////////////////////////////////////////////////////////
+CMonkeyPlan::CMonkeyPlan(const string& section)
+    : m_Probability(100), m_HostRegex(".*"), m_Name(section)
+{
+    /* Plan settings */
+    CNcbiRegistry& config = CNcbiApplication::Instance()->GetConfig();
+    string probability = config.Get(section, "probability");
+    if (probability != "") {
+        if (probability.find('%') != string::npos) {
+            probability = probability.substr(0, probability.length() - 1);
+            m_Probability = static_cast<unsigned short>(
+                NStr::StringToUInt(probability));
+        } else {
+            m_Probability = static_cast<unsigned short>(
+                NStr::StringToDouble(probability) * 100);
+        }
+    }
+    m_HostRegex = NStr::Replace(NStr::Replace(
+            config.Get(section, "host_match"), " ",  ""),
+                                               "\t", "");
+
+    x_ReadPortRange(config.Get(section, "port_match"));
+
+    /* Write rules */
+    x_LoadRules(section, "write",   m_WriteRules);
+    /* Read rules */
+    x_LoadRules(section, "read",    m_ReadRules);
+    /* Connect rules */
+    x_LoadRules(section, "connect", m_ConnectRules);
+    /* Poll rules */
+    x_LoadRules(section, "poll",    m_PollRules);
+}
+
+
+template<class Rule_Ty>
+void CMonkeyPlan::x_LoadRules(const string&    section,
+                              const string&    rule_type_str,
+                              vector<Rule_Ty>& container)
+{
+    CNcbiRegistry& config = CNcbiApplication::Instance()->GetConfig();
+    bool multi_rule = false;
+    string rule_str = config.Get(section, rule_type_str);
+    if (rule_str == "") {
+        /* Try check if there are multiple rules defined */
+        if ((rule_str = config.Get(section, rule_type_str + "1")) != "")
+            multi_rule = true;
+    }
+    if ( rule_str == "" )
+        return;
+    /* If a rule was read - parse it */
+    string temp_conf = NStr::Replace(rule_str, string(" "), string(""));
+    vector<string> params = s_Monkey_Split(temp_conf, ';');
+    container.push_back(Rule_Ty(params));
+    if ( multi_rule ) {
+        int rule_num = 2;
+        string val_name = rule_type_str + NStr::IntToString(rule_num++);
+        while ( (rule_str = config.Get(section, val_name)) != "" ) {
+            temp_conf = NStr::Replace(rule_str, string(" "), string(""));
+            params = s_Monkey_Split(temp_conf, ';');
+            container.push_back(Rule_Ty(params));
+            val_name = rule_type_str+ NStr::IntToString(rule_num++);
+        }
+    }
+}
+
+#ifndef NCBI_OS_MSWIN
+/** Regex-like check (might use some refactoring) */
+static bool s_MatchRegex(const string& to_match, const string& regex)
+{
+    /* Convert "match regex" task to "haystack and needle" task. We check 
+     * whether there is a wildcard in the beginning and/or in the end of
+     * regex (other cases are not supported). And then check if to_match 
+     * starts with, end with or contains the needle */
+
+    /* First - compatibility check. Functionality is limited. */
+    /* Check for special characters and combinations that cannot be processed.
+    * Method - remove combinations of characters that are supported and check
+    * the rest */
+    string exception_message = string("Pattern") + regex + " "
+        "cannot be processed because regular expressions "
+        "are not fully supported. You can use .* in the "
+        "beginning and in the end of a pattern and | to separate "
+        "patterns. Stop mark is set with \\\\.\n"
+        "Example:\n"
+        "host_match = .*nlm\\\\.nih.*|.*gov|10\\\\.55.*\n";
+        string filtered = NStr::Replace(NStr::Replace(regex, "\\.", ""),
+                                                             ".*" , "");
+    if (filtered.find_first_of("[]()+^?{}$.*\\") != string::npos) {
+        throw CMonkeyException(
+            CDiagCompileInfo(__FILE__, __LINE__),
+            NULL,
+            CMonkeyException::e_MonkeyInvalidArgs,
+            exception_message);
+    }
+    size_t pos = 0;
+    size_t last_find = 0;
+    bool start_wildcard = false, end_wildcard = false;
+    while ((last_find = NStr::Find(regex, ".*", pos)) != NPOS &&
+        pos < regex.length()) {
+        pos = last_find + 1;
+        if (last_find == 0) {
+            start_wildcard = true;
+        }
+        else if (last_find == regex.length() - strlen(".*")) {
+            end_wildcard = true;
+        }
+        else {
+            throw CMonkeyException(
+                CDiagCompileInfo(__FILE__, __LINE__),
+                NULL,
+                CMonkeyException::e_MonkeyInvalidArgs,
+                exception_message);
+        }
+    }
+    /*
+     * Run the "Needle in a haystack" task 
+     */
+    string needle = NStr::Replace(NStr::Replace(regex, ".*", ""), "\\.", ".");
+    if (start_wildcard && !end_wildcard) {
+        if (!NStr::StartsWith(to_match, needle)) {
+            return false;
+        }
+    }
+    else if (!start_wildcard && end_wildcard) {
+        if (!NStr::EndsWith(to_match, needle)) {
+            return false;
+        }
+    }
+    else if (start_wildcard && end_wildcard) {
+        if (NStr::Find(to_match, needle) == NPOS) {
+            return false;
+        }
+    }
+    return true;
+}
+#endif /* NCBI_OS_MSWIN */
+
+
+/* Compares supplied parameters to */
+bool CMonkeyPlan::Match(const string&  sock_host,
+                        unsigned short sock_port, 
+                        const string&  sock_url,
+                        unsigned short probability_left)
+{
+    /* Regex test just in case */
+    static int regex_works = 1; /* 0 for not working, 1 for working */
+#if 0
+    if (regex_works == -1) {
+        regex  test_regexp("test_regex"); /* should not match "test" */
+        string test_string = "test.*";
+        smatch test_find;
+        if (!regex_match(test_string, test_find, test_regexp)) {
+            regex_works = 0; /* we learn that regex implementation is fake */
+        }
+        regex_works = 1;
+    }
+#endif /* 0 */
+
+    /* Check that regex works and that at least one of hostname and IP 
+     * is not empty*/
+    if ( regex_works && !m_HostRegex.empty() &&
+            (sock_host.length() + sock_url.length() > 0) ) {
+#ifdef NCBI_OS_MSWIN
+        regex reg(m_HostRegex);
+        smatch find;
+        if (!regex_match(sock_host, find, reg) && 
+            !regex_match(sock_url,  find, reg)) {
+            return false;
+        }
+#else
+    /*
+     * Regex is not supported - work with simple simulation - only .* in
+     * beginning and end of pattern and | to separate patterns
+     */
+        vector<string> patterns = s_Monkey_Split(m_HostRegex, '|');
+        auto it = patterns.begin();
+        bool match_found = false;
+        for (  ;  it != patterns.end();  it++) {
+            if (s_MatchRegex(sock_url, *it) || s_MatchRegex(sock_host, *it)) {
+                match_found = true;
+                break;
+            }
+        }
+        if (!match_found) {
+            return false;
+        }
+#endif /* NCBI_OS_MSWIN */
+    }
+    /* If port match pattern is not set, any port is good */
+    bool port_match = m_PortRanges.empty();
+    auto port_iter = m_PortRanges.begin();
+    for (; port_iter != m_PortRanges.end(); port_iter++) {
+        if (sock_port >= *port_iter && sock_port <= *++port_iter) {
+            port_match = true;
+            break;
+        }
+    }
+    int rand_val = CMonkey::Instance()->GetRand(Key());
+    LOG_POST(Note << "[CMonkeyPlan::Match]  Checking if plan " << m_Name  
+                  << " will be matched. Random value is " 
+                  << rand_val << ", plan probability is " 
+                  << m_Probability << "%, probability left is "  
+                  << probability_left << "%, so probability threshold is"
+                  << m_Probability * 100 / probability_left << "%");
+    LOG_POST(Note << "[CMonkeyPlan::Match]  Plan " << m_Name << " was " 
+                  << ((port_match && ((rand_val % 100) < m_Probability)) ? 
+                      "" : "NOT ") << "matched");
+    return port_match ? ((rand_val % 100) < m_Probability*100/probability_left) 
+                                          : false;
+}
+
+
+bool CMonkeyPlan::WriteRule(MONKEY_SOCKTYPE        sock,
+                            const MONKEY_DATATYPE  data,
+                            MONKEY_LENTYPE         size,
+                            int                    flags,
+                            MONKEY_RETTYPE*        bytes_written,
+                            SOCK*                  sock_ptr)
+{
+    short probability_left = 100;
+    for (unsigned int i = 0;  i < m_WriteRules.size();  i++) {
+        m_WriteRules[i].AddSocket(sock);
+        unsigned short rule_prob = m_WriteRules[i].GetProbability(sock);
+        if (m_WriteRules[i].CheckRun(sock)) {
+            *bytes_written = m_WriteRules[i].Run(sock, data, size, flags, 
+                                                 sock_ptr);
+            return true;
+        }
+        /* If this rule did not engage, we go to the next rule, and
+           remember to normalize probability of next rule */
+        probability_left -= rule_prob;
+        if (probability_left <= 0) {
+            stringstream ss;
+            ss << "Probability below zero for write rule in plan " << m_Name
+                << ". Check config!";
+            throw CMonkeyException(
+                        CDiagCompileInfo(__FILE__, __LINE__),
+                        NULL, CMonkeyException::e_MonkeyInvalidArgs, 
+                        ss.str());
+        }
+    }
+    // If no rules engaged, return 0
+    return false;
+}
+
+
+bool CMonkeyPlan::ReadRule(MONKEY_SOCKTYPE        sock,
+                           MONKEY_DATATYPE        buf,
+                           MONKEY_LENTYPE         size,
+                           int                    flags,
+                           MONKEY_RETTYPE*        bytes_read,
+                           SOCK*                  sock_ptr)
+{
+    short probability_left = 100;
+    for (unsigned int i = 0;  i < m_ReadRules.size();  i++) {
+        m_ReadRules[i].AddSocket(sock);
+        unsigned short rule_prob = m_ReadRules[i].GetProbability(sock);
+        if (m_ReadRules[i].CheckRun(sock)) {
+            *bytes_read = m_ReadRules[i].Run(sock, buf, size, flags, sock_ptr);
+            return true;
+        }
+        /* If this rule did not engage, we go to the next rule, and
+           and remember to normalize probability of next rule */
+        probability_left -= rule_prob;
+        if (probability_left <= 0) {
+            stringstream ss;
+            ss << "Probability below zero for write rule in plan " << m_Name
+                << ". Check config!";
+            throw CMonkeyException(
+                        CDiagCompileInfo(__FILE__, __LINE__),
+                        NULL, CMonkeyException::e_MonkeyInvalidArgs, 
+                        ss.str());
+        }
+    }
+    return false;
+}
+
+
+bool CMonkeyPlan::ConnectRule(MONKEY_SOCKTYPE        sock,
+                              const struct sockaddr* name,
+                              MONKEY_SOCKLENTYPE     namelen,
+                              int*                   result)
+{
+    short probability_left = 100;
+    for (unsigned int i = 0; i < m_ConnectRules.size(); i++) {
+        m_ConnectRules[i].AddSocket(sock);
+        unsigned short rule_prob = m_ConnectRules[i].GetProbability(sock);
+        /* Check if the rule will trigger on this run. If not - we go to the 
+           next rule in plan */
+        if (m_ConnectRules[i].CheckRun(sock)) {
+            /* 'result' is the result of connect() launched in the rule. It can
+               even be result of original connect() with real parameters.
+               Or, it can be an error code of a failed fake connect() */
+            *result = m_ConnectRules[i].Run(sock, name, namelen);
+            return true;
+        }
+        /* If this rule did not engage, we go to the next rule, and
+           and remember to normalize probability of next rule */
+        probability_left -= rule_prob;
+        if (probability_left <= 0) {
+            stringstream ss;
+            ss << "Probability below zero for write rule in plan " << m_Name
+                << ". Check config!";
+            throw CMonkeyException(
+                        CDiagCompileInfo(__FILE__, __LINE__),
+                        NULL, CMonkeyException::e_MonkeyInvalidArgs, 
+                        ss.str());
+        }
+    }
+    // If no rules triggered
+    return false;
+}
+
+
+bool CMonkeyPlan::PollRule(size_t*     n,
+                           SOCK*       sock,
+                           EIO_Status* return_status)
+{
+    short probability_left = 100;
+    for (unsigned int i = 0;  i < m_PollRules.size();  i++) {
+        m_PollRules[i].AddSocket((*sock)->sock);
+        unsigned short rule_prob = m_PollRules[i].GetProbability((*sock)->sock);
+        if (m_PollRules[i].CheckRun((*sock)->sock)) {
+            return m_PollRules[i].Run(n, sock, return_status);
+        }
+        LOG_POST(Error << "[CMonkeyPlan::PollRule]  CHAOS MONKEY NOT "
+                          "ENGAGED!!! poll() passed");
+        /* If this rule did not engage, we go to the next rule, and
+           and remember to normalize probability of next rule */
+        probability_left -= rule_prob;
+        if (probability_left <= 0) {
+            stringstream ss;
+            ss << "Probability below zero for write rule in plan " << m_Name
+                << ". Check config!";
+            throw CMonkeyException(
+                        CDiagCompileInfo(__FILE__, __LINE__),
+                        NULL, CMonkeyException::e_MonkeyInvalidArgs, 
+                        ss.str());
+        }
+    }
+    // If no rules triggered, return 0
+    *return_status = EIO_Status::eIO_Success;
+    return false;
+}
+
+
+unsigned short CMonkeyPlan::GetProbabilty(void)
+{
+    return m_Probability;
+}
+
+
+void CMonkeyPlan::x_ReadPortRange(const string& conf)
+{
+    vector<string> ranges = s_Monkey_Split(conf, ',');
+    unsigned short from, to;
+    auto it = ranges.begin();
+    for (  ;  it != ranges.end();  it++  )  {
+        if (it->find('-') != string::npos) {
+            vector<string> ports = s_Monkey_Split(*it, '-');
+            from = static_cast<unsigned short>(NStr::StringToUInt(ports[0]));
+            to   = static_cast<unsigned short>(NStr::StringToUInt(ports[1]));
+        } else {
+            from = to = static_cast<unsigned short>(NStr::StringToUInt(*it));
+        }
+        /* From*/
+        m_PortRanges.push_back(from);
+        /* Until */
+        m_PortRanges.push_back(to);
+    }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// CMonkey
+//////////////////////////////////////////////////////////////////////////
+CMonkey*          CMonkey::sm_Instance   = NULL;
+FMonkeyHookSwitch CMonkey::sm_HookSwitch = NULL;
+
+
+CMonkey::CMonkey() : m_Probability(1.0), m_Enabled(false)
+{
+    if (sm_HookSwitch == NULL) {
+        throw CMonkeyException(
+            CDiagCompileInfo(__FILE__, __LINE__),
+            NULL, CMonkeyException::e_MonkeyInvalidArgs,
+            "Launch CONNECT_Init() before initializing CMonkey instance");
+    }
+    m_TlsToken = new CTls<int>;
+    m_TlsRandList = new CTls<vector<int> >;
+    m_TlsRandListPos = new CTls<int>;
+    srand((unsigned int)time(NULL));
+    m_Seed = rand();
+    LOG_POST(Note << "[CMonkey::CMonkey()]  Chaos Monkey seed is: " << m_Seed);
+    ReloadConfig();
+}
+
+
+CMonkey* CMonkey::Instance()
+{
+    CFastMutexGuard spawn_guard(s_SingletonMutex);
+
+    if (sm_Instance == NULL) {
+        sm_Instance = new CMonkey;
+    }
+    return sm_Instance;
+}
+
+
+bool CMonkey::IsEnabled()
+{
+    return m_Enabled;
+}
+
+
+void CMonkey::ReloadConfig(const string& config)
+{
+    assert(sm_HookSwitch != NULL);
+    CFastMutexGuard spawn_guard(s_ConfigMutex);
+    string          rules;
+    string          monkey_section = config.empty() ? s_GetMonkeySection() : 
+                                                      config;
+    list<string>    sections;
+    CNcbiRegistry&  reg = CNcbiApplication::Instance()->GetConfig();
+    if (ConnNetInfo_Boolean(reg.Get(kMonkeyMainSect, kEnablField).c_str()) != 1) 
+    {
+        LOG_POST(Note << "[CMonkey::ReloadConfig]  Chaos Monkey is disabled " 
+                      << "in [" << kMonkeyMainSect << "]");
+        m_Enabled = false;
+        return;
+    }
+    string seed = reg.Get(kMonkeyMainSect, kSeedField).c_str();
+    if (seed != "") {
+        LOG_POST(Note << "[CMonkey::ReloadConfig]  Chaos Monkey seed is set " 
+                      << "to " << seed << " in config");
+        SetSeed(NStr::StringToInt(seed));
+    }
+    reg.EnumerateSections(&sections);
+    /* If the section does not exist */
+    if (find(sections.begin(), sections.end(), monkey_section)
+        == sections.end()) {
+        m_Enabled = false;
+        return;
+    }
+    if (ConnNetInfo_Boolean(reg.Get(monkey_section, kEnablField).c_str()) != 1)
+    {
+        LOG_POST(Note << "[CMonkey::ReloadConfig]  Chaos Monkey is disabled " 
+                      << "in [" << monkey_section << "]");
+        m_Enabled = false;
+        return;
+    }
+    m_Enabled = true;
+    LOG_POST(Error << "[CMonkey::ReloadConfig]  Chaos Monkey is active!");
+    string probability = reg.Get(monkey_section, "probability");
+    if (probability != "") {
+        probability = NStr::Replace(probability, " ", "");
+        auto arr = s_Monkey_Split(probability, '=');
+        try {
+            if (*probability.rbegin() != '%') {
+                m_Probability = NStr::StringToDouble(probability) * 100;
+            }
+            else {
+                probability = probability.substr(0, probability.length() - 1);
+                m_Probability = NStr::StringToDouble(probability);
+            }
+        }
+        catch (const CStringException&) {
+            throw CMonkeyException(CDiagCompileInfo(__FILE__, __LINE__),
+                                   NULL, CMonkeyException::e_MonkeyInvalidArgs,
+                                   "Probability \"" + probability
+                                   + "\" for section " + monkey_section
+                                   + " could not be parsed");
+        }
+    }
+    // Disable hooks while Monkey initializes
+    sm_HookSwitch(eMonkeyHookSwitch_Disabled);
+    unsigned short total_probability = 0;
+    for (int i = 1;  ;  ++i) {
+        string section = monkey_section + "_PLAN" + NStr::IntToString(i);
+        if (find(sections.begin(), sections.end(), section) ==
+            sections.end()) {
+            break;
+        }
+        m_Plans.push_back(CMonkeyPlan(section));
+        total_probability += (*m_Plans.rbegin()).GetProbabilty();
+    }
+    /* Check that sum of probabilities for plans is less than 100%, otherwise -
+     * throw an exception with an easy-to-read message */
+    if (total_probability > 100) {
+        stringstream ss;
+        ss << "Total probability for plans in configuration " <<
+            monkey_section << " exceeds 100%. Please check that summary " <<
+            "probability for plans stays under 100% (where the remaining "
+            "percents go to connections that are not intercepted by any plan)."
+            "\nTurning Chaos Monkey off";
+        CORE_LOG(eLOG_Critical, ss.str().c_str());
+        m_Enabled = false;
+    }
+    if (m_Enabled) {
+        s_TimeoutingSocketInit();
+    }
+    else {
+        s_TimeoutingSocketDestroy();
+    }
+    sm_HookSwitch(m_Enabled ? eMonkeyHookSwitch_Enabled 
+                            : eMonkeyHookSwitch_Disabled);
+}
+
+
+MONKEY_RETTYPE CMonkey::Send(MONKEY_SOCKTYPE        sock,
+                             const MONKEY_DATATYPE  data,
+                             MONKEY_LENTYPE         size,
+                             int                    flags,
+                             SOCK*                  sock_ptr)
+{
+    string host_fqdn, host_IP;
+    unsigned short peer_port;
+    s_GetSocketDestinations(sock, &host_fqdn, &host_IP, NULL, &peer_port);
+    CMonkeyPlan* sock_plan = x_FindPlan(sock, host_fqdn, host_IP, peer_port);
+
+    if (sock_plan != NULL) {
+        MONKEY_RETTYPE bytes_written;
+        /* Plan may decide to leave connection untouched */
+        if ( sock_plan->WriteRule(sock, data, size, flags, &bytes_written, 
+                                  sock_ptr) )
+            return bytes_written;
+    }
+     return send(sock, (const char*)data, size, flags);
+}
+
+
+MONKEY_RETTYPE CMonkey::Recv(MONKEY_SOCKTYPE        sock,
+                             MONKEY_DATATYPE        buf,
+                             MONKEY_LENTYPE         size,
+                             int                    flags,
+                             SOCK*                  sock_ptr)
+{
+    string host_fqdn, host_IP;
+    unsigned short peer_port;
+    s_GetSocketDestinations(sock, &host_fqdn, &host_IP, NULL, &peer_port);
+
+    CMonkeyPlan* sock_plan = x_FindPlan(sock, host_fqdn, host_IP, peer_port);
+
+    if (sock_plan != NULL) {
+        MONKEY_RETTYPE bytes_read;
+        if (sock_plan->ReadRule(sock, buf, size, flags, &bytes_read, sock_ptr))
+            return bytes_read;
+    }
+    return recv(sock, buf, size, flags);
+}
+
+
+int CMonkey::Connect(MONKEY_SOCKTYPE        sock,
+                     const struct sockaddr* name,
+                     MONKEY_SOCKLENTYPE     namelen)
+{
+    union {
+        struct sockaddr    sa;
+        struct sockaddr_in in;
+#ifdef NCBI_OS_UNIX
+        struct sockaddr_un un;
+#endif /*NCBI_OS_UNIX*/
+    } addr;
+    addr.sa = *name;
+    unsigned int host = addr.in.sin_addr.s_addr;
+    string host_fqdn, host_IP;
+    unsigned short peer_port = ntohs(addr.in.sin_port);
+    host_fqdn = CSocketAPI::gethostbyaddr(host);
+    host_IP = CSocketAPI::HostPortToString(host, 0);
+
+    CMonkeyPlan* sock_plan = x_FindPlan(sock, host_fqdn, host_IP, peer_port);
+    if (sock_plan != NULL) {
+        int result;
+        if ( sock_plan->ConnectRule(sock, name, namelen, &result) )
+            return result;
+    }
+    return connect(sock, name, namelen);
+}
+
+
+bool CMonkey::Poll(size_t*      n,
+                   SSOCK_Poll** polls,
+                   EIO_Status*  return_status)
+{
+    size_t polls_iter       = 0;
+    SSOCK_Poll* new_polls   = 
+        static_cast<SSOCK_Poll*>(calloc(*n, sizeof(SSOCK_Poll)));
+    int polls_count         = 0;
+    while (polls_iter < *n) {
+        SOCK&        sock      = (*polls)[polls_iter].sock;
+        string       host_fqdn = CSocketAPI::gethostbyaddr(sock->host);
+        string       host_IP   = CSocketAPI::HostPortToString(sock->host, 0);
+        CMonkeyPlan* sock_plan = x_FindPlan(sock->id, "", "", sock->myport);
+        if (sock_plan == NULL ||
+            (sock_plan != NULL && !sock_plan->PollRule(n, &sock, return_status)) 
+            ) {
+            new_polls[polls_count++] = (*polls)[polls_iter];
+        }
+        polls_iter++;
+    }
+    *polls = new_polls;
+    *n = polls_count;
+    return false;
+}
+
+
+void CMonkey::Close(MONKEY_SOCKTYPE sock)
+{
+    auto sock_plan = m_KnownSockets.find(sock);
+    if (sock_plan != m_KnownSockets.end()) {
+        m_KnownSockets.erase(sock_plan);
+    }
+}
+
+
+void CMonkey::MonkeyHookSwitchSet(FMonkeyHookSwitch hook_switch_func)
+{
+    sm_HookSwitch = hook_switch_func;
+}
+
+
+/** Return plan for the socket, new or already assigned one. If the socket
+ * is ignored by Chaos Monkey, NULL is returned */
+CMonkeyPlan* CMonkey::x_FindPlan(MONKEY_SOCKTYPE sock,  const string& hostname, 
+                                 const string& host_IP, unsigned short port)
+{
+    CFastMutexGuard spawn_guard(s_KnownConnMutex);
+    auto sock_plan = m_KnownSockets.find(sock);
+    if (sock_plan != m_KnownSockets.end()) {
+        return sock_plan->second;
+    }
+    /* Plan was not found. First roll the dice to know if Monkey will process 
+     * current socket */
+    int rand_val = CMonkey::Instance()->GetRand(Key());
+    LOG_POST(Note << "[CMonkey::x_FindPlan]  Checking if connection will be "
+                  << "intercepted by Chaos Monkey. Random value is " 
+                  << rand_val << ", probability threshold is " 
+                  << m_Probability);
+    LOG_POST(Note << "[CMonkey::x_FindPlan]  The connection will be "
+                  << ((rand_val % 100 >= m_Probability) ? "NOT " : "") 
+                  << "processed.");
+    if (rand_val % 100 >= m_Probability) {
+        return NULL;
+    }
+    /* Now we can find a plan */
+    bool match_found = false;
+    unsigned short probability_left = 100; /* If we tried to match a plan with
+                                              n% probability with no luck,
+                                              next plan only has (100-n)% 
+                                              fraction of connections to match
+                                              against, so if its probability to
+                                              all connections is m%, its 
+                                              probability to connections left 
+                                              is m/(100-n)*100%. To count this,
+                                              we need probability_left */
+    for (unsigned int i = 0; i < m_Plans.size() && !match_found; i++) {
+        /* Match includes probability of plan*/
+        if (m_Plans[i].Match(host_IP, port, hostname, probability_left)) {
+            // 3. If found plan - use it and assign to this socket
+            m_KnownSockets[sock] = &m_Plans[i];
+            return m_KnownSockets[sock];
+        }
+        probability_left -= m_Plans[i].GetProbabilty();
+    }
+    /* If no plan triggered, then this socket will be always ignored */
+    m_KnownSockets[sock] = NULL;
+    return NULL;
+}
+
+
+bool CMonkey::RegisterThread(int token)
+{
+    if (!m_Enabled) {
+        ERR_POST(Error << "[CMonkey::RegisterThread]  Chaos Monkey is "
+                       << "disabled, the thread with token "
+                       << token << " was not registered");
+        return false;
+    }
+    CFastMutexGuard guard(s_SeedLogConfigMutex);
+    LOG_POST(Note << "[CMonkey::RegisterThread]  Registering thread with "
+                  << "token " << token);
+
+    stringstream ss;
+    ss << "[CMonkey::RegisterThread]  Token " << token 
+       << " has been already registered in CMonkey and cannot be used again";
+    if (m_RegisteredTokens.find(token) != m_RegisteredTokens.end()) {
+        throw CMonkeyException(
+            CDiagCompileInfo(__FILE__, __LINE__),
+            NULL, CMonkeyException::e_MonkeyInvalidArgs,
+            ss.str());
+    }
+    m_RegisteredTokens.insert(token);
+
+    /* Remember token */
+    m_TlsToken->SetValue(new int, s_TlsCleanup<int>);
+    *m_TlsToken->GetValue() = token;
+
+    vector<int>* rand_list = new vector<int>();
+    srand(m_Seed + token);
+    stringstream rand_list_str;
+    for (unsigned int i = 0; i < kRandCount; ++i) {
+        rand_list->push_back(rand());
+        rand_list_str << *rand_list->rbegin() << " ";
+    }
+    LOG_POST(Note << "[CMonkey::RegisterThread]  Random list for token "
+                  << token << " is " << rand_list_str.str());
+    m_TlsRandList->SetValue(rand_list, s_TlsCleanup< vector<int> >);
+
+    m_TlsRandListPos->SetValue(new int, s_TlsCleanup<int>);
+    *m_TlsRandListPos->GetValue() = 0;
+
+    return true;
+}
+
+
+int CMonkey::GetSeed()
+{
+    /* save m_seedlog to file */
+    return m_Seed;
+}
+
+
+void CMonkey::SetSeed(int seed)
+{
+    /* load m_seedlog from file */
+    m_Seed = seed;
+    LOG_POST(Info << "[CMonkey::SetSeed]  Chaos Monkey seed was manually "
+                     "changed to: " << m_Seed);
+}
+
+
+int CMonkey::GetRand(const CMonkeySeedKey& /* key */)
+{
+    if (m_TlsToken->GetValue() == NULL) {
+        return rand();
+    }
+    int& list_pos = *m_TlsRandListPos->GetValue();
+    if (++list_pos == kRandCount) {
+        list_pos = 0;
+    }
+    int next_list_pos = (list_pos + 1 == kRandCount) ? 0 : list_pos + 1;
+    LOG_POST(Note << "[CMonkey::GetRand]  Getting random value "
+                  << (*m_TlsRandList->GetValue())[list_pos]
+                  << " for thread " << *m_TlsToken->GetValue()
+                  << ". Next random value is "
+                  << (*m_TlsRandList->GetValue())[next_list_pos]);
+    return (*m_TlsRandList->GetValue())[list_pos];
+}
+
+
+END_NCBI_SCOPE
+
+#endif /* #ifdef NCBI_MONKEY */
+
diff --git a/c++/src/connect/ncbi_monkeyp.hpp b/c++/src/connect/ncbi_monkeyp.hpp
new file mode 100644
index 0000000..05250ed
--- /dev/null
+++ b/c++/src/connect/ncbi_monkeyp.hpp
@@ -0,0 +1,81 @@
+/* $Id: ncbi_monkeyp.hpp 503153 2016-06-01 19:11:37Z elisovdn $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's official duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* Author:  Dmitriy Elisov
+*
+* File Description:
+*   Chaos Monkey - a library that is hooked with ncbi_socket.c and introduces
+*   problems in network connectivity - losses, bad data, delays.
+*   difficulties
+*
+*/
+
+#ifndef CONNECT___NCBI_MONKEYP__HPP
+#define CONNECT___NCBI_MONKEYP__HPP
+
+#   include <connect/ncbi_monkey.hpp>
+
+BEGIN_NCBI_SCOPE
+
+
+/* A special class which opens access to writing to Monkey Action Log*/
+
+
+#ifdef NCBI_MONKEY_TESTS
+
+
+using namespace std;
+
+#define MONKEY_MOCK_MACRO()                                           \
+DECLARE_MONKEY_MOCK(bool, InterceptedRecv, false);               \
+DECLARE_MONKEY_MOCK(bool, InterceptedSend, false);                  \
+DECLARE_MONKEY_MOCK(bool, InterceptedConnect, false);               \
+DECLARE_MONKEY_MOCK(bool, InterceptedPoll, false);                  \
+DECLARE_MONKEY_MOCK(string, LastRecvContent, "");                   \
+DECLARE_MONKEY_MOCK(string, LastSendContent, "");                   \
+DECLARE_MONKEY_MOCK(EIO_Status, LastRecvStatus, eIO_Success);       \
+DECLARE_MONKEY_MOCK(EIO_Status, LastSendStatus, eIO_Success);       \
+DECLARE_MONKEY_MOCK(EIO_Status, LastConnectStatus, eIO_Success);
+
+
+#undef DECLARE_MONKEY_MOCK
+#define DECLARE_MONKEY_MOCK(ty,name,def_val/*not used*/)                       \
+    ty g_MonkeyMock_Get ## name();                                             \
+    void g_MonkeyMock_Set ## name(const ty& val);
+
+MONKEY_MOCK_MACRO()
+void g_Monkey_Foo();
+ 
+class CMonkeySpy
+{
+
+};
+
+
+#endif /* #ifdef NCBI_MONKEY_TESTS */
+
+END_NCBI_SCOPE
+
+#endif /* CONNECT___NCBI_MONKEYP__HPP */
\ No newline at end of file
diff --git a/c++/src/connect/ncbi_priv.c b/c++/src/connect/ncbi_priv.c
index a2f4511..87cd30c 100644
--- a/c++/src/connect/ncbi_priv.c
+++ b/c++/src/connect/ncbi_priv.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_priv.c 488838 2016-01-06 13:45:11Z elisovdn $
+/* $Id: ncbi_priv.c 507875 2016-07-21 21:24:44Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,26 +31,34 @@
  */
 
 #include "ncbi_priv.h"
-#if defined(NCBI_OS_UNIX)
+#if   defined(NCBI_OS_UNIX)
 #  include <unistd.h>
 #elif defined(NCBI_OS_MSWIN)
 #  include <windows.h>
 #else
 #  include <connect/ncbi_socket.h>
-#endif /*NCBI_OS_...*/
+#endif /*NCBI_OS*/
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 
-
 /* GLOBALS */
-int                     g_NCBI_ConnectRandomSeed = 0;
-MT_LOCK                 g_CORE_MT_Lock           = &g_CORE_MT_Lock_default;
-LOG                     g_CORE_Log               = 0;
-REG                     g_CORE_Registry          = 0;
-FNcbiGetAppName         g_CORE_GetAppName        = 0;
-FNcbiGetRequestID       g_CORE_GetRequestID      = 0;
-FNcbiGetRequestDtab     g_CORE_GetRequestDtab    = 0;
+TCORE_Set           g_CORE_Set               = 0;
+MT_LOCK             g_CORE_MT_Lock           = &g_CORE_MT_Lock_default;
+LOG                 g_CORE_Log               = 0;
+REG                 g_CORE_Registry          = 0;
+int                 g_NCBI_ConnectRandomSeed = 0;
+FNcbiGetAppName     g_CORE_GetAppName        = 0;
+FNcbiGetRequestID   g_CORE_GetRequestID      = 0;
+FNcbiGetRequestDtab g_CORE_GetRequestDtab    = 0;
+
+#ifdef NCBI_MONKEY
+FMonkeySend         g_MONKEY_Send            = 0;
+FMonkeyRecv         g_MONKEY_Recv            = 0;
+FMonkeyConnect      g_MONKEY_Connect         = 0;
+FMonkeyPoll         g_MONKEY_Poll            = 0;
+FMonkeyClose        g_MONKEY_Close           = 0;
+#endif /*NCBI_MONKEY*/
 
 
 extern int g_NCBI_ConnectSrandAddend(void)
diff --git a/c++/src/connect/ncbi_priv.h b/c++/src/connect/ncbi_priv.h
index e043cf2..72eeb08 100644
--- a/c++/src/connect/ncbi_priv.h
+++ b/c++/src/connect/ncbi_priv.h
@@ -1,7 +1,7 @@
 #ifndef CONNECT___NCBI_PRIV__H
 #define CONNECT___NCBI_PRIV__H
 
-/* $Id: ncbi_priv.h 488838 2016-01-06 13:45:11Z elisovdn $
+/* $Id: ncbi_priv.h 507875 2016-07-21 21:24:44Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -43,17 +43,28 @@
  * Registry:
  *    private global:  g_CORE_Registry
  *    macros:          CORE_REG_GET, CORE_REG_SET
+ * Setup accounting:   ECORE_Set
+ *    private global:  g_CORE_Set
  * Random generator seeding support
  *    private global:  g_NCBI_ConnectRandomSeed
  *    macro:           NCBI_CONNECT_SRAND_ADDEND
- * App name and NCBI ID support
+ * App name / NCBI ID / DTab support
  *    private globals: g_CORE_GetAppName
  *                     g_CORE_GetRequestID
+ *                     g_CORE_GetRequestDtab
  *
  */
 
 #include "ncbi_assert.h"
 #include <connect/ncbi_util.h>
+#ifdef NCBI_MONKEY
+#  if defined(NCBI_OS_MSWIN)
+#    include <WinSock2.h>
+#  else
+#    include <sys/socket.h>
+#    define SOCKET int
+#  endif /*NCBI_OS_MSWIN*/
+#endif /* NCBI_MONKEY */
 
 
 #ifdef __cplusplus
@@ -305,6 +316,22 @@ extern NCBI_XCONNECT_EXPORT int/*bool*/ g_CORE_RegistrySET
 
 
 /******************************************************************************
+ *  Setup accounting
+ */
+
+typedef enum {
+    eCORE_SetSSL  = 1,
+    eCORE_SetREG  = 4,
+    eCORE_SetLOG  = 2,
+    eCORE_SetLOCK = 8
+} ECORE_Set;
+typedef unsigned int TCORE_Set;
+
+
+extern TCORE_Set g_CORE_Set;
+
+
+/******************************************************************************
  *  Random generator seeding support
  */
 
@@ -332,12 +359,16 @@ extern NCBI_XCONNECT_EXPORT FNcbiGetRequestID g_CORE_GetRequestID;
 
 
 /******************************************************************************
- *  DTab-Local support (may return NULL; gets converted to "" at the user level)
+ *  DTab-Local support (returned NULL gets converted to "" at the user level)
  */
 typedef const char* (*FNcbiGetRequestDtab)(void);
 extern NCBI_XCONNECT_EXPORT FNcbiGetRequestDtab g_CORE_GetRequestDtab;
 
 
+/******************************************************************************
+ *  Miscellanea
+ */
+
 #ifdef __GNUC__
 #  define likely(x)    __builtin_expect(!!(x),1)
 #  define unlikely(x)  __builtin_expect(!!(x),0)
@@ -347,6 +378,63 @@ extern NCBI_XCONNECT_EXPORT FNcbiGetRequestDtab g_CORE_GetRequestDtab;
 #endif /*__GNUC__*/
 
 
+/******************************************************************************
+ *  NCBI Crazy Monkey support
+ */
+
+#ifdef NCBI_MONKEY
+/* UNIX and Windows have different prototypes for send(), recv(), etc., so
+ * some types have to be pre-selected based on current OS
+ */
+#   ifdef NCBI_OS_MSWIN
+#       define MONKEY_RETTYPE  int
+#       define MONKEY_SOCKTYPE SOCKET
+#       define MONKEY_DATATYPE char*
+#       define MONKEY_LENTYPE  int
+#       define MONKEY_SOCKLENTYPE  int
+#       define MONKEY_STDCALL __stdcall /* in Windows, socket functions have 
+                                           prototypes with __stdcall */
+#   else
+#       define MONKEY_RETTYPE  ssize_t
+#       define MONKEY_SOCKTYPE int
+#       define MONKEY_DATATYPE void*
+#       define MONKEY_LENTYPE  size_t
+#       define MONKEY_SOCKLENTYPE  socklen_t
+#       define MONKEY_STDCALL /* empty*/ 
+#   endif /* NCBI_OS_MSWIN */
+
+/******************************************************************************
+ *  Socket functions via Crazy Monkey
+ */
+typedef MONKEY_RETTYPE
+            (MONKEY_STDCALL  *FMonkeyRecv)  (MONKEY_SOCKTYPE       sock,
+                                             MONKEY_DATATYPE       buf,
+                                             MONKEY_LENTYPE        size,
+                                             int                   flags,
+                                             void* /* SOCK* */     sock_ptr);
+typedef MONKEY_RETTYPE
+            (MONKEY_STDCALL *FMonkeySend)  (MONKEY_SOCKTYPE        sock,
+                                            const MONKEY_DATATYPE  data,
+                                            MONKEY_LENTYPE         size,
+                                            int                    flags,
+                                            void* /* SOCK* */      sock_ptr);
+typedef int(MONKEY_STDCALL *FMonkeyConnect)(MONKEY_SOCKTYPE        sock,
+                                            const struct sockaddr* name,
+                                            MONKEY_SOCKLENTYPE     namelen);
+
+typedef int /* bool */    (*FMonkeyPoll)   (size_t*                n,
+                                            void* /*SSOCK_Poll[]* */polls,
+                                            EIO_Status*            ret_status);
+typedef void              (*FMonkeyClose)  (SOCKET sock); 
+
+extern NCBI_XCONNECT_EXPORT FMonkeySend     g_MONKEY_Send;
+extern NCBI_XCONNECT_EXPORT FMonkeyRecv     g_MONKEY_Recv;
+extern NCBI_XCONNECT_EXPORT FMonkeyPoll     g_MONKEY_Poll;
+extern NCBI_XCONNECT_EXPORT FMonkeyConnect  g_MONKEY_Connect;
+extern NCBI_XCONNECT_EXPORT FMonkeyClose    g_MONKEY_Close;
+#endif /*NCBI_MONKEY*/
+
+
 #ifdef __cplusplus
 }  /* extern "C" */
 #endif
diff --git a/c++/src/connect/ncbi_server_info.c b/c++/src/connect/ncbi_server_info.c
index 28eb087..542fe63 100644
--- a/c++/src/connect/ncbi_server_info.c
+++ b/c++/src/connect/ncbi_server_info.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_server_info.c 465213 2015-04-17 20:53:10Z lavr $
+/* $Id: ncbi_server_info.c 507385 2016-07-18 22:38:48Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -241,9 +241,8 @@ SSERV_Info* SERV_ReadInfoEx(const char* str,
     if (!info)
         return 0;
     info->host = host;
-    if (port)
-        info->port = port;
-    coef = mime = locl = priv = rate = sful = secu = time = flag = 0;/*false*/
+    info->port = port;
+    coef = mime = locl = priv = rate = sful = secu = time = flag = 0/*false*/;
     /* continue reading server info: optional parts... */
     while (*str  &&  isspace((unsigned char)(*str)))
         ++str;
@@ -262,7 +261,7 @@ SSERV_Info* SERV_ReadInfoEx(const char* str,
             case 'B':
                 if (coef)
                     break;
-                coef = 1;
+                coef = 1/*true*/;
                 d = NCBI_simple_atof(++str, &e);
                 if (e > str) {
                     if      (fabs(d) < SERV_MINIMAL_BONUS / 2.0)
@@ -278,7 +277,7 @@ SSERV_Info* SERV_ReadInfoEx(const char* str,
             case 'C':
                 if (mime  ||  type == fSERV_Dns)
                     break;
-                mime = 1;
+                mime = 1/*true*/;
                 if (MIME_ParseContentTypeEx(++str, &mime_t, &mime_s, &mime_e)){
                     info->mime_t = mime_t;
                     info->mime_s = mime_s;
@@ -291,7 +290,7 @@ SSERV_Info* SERV_ReadInfoEx(const char* str,
             case 'L':
                 if (locl)
                     break;
-                locl = 1;
+                locl = 1/*true*/;
                 if (sscanf(++str, "%3s%n", s, &n) >= 1) {
                     if (strcasecmp(s, "YES") == 0) {
                         info->site |=  fSERV_Local;
@@ -305,7 +304,7 @@ SSERV_Info* SERV_ReadInfoEx(const char* str,
             case 'P':
                 if (priv  ||  type == fSERV_Dns)
                     break;
-                priv = 1;
+                priv = 1/*true*/;
                 if (sscanf(++str, "%3s%n", s, &n) >= 1) {
                     if (strcasecmp(s, "YES") == 0) {
                         info->site |=  fSERV_Private;
@@ -319,7 +318,7 @@ SSERV_Info* SERV_ReadInfoEx(const char* str,
             case 'R':
                 if (rate)
                     break;
-                rate = 1;
+                rate = 1/*true*/;
                 d = NCBI_simple_atof(++str, &e);
                 if (e > str) {
                     if      (fabs(d) < SERV_MINIMAL_RATE / 2.0)
@@ -335,7 +334,7 @@ SSERV_Info* SERV_ReadInfoEx(const char* str,
             case 'S':
                 if (sful  ||  type == fSERV_Dns  ||  (type & fSERV_Http))
                     break;
-                sful = 1;
+                sful = 1/*true*/;
                 if (sscanf(++str, "%3s%n", s, &n) >= 1) {
                     if (strcasecmp(s, "YES") == 0) {
                         info->mode |=  fSERV_Stateful;
@@ -349,7 +348,7 @@ SSERV_Info* SERV_ReadInfoEx(const char* str,
             case '$':
                 if (secu  ||  type == fSERV_Dns)
                     break;
-                secu = 1;
+                secu = 1/*true*/;
                 if (sscanf(++str, "%3s%n", s, &n) >= 1) {
                     if (strcasecmp(s, "YES") == 0) {
                         info->mode |=  fSERV_Secure;
@@ -363,7 +362,7 @@ SSERV_Info* SERV_ReadInfoEx(const char* str,
             case 'T':
                 if (time)
                     break;
-                time = 1;
+                time = 1/*true*/;
                 if (sscanf(++str, "%lu%n", &t, &n) >= 1) {
                     info->time = (TNCBI_Time) t;
                     str += n;
@@ -372,7 +371,7 @@ SSERV_Info* SERV_ReadInfoEx(const char* str,
             }
         } else if (!flag) {
             size_t i;
-            flag = 1;
+            flag = 1/*true*/;
             for (i = 0;  i < sizeof(kFlags) / sizeof(kFlags[0]);  ++i) {
                 if (strncasecmp(str, kFlags[i].tag, kFlags[i].len) == 0) {
                     info->flag = kFlags[i].val;
@@ -387,15 +386,21 @@ SSERV_Info* SERV_ReadInfoEx(const char* str,
         while (*str  &&  isspace((unsigned char)(*str)))
             ++str;
     }
-    if (*str) {
+    if (!*str) {
+        if (name) {
+            strcpy((char*) info + SERV_SizeOfInfo(info), name);
+            if (info->type == fSERV_Dns)
+                info->u.dns.name = 1/*true*/;
+        } else if (info->type == fSERV_Dns)
+            info->u.dns.name = 0/*false*/;
+        if (!info->port
+            &&  (info->type == fSERV_Ncbid  ||  (info->type & fSERV_Http))) {
+            info->port = secu ? CONN_PORT_HTTPS : CONN_PORT_HTTP;
+        }
+    } else {
         free(info);
         info = 0;
-    } else if (name) {
-        strcpy((char*) info + SERV_SizeOfInfo(info), name);
-        if (info->type == fSERV_Dns)
-            info->u.dns.name = 1/*true*/;
-    } else if (info->type == fSERV_Dns)
-        info->u.dns.name = 0/*false*/;
+    }
     return info;
 }
 
@@ -485,15 +490,15 @@ static SSERV_Info* s_Ncbid_Read(const char** str, size_t add)
 
     if (!(args = strdup(*str)))
         return 0;
-    for (c = args;  *c;  c++) {
+    for (c = args;  *c;  ++c) {
         if (isspace((unsigned char)(*c))) {
             *c++ = '\0';
             while (*c  &&  isspace((unsigned char)(*c)))
-                c++;
+                ++c;
             break;
         }
     }
-    info = SERV_CreateNcbidInfoEx(0, CONN_PORT_HTTP, args, add);
+    info = SERV_CreateNcbidInfoEx(0, 0, args, add);
     if (info)
         *str += c - args;
     free(args);
@@ -640,17 +645,17 @@ static SSERV_Info* s_HttpAny_Read(ESERV_Type type,const char** str, size_t add)
 
     if (!**str  ||  !(path = strdup(*str)))
         return 0;
-    for (c = path;  *c;  c++) {
+    for (c = path;  *c;  ++c) {
         if (isspace((unsigned char)(*c))) {
             *c++ = '\0';
             while (*c  &&  isspace((unsigned char)(*c)))
-                c++;
+                ++c;
             break;
         }
     }
     if ((args = strchr(path, '?')) != 0)
         *args++ = '\0';
-    info = SERV_CreateHttpInfoEx(type, 0, CONN_PORT_HTTP, path, args, add);
+    info = SERV_CreateHttpInfoEx(type, 0, 0, path, args, add);
     if (info)
         *str += c - path;
     free(path);
diff --git a/c++/src/connect/ncbi_service.c b/c++/src/connect/ncbi_service.c
index 5c92a23..f4f9ecc 100644
--- a/c++/src/connect/ncbi_service.c
+++ b/c++/src/connect/ncbi_service.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_service.c 488579 2016-01-01 00:38:12Z lavr $
+/* $Id: ncbi_service.c 513929 2016-09-16 15:08:30Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -239,7 +239,7 @@ static SERV_ITER x_Open(const char*         service,
         iter->reverse_dns   = 1;
     if (types & fSERV_Stateless)
         iter->stateless     = 1;
-    iter->external          = external;
+    iter->external          = external ? 1 : 0;
     if (arg  &&  *arg) {
         iter->arg           = arg;
         iter->arglen        = strlen(arg);
@@ -275,6 +275,8 @@ static SERV_ITER x_Open(const char*         service,
     iter->o_skip = iter->n_skip;
 
     if (net_info) {
+        if (net_info->external)
+            iter->external = 1;
         if (net_info->firewall)
             iter->types |= fSERV_Firewall;
         if (net_info->stateless)
@@ -692,7 +694,7 @@ int/*bool*/ SERV_Update(SERV_ITER iter, const char* text, int code)
 }
 
 
-static void s_SetDefaultReferer(SERV_ITER iter, SConnNetInfo* net_info)
+static void s_SetDefaultReferer(SConnNetInfo* net_info, SERV_ITER iter)
 {
     char* str, *referer = 0;
 
@@ -733,8 +735,8 @@ char* SERV_Print(SERV_ITER iter, SConnNetInfo* net_info, int/*bool*/ but_last)
     static const char kAcceptedServerTypes[] = "Accepted-Server-Types:";
     static const char kClientRevision[] = "Client-Revision: %u.%u\r\n";
     static const char kUsedServerInfo[] = "Used-Server-Info: ";
+    static const char kNcbiExternal[] = NCBI_EXTERNAL ": Y\r\n";
     static const char kNcbiFWPorts[] = "NCBI-Firewall-Ports: ";
-    static const char kServerCount[] = "Server-Count: ";
     static const char kPreference[] = "Preference: ";
     static const char kSkipInfo[] = "Skip-Info-%u: ";
     static const char kAffinity[] = "Affinity: ";
@@ -754,7 +756,7 @@ char* SERV_Print(SERV_ITER iter, SConnNetInfo* net_info, int/*bool*/ but_last)
     if (iter) {
         assert(iter->op);
         if (net_info  &&  !net_info->http_referer  &&  iter->op->mapper)
-            s_SetDefaultReferer(iter, net_info);
+            s_SetDefaultReferer(net_info, iter);
         /* Accepted server types */
         buflen = sizeof(kAcceptedServerTypes) - 1;
         memcpy(buffer, kAcceptedServerTypes, buflen);
@@ -777,13 +779,9 @@ char* SERV_Print(SERV_ITER iter, SConnNetInfo* net_info, int/*bool*/ but_last)
                 return 0;
             }
         }
-        if (iter->ismask  ||  (iter->pref  &&  (iter->host | iter->port))) {
-            /* FIXME: To obsolete? */
-            /* How many server-infos for the dispatcher to send to us */
-            if (!BUF_Write(&buf, kServerCount, sizeof(kServerCount) - 1)  ||
-                !BUF_Write(&buf,
-                           iter->ismask ? "10\r\n" : "ALL\r\n",
-                           iter->ismask ?       4  :        5)) {
+        if (iter->external) {
+            /* External */
+            if (!BUF_Write(&buf, kNcbiExternal, sizeof(kNcbiExternal)-1)) {
                 BUF_Destroy(buf);
                 return 0;
             }
diff --git a/c++/src/connect/ncbi_service_connector.c b/c++/src/connect/ncbi_service_connector.c
index bef1bb9..f6394d3 100644
--- a/c++/src/connect/ncbi_service_connector.c
+++ b/c++/src/connect/ncbi_service_connector.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_service_connector.c 465077 2015-04-16 17:34:16Z lavr $
+/* $Id: ncbi_service_connector.c 516325 2016-10-12 17:18:28Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -648,6 +648,8 @@ static CONNECTOR s_Open(SServiceConnector* uuu,
         switch (info->type) {
         case fSERV_Ncbid:
             /* Connection directly to NCBID, add NCBID-specific tags */
+            if (info->mode & fSERV_Secure)
+                net_info->scheme = eURL_Https;
             if (net_info->stateless) {
                 /* Connection request with data */
                 user_header = "Connection-Mode: STATELESS\r\n"; /*default*/
@@ -702,6 +704,8 @@ static CONNECTOR s_Open(SServiceConnector* uuu,
         EMIME_Type     mime_t;
         EMIME_SubType  mime_s;
         EMIME_Encoding mime_e;
+        if (!net_info->scheme)
+            net_info->scheme = eURL_Https;
         if (net_info->stateless
             ||  (info  &&  (info->u.firewall.type & fSERV_Http))) {
             if (info) {
@@ -724,7 +728,7 @@ static CONNECTOR s_Open(SServiceConnector* uuu,
             mime_s = eMIME_Undefined;
             mime_e = eENCOD_None;
         }
-        /* Firewall/relay connection to dispatcher, special tags */
+        /* Firewall/relay connection thru dispatcher, special tags */
         user_header = (net_info->stateless
                        ? "Client-Mode: STATELESS_ONLY\r\n" /*default*/
                        : "Client-Mode: STATEFUL_CAPABLE\r\n");
@@ -849,6 +853,8 @@ static CONNECTOR s_Open(SServiceConnector* uuu,
         net_info->port = uuu->port;
         assert(!uuu->descr);
         uuu->descr = x_HostPort(net_info->host, net_info->port);
+        if (net_info->http_proxy_host[0]  &&  net_info->http_proxy_port)
+            net_info->scheme = uuu->net_info->scheme;
         return s_SocketConnectorBuilder(net_info, uuu->descr, status,
                                         &uuu->ticket,
                                         uuu->ticket ? sizeof(uuu->ticket) : 0,
@@ -951,12 +957,11 @@ static EIO_Status s_VT_Open(CONNECTOR connector, const STimeout* timeout)
         if (!uuu->iter  &&  !s_OpenDispatcher(uuu))
             break;
 
-        if (uuu->net_info->firewall
-            &&  strcasecmp(SERV_MapperName(uuu->iter), "local") != 0) {
-            info = 0;
-        } else if (!(info = s_GetNextInfo(uuu, 0/*any*/)))
+        if (!(info = s_GetNextInfo(uuu, 0/*any*/))
+            &&  (!uuu->net_info->firewall
+                 ||  strcasecmp(SERV_MapperName(uuu->iter), "local") == 0)) {
             break;
-
+        }
         if (uuu->type) {
             free((void*) uuu->type);
             uuu->type = 0;
@@ -983,7 +988,7 @@ static EIO_Status s_VT_Open(CONNECTOR connector, const STimeout* timeout)
 
         /* Setup the new connector on a temporary meta-connector... */
         memset(&uuu->meta, 0, sizeof(uuu->meta));
-        if ((status = METACONN_Add(&uuu->meta, c)) != eIO_Success) {
+        if ((status = METACONN_Insert(&uuu->meta, c)) != eIO_Success) {
             x_DestroyConnector(c);
             continue;
         }
@@ -1027,15 +1032,13 @@ static EIO_Status s_VT_Open(CONNECTOR connector, const STimeout* timeout)
             break;
 
         if (!stateless  &&  (!info  ||  info->type == fSERV_Firewall)) {
-            static const char kFWLink[] = { "http://www.ncbi.nlm.nih.gov"
-                                            "/IEB/ToolBox/NETWORK"
-                                            "/dispatcher.html#Firewalling" };
+            static const char kFWDLink[] = CONN_FWD_LINK;
             CORE_LOGF_X(6, eLOG_Error,
                         ("[%s]  %s connection failure (%s) usually"
                          " indicates possible firewall configuration"
                          " problems; please consult <%s>", uuu->service,
                          !info ? "Firewall" : "Stateful relay",
-                         IO_StatusStr(status), kFWLink));
+                         IO_StatusStr(status), kFWDLink));
         }
 
         s_Close(connector, timeout, 0/*retain*/);
diff --git a/c++/src/connect/ncbi_socket.c b/c++/src/connect/ncbi_socket.c
index a792801..2c092db 100644
--- a/c++/src/connect/ncbi_socket.c
+++ b/c++/src/connect/ncbi_socket.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_socket.c 495662 2016-03-18 22:10:31Z ucko $
+/* $Id: ncbi_socket.c 517038 2016-10-20 11:20:53Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -131,7 +131,14 @@
 #endif /* MAXHOSTNAMELEN */
 
 
-
+#ifdef NCBI_MONKEY
+/* A hack - we know that SOCK variable has name "sock" in code.
+ * If the desired behavior is timeout, "sock" will be replaced with a
+ * connection to non-working server */
+#   define send(a,b,c,d)  ((g_MONKEY_Send == NULL)    ? send(a,b,c,d)  : g_MONKEY_Send(a,b,c,d,&sock))
+#   define recv(a,b,c,d)  ((g_MONKEY_Recv == NULL)    ? recv(a,b,c,d)  : g_MONKEY_Recv(a,b,c,d,&sock))
+#   define connect(a,b,c) ((g_MONKEY_Connect == NULL) ? connect(a,b,c) : g_MONKEY_Connect(a,b,c))
+#endif
 /******************************************************************************
  *  TYPEDEFS & MACROS
  */
@@ -151,6 +158,7 @@
 #  define SOCK_NFDS(s)          0
 #  define SOCK_CLOSE(s)         closesocket(s)
 #  define SOCK_EVENTS           (FD_CLOSE|FD_CONNECT|FD_OOB|FD_WRITE|FD_READ)
+#  define WIN_INT_CAST          (int)
 /* NCBI_OS_MSWIN */
 
 #elif defined(NCBI_OS_UNIX)
@@ -158,6 +166,7 @@
 #  define SOCK_INVALID          (-1)
 #  define SOCK_ERRNO            errno
 #  define SOCK_NFDS(s)          ((s) + 1)
+#  define WIN_INT_CAST          /* no cast */
 #  ifdef NCBI_OS_BEOS
 #    define SOCK_CLOSE(s)       closesocket(s)
 #  else
@@ -270,7 +279,7 @@ static const char* s_StrError(SOCK sock, int error)
         return 0;
 
     if (sock) {
-        FSSLError sslerror = s_SSL ? s_SSL->Error : 0;
+        FSSLError sslerror = sock->session  &&  s_SSL ? s_SSL->Error : 0;
         if (sslerror) {
             const char* strerr = sslerror(sock->session == SESSION_INVALID
                                           ? 0 : sock->session, error);
@@ -796,13 +805,18 @@ static EIO_Status s_Init(void)
     s_Initialized = 1/*inited*/;
 #ifndef NCBI_OS_MSWIN
     {{
-        static int/*bool*/ s_AtExitSet = 0;
+        static void*/*bool*/ s_AtExitSet = 0;
+#ifdef NCBI_CXX_TOOLKIT
+        if (!NCBI_SwapPointers(&s_AtExitSet, (void*) 1))
+            atexit((void (*)(void)) SOCK_ShutdownAPI);
+#else
         if (!s_AtExitSet) {
+            s_AtExitSet = (void*) 1;
             atexit((void (*)(void)) SOCK_ShutdownAPI);
-            s_AtExitSet = 1;
         }
+#endif /*NCBI_CXX_TOOLKIT*/
     }}
-#endif
+#endif /*NCBI_OS_MSWIN*/
 
     CORE_UNLOCK;
     CORE_TRACE("[SOCK::InitializeAPI]  End");
@@ -1148,8 +1162,8 @@ static unsigned int s_gethostbyname_(const char* hostname, ESwitch log)
     }
 
 #ifdef NCBI_OS_DARWIN
-out:
-#endif
+ out:
+#endif /*NCBI_OS_DARWIN*/
 #if defined(_DEBUG)  &&  !defined(NDEBUG)
     if (!SOCK_isipEx(hostname, 1)  ||  !host) {
         char addr[40];
@@ -2152,7 +2166,7 @@ static EIO_Status s_Select(size_t                n,
                            SSOCK_Poll            polls[],
                            const struct timeval* tv,
                            int/*bool*/           asis)
-{
+{ 
 #if defined(NCBI_OS_MSWIN)  &&  defined(NCBI_CXX_TOOLKIT)
     DWORD  wait = tv ? tv->tv_sec * 1000 + (tv->tv_usec + 500)/1000 : INFINITE;
     HANDLE what[MAXIMUM_WAIT_OBJECTS];
@@ -2639,7 +2653,7 @@ static EIO_Status s_IsConnected_(SOCK                  sock,
                     if (sock->log == eOn
                         ||  (sock->log == eDefault  &&  s_Log == eOn)) {
                         CORE_LOGF(eLOG_Trace,
-                                  ("%sSSL session established%s%s",
+                                  ("%sSSL session created%s%s",
                                    s_ID(sock, _id),
                                    &" "[!desc], desc ? desc : ""));
                     }
@@ -2664,11 +2678,11 @@ static EIO_Status s_IsConnected(SOCK sock, const struct timeval* tv)
     EIO_Status  status = s_IsConnected_(sock, tv, &what, &unused, 0);
     if (s_ErrHook  &&  status != eIO_Success  &&  status != eIO_Timeout) {
         SSOCK_ErrInfo info;
+        char          addr[40];
         memset(&info, 0, sizeof(info));
         info.type = eSOCK_ErrIO;
         info.sock = sock;
         if (sock->port) {
-            char addr[40];
             SOCK_ntoa(sock->host, addr, sizeof(addr));
             info.host =       addr;
             info.port = sock->port;
@@ -2710,12 +2724,7 @@ static EIO_Status s_Recv(SOCK    sock,
     readable = 0/*false*/;
     for (;;) { /* optionally auto-resume if interrupted */
         int error;
-
-        int x_read = recv(sock->sock, buf,
-#ifdef NCBI_OS_MSWIN
-                          /*WINSOCK wants it weird*/ (int)
-#endif /*NCBI_OS_MSWIN*/
-                          size, 0/*flags*/);
+        int x_read = recv(sock->sock, buf, WIN_INT_CAST size, 0/*flags*/);
 #ifdef NCBI_OS_MSWIN
         /* recv() resets IO event recording */
         sock->readable = sock->closing;
@@ -2907,8 +2916,9 @@ static EIO_Status s_Read_(SOCK    sock,
                 break/*error*/;
             }
             status = sslread(sock->session, x_buf, n_todo, &x_read, &error);
-            assert(status == eIO_Success  ||  error);
             assert(status == eIO_Success  ||  !x_read);
+            assert(status == eIO_Success  ||  error);
+            assert(x_read <= n_todo);
 
             /* statistics & logging */
             if ((status != eIO_Success  &&  sock->log != eOff)  ||
@@ -3012,11 +3022,11 @@ static EIO_Status s_Read(SOCK    sock,
         &&  (status != eIO_Closed
              ||  !(sock->r_status == eIO_Success  &&  sock->eof))) {
         SSOCK_ErrInfo info;
+        char          addr[40];
         memset(&info, 0, sizeof(info));
         info.type = eSOCK_ErrIO;
         info.sock = sock;
         if (sock->port) {
-            char addr[40];
             SOCK_ntoa(sock->host, addr, sizeof(addr));
             info.host =       addr;
             info.port = sock->port;
@@ -3204,11 +3214,7 @@ static EIO_Status s_Send(SOCK        sock,
     for (;;) { /* optionally auto-resume if interrupted */
         int error = 0;
 
-        int x_written = send(sock->sock, (void*) data,
-#ifdef NCBI_OS_MSWIN
-                             /*WINSOCK wants it weird*/ (int)
-#endif /*NCBI_OS_MSWIN*/
-                             size, flag < 0 ? MSG_OOB : 0);
+        int x_written = send(sock->sock, (void*) data, WIN_INT_CAST size, flag < 0 ? MSG_OOB : 0);
 
         if (x_written >= 0  ||
             (x_written < 0  &&  ((error = SOCK_ERRNO) == SOCK_EPIPE       ||
@@ -3353,8 +3359,8 @@ static EIO_Status s_Send(SOCK        sock,
 
 /* Wrapper for s_Send() that slices the output buffer for some brain-dead
  * systems (e.g. old Macs) that cannot handle large data chunks in "send()".
- * Return eIO_Success if some data have been successfully sent;
- * an error code if nothing at all has been sent.
+ * Return eIO_Success only if some data have been successfully sent;
+ * otherwise, an error code if nothing at all has been sent.
  */
 #ifdef SOCK_SEND_SLICE
 #  undef s_Send
@@ -3370,17 +3376,17 @@ static EIO_Status s_Send(SOCK        sock,
     assert(!*n_written);
 
     do {
-        size_t      n_todo = size > SOCK_SEND_SLICE ? SOCK_SEND_SLICE : size;
-        const char* temp   = (const char*) data + *n_written;
-        size_t      n_done = 0;
-        status = s_Send_(sock, temp, n_todo, &n_done, flag);
-        assert(status == eIO_Success  ||  !n_done);
+        size_t n_todo = size > SOCK_SEND_SLICE ? SOCK_SEND_SLICE : size;
+        size_t n_done = 0;
+        status = s_Send_(sock, data, n_todo, &n_done, flag);
+        assert((status == eIO_Success) == (n_done > 0));
         if (status != eIO_Success)
             break;
         *n_written += n_done;
         if (n_todo != n_done)
             break;
         size       -= n_done;
+        data        = (const char*) data + n_done;
     } while (size);
 
     return *n_written ? eIO_Success : status;
@@ -3388,13 +3394,14 @@ static EIO_Status s_Send(SOCK        sock,
 #endif /*SOCK_SEND_SLICE*/
 
 
+/* Return eIO_Success iff some data have been written; error code otherwise */
 static EIO_Status s_WriteData(SOCK        sock,
                               const void* data,
                               size_t      size,
                               size_t*     n_written,
                               int/*bool*/ oob)
 {
-    assert(sock->type == eSocket  &&  !sock->pending  &&  size > 0);
+    assert(sock->type == eSocket  &&  !sock->pending  &&  size);
 
     if (sock->session) {
         int error;
@@ -3408,6 +3415,7 @@ static EIO_Status s_WriteData(SOCK        sock,
         status = sslwrite(sock->session, data, size, n_written, &error);
         assert((status == eIO_Success) == (*n_written > 0));
         assert(status == eIO_Success  ||  error);
+        assert(*n_written <= size);
 
         /* statistics & logging */
         if ((status != eIO_Success  &&  sock->log != eOff)  ||
@@ -3443,16 +3451,17 @@ static size_t x_WriteBuf(void* data, const void* buf, size_t size)
     do {
         size_t x_written;
         ctx->status = s_WriteData(ctx->sock, buf, size, &x_written, 0);
-        if (ctx->status != eIO_Success) {
-            assert(!x_written);
+        assert((ctx->status == eIO_Success) == (x_written > 0));
+        assert(x_written <= size);
+        if (ctx->status != eIO_Success)
             break;
-        }
         n_written += x_written;
         size      -= x_written;
         buf        = (const char*) buf + x_written;
     } while (size);
 
     assert(!size/*n_written == initial size*/  ||  ctx->status != eIO_Success);
+
     return n_written;
 }
 
@@ -3565,7 +3574,7 @@ static EIO_Status s_Write_(SOCK        sock,
         return size ? status : eIO_Success;
     }
 
-    assert(sock->w_len == 0);
+    assert(size  &&  sock->w_len == 0);
     return s_WriteData(sock, data, size, n_written, oob);
 }
 
@@ -3579,11 +3588,11 @@ static EIO_Status s_Write(SOCK        sock,
     EIO_Status status = s_Write_(sock, data, size, n_written, oob);
     if (s_ErrHook  &&  status != eIO_Success) {
         SSOCK_ErrInfo info;
+        char          addr[40];
         memset(&info, 0, sizeof(info));
         info.type = eSOCK_ErrIO;
         info.sock = sock;
         if (sock->port) {
-            char addr[40];
             SOCK_ntoa(sock->host, addr, sizeof(addr));
             info.host =       addr;
             info.port = sock->port;
@@ -3648,7 +3657,7 @@ static EIO_Status s_Shutdown(SOCK                  sock,
     case eIO_Close:
         if (sock->w_status != eIO_Closed) {
             if ((status = s_WritePending(sock, tv, 0, 0)) != eIO_Success) {
-                if (!sock->pending   &&  sock->w_len) {
+                if (!sock->pending  &&  sock->w_len) {
                     CORE_LOGF_X(13, !tv  ||  (tv->tv_sec | tv->tv_usec)
                                 ? eLOG_Warning : eLOG_Trace,
                                 ("%s[SOCK::%s] "
@@ -3665,7 +3674,7 @@ static EIO_Status s_Shutdown(SOCK                  sock,
                 } else if (!(dir & eIO_ReadWrite))
                     status = eIO_Success;
             }
-            if (sock->session  &&  !sock->pending) {
+            if (!sock->pending  &&  sock->session) {
                 FSSLClose sslclose = s_SSL ? s_SSL->Close : 0;
                 assert(sock->session != SESSION_INVALID);
                 if (sslclose) {
@@ -3714,11 +3723,7 @@ static EIO_Status s_Shutdown(SOCK                  sock,
     }
     assert((EIO_Event)(dir | eIO_ReadWrite) == eIO_ReadWrite);
     
-#ifndef NCBI_OS_MSWIN
-    /* on MS-Win, socket shutdown for write apparently messes up (?!)
-     * with later reading, especially when reading a lot of data... */
-
-#  ifdef NCBI_OS_BSD
+#ifdef NCBI_OS_BSD
     /* at least on FreeBSD: shutting down a socket for write (i.e. forcing to
      * send a FIN) for a socket that has been already closed by another end
      * (e.g. when peer has done writing, so this end has done reading and is
@@ -3726,38 +3731,27 @@ static EIO_Status s_Shutdown(SOCK                  sock,
      * see kern/146845 @ http://www.freebsd.org/cgi/query-pr.cgi?pr=146845 */
     if (dir == eIO_ReadWrite  &&  how != SOCK_SHUTDOWN_RDWR)
         return status;
-#  endif /*NCBI_OS_BSD*/
+#endif /*NCBI_OS_BSD*/
 
-#  ifdef NCBI_OS_UNIX
+#ifdef NCBI_OS_UNIX
     if (sock->path[0])
         return status;
-#  endif /*NCBI_OS_UNIX*/
+#endif /*NCBI_OS_UNIX*/
+
+#ifndef NCBI_OS_MSWIN
+    /* on MS-Win, socket shutdown for write apparently messes up (?!)
+     * with later reading, especially when reading a lot of data... */
 
     if (s_Initialized > 0  &&  shutdown(sock->sock, how) != 0) {
-        error = SOCK_ERRNO;
-#  ifdef NCBI_OS_MSWIN
-        if (error == WSANOTINITIALISED)
-            s_Initialized = -1/*deinited*/;
-        else
-#  endif /*NCBI_OS_MSWIN*/
-        if (
-#  if   defined(NCBI_OS_LINUX)/*bug in the Linux kernel to report*/  || \
-        defined(NCBI_OS_IRIX)                                        || \
-        defined(NCBI_OS_OSF1)
-            error != SOCK_ENOTCONN
-#  else
-            error != SOCK_ENOTCONN  ||  sock->pending
-#  endif /*UNIX flavors*/
-            ) {
-            const char* strerr = SOCK_STRERROR(error);
-            CORE_LOGF_ERRNO_EXX(16, eLOG_Trace,
-                                error, strerr ? strerr : "",
-                                ("%s[SOCK::Shutdown] "
-                                 " Failed shutdown(%s)",
-                                 s_ID(sock, _id), dir == eIO_Read ? "R" :
-                                 dir == eIO_Write ? "W" : "RW"));
-            UTIL_ReleaseBuffer(strerr);
-        }
+        const char* strerr = SOCK_STRERROR(error = SOCK_ERRNO);
+        CORE_LOGF_ERRNO_EXX(16, eLOG_Trace,
+                            error, strerr ? strerr : "",
+                            ("%s[SOCK::Shutdown] "
+                             " Failed shutdown(%s)",
+                             s_ID(sock, _id), dir == eIO_Read ? "R" :
+                             dir == eIO_Write ? "W" : "RW"));
+        UTIL_ReleaseBuffer(strerr);
+        status = eIO_Unknown;
     }
 #endif /*!NCBI_OS_MSWIN*/
 
@@ -3952,14 +3946,20 @@ static EIO_Status s_Close_(SOCK sock, int abort)
 
 static EIO_Status s_Close(SOCK sock)
 {
+#if defined NCBI_MONKEY
+    /* Not interception of close(). 
+       We only tell Monkey to "forget" this socket */
+    if (g_MONKEY_Close != NULL)
+        g_MONKEY_Close(sock->sock);
+#endif /* NCBI_MONKEY */
     EIO_Status status = s_Close_(sock, 0/*orderly*/);
     if (s_ErrHook  &&  status != eIO_Success) {
         SSOCK_ErrInfo info;
+        char          addr[40];
         memset(&info, 0, sizeof(info));
         info.type = eSOCK_ErrIO;
         info.sock = sock;
         if (sock->port) {
-            char addr[40];
             SOCK_ntoa(sock->host, addr, sizeof(addr));
             info.host =       addr;
             info.port = sock->port;
@@ -4053,6 +4053,11 @@ static EIO_Status s_Connect_(SOCK            sock,
     } else
 #endif /*NCBI_OS_UNIX*/
     {
+        /* first, set the port to connect to (same port if zero) */
+        if (port)
+            sock->port = port;
+        else
+            assert(sock->port);
         /* get address of the remote host (assume the same host if NULL) */
         if (host && !(sock->host = s_gethostbyname(host, (ESwitch)sock->log))){
             CORE_LOGF_X(22, eLOG_Error,
@@ -4061,11 +4066,6 @@ static EIO_Status s_Connect_(SOCK            sock,
                          s_ID(sock, _id), MAXHOSTNAMELEN, host));
             return eIO_Unknown;
         }
-        /* set the port to connect to (same port if zero) */
-        if (port)
-            sock->port = port;
-        else
-            assert(sock->port);
         addrlen = (TSOCK_socklen_t) sizeof(addr.in);
 #ifdef HAVE_SIN_LEN
         addr.in.sin_len         = addrlen;
@@ -4284,22 +4284,16 @@ static EIO_Status s_Connect(SOCK            sock,
     EIO_Status status = s_Connect_(sock, host, port, timeout);
     if (status != eIO_Success) {
         SSOCK_ErrInfo info;
+        char          addr[40];
         memset(&info, 0, sizeof(info));
         info.type = eSOCK_ErrIO;
         info.sock = sock;
-        if (sock->port) {
-            char addr[40];
-            if (sock->host) {
-                SOCK_ntoa(sock->host, addr, sizeof(addr));
-                info.host = addr;
-            } else
-                info.host = host;
-            info.port = port;
-        }
-#ifdef NCBI_OS_UNIX
-        else
-            info.host = sock->path;
-#endif /*NCBI_OS_UNIX*/
+        if (sock->host) {
+            SOCK_ntoa(sock->host, addr, sizeof(addr));
+            info.host = addr;
+        } else
+            info.host = host;
+        info.port = port;
         info.status = status;
         s_ErrorCallback(&info);
     }
@@ -6252,11 +6246,11 @@ extern EIO_Status SOCK_Shutdown(SOCK      sock,
     status = s_Shutdown(sock, dir, SOCK_GET_TIMEOUT(sock, c));
     if (s_ErrHook  &&  status != eIO_Success) {
         SSOCK_ErrInfo info;
+        char          addr[40];
         memset(&info, 0, sizeof(info));
         info.type = eSOCK_ErrIO;
         info.sock = sock;
         if (sock->port) {
-            char addr[40];
             SOCK_ntoa(sock->host, addr, sizeof(addr));
             info.host =       addr;
             info.port = sock->port;
@@ -6346,6 +6340,7 @@ extern EIO_Status SOCK_CloseOSHandle(const void* handle, size_t handle_size)
             error == SOCK_ENETRESET   ||
             error == SOCK_ECONNRESET  ||
             error == SOCK_ECONNABORTED) {
+            status = eIO_Closed;
             break;
         }
         if (error != SOCK_EINTR) {
@@ -6467,11 +6462,11 @@ extern EIO_Status SOCK_Wait(SOCK            sock,
     status = s_Wait(sock, event, timeout);
     if (s_ErrHook  &&  status != eIO_Success  &&  status != eIO_Timeout) {
         SSOCK_ErrInfo info;
+        char          addr[40];
         memset(&info, 0, sizeof(info));
         info.type = eSOCK_ErrIO;
         info.sock = sock;
         if (sock->port) {
-            char addr[40];
             SOCK_ntoa(sock->host, addr, sizeof(addr));
             info.host =       addr;
             info.port = sock->port;
@@ -6493,38 +6488,82 @@ extern EIO_Status SOCK_Poll(size_t          n,
                             const STimeout* timeout,
                             size_t*         n_ready)
 {
+    EIO_Status status;
+#if defined NCBI_MONKEY
+    int/*bool*/ call_intercepted = 0;
+    size_t      orig_n = n;
+    SSOCK_Poll* orig_polls = polls; /* to know if 'polls' was replaced */
+    EIO_Status  mnk_status = -1;
+    if (g_MONKEY_Poll != NULL) {
+        /* Not a poll function itself, just removes some of "polls" items */
+        call_intercepted = g_MONKEY_Poll(&n, &polls, &mnk_status);
+    }
+    /* Even if call was intercepted, s_Select continues as if nothing
+    happened, because what we did is just removed some SSOCK_Poll pointers.
+    The changes made in s_Select will appear in the original array, but only
+    for those SSOCK_Poll's that were left by Monkey */
+#endif /* defined NCBI_MONKEY */
     struct timeval tv;
     size_t         i;
 
     if (n  &&  !polls) {
-        if ( n_ready )
+        if (n_ready)
             *n_ready = 0;
         return eIO_InvalidArg;
     }
 
-    for (i = 0;  i < n;  i++) {
+    for (i = 0; i < n; i++) {
         SOCK sock = polls[i].sock;
         polls[i].revent =
-            sock  &&  sock->type == eTrigger  &&  ((TRIGGER) sock)->isset.ptr
+            sock  &&  sock->type == eTrigger && ((TRIGGER)sock)->isset.ptr
             ? polls[i].event
             : eIO_Open;
-        if (!sock  ||  !(sock->type & eSocket)  ||  sock->sock == SOCK_INVALID)
+        if (!sock || !(sock->type & eSocket) || sock->sock == SOCK_INVALID)
             continue;
-        if ((polls[i].event & eIO_Read)  &&  BUF_Size(sock->r_buf) != 0) {
+        if ((polls[i].event & eIO_Read) && BUF_Size(sock->r_buf) != 0) {
             polls[i].revent = eIO_Read;
             continue;
         }
         if (sock->type != eSocket)
             continue;
         if ((polls[i].event == eIO_Read
-             &&  (sock->r_status == eIO_Closed  ||  sock->eof))  ||
+            && (sock->r_status == eIO_Closed || sock->eof)) ||
             (polls[i].event == eIO_Write
-             &&   sock->w_status == eIO_Closed)) {
+            &&   sock->w_status == eIO_Closed)) {
             polls[i].revent = eIO_Close;
         }
     }
 
-    return s_SelectStallsafe(n, polls, s_to2tv(timeout, &tv), n_ready);
+    status = s_SelectStallsafe(n, polls, s_to2tv(timeout, &tv), n_ready);
+#if defined NCBI_MONKEY
+    /* Copy poll results to the original array. Probably Monkey excluded 
+     * some sockets from array, so we need two iterators */
+    if (orig_polls != polls) {
+        size_t orig_iter = 0, new_iter = 0;
+        /* First - initialize events with eIO_Open (no event) */
+        for (orig_iter = 0;  orig_iter < orig_n;  orig_iter++) {
+            orig_polls[orig_iter].event = eIO_Open /* no event */;
+            orig_polls[orig_iter].revent = eIO_Open /* no event */;
+        }
+        for (; new_iter < n; new_iter++) {
+            while (orig_iter < orig_n) {
+                if (orig_polls[orig_iter].sock->sock 
+                                           == polls[new_iter].sock->sock) {
+                    orig_polls[orig_iter].event  = polls[new_iter].event;
+                    orig_polls[orig_iter].revent = polls[new_iter].revent;
+                    break; /* Item found! Now increase new_iter */
+                }
+                orig_iter++;
+            }
+        }
+        free(polls);
+        polls = orig_polls;
+        if (mnk_status != -1) {
+            return mnk_status;
+        }
+    }
+#endif /* defined NCBI_MONKEY */
+    return status;
 }
 
 
@@ -7525,8 +7564,8 @@ extern EIO_Status DSOCK_RecvMsg(SOCK            sock,
     status = s_RecvMsg(sock, buf, bufsize, msgsize, msglen,
                        sender_addr, sender_port);
     if (s_ErrHook  &&  status != eIO_Success) {
-        char          addr[40];
         SSOCK_ErrInfo info;
+        char          addr[40];
         memset(&info, 0, sizeof(info));
         info.type = eSOCK_ErrIO;
         info.sock = sock;
@@ -7568,8 +7607,8 @@ extern EIO_Status DSOCK_SendMsg(SOCK           sock,
 
     status = s_SendMsg(sock, host, port, data, datalen);
     if (s_ErrHook  &&  status != eIO_Success) {
-        char          addr[40];
         SSOCK_ErrInfo info;
+        char          addr[40];
         memset(&info, 0, sizeof(info));
         info.type = eSOCK_ErrIO;
         info.sock = sock;
@@ -7953,7 +7992,7 @@ extern int/*bool*/ SOCK_isipEx(const char* str, int/*bool*/ fullquad)
         if (!isdigit((unsigned char)(*str)))
             return 0/*false*/;
         errno = 0;
-        val = strtoul(str, &e, fullquad ? 10 : 0);
+        val = strtoul(str, &e, 0);
         if (errno  ||  str == e)
             return 0/*false*/;
         str = e;
@@ -7983,7 +8022,7 @@ extern int/*bool*/ SOCK_IsLoopbackAddress(unsigned int ip)
             &&  (addr & IN_CLASSA_NET) == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT);
 #else
         return !((addr & 0xFF000000) ^ (INADDR_LOOPBACK-1));
-#  endif /*IN_CLASSA && IN_CLASSA_NET && IN_CLASSA_NSHIFT*/
+#endif /*IN_CLASSA && IN_CLASSA_NET && IN_CLASSA_NSHIFT*/
     }
     return 0/*false*/;
 }
@@ -8218,6 +8257,8 @@ extern void SOCK_SetupSSL(FSSLSetup setup)
             CORE_LOG(eLOG_Critical, "Cannot reset SSL while it is in use");
     }
 
+    g_CORE_Set |= eCORE_SetSSL;
+
     CORE_UNLOCK;
 }
 
diff --git a/c++/src/connect/ncbi_util.c b/c++/src/connect/ncbi_util.c
index 0dbe8fa..55205f5 100644
--- a/c++/src/connect/ncbi_util.c
+++ b/c++/src/connect/ncbi_util.c
@@ -1,4 +1,4 @@
-/* $Id: ncbi_util.c 488579 2016-01-01 00:38:12Z lavr $
+/* $Id: ncbi_util.c 507875 2016-07-21 21:24:44Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -72,7 +72,6 @@
 #define NCBI_USE_PRECOMPILED_CRC32_TABLES 1
 
 
-
 /******************************************************************************
  *  MT locking
  */
@@ -81,6 +80,7 @@ extern void CORE_SetLOCK(MT_LOCK lk)
 {
     MT_LOCK old_lk = g_CORE_MT_Lock;
     g_CORE_MT_Lock = lk;
+    g_CORE_Set |= eCORE_SetLOCK;
     if (old_lk  &&  old_lk != lk)
         MT_LOCK_Delete(old_lk);
 }
@@ -104,6 +104,7 @@ extern void CORE_SetLOG(LOG lg)
     CORE_LOCK_WRITE;
     old_lg = g_CORE_Log;
     g_CORE_Log = lg;
+    g_CORE_Set |= eCORE_SetLOG;
     CORE_UNLOCK;
     if (old_lg  &&  old_lg != lg)
         LOG_Delete(old_lg);
@@ -610,6 +611,7 @@ extern void CORE_SetREG(REG rg)
     CORE_LOCK_WRITE;
     old_rg = g_CORE_Registry;
     g_CORE_Registry = rg;
+    g_CORE_Set |= eCORE_SetREG;
     CORE_UNLOCK;
     if (old_rg  &&  old_rg != rg)
         REG_Delete(old_rg);
diff --git a/c++/src/connect/parson.c b/c++/src/connect/parson.c
new file mode 100644
index 0000000..9b6267b
--- /dev/null
+++ b/c++/src/connect/parson.c
@@ -0,0 +1,1767 @@
+/*
+ Parson ( http://kgabis.github.com/parson/ )
+ Copyright (c) 2012 - 2016 Krzysztof Gabis
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+#ifdef _MSC_VER
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif /* _CRT_SECURE_NO_WARNINGS */
+#endif /* _MSC_VER */
+
+#include "parson.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#define STARTING_CAPACITY         15
+#define ARRAY_MAX_CAPACITY    122880 /* 15*(2^13) */
+#define OBJECT_MAX_CAPACITY      960 /* 15*(2^6)  */
+#define MAX_NESTING               19
+#define DOUBLE_SERIALIZATION_FORMAT "%f"
+
+#define SIZEOF_TOKEN(a)       (sizeof(a) - 1)
+#define SKIP_CHAR(str)        ((*str)++)
+#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
+#define MAX(a, b)             ((a) > (b) ? (a) : (b))
+
+#undef malloc
+#undef free
+
+static x_JSON_Malloc_Function parson_malloc = malloc;
+static x_JSON_Free_Function parson_free = free;
+
+#define IS_CONT(b) (((unsigned char)(b) & 0xC0) == 0x80) /* is utf-8 continuation byte */
+
+/* Type definitions */
+typedef union x_json_value_value {
+    char        *string;
+    double       number;
+    x_JSON_Object *object;
+    x_JSON_Array  *array;
+    int          boolean;
+    int          null;
+} x_JSON_Value_Value;
+
+struct x_json_value_t {
+    x_JSON_Value_Type     type;
+    x_JSON_Value_Value    value;
+};
+
+struct x_json_object_t {
+    char       **names;
+    x_JSON_Value **values;
+    size_t       count;
+    size_t       capacity;
+};
+
+struct x_json_array_t {
+    x_JSON_Value **items;
+    size_t       count;
+    size_t       capacity;
+};
+
+/* Various */
+static char * read_file(const char *filename);
+static void   remove_comments(char *string, const char *start_token, const char *end_token);
+static char * parson_strndup(const char *string, size_t n);
+static char * parson_strdup(const char *string);
+static int    is_utf16_hex(const unsigned char *string);
+static int    num_bytes_in_utf8_sequence(unsigned char c);
+static int    verify_utf8_sequence(const unsigned char *string, int *len);
+static int    is_valid_utf8(const char *string, size_t string_len);
+static int    is_decimal(const char *string, size_t length);
+
+/* JSON Object */
+static x_JSON_Object * x_json_object_init(void);
+static x_JSON_Status   x_json_object_add(x_JSON_Object *object, const char *name, x_JSON_Value *value);
+static x_JSON_Status   x_json_object_resize(x_JSON_Object *object, size_t new_capacity);
+static x_JSON_Value  * x_json_object_nget_value(const x_JSON_Object *object, const char *name, size_t n);
+static void            x_json_object_free(x_JSON_Object *object);
+
+/* JSON Array */
+static x_JSON_Array * x_json_array_init(void);
+static x_JSON_Status  x_json_array_add(x_JSON_Array *array, x_JSON_Value *value);
+static x_JSON_Status  x_json_array_resize(x_JSON_Array *array, size_t new_capacity);
+static void           x_json_array_free(x_JSON_Array *array);
+
+/* JSON Value */
+static x_JSON_Value * x_json_value_init_string_no_copy(char *string);
+
+/* Parser */
+static void         skip_quotes(const char **string);
+static int          parse_utf_16(const char **unprocessed, char **processed);
+static char *       process_string(const char *input, size_t len);
+static char *       get_quoted_string(const char **string);
+static x_JSON_Value * parse_object_value(const char **string, size_t nesting);
+static x_JSON_Value * parse_array_value(const char **string, size_t nesting);
+static x_JSON_Value * parse_string_value(const char **string);
+static x_JSON_Value * parse_boolean_value(const char **string);
+static x_JSON_Value * parse_number_value(const char **string);
+static x_JSON_Value * parse_null_value(const char **string);
+static x_JSON_Value * parse_value(const char **string, size_t nesting);
+
+/* Serialization */
+static int    x_json_serialize_to_buffer_r(const x_JSON_Value *value, char *buf, int level, int is_pretty, char *num_buf);
+static int    x_json_serialize_string(const char *string, char *buf);
+static int    append_indent(char *buf, int level);
+static int    append_string(char *buf, const char *string);
+
+/* Various */
+static char * parson_strndup(const char *string, size_t n) {
+    char *output_string = (char*)parson_malloc(n + 1);
+    if (!output_string)
+        return NULL;
+    output_string[n] = '\0';
+    strncpy(output_string, string, n);
+    return output_string;
+}
+
+static char * parson_strdup(const char *string) {
+    return parson_strndup(string, strlen(string));
+}
+
+static int is_utf16_hex(const unsigned char *s) {
+    return isxdigit(s[0]) && isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]);
+}
+
+static int num_bytes_in_utf8_sequence(unsigned char c) {
+    if (c == 0xC0 || c == 0xC1 || c > 0xF4 || IS_CONT(c)) {
+        return 0;
+    } else if ((c & 0x80) == 0) {    /* 0xxxxxxx */
+        return 1;
+    } else if ((c & 0xE0) == 0xC0) { /* 110xxxxx */
+        return 2;
+    } else if ((c & 0xF0) == 0xE0) { /* 1110xxxx */
+        return 3;
+    } else if ((c & 0xF8) == 0xF0) { /* 11110xxx */
+        return 4;
+    }
+    return 0; /* won't happen */
+}
+
+static int verify_utf8_sequence(const unsigned char *string, int *len) {
+    unsigned int cp = 0;
+    *len = num_bytes_in_utf8_sequence(string[0]);
+
+    if (*len == 1) {
+        cp = string[0];
+    } else if (*len == 2 && IS_CONT(string[1])) {
+        cp = string[0] & 0x1F;
+        cp = (cp << 6) | (string[1] & 0x3F);
+    } else if (*len == 3 && IS_CONT(string[1]) && IS_CONT(string[2])) {
+        cp = ((unsigned char)string[0]) & 0xF;
+        cp = (cp << 6) | (string[1] & 0x3F);
+        cp = (cp << 6) | (string[2] & 0x3F);
+    } else if (*len == 4 && IS_CONT(string[1]) && IS_CONT(string[2]) && IS_CONT(string[3])) {
+        cp = string[0] & 0x7;
+        cp = (cp << 6) | (string[1] & 0x3F);
+        cp = (cp << 6) | (string[2] & 0x3F);
+        cp = (cp << 6) | (string[3] & 0x3F);
+    } else {
+        return 0;
+    }
+
+    /* overlong encodings */
+    if ((cp < 0x80    && *len > 1) ||
+        (cp < 0x800   && *len > 2) ||
+        (cp < 0x10000 && *len > 3)) {
+        return 0;
+    }
+
+    /* invalid unicode */
+    if (cp > 0x10FFFF) {
+        return 0;
+    }
+
+    /* surrogate halves */
+    if (cp >= 0xD800 && cp <= 0xDFFF) {
+        return 0;
+    }
+
+    return 1;
+}
+
+static int is_valid_utf8(const char *string, size_t string_len) {
+    int len = 0;
+    const char *string_end =  string + string_len;
+    while (string < string_end) {
+        if (!verify_utf8_sequence((const unsigned char*)string, &len)) {
+            return 0;
+        }
+        string += len;
+    }
+    return 1;
+}
+
+static int is_decimal(const char *string, size_t length) {
+    if (length > 1 && string[0] == '0' && string[1] != '.')
+        return 0;
+    if (length > 2 && !strncmp(string, "-0", 2) && string[2] != '.')
+        return 0;
+    while (length--)
+        if (strchr("xX", string[length]))
+            return 0;
+    return 1;
+}
+
+static char * read_file(const char * filename) {
+    FILE *fp = fopen(filename, "r");
+    size_t file_size;
+    long pos;
+    char *file_contents;
+    if (!fp)
+        return NULL;
+    fseek(fp, 0L, SEEK_END);
+    pos = ftell(fp);
+    if (pos < 0) {
+        fclose(fp);
+        return NULL;
+    }
+    file_size = pos;
+    rewind(fp);
+    file_contents = (char*)parson_malloc(sizeof(char) * (file_size + 1));
+    if (!file_contents) {
+        fclose(fp);
+        return NULL;
+    }
+    if (fread(file_contents, file_size, 1, fp) < 1) {
+        if (ferror(fp)) {
+            fclose(fp);
+            parson_free(file_contents);
+            return NULL;
+        }
+    }
+    fclose(fp);
+    file_contents[file_size] = '\0';
+    return file_contents;
+}
+
+static void remove_comments(char *string, const char *start_token, const char *end_token) {
+    int in_string = 0, escaped = 0;
+    size_t i;
+    char *ptr = NULL, current_char;
+    size_t start_token_len = strlen(start_token);
+    size_t end_token_len = strlen(end_token);
+    if (start_token_len == 0 || end_token_len == 0)
+    	return;
+    while ((current_char = *string) != '\0') {
+        if (current_char == '\\' && !escaped) {
+            escaped = 1;
+            string++;
+            continue;
+        } else if (current_char == '\"' && !escaped) {
+            in_string = !in_string;
+        } else if (!in_string && strncmp(string, start_token, start_token_len) == 0) {
+			for(i = 0; i < start_token_len; i++)
+                string[i] = ' ';
+        	string = string + start_token_len;
+            ptr = strstr(string, end_token);
+            if (!ptr)
+                return;
+            for (i = 0; i < (ptr - string) + end_token_len; i++)
+                string[i] = ' ';
+          	string = ptr + end_token_len - 1;
+        }
+        escaped = 0;
+        string++;
+    }
+}
+
+/* JSON Object */
+static x_JSON_Object * x_json_object_init(void) {
+    x_JSON_Object *new_obj = (x_JSON_Object*)parson_malloc(sizeof(x_JSON_Object));
+    if (!new_obj)
+        return NULL;
+    new_obj->names = (char**)NULL;
+    new_obj->values = (x_JSON_Value**)NULL;
+    new_obj->capacity = 0;
+    new_obj->count = 0;
+    return new_obj;
+}
+
+static x_JSON_Status x_json_object_add(x_JSON_Object *object, const char *name, x_JSON_Value *value) {
+    size_t index = 0;
+    if (object == NULL || name == NULL || value == NULL) {
+        return JSONFailure;
+    }
+    if (x_json_object_get_value(object, name) != NULL) {
+        return JSONFailure;
+    }
+    if (object->count >= object->capacity) {
+        size_t new_capacity = MAX(object->capacity * 2, STARTING_CAPACITY);
+        if (new_capacity > OBJECT_MAX_CAPACITY)
+            return JSONFailure;
+        if (x_json_object_resize(object, new_capacity) == JSONFailure)
+            return JSONFailure;
+    }
+    index = object->count;
+    object->names[index] = parson_strdup(name);
+    if (object->names[index] == NULL)
+        return JSONFailure;
+    object->values[index] = value;
+    object->count++;
+    return JSONSuccess;
+}
+
+static x_JSON_Status x_json_object_resize(x_JSON_Object *object, size_t new_capacity) {
+    char **temp_names = NULL;
+    x_JSON_Value **temp_values = NULL;
+
+    if ((object->names == NULL && object->values != NULL) ||
+        (object->names != NULL && object->values == NULL) ||
+        new_capacity == 0) {
+            return JSONFailure; /* Shouldn't happen */
+    }
+
+    temp_names = (char**)parson_malloc(new_capacity * sizeof(char*));
+    if (temp_names == NULL)
+        return JSONFailure;
+
+    temp_values = (x_JSON_Value**)parson_malloc(new_capacity * sizeof(x_JSON_Value*));
+    if (temp_values == NULL) {
+        parson_free(temp_names);
+        return JSONFailure;
+    }
+
+    if (object->names != NULL && object->values != NULL && object->count > 0) {
+        memcpy(temp_names, object->names, object->count * sizeof(char*));
+        memcpy(temp_values, object->values, object->count * sizeof(x_JSON_Value*));
+    }
+    parson_free(object->names);
+    parson_free(object->values);
+    object->names = temp_names;
+    object->values = temp_values;
+    object->capacity = new_capacity;
+    return JSONSuccess;
+}
+
+static x_JSON_Value * x_json_object_nget_value(const x_JSON_Object *object, const char *name, size_t n) {
+    size_t i, name_length;
+    for (i = 0; i < x_json_object_get_count(object); i++) {
+        name_length = strlen(object->names[i]);
+        if (name_length != n)
+            continue;
+        if (strncmp(object->names[i], name, n) == 0)
+            return object->values[i];
+    }
+    return NULL;
+}
+
+static void x_json_object_free(x_JSON_Object *object) {
+    while(object->count--) {
+        parson_free(object->names[object->count]);
+        x_json_value_free(object->values[object->count]);
+    }
+    parson_free(object->names);
+    parson_free(object->values);
+    parson_free(object);
+}
+
+/* JSON Array */
+static x_JSON_Array * x_json_array_init(void) {
+    x_JSON_Array *new_array = (x_JSON_Array*)parson_malloc(sizeof(x_JSON_Array));
+    if (!new_array)
+        return NULL;
+    new_array->items = (x_JSON_Value**)NULL;
+    new_array->capacity = 0;
+    new_array->count = 0;
+    return new_array;
+}
+
+static x_JSON_Status x_json_array_add(x_JSON_Array *array, x_JSON_Value *value) {
+    if (array->count >= array->capacity) {
+        size_t new_capacity = MAX(array->capacity * 2, STARTING_CAPACITY);
+        if (new_capacity > ARRAY_MAX_CAPACITY)
+            return JSONFailure;
+        if (x_json_array_resize(array, new_capacity) == JSONFailure)
+            return JSONFailure;
+    }
+    array->items[array->count] = value;
+    array->count++;
+    return JSONSuccess;
+}
+
+static x_JSON_Status x_json_array_resize(x_JSON_Array *array, size_t new_capacity) {
+    x_JSON_Value **new_items = NULL;
+    if (new_capacity == 0) {
+        return JSONFailure;
+    }
+    new_items = (x_JSON_Value**)parson_malloc(new_capacity * sizeof(x_JSON_Value*));
+    if (new_items == NULL) {
+        return JSONFailure;
+    }
+    if (array->items != NULL && array->count > 0) {
+        memcpy(new_items, array->items, array->count * sizeof(x_JSON_Value*));
+    }
+    parson_free(array->items);
+    array->items = new_items;
+    array->capacity = new_capacity;
+    return JSONSuccess;
+}
+
+static void x_json_array_free(x_JSON_Array *array) {
+    while (array->count--)
+        x_json_value_free(array->items[array->count]);
+    parson_free(array->items);
+    parson_free(array);
+}
+
+/* JSON Value */
+static x_JSON_Value * x_json_value_init_string_no_copy(char *string) {
+    x_JSON_Value *new_value = (x_JSON_Value*)parson_malloc(sizeof(x_JSON_Value));
+    if (!new_value)
+        return NULL;
+    new_value->type = JSONString;
+    new_value->value.string = string;
+    return new_value;
+}
+
+/* Parser */
+static void skip_quotes(const char **string) {
+    SKIP_CHAR(string);
+    while (**string != '\"') {
+        if (**string == '\0')
+            return;
+        if (**string == '\\') {
+            SKIP_CHAR(string);
+            if (**string == '\0')
+                return;
+        }
+        SKIP_CHAR(string);
+    }
+    SKIP_CHAR(string);
+}
+
+static int parse_utf_16(const char **unprocessed, char **processed) {
+    unsigned int cp, lead, trail;
+    char *processed_ptr = *processed;
+    const char *unprocessed_ptr = *unprocessed;
+    unprocessed_ptr++; /* skips u */
+    if (!is_utf16_hex((const unsigned char*)unprocessed_ptr) || sscanf(unprocessed_ptr, "%4x", &cp) == EOF)
+            return JSONFailure;
+    if (cp < 0x80) {
+        *processed_ptr = cp; /* 0xxxxxxx */
+    } else if (cp < 0x800) {
+        *processed_ptr++ = ((cp >> 6) & 0x1F) | 0xC0; /* 110xxxxx */
+        *processed_ptr   = ((cp     ) & 0x3F) | 0x80; /* 10xxxxxx */
+    } else if (cp < 0xD800 || cp > 0xDFFF) {
+        *processed_ptr++ = ((cp >> 12) & 0x0F) | 0xE0; /* 1110xxxx */
+        *processed_ptr++ = ((cp >> 6)  & 0x3F) | 0x80; /* 10xxxxxx */
+        *processed_ptr   = ((cp     )  & 0x3F) | 0x80; /* 10xxxxxx */
+    } else if (cp >= 0xD800 && cp <= 0xDBFF) { /* lead surrogate (0xD800..0xDBFF) */
+        lead = cp;
+        unprocessed_ptr += 4; /* should always be within the buffer, otherwise previous sscanf would fail */
+        if (*unprocessed_ptr++ != '\\' || *unprocessed_ptr++ != 'u' || /* starts with \u? */
+            !is_utf16_hex((const unsigned char*)unprocessed_ptr)          ||
+            sscanf(unprocessed_ptr, "%4x", &trail) == EOF           ||
+            trail < 0xDC00 || trail > 0xDFFF) { /* valid trail surrogate? (0xDC00..0xDFFF) */
+                return JSONFailure;
+        }
+        cp = ((((lead-0xD800)&0x3FF)<<10)|((trail-0xDC00)&0x3FF))+0x010000;
+        *processed_ptr++ = (((cp >> 18) & 0x07) | 0xF0); /* 11110xxx */
+        *processed_ptr++ = (((cp >> 12) & 0x3F) | 0x80); /* 10xxxxxx */
+        *processed_ptr++ = (((cp >> 6)  & 0x3F) | 0x80); /* 10xxxxxx */
+        *processed_ptr   = (((cp     )  & 0x3F) | 0x80); /* 10xxxxxx */
+    } else { /* trail surrogate before lead surrogate */
+        return JSONFailure;
+    }
+    unprocessed_ptr += 3;
+    *processed = processed_ptr;
+    *unprocessed = unprocessed_ptr;
+    return JSONSuccess;
+}
+
+
+/* Copies and processes passed string up to supplied length.
+Example: "\u006Corem ipsum" -> lorem ipsum */
+static char* process_string(const char *input, size_t len) {
+    const char *input_ptr = input;
+    size_t initial_size = (len + 1) * sizeof(char);
+    size_t final_size = 0;
+    char *output = (char*)parson_malloc(initial_size);
+    char *output_ptr = output;
+    char *resized_output = NULL;
+    while ((*input_ptr != '\0') && (size_t)(input_ptr - input) < len) {
+        if (*input_ptr == '\\') {
+            input_ptr++;
+            switch (*input_ptr) {
+                case '\"': *output_ptr = '\"'; break;
+                case '\\': *output_ptr = '\\'; break;
+                case '/':  *output_ptr = '/';  break;
+                case 'b':  *output_ptr = '\b'; break;
+                case 'f':  *output_ptr = '\f'; break;
+                case 'n':  *output_ptr = '\n'; break;
+                case 'r':  *output_ptr = '\r'; break;
+                case 't':  *output_ptr = '\t'; break;
+                case 'u':
+                    if (parse_utf_16(&input_ptr, &output_ptr) == JSONFailure)
+                        goto error;
+                    break;
+                default:
+                    goto error;
+            }
+        } else if ((unsigned char)*input_ptr < 0x20) {
+            goto error; /* 0x00-0x19 are invalid characters for json string (http://www.ietf.org/rfc/rfc4627.txt) */
+        } else {
+            *output_ptr = *input_ptr;
+        }
+        output_ptr++;
+        input_ptr++;
+    }
+    *output_ptr = '\0';
+    /* resize to new length */
+    final_size = (size_t)(output_ptr-output) + 1;
+    resized_output = (char*)parson_malloc(final_size);
+    if (resized_output == NULL)
+        goto error;
+    memcpy(resized_output, output, final_size);
+    parson_free(output);
+    return resized_output;
+error:
+    parson_free(output);
+    return NULL;
+}
+
+/* Return processed contents of a string between quotes and
+   skips passed argument to a matching quote. */
+static char * get_quoted_string(const char **string) {
+    const char *string_start = *string;
+    size_t string_len = 0;
+    skip_quotes(string);
+    string_len = *string - string_start - 2; /* length without quotes */
+    return process_string(string_start + 1, string_len);
+}
+
+static x_JSON_Value * parse_value(const char **string, size_t nesting) {
+    if (nesting > MAX_NESTING)
+        return NULL;
+    SKIP_WHITESPACES(string);
+    switch (**string) {
+        case '{':
+            return parse_object_value(string, nesting + 1);
+        case '[':
+            return parse_array_value(string, nesting + 1);
+        case '\"':
+            return parse_string_value(string);
+        case 'f': case 't':
+            return parse_boolean_value(string);
+        case '-':
+        case '0': case '1': case '2': case '3': case '4':
+        case '5': case '6': case '7': case '8': case '9':
+            return parse_number_value(string);
+        case 'n':
+            return parse_null_value(string);
+        default:
+            return NULL;
+    }
+}
+
+static x_JSON_Value * parse_object_value(const char **string, size_t nesting) {
+    x_JSON_Value *output_value = x_json_value_init_object(), *new_value = NULL;
+    x_JSON_Object *output_object = x_json_value_get_object(output_value);
+    char *new_key = NULL;
+    if (output_value == NULL)
+        return NULL;
+    SKIP_CHAR(string);
+    SKIP_WHITESPACES(string);
+    if (**string == '}') { /* empty object */
+        SKIP_CHAR(string);
+        return output_value;
+    }
+    while (**string != '\0') {
+        new_key = get_quoted_string(string);
+        SKIP_WHITESPACES(string);
+        if (new_key == NULL || **string != ':') {
+            x_json_value_free(output_value);
+            return NULL;
+        }
+        SKIP_CHAR(string);
+        new_value = parse_value(string, nesting);
+        if (new_value == NULL) {
+            parson_free(new_key);
+            x_json_value_free(output_value);
+            return NULL;
+        }
+        if(x_json_object_add(output_object, new_key, new_value) == JSONFailure) {
+            parson_free(new_key);
+            parson_free(new_value);
+            x_json_value_free(output_value);
+            return NULL;
+        }
+        parson_free(new_key);
+        SKIP_WHITESPACES(string);
+        if (**string != ',')
+            break;
+        SKIP_CHAR(string);
+        SKIP_WHITESPACES(string);
+    }
+    SKIP_WHITESPACES(string);
+    if (**string != '}' || /* Trim object after parsing is over */
+        x_json_object_resize(output_object, x_json_object_get_count(output_object)) == JSONFailure) {
+            x_json_value_free(output_value);
+            return NULL;
+    }
+    SKIP_CHAR(string);
+    return output_value;
+}
+
+static x_JSON_Value * parse_array_value(const char **string, size_t nesting) {
+    x_JSON_Value *output_value = x_json_value_init_array(), *new_array_value = NULL;
+    x_JSON_Array *output_array = x_json_value_get_array(output_value);
+    if (!output_value)
+        return NULL;
+    SKIP_CHAR(string);
+    SKIP_WHITESPACES(string);
+    if (**string == ']') { /* empty array */
+        SKIP_CHAR(string);
+        return output_value;
+    }
+    while (**string != '\0') {
+        new_array_value = parse_value(string, nesting);
+        if (!new_array_value) {
+            x_json_value_free(output_value);
+            return NULL;
+        }
+        if(x_json_array_add(output_array, new_array_value) == JSONFailure) {
+            parson_free(new_array_value);
+            x_json_value_free(output_value);
+            return NULL;
+        }
+        SKIP_WHITESPACES(string);
+        if (**string != ',')
+            break;
+        SKIP_CHAR(string);
+        SKIP_WHITESPACES(string);
+    }
+    SKIP_WHITESPACES(string);
+    if (**string != ']' || /* Trim array after parsing is over */
+        x_json_array_resize(output_array, x_json_array_get_count(output_array)) == JSONFailure) {
+            x_json_value_free(output_value);
+            return NULL;
+    }
+    SKIP_CHAR(string);
+    return output_value;
+}
+
+static x_JSON_Value * parse_string_value(const char **string) {
+    x_JSON_Value *value = NULL;
+    char *new_string = get_quoted_string(string);
+    if (new_string == NULL)
+        return NULL;
+    value = x_json_value_init_string_no_copy(new_string);
+    if (value == NULL) {
+        parson_free(new_string);
+        return NULL;
+    }
+    return value;
+}
+
+static x_JSON_Value * parse_boolean_value(const char **string) {
+    size_t true_token_size = SIZEOF_TOKEN("true");
+    size_t false_token_size = SIZEOF_TOKEN("false");
+    if (strncmp("true", *string, true_token_size) == 0) {
+        *string += true_token_size;
+        return x_json_value_init_boolean(1);
+    } else if (strncmp("false", *string, false_token_size) == 0) {
+        *string += false_token_size;
+        return x_json_value_init_boolean(0);
+    }
+    return NULL;
+}
+
+static x_JSON_Value * parse_number_value(const char **string) {
+    char *end;
+    double number = strtod(*string, &end);
+    x_JSON_Value *output_value;
+    if (is_decimal(*string, end - *string)) {
+        *string = end;
+        output_value = x_json_value_init_number(number);
+    } else {
+        output_value = NULL;
+    }
+    return output_value;
+}
+
+static x_JSON_Value * parse_null_value(const char **string) {
+    size_t token_size = SIZEOF_TOKEN("null");
+    if (strncmp("null", *string, token_size) == 0) {
+        *string += token_size;
+        return x_json_value_init_null();
+    }
+    return NULL;
+}
+
+/* Serialization */
+#define APPEND_STRING(str) do { written = append_string(buf, (str));\
+                                if (written < 0) { return -1; }\
+                                if (buf != NULL) { buf += written; }\
+                                written_total += written; } while(0)
+
+#define APPEND_INDENT(level) do { written = append_indent(buf, (level));\
+                                  if (written < 0) { return -1; }\
+                                  if (buf != NULL) { buf += written; }\
+                                  written_total += written; } while(0)
+
+static int x_json_serialize_to_buffer_r(const x_JSON_Value *value, char *buf, int level, int is_pretty, char *num_buf)
+{
+    const char *key = NULL, *string = NULL;
+    x_JSON_Value *temp_value = NULL;
+    x_JSON_Array *array = NULL;
+    x_JSON_Object *object = NULL;
+    size_t i = 0, count = 0;
+    double num = 0.0;
+    int written = -1, written_total = 0;
+
+    switch (x_json_value_get_type(value)) {
+        case JSONArray:
+            array = x_json_value_get_array(value);
+            count = x_json_array_get_count(array);
+            APPEND_STRING("[");
+            if (count > 0 && is_pretty)
+                APPEND_STRING("\n");
+            for (i = 0; i < count; i++) {
+                if (is_pretty)
+                    APPEND_INDENT(level+1);
+                temp_value = x_json_array_get_value(array, i);
+                written = x_json_serialize_to_buffer_r(temp_value, buf, level+1, is_pretty, num_buf);
+                if (written < 0)
+                    return -1;
+                if (buf != NULL)
+                    buf += written;
+                written_total += written;
+                if (i < (count - 1))
+                    APPEND_STRING(",");
+                if (is_pretty)
+                    APPEND_STRING("\n");
+            }
+            if (count > 0 && is_pretty)
+                APPEND_INDENT(level);
+            APPEND_STRING("]");
+            return written_total;
+        case JSONObject:
+            object = x_json_value_get_object(value);
+            count  = x_json_object_get_count(object);
+            APPEND_STRING("{");
+            if (count > 0 && is_pretty)
+                APPEND_STRING("\n");
+            for (i = 0; i < count; i++) {
+                key = x_json_object_get_name(object, i);
+                if (is_pretty)
+                    APPEND_INDENT(level+1);
+                written = x_json_serialize_string(key, buf);
+                if (written < 0)
+                    return -1;
+                if (buf != NULL)
+                    buf += written;
+                written_total += written;
+                APPEND_STRING(":");
+                if (is_pretty)
+                    APPEND_STRING(" ");
+                temp_value = x_json_object_get_value(object, key);
+                written = x_json_serialize_to_buffer_r(temp_value, buf, level+1, is_pretty, num_buf);
+                if (written < 0)
+                    return -1;
+                if (buf != NULL)
+                    buf += written;
+                written_total += written;
+                if (i < (count - 1))
+                    APPEND_STRING(",");
+                if (is_pretty)
+                    APPEND_STRING("\n");
+            }
+            if (count > 0 && is_pretty)
+                APPEND_INDENT(level);
+            APPEND_STRING("}");
+            return written_total;
+        case JSONString:
+            string = x_json_value_get_string(value);
+            written = x_json_serialize_string(string, buf);
+            if (written < 0)
+                return -1;
+            if (buf != NULL)
+                buf += written;
+            written_total += written;
+            return written_total;
+        case JSONBoolean:
+            if (x_json_value_get_boolean(value))
+                APPEND_STRING("true");
+            else
+                APPEND_STRING("false");
+            return written_total;
+        case JSONNumber:
+            num = x_json_value_get_number(value);
+            if (buf != NULL)
+                num_buf = buf;
+            if (num == ((double)(int)num)) /*  check if num is integer */
+                written = sprintf(num_buf, "%d", (int)num);
+            else
+                written = sprintf(num_buf, DOUBLE_SERIALIZATION_FORMAT, num);
+            if (written < 0)
+                return -1;
+            if (buf != NULL)
+                buf += written;
+            written_total += written;
+            return written_total;
+        case JSONNull:
+            APPEND_STRING("null");
+            return written_total;
+        case JSONError:
+            return -1;
+        default:
+            return -1;
+    }
+}
+
+static int x_json_serialize_string(const char *string, char *buf) {
+    size_t i = 0, len = strlen(string);
+    char c = '\0';
+    int written = -1, written_total = 0;
+    APPEND_STRING("\"");
+    for (i = 0; i < len; i++) {
+        c = string[i];
+        switch (c) {
+            case '\"': APPEND_STRING("\\\""); break;
+            case '\\': APPEND_STRING("\\\\"); break;
+            case '/':  APPEND_STRING("\\/"); break; /* to make json embeddable in xml\/html */
+            case '\b': APPEND_STRING("\\b"); break;
+            case '\f': APPEND_STRING("\\f"); break;
+            case '\n': APPEND_STRING("\\n"); break;
+            case '\r': APPEND_STRING("\\r"); break;
+            case '\t': APPEND_STRING("\\t"); break;
+            default:
+                if (buf != NULL) {
+                    buf[0] = c;
+                    buf += 1;
+                }
+                written_total += 1;
+                break;
+        }
+    }
+    APPEND_STRING("\"");
+    return written_total;
+}
+
+static int append_indent(char *buf, int level) {
+    int i;
+    int written = -1, written_total = 0;
+    for (i = 0; i < level; i++) {
+        APPEND_STRING("    ");
+    }
+    return written_total;
+}
+
+static int append_string(char *buf, const char *string) {
+    if (buf == NULL) {
+        return (int)strlen(string);
+    }
+    return sprintf(buf, "%s", string);
+}
+
+#undef APPEND_STRING
+#undef APPEND_INDENT
+
+/* Parser API */
+x_JSON_Value * x_json_parse_file(const char *filename) {
+    char *file_contents = read_file(filename);
+    x_JSON_Value *output_value = NULL;
+    if (file_contents == NULL)
+        return NULL;
+    output_value = x_json_parse_string(file_contents);
+    parson_free(file_contents);
+    return output_value;
+}
+
+x_JSON_Value * x_json_parse_file_with_comments(const char *filename) {
+    char *file_contents = read_file(filename);
+    x_JSON_Value *output_value = NULL;
+    if (file_contents == NULL)
+        return NULL;
+    output_value = x_json_parse_string_with_comments(file_contents);
+    parson_free(file_contents);
+    return output_value;
+}
+
+x_JSON_Value * x_json_parse_string(const char *string) {
+    if (string == NULL)
+        return NULL;
+    return parse_value((const char**)&string, 0);
+}
+
+x_JSON_Value * x_json_parse_string_with_comments(const char *string) {
+    x_JSON_Value *result = NULL;
+    char *string_mutable_copy = NULL, *string_mutable_copy_ptr = NULL;
+    string_mutable_copy = parson_strdup(string);
+    if (string_mutable_copy == NULL)
+        return NULL;
+    remove_comments(string_mutable_copy, "/*", "*/");
+    remove_comments(string_mutable_copy, "//", "\n");
+    string_mutable_copy_ptr = string_mutable_copy;
+    result = parse_value((const char**)&string_mutable_copy_ptr, 0);
+    parson_free(string_mutable_copy);
+    return result;
+}
+
+/* JSON Object API */
+
+x_JSON_Value * x_json_object_get_value(const x_JSON_Object *object, const char *name) {
+    if (object == NULL || name == NULL)
+        return NULL;
+    return x_json_object_nget_value(object, name, strlen(name));
+}
+
+const char * x_json_object_get_string(const x_JSON_Object *object, const char *name) {
+    return x_json_value_get_string(x_json_object_get_value(object, name));
+}
+
+double x_json_object_get_number(const x_JSON_Object *object, const char *name) {
+    return x_json_value_get_number(x_json_object_get_value(object, name));
+}
+
+x_JSON_Object * x_json_object_get_object(const x_JSON_Object *object, const char *name) {
+    return x_json_value_get_object(x_json_object_get_value(object, name));
+}
+
+x_JSON_Array * x_json_object_get_array(const x_JSON_Object *object, const char *name) {
+    return x_json_value_get_array(x_json_object_get_value(object, name));
+}
+
+int x_json_object_get_boolean(const x_JSON_Object *object, const char *name) {
+    return x_json_value_get_boolean(x_json_object_get_value(object, name));
+}
+
+x_JSON_Value * x_json_object_dotget_value(const x_JSON_Object *object, const char *name) {
+    const char *dot_position = strchr(name, '.');
+    if (!dot_position)
+        return x_json_object_get_value(object, name);
+    object = x_json_value_get_object(x_json_object_nget_value(object, name, dot_position - name));
+    return x_json_object_dotget_value(object, dot_position + 1);
+}
+
+const char * x_json_object_dotget_string(const x_JSON_Object *object, const char *name) {
+    return x_json_value_get_string(x_json_object_dotget_value(object, name));
+}
+
+double x_json_object_dotget_number(const x_JSON_Object *object, const char *name) {
+    return x_json_value_get_number(x_json_object_dotget_value(object, name));
+}
+
+x_JSON_Object * x_json_object_dotget_object(const x_JSON_Object *object, const char *name) {
+    return x_json_value_get_object(x_json_object_dotget_value(object, name));
+}
+
+x_JSON_Array * x_json_object_dotget_array(const x_JSON_Object *object, const char *name) {
+    return x_json_value_get_array(x_json_object_dotget_value(object, name));
+}
+
+int x_json_object_dotget_boolean(const x_JSON_Object *object, const char *name) {
+    return x_json_value_get_boolean(x_json_object_dotget_value(object, name));
+}
+
+size_t x_json_object_get_count(const x_JSON_Object *object) {
+    return object ? object->count : 0;
+}
+
+const char * x_json_object_get_name(const x_JSON_Object *object, size_t index) {
+    if (object == NULL || index >= x_json_object_get_count(object))
+        return NULL;
+    return object->names[index];
+}
+
+x_JSON_Value * x_json_object_get_value_at(const x_JSON_Object *object, size_t index) {
+    if (object == NULL || index >= x_json_object_get_count(object))
+        return NULL;
+    return object->values[index];
+}
+
+/* JSON Array API */
+x_JSON_Value * x_json_array_get_value(const x_JSON_Array *array, size_t index) {
+    if (array == NULL || index >= x_json_array_get_count(array))
+        return NULL;
+    return array->items[index];
+}
+
+const char * x_json_array_get_string(const x_JSON_Array *array, size_t index) {
+    return x_json_value_get_string(x_json_array_get_value(array, index));
+}
+
+double x_json_array_get_number(const x_JSON_Array *array, size_t index) {
+    return x_json_value_get_number(x_json_array_get_value(array, index));
+}
+
+x_JSON_Object * x_json_array_get_object(const x_JSON_Array *array, size_t index) {
+    return x_json_value_get_object(x_json_array_get_value(array, index));
+}
+
+x_JSON_Array * x_json_array_get_array(const x_JSON_Array *array, size_t index) {
+    return x_json_value_get_array(x_json_array_get_value(array, index));
+}
+
+int x_json_array_get_boolean(const x_JSON_Array *array, size_t index) {
+    return x_json_value_get_boolean(x_json_array_get_value(array, index));
+}
+
+size_t x_json_array_get_count(const x_JSON_Array *array) {
+    return array ? array->count : 0;
+}
+
+/* JSON Value API */
+x_JSON_Value_Type x_json_value_get_type(const x_JSON_Value *value) {
+    return value ? value->type : JSONError;
+}
+
+x_JSON_Object * x_json_value_get_object(const x_JSON_Value *value) {
+    return x_json_value_get_type(value) == JSONObject ? value->value.object : NULL;
+}
+
+x_JSON_Array * x_json_value_get_array(const x_JSON_Value *value) {
+    return x_json_value_get_type(value) == JSONArray ? value->value.array : NULL;
+}
+
+const char * x_json_value_get_string(const x_JSON_Value *value) {
+    return x_json_value_get_type(value) == JSONString ? value->value.string : NULL;
+}
+
+double x_json_value_get_number(const x_JSON_Value *value) {
+    return x_json_value_get_type(value) == JSONNumber ? value->value.number : 0;
+}
+
+int x_json_value_get_boolean(const x_JSON_Value *value) {
+    return x_json_value_get_type(value) == JSONBoolean ? value->value.boolean : -1;
+}
+
+void x_json_value_free(x_JSON_Value *value) {
+    switch (x_json_value_get_type(value)) {
+        case JSONObject:
+            x_json_object_free(value->value.object);
+            break;
+        case JSONString:
+            if (value->value.string) { parson_free(value->value.string); }
+            break;
+        case JSONArray:
+            x_json_array_free(value->value.array);
+            break;
+        default:
+            break;
+    }
+    parson_free(value);
+}
+
+x_JSON_Value * x_json_value_init_object(void) {
+    x_JSON_Value *new_value = (x_JSON_Value*)parson_malloc(sizeof(x_JSON_Value));
+    if (!new_value)
+        return NULL;
+    new_value->type = JSONObject;
+    new_value->value.object = x_json_object_init();
+    if (!new_value->value.object) {
+        parson_free(new_value);
+        return NULL;
+    }
+    return new_value;
+}
+
+x_JSON_Value * x_json_value_init_array(void) {
+    x_JSON_Value *new_value = (x_JSON_Value*)parson_malloc(sizeof(x_JSON_Value));
+    if (!new_value)
+        return NULL;
+    new_value->type = JSONArray;
+    new_value->value.array = x_json_array_init();
+    if (!new_value->value.array) {
+        parson_free(new_value);
+        return NULL;
+    }
+    return new_value;
+}
+
+x_JSON_Value * x_json_value_init_string(const char *string) {
+    char *copy = NULL;
+    x_JSON_Value *value;
+    size_t string_len = 0;
+    if (string == NULL)
+        return NULL;
+    string_len = strlen(string);
+    if (!is_valid_utf8(string, string_len))
+        return NULL;
+    copy = parson_strndup(string, string_len);
+    if (copy == NULL)
+        return NULL;
+    value = x_json_value_init_string_no_copy(copy);
+    if (value == NULL)
+        parson_free(copy);
+    return value;
+}
+
+x_JSON_Value * x_json_value_init_number(double number) {
+    x_JSON_Value *new_value = (x_JSON_Value*)parson_malloc(sizeof(x_JSON_Value));
+    if (!new_value)
+        return NULL;
+    new_value->type = JSONNumber;
+    new_value->value.number = number;
+    return new_value;
+}
+
+x_JSON_Value * x_json_value_init_boolean(int boolean) {
+    x_JSON_Value *new_value = (x_JSON_Value*)parson_malloc(sizeof(x_JSON_Value));
+    if (!new_value)
+        return NULL;
+    new_value->type = JSONBoolean;
+    new_value->value.boolean = boolean ? 1 : 0;
+    return new_value;
+}
+
+x_JSON_Value * x_json_value_init_null(void) {
+    x_JSON_Value *new_value = (x_JSON_Value*)parson_malloc(sizeof(x_JSON_Value));
+    if (!new_value)
+        return NULL;
+    new_value->type = JSONNull;
+    return new_value;
+}
+
+x_JSON_Value * x_json_value_deep_copy(const x_JSON_Value *value) {
+    size_t i = 0;
+    x_JSON_Value *return_value = NULL, *temp_value_copy = NULL, *temp_value = NULL;
+    const char *temp_string = NULL, *temp_key = NULL;
+    char *temp_string_copy = NULL;
+    x_JSON_Array *temp_array = NULL, *temp_array_copy = NULL;
+    x_JSON_Object *temp_object = NULL, *temp_object_copy = NULL;
+
+    switch (x_json_value_get_type(value)) {
+        case JSONArray:
+            temp_array = x_json_value_get_array(value);
+            return_value = x_json_value_init_array();
+            if (return_value == NULL)
+                return NULL;
+            temp_array_copy = x_json_value_get_array(return_value);
+            for (i = 0; i < x_json_array_get_count(temp_array); i++) {
+                temp_value = x_json_array_get_value(temp_array, i);
+                temp_value_copy = x_json_value_deep_copy(temp_value);
+                if (temp_value_copy == NULL) {
+                    x_json_value_free(return_value);
+                    return NULL;
+                }
+                if (x_json_array_add(temp_array_copy, temp_value_copy) == JSONFailure) {
+                    x_json_value_free(return_value);
+                    x_json_value_free(temp_value_copy);
+                    return NULL;
+                }
+            }
+            return return_value;
+        case JSONObject:
+            temp_object = x_json_value_get_object(value);
+            return_value = x_json_value_init_object();
+            if (return_value == NULL)
+                return NULL;
+            temp_object_copy = x_json_value_get_object(return_value);
+            for (i = 0; i < x_json_object_get_count(temp_object); i++) {
+                temp_key = x_json_object_get_name(temp_object, i);
+                temp_value = x_json_object_get_value(temp_object, temp_key);
+                temp_value_copy = x_json_value_deep_copy(temp_value);
+                if (temp_value_copy == NULL) {
+                    x_json_value_free(return_value);
+                    return NULL;
+                }
+                if (x_json_object_add(temp_object_copy, temp_key, temp_value_copy) == JSONFailure) {
+                    x_json_value_free(return_value);
+                    x_json_value_free(temp_value_copy);
+                    return NULL;
+                }
+            }
+            return return_value;
+        case JSONBoolean:
+            return x_json_value_init_boolean(x_json_value_get_boolean(value));
+        case JSONNumber:
+            return x_json_value_init_number(x_json_value_get_number(value));
+        case JSONString:
+            temp_string = x_json_value_get_string(value);
+            temp_string_copy = parson_strdup(temp_string);
+            if (temp_string_copy == NULL)
+                return NULL;
+            return_value = x_json_value_init_string_no_copy(temp_string_copy);
+            if (return_value == NULL)
+                parson_free(temp_string_copy);
+            return return_value;
+        case JSONNull:
+            return x_json_value_init_null();
+        case JSONError:
+            return NULL;
+        default:
+            return NULL;
+    }
+}
+
+size_t x_json_serialization_size(const x_JSON_Value *value) {
+    char num_buf[1100]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */
+    int res = x_json_serialize_to_buffer_r(value, NULL, 0, 0, num_buf);
+    return res < 0 ? 0 : (size_t)(res + 1);
+}
+
+x_JSON_Status x_json_serialize_to_buffer(const x_JSON_Value *value, char *buf, size_t buf_size_in_bytes) {
+    int written = -1;
+    size_t needed_size_in_bytes = x_json_serialization_size(value);
+    if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) {
+        return JSONFailure;
+    }
+    written = x_json_serialize_to_buffer_r(value, buf, 0, 0, NULL);
+    if (written < 0)
+        return JSONFailure;
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_serialize_to_file(const x_JSON_Value *value, const char *filename) {
+    x_JSON_Status return_code = JSONSuccess;
+    FILE *fp = NULL;
+    char *serialized_string = x_json_serialize_to_string(value);
+    if (serialized_string == NULL) {
+        return JSONFailure;
+    }
+    fp = fopen (filename, "w");
+    if (fp == NULL) {
+        x_json_free_serialized_string(serialized_string);
+        return JSONFailure;
+    }
+    if (fputs(serialized_string, fp) == EOF) {
+        return_code = JSONFailure;
+    }
+    if (fclose(fp) == EOF) {
+        return_code = JSONFailure;
+    }
+    x_json_free_serialized_string(serialized_string);
+    return return_code;
+}
+
+char * x_json_serialize_to_string(const x_JSON_Value *value) {
+    x_JSON_Status serialization_result = JSONFailure;
+    size_t buf_size_bytes = x_json_serialization_size(value);
+    char *buf = NULL;
+    if (buf_size_bytes == 0) {
+        return NULL;
+    }
+    buf = (char*)parson_malloc(buf_size_bytes);
+    if (buf == NULL)
+        return NULL;
+    serialization_result = x_json_serialize_to_buffer(value, buf, buf_size_bytes);
+    if (serialization_result == JSONFailure) {
+        x_json_free_serialized_string(buf);
+        return NULL;
+    }
+    return buf;
+}
+
+size_t x_json_serialization_size_pretty(const x_JSON_Value *value) {
+    char num_buf[1100]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */
+    int res = x_json_serialize_to_buffer_r(value, NULL, 0, 1, num_buf);
+    return res < 0 ? 0 : (size_t)(res + 1);
+}
+
+x_JSON_Status x_json_serialize_to_buffer_pretty(const x_JSON_Value *value, char *buf, size_t buf_size_in_bytes) {
+    int written = -1;
+    size_t needed_size_in_bytes = x_json_serialization_size_pretty(value);
+    if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes)
+        return JSONFailure;
+    written = x_json_serialize_to_buffer_r(value, buf, 0, 1, NULL);
+    if (written < 0)
+        return JSONFailure;
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_serialize_to_file_pretty(const x_JSON_Value *value, const char *filename) {
+    x_JSON_Status return_code = JSONSuccess;
+    FILE *fp = NULL;
+    char *serialized_string = x_json_serialize_to_string_pretty(value);
+    if (serialized_string == NULL) {
+        return JSONFailure;
+    }
+    fp = fopen (filename, "w");
+    if (fp == NULL) {
+        x_json_free_serialized_string(serialized_string);
+        return JSONFailure;
+    }
+    if (fputs(serialized_string, fp) == EOF) {
+        return_code = JSONFailure;
+    }
+    if (fclose(fp) == EOF) {
+        return_code = JSONFailure;
+    }
+    x_json_free_serialized_string(serialized_string);
+    return return_code;
+}
+
+char * x_json_serialize_to_string_pretty(const x_JSON_Value *value) {
+    x_JSON_Status serialization_result = JSONFailure;
+    size_t buf_size_bytes = x_json_serialization_size_pretty(value);
+    char *buf = NULL;
+    if (buf_size_bytes == 0) {
+        return NULL;
+    }
+    buf = (char*)parson_malloc(buf_size_bytes);
+    if (buf == NULL)
+        return NULL;
+    serialization_result = x_json_serialize_to_buffer_pretty(value, buf, buf_size_bytes);
+    if (serialization_result == JSONFailure) {
+        x_json_free_serialized_string(buf);
+        return NULL;
+    }
+    return buf;
+}
+
+void x_json_free_serialized_string(char *string) {
+    parson_free(string);
+}
+
+x_JSON_Status x_json_array_remove(x_JSON_Array *array, size_t ix) {
+    x_JSON_Value *temp_value = NULL;
+    size_t last_element_ix = 0;
+    if (array == NULL || ix >= x_json_array_get_count(array)) {
+        return JSONFailure;
+    }
+    last_element_ix = x_json_array_get_count(array) - 1;
+    x_json_value_free(x_json_array_get_value(array, ix));
+    if (ix != last_element_ix) { /* Replace value with one from the end of array */
+        temp_value = x_json_array_get_value(array, last_element_ix);
+        if (temp_value == NULL) {
+            return JSONFailure;
+        }
+        array->items[ix] = temp_value;
+    }
+    array->count -= 1;
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_array_replace_value(x_JSON_Array *array, size_t ix, x_JSON_Value *value) {
+    if (array == NULL || value == NULL || ix >= x_json_array_get_count(array)) {
+        return JSONFailure;
+    }
+    x_json_value_free(x_json_array_get_value(array, ix));
+    array->items[ix] = value;
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_array_replace_string(x_JSON_Array *array, size_t i, const char* string) {
+    x_JSON_Value *value = x_json_value_init_string(string);
+    if (value == NULL)
+        return JSONFailure;
+    if (x_json_array_replace_value(array, i, value) == JSONFailure) {
+        x_json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_array_replace_number(x_JSON_Array *array, size_t i, double number) {
+    x_JSON_Value *value = x_json_value_init_number(number);
+    if (value == NULL)
+        return JSONFailure;
+    if (x_json_array_replace_value(array, i, value) == JSONFailure) {
+        x_json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_array_replace_boolean(x_JSON_Array *array, size_t i, int boolean) {
+    x_JSON_Value *value = x_json_value_init_boolean(boolean);
+    if (value == NULL)
+        return JSONFailure;
+    if (x_json_array_replace_value(array, i, value) == JSONFailure) {
+        x_json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_array_replace_null(x_JSON_Array *array, size_t i) {
+    x_JSON_Value *value = x_json_value_init_null();
+    if (value == NULL)
+        return JSONFailure;
+    if (x_json_array_replace_value(array, i, value) == JSONFailure) {
+        x_json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_array_clear(x_JSON_Array *array) {
+    size_t i = 0;
+    if (array == NULL)
+        return JSONFailure;
+    for (i = 0; i < x_json_array_get_count(array); i++) {
+        x_json_value_free(x_json_array_get_value(array, i));
+    }
+    array->count = 0;
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_array_append_value(x_JSON_Array *array, x_JSON_Value *value) {
+    if (array == NULL || value == NULL)
+        return JSONFailure;
+    return x_json_array_add(array, value);
+}
+
+x_JSON_Status x_json_array_append_string(x_JSON_Array *array, const char *string) {
+    x_JSON_Value *value = x_json_value_init_string(string);
+    if (value == NULL)
+        return JSONFailure;
+    if (x_json_array_append_value(array, value) == JSONFailure) {
+        x_json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_array_append_number(x_JSON_Array *array, double number) {
+    x_JSON_Value *value = x_json_value_init_number(number);
+    if (value == NULL)
+        return JSONFailure;
+    if (x_json_array_append_value(array, value) == JSONFailure) {
+        x_json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_array_append_boolean(x_JSON_Array *array, int boolean) {
+    x_JSON_Value *value = x_json_value_init_boolean(boolean);
+    if (value == NULL)
+        return JSONFailure;
+    if (x_json_array_append_value(array, value) == JSONFailure) {
+        x_json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_array_append_null(x_JSON_Array *array) {
+    x_JSON_Value *value = x_json_value_init_null();
+    if (value == NULL)
+        return JSONFailure;
+    if (x_json_array_append_value(array, value) == JSONFailure) {
+        x_json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_object_set_value(x_JSON_Object *object, const char *name, x_JSON_Value *value) {
+    size_t i = 0;
+    x_JSON_Value *old_value;
+    if (object == NULL || name == NULL || value == NULL)
+        return JSONFailure;
+    old_value = x_json_object_get_value(object, name);
+    if (old_value != NULL) { /* free and overwrite old value */
+        x_json_value_free(old_value);
+        for (i = 0; i < x_json_object_get_count(object); i++) {
+            if (strcmp(object->names[i], name) == 0) {
+                object->values[i] = value;
+                return JSONSuccess;
+            }
+        }
+    }
+    /* add new key value pair */
+    return x_json_object_add(object, name, value);
+}
+
+x_JSON_Status x_json_object_set_string(x_JSON_Object *object, const char *name, const char *string) {
+    return x_json_object_set_value(object, name, x_json_value_init_string(string));
+}
+
+x_JSON_Status x_json_object_set_number(x_JSON_Object *object, const char *name, double number) {
+    return x_json_object_set_value(object, name, x_json_value_init_number(number));
+}
+
+x_JSON_Status x_json_object_set_boolean(x_JSON_Object *object, const char *name, int boolean) {
+    return x_json_object_set_value(object, name, x_json_value_init_boolean(boolean));
+}
+
+x_JSON_Status x_json_object_set_null(x_JSON_Object *object, const char *name) {
+    return x_json_object_set_value(object, name, x_json_value_init_null());
+}
+
+x_JSON_Status x_json_object_dotset_value(x_JSON_Object *object, const char *name, x_JSON_Value *value) {
+    const char *dot_pos = NULL;
+    char *current_name = NULL;
+    x_JSON_Object *temp_obj = NULL;
+    x_JSON_Value *new_value = NULL;
+    if (value == NULL || name == NULL || value == NULL)
+        return JSONFailure;
+    dot_pos = strchr(name, '.');
+    if (dot_pos == NULL) {
+        return x_json_object_set_value(object, name, value);
+    } else {
+        current_name = parson_strndup(name, dot_pos - name);
+        temp_obj = x_json_object_get_object(object, current_name);
+        if (temp_obj == NULL) {
+            new_value = x_json_value_init_object();
+            if (new_value == NULL) {
+                parson_free(current_name);
+                return JSONFailure;
+            }
+            if (x_json_object_add(object, current_name, new_value) == JSONFailure) {
+                x_json_value_free(new_value);
+                parson_free(current_name);
+                return JSONFailure;
+            }
+            temp_obj = x_json_object_get_object(object, current_name);
+        }
+        parson_free(current_name);
+        return x_json_object_dotset_value(temp_obj, dot_pos + 1, value);
+    }
+}
+
+x_JSON_Status x_json_object_dotset_string(x_JSON_Object *object, const char *name, const char *string) {
+    x_JSON_Value *value = x_json_value_init_string(string);
+    if (value == NULL)
+        return JSONFailure;
+    if (x_json_object_dotset_value(object, name, value) == JSONFailure) {
+        x_json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_object_dotset_number(x_JSON_Object *object, const char *name, double number) {
+    x_JSON_Value *value = x_json_value_init_number(number);
+    if (value == NULL)
+        return JSONFailure;
+    if (x_json_object_dotset_value(object, name, value) == JSONFailure) {
+        x_json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_object_dotset_boolean(x_JSON_Object *object, const char *name, int boolean) {
+    x_JSON_Value *value = x_json_value_init_boolean(boolean);
+    if (value == NULL)
+        return JSONFailure;
+    if (x_json_object_dotset_value(object, name, value) == JSONFailure) {
+        x_json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_object_dotset_null(x_JSON_Object *object, const char *name) {
+    x_JSON_Value *value = x_json_value_init_null();
+    if (value == NULL)
+        return JSONFailure;
+    if (x_json_object_dotset_value(object, name, value) == JSONFailure) {
+        x_json_value_free(value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_object_remove(x_JSON_Object *object, const char *name) {
+    size_t i = 0, last_item_index = 0;
+    if (object == NULL || x_json_object_get_value(object, name) == NULL)
+        return JSONFailure;
+    last_item_index = x_json_object_get_count(object) - 1;
+    for (i = 0; i < x_json_object_get_count(object); i++) {
+        if (strcmp(object->names[i], name) == 0) {
+            parson_free(object->names[i]);
+            x_json_value_free(object->values[i]);
+            if (i != last_item_index) { /* Replace key value pair with one from the end */
+                object->names[i] = object->names[last_item_index];
+                object->values[i] = object->values[last_item_index];
+            }
+            object->count -= 1;
+            return JSONSuccess;
+        }
+    }
+    return JSONFailure; /* No execution path should end here */
+}
+
+x_JSON_Status x_json_object_dotremove(x_JSON_Object *object, const char *name) {
+    const char *dot_pos = strchr(name, '.');
+    char *current_name = NULL;
+    x_JSON_Object *temp_obj = NULL;
+    if (dot_pos == NULL) {
+        return x_json_object_remove(object, name);
+    } else {
+        current_name = parson_strndup(name, dot_pos - name);
+        temp_obj = x_json_object_get_object(object, current_name);
+        if (temp_obj == NULL) {
+            parson_free(current_name);
+            return JSONFailure;
+        }
+        parson_free(current_name);
+        return x_json_object_dotremove(temp_obj, dot_pos + 1);
+    }
+}
+
+x_JSON_Status x_json_object_clear(x_JSON_Object *object) {
+    size_t i = 0;
+    if (object == NULL) {
+        return JSONFailure;
+    }
+    for (i = 0; i < x_json_object_get_count(object); i++) {
+        parson_free(object->names[i]);
+        x_json_value_free(object->values[i]);
+    }
+    object->count = 0;
+    return JSONSuccess;
+}
+
+x_JSON_Status x_json_validate(const x_JSON_Value *schema, const x_JSON_Value *value) {
+    x_JSON_Value *temp_schema_value = NULL, *temp_value = NULL;
+    x_JSON_Array *schema_array = NULL, *value_array = NULL;
+    x_JSON_Object *schema_object = NULL, *value_object = NULL;
+    x_JSON_Value_Type schema_type = JSONError, value_type = JSONError;
+    const char *key = NULL;
+    size_t i = 0, count = 0;
+    if (schema == NULL || value == NULL)
+        return JSONFailure;
+    schema_type = x_json_value_get_type(schema);
+    value_type = x_json_value_get_type(value);
+    if (schema_type != value_type && schema_type != JSONNull) /* null represents all values */
+        return JSONFailure;
+    switch (schema_type) {
+        case JSONArray:
+            schema_array = x_json_value_get_array(schema);
+            value_array = x_json_value_get_array(value);
+            count = x_json_array_get_count(schema_array);
+            if (count == 0)
+                return JSONSuccess; /* Empty array allows all types */
+            /* Get first value from array, rest is ignored */
+            temp_schema_value = x_json_array_get_value(schema_array, 0);
+            for (i = 0; i < x_json_array_get_count(value_array); i++) {
+                temp_value = x_json_array_get_value(value_array, i);
+                if (x_json_validate(temp_schema_value, temp_value) == 0) {
+                    return JSONFailure;
+                }
+            }
+            return JSONSuccess;
+        case JSONObject:
+            schema_object = x_json_value_get_object(schema);
+            value_object = x_json_value_get_object(value);
+            count = x_json_object_get_count(schema_object);
+            if (count == 0)
+                return JSONSuccess; /* Empty object allows all objects */
+            else if (x_json_object_get_count(value_object) < count)
+                return JSONFailure; /* Tested object mustn't have less name-value pairs than schema */
+            for (i = 0; i < count; i++) {
+                key = x_json_object_get_name(schema_object, i);
+                temp_schema_value = x_json_object_get_value(schema_object, key);
+                temp_value = x_json_object_get_value(value_object, key);
+                if (temp_value == NULL)
+                    return JSONFailure;
+                if (x_json_validate(temp_schema_value, temp_value) == JSONFailure)
+                    return JSONFailure;
+            }
+            return JSONSuccess;
+        case JSONString: case JSONNumber: case JSONBoolean: case JSONNull:
+            return JSONSuccess; /* equality already tested before switch */
+        case JSONError: default:
+            return JSONFailure;
+    }
+}
+
+x_JSON_Status x_json_value_equals(const x_JSON_Value *a, const x_JSON_Value *b) {
+    x_JSON_Object *a_object = NULL, *b_object = NULL;
+    x_JSON_Array *a_array = NULL, *b_array = NULL;
+    const char *a_string = NULL, *b_string = NULL;
+    const char *key = NULL;
+    size_t a_count = 0, b_count = 0, i = 0;
+    x_JSON_Value_Type a_type, b_type;
+    a_type = x_json_value_get_type(a);
+    b_type = x_json_value_get_type(b);
+    if (a_type != b_type) {
+        return 0;
+    }
+    switch (a_type) {
+        case JSONArray:
+            a_array = x_json_value_get_array(a);
+            b_array = x_json_value_get_array(b);
+            a_count = x_json_array_get_count(a_array);
+            b_count = x_json_array_get_count(b_array);
+            if (a_count != b_count) {
+                return 0;
+            }
+            for (i = 0; i < a_count; i++) {
+                if (!x_json_value_equals(x_json_array_get_value(a_array, i),
+                                       x_json_array_get_value(b_array, i))) {
+                    return 0;
+                }
+            }
+            return 1;
+        case JSONObject:
+            a_object = x_json_value_get_object(a);
+            b_object = x_json_value_get_object(b);
+            a_count = x_json_object_get_count(a_object);
+            b_count = x_json_object_get_count(b_object);
+            if (a_count != b_count) {
+                return 0;
+            }
+            for (i = 0; i < a_count; i++) {
+                key = x_json_object_get_name(a_object, i);
+                if (!x_json_value_equals(x_json_object_get_value(a_object, key),
+                                       x_json_object_get_value(b_object, key))) {
+                    return 0;
+                }
+            }
+            return 1;
+        case JSONString:
+            a_string = x_json_value_get_string(a);
+            b_string = x_json_value_get_string(b);
+            return strcmp(a_string, b_string) == 0;
+        case JSONBoolean:
+            return x_json_value_get_boolean(a) == x_json_value_get_boolean(b);
+        case JSONNumber:
+            return fabs(x_json_value_get_number(a) - x_json_value_get_number(b)) < 0.000001; /* EPSILON */
+        case JSONError:
+            return 1;
+        case JSONNull:
+            return 1;
+        default:
+            return 1;
+    }
+}
+
+x_JSON_Value_Type x_json_type(const x_JSON_Value *value) {
+    return x_json_value_get_type(value);
+}
+
+x_JSON_Object * x_json_object (const x_JSON_Value *value) {
+    return x_json_value_get_object(value);
+}
+
+x_JSON_Array * x_json_array  (const x_JSON_Value *value) {
+    return x_json_value_get_array(value);
+}
+
+const char * x_json_string (const x_JSON_Value *value) {
+    return x_json_value_get_string(value);
+}
+
+double x_json_number (const x_JSON_Value *value) {
+    return x_json_value_get_number(value);
+}
+
+int x_json_boolean(const x_JSON_Value *value) {
+    return x_json_value_get_boolean(value);
+}
+
+void x_json_set_allocation_functions(x_JSON_Malloc_Function malloc_fun, x_JSON_Free_Function free_fun) {
+    parson_malloc = malloc_fun;
+    parson_free = free_fun;
+}
diff --git a/c++/src/connect/parson.h b/c++/src/connect/parson.h
new file mode 100644
index 0000000..e905f41
--- /dev/null
+++ b/c++/src/connect/parson.h
@@ -0,0 +1,223 @@
+/*
+ Parson ( http://kgabis.github.com/parson/ )
+ Copyright (c) 2012 - 2016 Krzysztof Gabis
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#ifndef parson_parson_h
+#define parson_parson_h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stddef.h>   /* size_t */
+
+/* Types and enums */
+typedef struct x_json_object_t x_JSON_Object;
+typedef struct x_json_array_t  x_JSON_Array;
+typedef struct x_json_value_t  x_JSON_Value;
+
+enum x_json_value_type {
+    JSONError   = -1,
+    JSONNull    = 1,
+    JSONString  = 2,
+    JSONNumber  = 3,
+    JSONObject  = 4,
+    JSONArray   = 5,
+    JSONBoolean = 6
+};
+typedef int x_JSON_Value_Type;
+
+enum x_json_result_t {
+    JSONSuccess = 0,
+    JSONFailure = -1
+};
+typedef int x_JSON_Status;
+
+typedef void * (*x_JSON_Malloc_Function)(size_t);
+typedef void   (*x_JSON_Free_Function)(void *);
+
+/* Call only once, before calling any other function from parson API. If not called, malloc and free
+   from stdlib will be used for all allocations */
+void x_json_set_allocation_functions(x_JSON_Malloc_Function malloc_fun, x_JSON_Free_Function free_fun);
+
+/* Parses first JSON value in a file, returns NULL in case of error */
+x_JSON_Value * x_json_parse_file(const char *filename);
+
+/* Parses first JSON value in a file and ignores comments (/ * * / and //),
+   returns NULL in case of error */
+x_JSON_Value * x_json_parse_file_with_comments(const char *filename);
+
+/*  Parses first JSON value in a string, returns NULL in case of error */
+x_JSON_Value * x_json_parse_string(const char *string);
+
+/*  Parses first JSON value in a string and ignores comments (/ * * / and //),
+    returns NULL in case of error */
+x_JSON_Value * x_json_parse_string_with_comments(const char *string);
+
+/* Serialization */
+size_t      x_json_serialization_size(const x_JSON_Value *value); /* returns 0 on fail */
+x_JSON_Status x_json_serialize_to_buffer(const x_JSON_Value *value, char *buf, size_t buf_size_in_bytes);
+x_JSON_Status x_json_serialize_to_file(const x_JSON_Value *value, const char *filename);
+char *      x_json_serialize_to_string(const x_JSON_Value *value);
+
+/* Pretty serialization */
+size_t      x_json_serialization_size_pretty(const x_JSON_Value *value); /* returns 0 on fail */
+x_JSON_Status x_json_serialize_to_buffer_pretty(const  x_JSON_Value *value, char *buf, size_t buf_size_in_bytes);
+x_JSON_Status x_json_serialize_to_file_pretty(const  x_JSON_Value *value, const char *filename);
+char *      x_json_serialize_to_string_pretty(const  x_JSON_Value *value);
+
+void        x_json_free_serialized_string(char *string); /* frees string from json_serialize_to_string and json_serialize_to_string_pretty */
+
+/* Comparing */
+int  x_json_value_equals(const  x_JSON_Value *a, const  x_JSON_Value *b);
+
+/* Validation
+   This is *NOT* JSON Schema. It validates json by checking if object have identically
+   named fields with matching types.
+   For example schema {"name":"", "age":0} will validate
+   {"name":"Joe", "age":25} and {"name":"Joe", "age":25, "gender":"m"},
+   but not {"name":"Joe"} or {"name":"Joe", "age":"Cucumber"}.
+   In case of arrays, only first value in schema is checked against all values in tested array.
+   Empty objects ({}) validate all objects, empty arrays ([]) validate all arrays,
+   null validates values of every type.
+ */
+x_JSON_Status json_validate(const  x_JSON_Value *schema, const  x_JSON_Value *value);
+
+/*
+ * JSON Object
+ */
+x_JSON_Value  * x_json_object_get_value  (const x_JSON_Object *object, const char *name);
+const char  * x_json_object_get_string (const x_JSON_Object *object, const char *name);
+x_JSON_Object * x_json_object_get_object (const x_JSON_Object *object, const char *name);
+x_JSON_Array  * x_json_object_get_array  (const x_JSON_Object *object, const char *name);
+double        x_json_object_get_number (const x_JSON_Object *object, const char *name); /* returns 0 on fail */
+int           x_json_object_get_boolean(const x_JSON_Object *object, const char *name); /* returns -1 on fail */
+
+/* dotget functions enable addressing values with dot notation in nested objects,
+ just like in structs or c++/java/c# objects (e.g. objectA.objectB.value).
+ Because valid names in JSON can contain dots, some values may be inaccessible
+ this way. */
+x_JSON_Value  * x_json_object_dotget_value  (const x_JSON_Object *object, const char *name);
+const char  * x_json_object_dotget_string (const x_JSON_Object *object, const char *name);
+x_JSON_Object * x_json_object_dotget_object (const x_JSON_Object *object, const char *name);
+x_JSON_Array  * x_json_object_dotget_array  (const x_JSON_Object *object, const char *name);
+double        x_json_object_dotget_number (const x_JSON_Object *object, const char *name); /* returns 0 on fail */
+int           x_json_object_dotget_boolean(const x_JSON_Object *object, const char *name); /* returns -1 on fail */
+
+/* Functions to get available names */
+size_t        x_json_object_get_count   (const x_JSON_Object *object);
+const char  * x_json_object_get_name    (const x_JSON_Object *object, size_t index);
+x_JSON_Value  * x_json_object_get_value_at(const x_JSON_Object *object, size_t index);
+
+/* Creates new name-value pair or frees and replaces old value with a new one.
+ * json_object_set_value does not copy passed value so it shouldn't be freed afterwards. */
+x_JSON_Status x_json_object_set_value(x_JSON_Object *object, const char *name,  x_JSON_Value *value);
+x_JSON_Status x_json_object_set_string(x_JSON_Object *object, const char *name, const char *string);
+x_JSON_Status x_json_object_set_number(x_JSON_Object *object, const char *name, double number);
+x_JSON_Status x_json_object_set_boolean(x_JSON_Object *object, const char *name, int boolean);
+x_JSON_Status x_json_object_set_null(x_JSON_Object *object, const char *name);
+
+/* Works like dotget functions, but creates whole hierarchy if necessary.
+ * json_object_dotset_value does not copy passed value so it shouldn't be freed afterwards. */
+x_JSON_Status x_json_object_dotset_value(x_JSON_Object *object, const char *name,  x_JSON_Value *value);
+x_JSON_Status x_json_object_dotset_string(x_JSON_Object *object, const char *name, const char *string);
+x_JSON_Status x_json_object_dotset_number(x_JSON_Object *object, const char *name, double number);
+x_JSON_Status x_json_object_dotset_boolean(x_JSON_Object *object, const char *name, int boolean);
+x_JSON_Status x_json_object_dotset_null(x_JSON_Object *object, const char *name);
+
+/* Frees and removes name-value pair */
+x_JSON_Status x_json_object_remove(x_JSON_Object *object, const char *name);
+
+/* Works like dotget function, but removes name-value pair only on exact match. */
+x_JSON_Status x_json_object_dotremove(x_JSON_Object *object, const char *key);
+
+/* Removes all name-value pairs in object */
+x_JSON_Status x_json_object_clear(x_JSON_Object *object);
+
+/*
+ *JSON Array
+ */
+x_JSON_Value  * x_json_array_get_value  (const x_JSON_Array *array, size_t index);
+const char  * x_json_array_get_string (const x_JSON_Array *array, size_t index);
+x_JSON_Object * x_json_array_get_object (const x_JSON_Array *array, size_t index);
+x_JSON_Array  * x_json_array_get_array  (const x_JSON_Array *array, size_t index);
+double        x_json_array_get_number (const x_JSON_Array *array, size_t index); /* returns 0 on fail */
+int           x_json_array_get_boolean(const x_JSON_Array *array, size_t index); /* returns -1 on fail */
+size_t        x_json_array_get_count  (const x_JSON_Array *array);
+
+/* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist.
+ * Order of values in array may change during execution.  */
+x_JSON_Status json_array_remove(x_JSON_Array *array, size_t i);
+
+/* Frees and removes from array value at given index and replaces it with given one.
+ * Does nothing and returns JSONFailure if index doesn't exist.
+ * json_array_replace_value does not copy passed value so it shouldn't be freed afterwards. */
+x_JSON_Status x_json_array_replace_value(x_JSON_Array *array, size_t i,  x_JSON_Value *value);
+x_JSON_Status x_json_array_replace_string(x_JSON_Array *array, size_t i, const char* string);
+x_JSON_Status x_json_array_replace_number(x_JSON_Array *array, size_t i, double number);
+x_JSON_Status x_json_array_replace_boolean(x_JSON_Array *array, size_t i, int boolean);
+x_JSON_Status x_json_array_replace_null(x_JSON_Array *array, size_t i);
+
+/* Frees and removes all values from array */
+x_JSON_Status x_json_array_clear(x_JSON_Array *array);
+
+/* Appends new value at the end of array.
+ * json_array_append_value does not copy passed value so it shouldn't be freed afterwards. */
+x_JSON_Status x_json_array_append_value(x_JSON_Array *array,  x_JSON_Value *value);
+x_JSON_Status x_json_array_append_string(x_JSON_Array *array, const char *string);
+x_JSON_Status x_json_array_append_number(x_JSON_Array *array, double number);
+x_JSON_Status x_json_array_append_boolean(x_JSON_Array *array, int boolean);
+x_JSON_Status x_json_array_append_null(x_JSON_Array *array);
+
+/*
+ *JSON Value
+ */
+x_JSON_Value * x_json_value_init_object (void);
+x_JSON_Value * x_json_value_init_array  (void);
+x_JSON_Value * x_json_value_init_string (const char *string); /* copies passed string */
+x_JSON_Value * x_json_value_init_number (double number);
+x_JSON_Value * x_json_value_init_boolean(int boolean);
+x_JSON_Value * x_json_value_init_null   (void);
+x_JSON_Value * x_json_value_deep_copy   (const  x_JSON_Value *value);
+void         x_json_value_free        (x_JSON_Value *value);
+
+x_JSON_Value_Type x_json_value_get_type   (const  x_JSON_Value *value);
+x_JSON_Object *   x_json_value_get_object (const  x_JSON_Value *value);
+x_JSON_Array  *   x_json_value_get_array  (const  x_JSON_Value *value);
+const char  *   x_json_value_get_string (const  x_JSON_Value *value);
+double          x_json_value_get_number (const  x_JSON_Value *value);
+int             x_json_value_get_boolean(const  x_JSON_Value *value);
+
+/* Same as above, but shorter */
+x_JSON_Value_Type x_json_type   (const  x_JSON_Value *value);
+x_JSON_Object *   x_json_object (const  x_JSON_Value *value);
+x_JSON_Array  *   x_json_array  (const  x_JSON_Value *value);
+const char  *   x_json_string (const  x_JSON_Value *value);
+double          x_json_number (const  x_JSON_Value *value);
+int             x_json_boolean(const  x_JSON_Value *value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c++/src/connect/server.cpp b/c++/src/connect/server.cpp
index 7fb6ff6..a28f0c1 100644
--- a/c++/src/connect/server.cpp
+++ b/c++/src/connect/server.cpp
@@ -1,4 +1,4 @@
-/* $Id: server.cpp 467185 2015-05-11 14:50:34Z sadyrovr $
+/* $Id: server.cpp 506707 2016-07-11 15:26:50Z satskyse $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -54,11 +54,12 @@ static CSafeStatic<TParamServerCatchExceptions> s_ServerCatchExceptions;
 // IServer_MessageHandler implementation
 void IServer_MessageHandler::OnRead(void)
 {
-    CSocket &socket = GetSocket();
-    CServer_Connection* conn = static_cast<CServer_Connection*>(&socket);
-    char read_buf[4096];
-    size_t n_read;
-    EIO_Status status = socket.Read(read_buf, sizeof(read_buf), &n_read);
+    CSocket &               socket = GetSocket();
+    CServer_Connection *    conn = static_cast<CServer_Connection*>(&socket);
+    char                    read_buf[4096];
+    size_t                  n_read;
+    EIO_Status              status = socket.Read(read_buf, sizeof(read_buf),
+                                                 &n_read);
     switch (status) {
     case eIO_Success:
         break;
@@ -69,19 +70,27 @@ void IServer_MessageHandler::OnRead(void)
         this->OnClose(IServer_ConnectionHandler::eClientClose);
         return;
     default:
-        // TODO: ??? OnError
+        string      err_message("Error reading from the client socket (");
+
+        err_message += socket.GetPeerAddress() + "): " +
+                       string(IO_StatusStr(status)) + "(" +
+                       NStr::NumericToString(static_cast<int>(status)) + ")";
+
+        this->OnError(err_message);
         return;
     }
-    int message_tail;
-    char *buf_ptr = read_buf;
+
+    int         message_tail;
+    char *      buf_ptr = read_buf;
     for ( ;n_read > 0  &&  conn->type == eActiveSocket; ) {
         message_tail = this->CheckMessage(&m_Buffer, buf_ptr, n_read);
+
         // TODO: what should we do if message_tail > n_read?
         if (message_tail < 0) {
             return;
-        } else {
-            this->OnMessage(m_Buffer);
         }
+
+        this->OnMessage(m_Buffer);
         int consumed = int(n_read) - message_tail;
         buf_ptr += consumed;
         n_read -= consumed;
@@ -117,12 +126,12 @@ CBlockingQueue_ForServer::Put(const TRequest& data)
 {
     CMutexGuard guard(m_Mutex);
     if (m_Queue.empty()) {
-#ifdef NCBI_HAVE_CONDITIONAL_VARIABLE
+        #ifdef NCBI_HAVE_CONDITIONAL_VARIABLE
         m_GetCond.SignalAll();
-#else
+        #else
         m_GetSem.TryWait(); // is this still needed?
         m_GetSem.Post();
-#endif
+        #endif
     }
     TItemHandle handle(new CQueueItem(data));
     m_Queue.push_back(handle);
@@ -135,22 +144,23 @@ CBlockingQueue_ForServer::GetHandle(void)
     CMutexGuard guard(m_Mutex);
 
     while (m_Queue.empty()) {
-#ifdef NCBI_HAVE_CONDITIONAL_VARIABLE
+        #ifdef NCBI_HAVE_CONDITIONAL_VARIABLE
         m_GetCond.WaitForSignal(m_Mutex);
-#else
+        #else
         m_GetSem.TryWait();
         m_GetSem.Post();
-#endif
+        #endif
     }
 
     TItemHandle handle(m_Queue.front());
     m_Queue.pop_front();
-#ifndef NCBI_HAVE_CONDITIONAL_VARIABLE
+
+    #ifndef NCBI_HAVE_CONDITIONAL_VARIABLE
     if (!m_Queue.empty()) {
         m_GetSem.TryWait();
         m_GetSem.Post();
     }
-#endif
+    #endif
 
     guard.Release(); // avoid possible deadlocks from x_SetStatus
     handle->x_SetStatus(CQueueItemBase::eActive);
@@ -195,7 +205,7 @@ CThreadInPool_ForServer::x_HandleOneRequest(bool catch_all)
     if (catch_all) {
         try {
             ProcessRequest(handle);
-        } catch (std::exception& e) {
+        } catch (const std::exception &  e) {
             handle->MarkAsForciblyCaught();
             NCBI_REPORT_EXCEPTION_X(9, "Exception from thread in pool: ", e);
             // throw;
@@ -250,18 +260,6 @@ CPoolOfThreads_ForServer::CPoolOfThreads_ForServer(unsigned int max_threads,
       m_KilledAll(false)
 {
     m_ThreadCount.Set(0);
-    m_PutQueueNum.Set(0);
-    m_GetQueueNum.Set(0);
-
-    // The original developer used malloc(...) here to allocate the required
-    // number of bytes for an array. It is unknown why that decision was made.
-    // Later on it was decided to replace malloc(...) with new to have a pure
-    // C++ style in the code.
-    m_Queues = (TQueue**) new char[m_MaxThreads * sizeof(m_Queues[0])];
-
-    for (TACValue i = 0; i < m_MaxThreads; ++i) {
-        m_Queues[i] = new TQueue();
-    }
 }
 
 CPoolOfThreads_ForServer::~CPoolOfThreads_ForServer(void)
@@ -272,17 +270,10 @@ CPoolOfThreads_ForServer::~CPoolOfThreads_ForServer(void)
 
     CAtomicCounter::TValue n = m_ThreadCount.Get();
     if (n) {
-        ERR_POST_X(10, Warning << "CPoolOfThreads_ForServer::~CPoolOfThreads_ForServer: "
-                               << n << " thread(s) still active");
-    } else {
-        // It seems to be safe to destroy the allocated array if all the
-        // threads were stopped.
-        for (TACValue i = 0; i < m_MaxThreads; ++i) {
-            delete m_Queues[i];
-        }
-        delete [] (char *)(m_Queues);
+        ERR_POST_X(10, Warning
+                   << "CPoolOfThreads_ForServer::~CPoolOfThreads_ForServer: "
+                   << n << " thread(s) still active");
     }
-    // Just in case let's deliberately not destroy all queues.
 }
 
 void
@@ -299,15 +290,13 @@ CPoolOfThreads_ForServer::Spawn(unsigned int num_threads)
 void
 CPoolOfThreads_ForServer::AcceptRequest(const TRequest& req)
 {
-    Uint4 q_num = Uint4(m_PutQueueNum.Add(1)) % m_MaxThreads;
-    m_Queues[q_num]->Put(req);
+    m_Queue.Put(req);
 }
 
 CPoolOfThreads_ForServer::TItemHandle
 CPoolOfThreads_ForServer::GetHandle(void)
 {
-    Uint4 q_num = Uint4(m_GetQueueNum.Add(1)) % m_MaxThreads;
-    return m_Queues[q_num]->GetHandle();
+    return m_Queue.GetHandle();
 }
 
 
@@ -638,6 +627,12 @@ void CServer::AddListener(IServer_ConnectionFactory* factory,
 }
 
 
+bool CServer::RemoveListener(unsigned short  port)
+{
+    return m_ConnectionPool->RemoveListener(port);
+}
+
+
 void CServer::SetParameters(const SServer_Parameters& new_params)
 {
     if (new_params.init_threads <= 0  ||
@@ -685,12 +680,10 @@ void CServer::x_DoRun(void)
     vector<CSocketAPI::SPoll> polls;
     size_t     count;
     typedef vector<IServer_ConnectionBase*> TConnsList;
-    typedef vector<CRef<CStdRequest> > TReqsList;
     TConnsList timer_requests;
     TConnsList revived_conns;
     TConnsList to_close_conns;
     TConnsList to_delete_conns;
-    TReqsList to_add_reqs;
     STimeout timer_timeout;
     const STimeout* timeout;
 
@@ -706,24 +699,22 @@ void CServer::x_DoRun(void)
             CRef<CStdRequest> req(conn_base->CreateRequest(
                                                 evt, *m_ConnectionPool,
                                                 m_Parameters->idle_timeout));
-            to_add_reqs.push_back(req);
+            m_ThreadPool->AcceptRequest(req);
         }
         ITERATE(TConnsList, it, to_close_conns) {
             IServer_ConnectionBase* conn_base = *it;
             CRef<CStdRequest> req(conn_base->CreateRequest(
                                                 eServIO_Inactivity, *m_ConnectionPool,
                                                 m_Parameters->idle_timeout));
-            to_add_reqs.push_back(req);
+            m_ThreadPool->AcceptRequest(req);
         }
         ITERATE(TConnsList, it, to_delete_conns) {
             IServer_ConnectionBase* conn_base = *it;
             CRef<CStdRequest> req(conn_base->CreateRequest(
                                                 eServIO_Delete, *m_ConnectionPool,
                                                 m_Parameters->idle_timeout));
-            to_add_reqs.push_back(req);
+            m_ThreadPool->AcceptRequest(req);
         }
-        x_AddRequests(to_add_reqs);
-        to_add_reqs.clear();
 
         timeout = m_Parameters->accept_timeout;
 
@@ -767,17 +758,22 @@ void CServer::x_DoRun(void)
                     IServer_ConnectionBase* conn_base = *it;
                     CRef<CStdRequest> req(conn_base->CreateRequest(
                                           (EServIO_Event)-1, *m_ConnectionPool, timeout));
-                    to_add_reqs.push_back(req);
+                    m_ThreadPool->AcceptRequest(req);
                 }
-                x_AddRequests(to_add_reqs);
-                to_add_reqs.clear();
             }
             continue;
         }
 
         m_ConnectionPool->SetAllActive(polls);
         ITERATE (vector<CSocketAPI::SPoll>, it, polls) {
-            if (!it->m_REvent) continue;
+            if (!it->m_REvent)
+                continue;
+            CTrigger *      trigger = dynamic_cast<CTrigger *>(it->m_Pollable);
+            if (trigger) {
+                trigger->Reset();
+                continue;
+            }
+
             IServer_ConnectionBase* conn_base =
                 dynamic_cast<IServer_ConnectionBase*>(it->m_Pollable);
             _ASSERT(conn_base);
@@ -785,11 +781,8 @@ void CServer::x_DoRun(void)
                                                 IOEventToServIOEvent(it->m_REvent),
                                                 *m_ConnectionPool,
                                                 m_Parameters->idle_timeout));
-            if (req)
-                to_add_reqs.push_back(req);
+            m_ThreadPool->AcceptRequest(req);
         }
-        x_AddRequests(to_add_reqs);
-        to_add_reqs.clear();
     }
 }
 
@@ -802,7 +795,7 @@ void CServer::Run(void)
     if (s_ServerCatchExceptions->Get()) {
         try {
             x_DoRun();
-        } catch (CException& ex) {
+        } catch (const CException &  ex) {
             ERR_POST(ex);
             // Avoid collateral damage from destroying the thread pool
             // while worker threads are active (or, worse, initializing).
@@ -846,23 +839,6 @@ void CServer::DeferConnectionProcessing(CSocket* sock)
 }
 
 
-void CServer::Init()
-{
-}
-
-
-void CServer::Exit()
-{
-}
-
-
-void CServer::x_AddRequests(const vector<CRef<CStdRequest> >& reqs)
-{
-    ITERATE(vector<CRef<CStdRequest> >, it, reqs) {
-        m_ThreadPool->AcceptRequest(*it);
-    }
-}
-
 void CServer::AddConnectionToPool(CServer_Connection* conn)
 {
     if (!m_ConnectionPool->Add(conn, eInactiveSocket)) {
@@ -881,6 +857,11 @@ void CServer::WakeUpPollCycle(void)
     m_ConnectionPool->PingControlConnection();
 }
 
+vector<unsigned short>  CServer::GetListenerPorts(void)
+{
+    return m_ConnectionPool->GetListenerPorts();
+}
+
 /////////////////////////////////////////////////////////////////////////////
 // SServer_Parameters implementation
 
diff --git a/c++/src/connect/services/Makefile.xconnserv.lib b/c++/src/connect/services/Makefile.xconnserv.lib
index b53185b..52ff3b4 100644
--- a/c++/src/connect/services/Makefile.xconnserv.lib
+++ b/c++/src/connect/services/Makefile.xconnserv.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.xconnserv.lib 485672 2015-11-24 20:44:56Z sadyrovr $
+# $Id: Makefile.xconnserv.lib 520437 2016-11-28 18:35:09Z ivanov $
 
 SRC     = grid_worker ns_client_factory grid_worker_app \
           grid_client grid_client_app \
@@ -11,7 +11,7 @@ SRC     = grid_worker ns_client_factory grid_worker_app \
           netschedule_api_reader netschedule_api_admin netschedule_api_getjob \
           netschedule_key netschedule_api_expt \
           netcache_key netcache_rw netcache_params netcache_api \
-          netcache_api_admin \
+          netcache_api_admin netcache_search \
           netservice_protocol_parser util clparser \
           json_over_uttp netstorage netstorage_rpc \
           netstorageobjectloc netstorageobjectinfo netstorage_direct_nc \
diff --git a/c++/src/connect/services/grid_client.cpp b/c++/src/connect/services/grid_client.cpp
index 4c9f4b3..34bda8c 100644
--- a/c++/src/connect/services/grid_client.cpp
+++ b/c++/src/connect/services/grid_client.cpp
@@ -1,4 +1,4 @@
-/*  $Id: grid_client.cpp 492603 2016-02-18 19:27:56Z ivanov $
+/*  $Id: grid_client.cpp 492431 2016-02-17 17:05:04Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/connect/services/grid_control_thread.cpp b/c++/src/connect/services/grid_control_thread.cpp
index b88b68c..3063da1 100644
--- a/c++/src/connect/services/grid_control_thread.cpp
+++ b/c++/src/connect/services/grid_control_thread.cpp
@@ -1,4 +1,4 @@
-/*  $Id: grid_control_thread.cpp 491697 2016-02-08 18:44:39Z ivanov $
+/*  $Id: grid_control_thread.cpp 491506 2016-02-05 16:08:02Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/connect/services/grid_worker.cpp b/c++/src/connect/services/grid_worker.cpp
index 647107e..d055394 100644
--- a/c++/src/connect/services/grid_worker.cpp
+++ b/c++/src/connect/services/grid_worker.cpp
@@ -1,4 +1,4 @@
-/*  $Id: grid_worker.cpp 499332 2016-04-25 17:42:11Z ivanov $
+/*  $Id: grid_worker.cpp 509503 2016-08-05 19:09:23Z fukanchi $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -420,31 +420,31 @@ void SGridWorkerNodeImpl::x_WNCoreInit()
         }
     }
     m_NSTimeout = reg.GetInt(kServerSec,
-            "job_wait_timeout", DEFAULT_NS_TIMEOUT, 0, IRegistry::eReturn);
+            "job_wait_timeout", DEFAULT_NS_TIMEOUT, 0, IRegistry::eErrPost);
 
     {{
         string memlimitstr(reg.GetString(kServerSec,
-                "total_memory_limit", kEmptyStr, IRegistry::eReturn));
+                "total_memory_limit", kEmptyStr));
 
         if (!memlimitstr.empty())
             m_TotalMemoryLimit = NStr::StringToUInt8_DataSize(memlimitstr);
     }}
 
     m_TotalTimeLimit = reg.GetInt(kServerSec,
-            "total_time_limit", 0, 0, IRegistry::eReturn);
+            "total_time_limit", 0, 0, IRegistry::eErrPost);
 
     m_StartupTime = time(0);
 
     CGridGlobals::GetInstance().SetReuseJobObject(reg.GetBool(kServerSec,
-        "reuse_job_object", false, 0, CNcbiRegistry::eReturn));
+        "reuse_job_object", false, 0, CNcbiRegistry::eErrPost));
     CGridGlobals::GetInstance().SetWorker(this);
 
     m_LogRequested = reg.GetBool(kServerSec,
-        "log", false, 0, IRegistry::eReturn);
+        "log", false, 0, IRegistry::eErrPost);
     m_ProgressLogRequested = reg.GetBool(kServerSec,
-        "log_progress", false, 0, IRegistry::eReturn);
+        "log_progress", false, 0, IRegistry::eErrPost);
     m_ThreadPoolTimeout = reg.GetInt(kServerSec,
-        "thread_pool_timeout", 30, 0, IRegistry::eReturn);
+        "thread_pool_timeout", 30, 0, IRegistry::eErrPost);
 }
 
 void SGridWorkerNodeImpl::x_StartWorkerThreads()
@@ -456,7 +456,7 @@ void SGridWorkerNodeImpl::x_StartWorkerThreads()
 
     try {
         unsigned init_threads = m_App.GetConfig().GetInt("server",
-                "init_threads", 1, 0, IRegistry::eReturn);
+                "init_threads", 1, 0, IRegistry::eErrPost);
 
         m_ThreadPool->Spawn(init_threads <= m_MaxThreads ?
                 init_threads : m_MaxThreads);
@@ -543,7 +543,7 @@ int SGridWorkerNodeImpl::Run(
 
 #ifdef NCBI_OS_UNIX
     bool is_daemon = daemonize != eDefault ? daemonize == eOn :
-            reg.GetBool(kServerSec, "daemon", false, 0, CNcbiRegistry::eReturn);
+            reg.GetBool(kServerSec, "daemon", false, 0, CNcbiRegistry::eErrPost);
 #endif
 
     vector<string> vhosts;
@@ -571,17 +571,17 @@ int SGridWorkerNodeImpl::Run(
     }
 
     m_CommitJobInterval = reg.GetInt(kServerSec, "commit_job_interval",
-            COMMIT_JOB_INTERVAL_DEFAULT, 0, IRegistry::eReturn);
+            COMMIT_JOB_INTERVAL_DEFAULT, 0, IRegistry::eErrPost);
     if (m_CommitJobInterval == 0)
         m_CommitJobInterval = 1;
 
     m_CheckStatusPeriod = reg.GetInt(kServerSec,
-            "check_status_period", 2, 0, IRegistry::eReturn);
+            "check_status_period", 2, 0, IRegistry::eErrPost);
     if (m_CheckStatusPeriod == 0)
         m_CheckStatusPeriod = 1;
 
     m_DefaultPullbackTimeout = reg.GetInt(kServerSec,
-            "default_pullback_timeout", 0, 0, IRegistry::eReturn);
+            "default_pullback_timeout", 0, 0, IRegistry::eErrPost);
 
     if (reg.HasEntry(kServerSec, "wait_server_timeout")) {
         ERR_POST_X(52, "[" << kServerSec <<
@@ -671,7 +671,7 @@ int SGridWorkerNodeImpl::Run(
 
 #ifdef NCBI_OS_UNIX
     bool reliable_cleanup = reg.GetBool(kServerSec,
-            "reliable_cleanup", false, 0, CNcbiRegistry::eReturn);
+            "reliable_cleanup", false, 0, CNcbiRegistry::eErrPost);
 
     if (reliable_cleanup) {
         TPid child_pid = CProcess::Fork();
@@ -754,27 +754,27 @@ int SGridWorkerNodeImpl::Run(
     }
 
     m_JobsPerClientIP.ResetJobCounter((unsigned) reg.GetInt(kServerSec,
-            "max_jobs_per_client_ip", 0, 0, IRegistry::eReturn));
+            "max_jobs_per_client_ip", 0, 0, IRegistry::eErrPost));
     m_JobsPerSessionID.ResetJobCounter((unsigned) reg.GetInt(kServerSec,
-            "max_jobs_per_session_id", 0, 0, IRegistry::eReturn));
+            "max_jobs_per_session_id", 0, 0, IRegistry::eErrPost));
 
     CWNJobWatcher& watcher(CGridGlobals::GetInstance().GetJobWatcher());
     watcher.SetMaxJobsAllowed(reg.GetInt(kServerSec,
-            "max_total_jobs", 0, 0, IRegistry::eReturn));
+            "max_total_jobs", 0, 0, IRegistry::eErrPost));
     watcher.SetMaxFailuresAllowed(reg.GetInt(kServerSec,
-            "max_failed_jobs", 0, 0, IRegistry::eReturn));
+            "max_failed_jobs", 0, 0, IRegistry::eErrPost));
     watcher.SetInfiniteLoopTime(reg.GetInt(kServerSec,
-            "infinite_loop_time", 0, 0, IRegistry::eReturn));
+            "infinite_loop_time", 0, 0, IRegistry::eErrPost));
     CGridGlobals::GetInstance().SetUDPPort(
             m_NSExecutor->m_NotificationHandler.GetPort());
 
     IWorkerNodeIdleTask* task = NULL;
 
     unsigned idle_run_delay = reg.GetInt(kServerSec,
-        "idle_run_delay", 30, 0, IRegistry::eReturn);
+        "idle_run_delay", 30, 0, IRegistry::eErrPost);
 
     unsigned auto_shutdown = reg.GetInt(kServerSec,
-        "auto_shutdown_if_idle", 0, 0, IRegistry::eReturn);
+        "auto_shutdown_if_idle", 0, 0, IRegistry::eErrPost);
 
     if (idle_run_delay > 0)
         task = m_JobProcessorFactory->GetIdleTask();
@@ -813,7 +813,7 @@ int SGridWorkerNodeImpl::Run(
     LOG_POST_X(31, Info << "Shutting down...");
 
     bool force_exit = reg.GetBool(kServerSec,
-            "force_exit", false, 0, CNcbiRegistry::eReturn);
+            "force_exit", false, 0, CNcbiRegistry::eErrPost);
     if (force_exit) {
         ERR_POST_X(45, "Force exit (worker threads will not be waited for)");
     } else
diff --git a/c++/src/connect/services/grid_worker_app.cpp b/c++/src/connect/services/grid_worker_app.cpp
index 75c18f2..6c5c1e6 100644
--- a/c++/src/connect/services/grid_worker_app.cpp
+++ b/c++/src/connect/services/grid_worker_app.cpp
@@ -1,4 +1,4 @@
-/*  $Id: grid_worker_app.cpp 491697 2016-02-08 18:44:39Z ivanov $
+/*  $Id: grid_worker_app.cpp 491506 2016-02-05 16:08:02Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/connect/services/grid_worker_impl.hpp b/c++/src/connect/services/grid_worker_impl.hpp
index 76fb181..4ce913e 100644
--- a/c++/src/connect/services/grid_worker_impl.hpp
+++ b/c++/src/connect/services/grid_worker_impl.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES__GRID_WORKER_IMPL__HPP
 #define CONNECT_SERVICES__GRID_WORKER_IMPL__HPP
 
-/*  $Id: grid_worker_impl.hpp 488742 2016-01-05 15:56:22Z sadyrovr $
+/*  $Id: grid_worker_impl.hpp 518714 2016-11-07 18:04:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,12 +32,13 @@
  *    Common NetSchedule Worker Node declarations
  */
 
-#include <corelib/hash_set.hpp>
 
 #include "wn_commit_thread.hpp"
 #include "wn_cleanup.hpp"
 #include "netschedule_api_impl.hpp"
 
+#include <unordered_set>
+
 BEGIN_NCBI_SCOPE
 
 /////////////////////////////////////////////////////////////////////////////
@@ -273,7 +274,7 @@ struct SGridWorkerNodeImpl : public CObject
 
     private:
         CFastMutex m_Mutex;
-        hash_set<string> m_Ids;
+        unordered_set<string> m_Ids;
     };
 
     SJobsInProgress m_JobsInProgress;
@@ -345,6 +346,7 @@ private:
         bool CheckEntry(
                 SEntry& entry,
                 const string& prio_aff_list,
+                bool any_affinity,
                 CNetScheduleJob& job,
                 CNetScheduleAPI::EJobStatus* job_status);
         void ReturnJob(CNetScheduleJob& job);
diff --git a/c++/src/connect/services/json_over_uttp.cpp b/c++/src/connect/services/json_over_uttp.cpp
index 36c7526..8c37858 100644
--- a/c++/src/connect/services/json_over_uttp.cpp
+++ b/c++/src/connect/services/json_over_uttp.cpp
@@ -1,4 +1,4 @@
-/*  $Id: json_over_uttp.cpp 495785 2016-03-21 16:50:59Z ivanov $
+/*  $Id: json_over_uttp.cpp 502217 2016-05-23 15:32:11Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -40,6 +40,49 @@
 
 BEGIN_NCBI_SCOPE
 
+class CJsonParser
+{
+public:
+    CJsonNode ParseObject(const string& ns_output)
+    {
+        m_Ch = (m_NSOutput = ns_output).c_str();
+
+        return ParseObject('\0');
+    }
+
+    CJsonNode ParseArray(const string& ns_output)
+    {
+        m_Ch = (m_NSOutput = ns_output).c_str();
+
+        return ParseArray('\0');
+    }
+
+    CJsonNode ParseJSON(const string& json);
+
+private:
+    size_t GetRemainder() const
+    {
+        return m_NSOutput.length() - (m_Ch - m_NSOutput.data());
+    }
+
+    size_t GetPosition() const
+    {
+        return m_Ch - m_NSOutput.data() + 1;
+    }
+
+    string ParseString(size_t max_len);
+    Int8 ParseInt(size_t len);
+    double ParseDouble(size_t len);
+    bool MoreNodes();
+
+    CJsonNode ParseObject(char closing_char);
+    CJsonNode ParseArray(char closing_char);
+    CJsonNode ParseValue();
+
+    string m_NSOutput;
+    const char* m_Ch;
+};
+
 const char* CJsonException::GetErrCodeString() const
 {
     switch (GetErrCode()) {
@@ -911,6 +954,261 @@ string CJsonNode::Repr(TReprFlags flags) const
     return CNcbiOstrstreamToString(oss);
 }
 
+#define INVALID_FORMAT_ERROR() \
+    NCBI_THROW2(CStringException, eFormat, \
+            (*m_Ch == '\0' ? "Unexpected end of output" : \
+                    "Syntax error in structured output"), \
+            GetPosition())
+
+CJsonNode CJsonParser::ParseJSON(const string& json)
+{
+    m_Ch = (m_NSOutput = json).c_str();
+
+    while (isspace((unsigned char) *m_Ch))
+        ++m_Ch;
+
+    CJsonNode root;
+
+    switch (*m_Ch) {
+    case '[':
+        ++m_Ch;
+        root = ParseArray(']');
+        break;
+
+    case '{':
+        ++m_Ch;
+        root = ParseObject('}');
+        break;
+
+    default:
+        INVALID_FORMAT_ERROR();
+    }
+
+    while (isspace((unsigned char) *m_Ch))
+        ++m_Ch;
+
+    if (*m_Ch != '\0') {
+        INVALID_FORMAT_ERROR();
+    }
+
+    return root;
+}
+
+string CJsonParser::ParseString(size_t max_len)
+{
+    size_t len;
+    string val(NStr::ParseQuoted(CTempString(m_Ch, max_len), &len));
+
+    m_Ch += len;
+    return val;
+}
+
+Int8 CJsonParser::ParseInt(size_t len)
+{
+    Int8 val = NStr::StringToInt8(CTempString(m_Ch, len));
+
+    if (*m_Ch == '-') {
+        ++m_Ch;
+        --len;
+    }
+    if (*m_Ch == '0' && len > 1) {
+        NCBI_THROW2(CStringException, eFormat,
+                "Leading zeros are not allowed", GetPosition());
+    }
+
+    m_Ch += len;
+    return val;
+}
+
+double CJsonParser::ParseDouble(size_t len)
+{
+    double val = NStr::StringToDouble(CTempString(m_Ch, len));
+
+    m_Ch += len;
+    return val;
+}
+
+bool CJsonParser::MoreNodes()
+{
+    while (isspace((unsigned char) *m_Ch))
+        ++m_Ch;
+    if (*m_Ch != ',')
+        return false;
+    while (isspace((unsigned char) *++m_Ch))
+        ;
+    return true;
+}
+
+CJsonNode CJsonParser::ParseObject(char closing_char)
+{
+    CJsonNode result(CJsonNode::NewObjectNode());
+
+    while (isspace((unsigned char) *m_Ch))
+        ++m_Ch;
+
+    if (*m_Ch == closing_char) {
+        ++m_Ch;
+        return result;
+    }
+
+    while (*m_Ch == '\'' || *m_Ch == '"') {
+        // New attribute/value pair
+        string attr_name(ParseString(GetRemainder()));
+
+        while (isspace((unsigned char) *m_Ch))
+            ++m_Ch;
+        if (*m_Ch == ':' || *m_Ch == '=')
+            while (isspace((unsigned char) *++m_Ch))
+                ;
+
+        result.SetByKey(attr_name, ParseValue());
+
+        if (!MoreNodes()) {
+            if (*m_Ch != closing_char)
+                break;
+            ++m_Ch;
+            return result;
+        }
+    }
+
+    INVALID_FORMAT_ERROR();
+}
+
+CJsonNode CJsonParser::ParseArray(char closing_char)
+{
+    CJsonNode result(CJsonNode::NewArrayNode());
+
+    while (isspace((unsigned char) *m_Ch))
+        ++m_Ch;
+
+    if (*m_Ch == closing_char) {
+        ++m_Ch;
+        return result;
+    }
+
+    do
+        result.Append(ParseValue());
+    while (MoreNodes());
+
+    if (*m_Ch == closing_char) {
+        ++m_Ch;
+        return result;
+    }
+
+    INVALID_FORMAT_ERROR();
+}
+
+CJsonNode CJsonParser::ParseValue()
+{
+    size_t max_len = GetRemainder();
+    size_t len = 0;
+
+    switch (*m_Ch) {
+    /* Array */
+    case '[':
+        ++m_Ch;
+        return ParseArray(']');
+
+    /* Object */
+    case '{':
+        ++m_Ch;
+        return ParseObject('}');
+
+    /* String */
+    case '\'':
+    case '"':
+        return CJsonNode::NewStringNode(ParseString(max_len));
+
+    /* Number */
+    case '-':
+        // Check that there's at least one digit after the minus sign.
+        if (max_len <= 1 || !isdigit((unsigned char) m_Ch[1])) {
+            ++m_Ch;
+            break;
+        }
+        len = 1;
+
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+        // Skim through the integer part.
+        do
+            if (++len >= max_len)
+                return CJsonNode::NewIntegerNode(ParseInt(len));
+        while (isdigit((unsigned char) m_Ch[len]));
+
+        // Stumbled upon a non-digit character -- check
+        // if it's a fraction part or an exponent part.
+        switch (m_Ch[len]) {
+        case '.':
+            if (++len == max_len || !isdigit((unsigned char) m_Ch[len])) {
+                NCBI_THROW2(CStringException, eFormat,
+                        "At least one digit after the decimal "
+                        "point is required", GetPosition());
+            }
+            for (;;) {
+                if (++len == max_len)
+                    return CJsonNode::NewDoubleNode(ParseDouble(len));
+
+                if (!isdigit((unsigned char) m_Ch[len])) {
+                    if (m_Ch[len] == 'E' || m_Ch[len] == 'e')
+                        break;
+
+                    return CJsonNode::NewDoubleNode(ParseDouble(len));
+                }
+            }
+            /* FALL THROUGH */
+
+        case 'E':
+        case 'e':
+            if (++len == max_len ||
+                    (m_Ch[len] == '-' || m_Ch[len] == '+' ?
+                            ++len == max_len ||
+                                    !isdigit((unsigned char) m_Ch[len]) :
+                            !isdigit((unsigned char) m_Ch[len]))) {
+                m_Ch += len;
+                NCBI_THROW2(CStringException, eFormat,
+                        "Invalid exponent specification", GetPosition());
+            }
+            while (++len < max_len && isdigit((unsigned char) m_Ch[len]))
+                ;
+            return CJsonNode::NewDoubleNode(ParseDouble(len));
+
+        default:
+            return CJsonNode::NewIntegerNode(ParseInt(len));
+        }
+
+    /* Constant */
+    case 'F': case 'f': case 'N': case 'n':
+    case 'T': case 't': case 'Y': case 'y':
+        while (len <= max_len && isalpha((unsigned char) m_Ch[len]))
+            ++len;
+
+        {
+            CTempString val(m_Ch, len);
+            m_Ch += len;
+            return val == "null" ? CJsonNode::NewNullNode() :
+                CJsonNode::NewBooleanNode(NStr::StringToBool(val));
+        }
+    }
+
+    INVALID_FORMAT_ERROR();
+}
+
+CJsonNode CJsonNode::ParseObject(const string& json)
+{
+    return CJsonParser().ParseObject(json);
+}
+
+CJsonNode CJsonNode::ParseArray(const string& json)
+{
+    return CJsonParser().ParseArray(json);
+}
+
+CJsonNode CJsonNode::ParseJSON(const string& json)
+{
+    return CJsonParser().ParseJSON(json);
+}
+
 const char* CJsonOverUTTPException::GetErrCodeString() const
 {
     switch (GetErrCode()) {
diff --git a/c++/src/connect/services/netcache_api.cpp b/c++/src/connect/services/netcache_api.cpp
index 4666016..b5b4111 100644
--- a/c++/src/connect/services/netcache_api.cpp
+++ b/c++/src/connect/services/netcache_api.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netcache_api.cpp 497256 2016-04-05 15:59:16Z ivanov $
+/*  $Id: netcache_api.cpp 520436 2016-11-28 18:34:35Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -174,6 +174,9 @@ void CNetCacheServerListener::OnInit(CObject* api_impl,
                 }
             }
         }
+
+        nc_impl->m_ProlongBlobLifetimeOnWrite = config->GetBool(config_section,
+                "prolong_blob_lifetime_on_write", CConfig::eErr_NoThrow, true);
     } else {
         nc_impl->m_TempDir = default_temp_dir;
         nc_impl->m_CacheInput = false;
@@ -568,6 +571,7 @@ CNetServerConnection SNetCacheAPIImpl::InitiateWriteCmd(
 
     m_UseNextSubHitID.ProperCommand();
     AppendClientIPSessionIDPasswordAgeHitID(&cmd, parameters);
+    if (!m_ProlongBlobLifetimeOnWrite) cmd.append(" flags=1");
 
     CNetServer::SExecResult exec_result;
 
diff --git a/c++/src/connect/services/netcache_api_impl.hpp b/c++/src/connect/services/netcache_api_impl.hpp
index 382449b..1d820fa 100644
--- a/c++/src/connect/services/netcache_api_impl.hpp
+++ b/c++/src/connect/services/netcache_api_impl.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES___NETCACHE_API_IMPL__HPP
 #define CONNECT_SERVICES___NETCACHE_API_IMPL__HPP
 
-/*  $Id: netcache_api_impl.hpp 492602 2016-02-18 19:27:34Z ivanov $
+/*  $Id: netcache_api_impl.hpp 520437 2016-11-28 18:35:09Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -33,6 +33,7 @@
 
 #include "netcache_rw.hpp"
 #include "netservice_api_impl.hpp"
+#include <connect/services/netcache_search.hpp>
 
 BEGIN_NCBI_SCOPE
 
@@ -140,6 +141,7 @@ struct NCBI_XCONNECT_EXPORT SNetCacheAPIImpl : public CObject
     CCompoundIDPool m_CompoundIDPool;
 
     SUseNextSubHitID m_UseNextSubHitID;
+    bool m_ProlongBlobLifetimeOnWrite = true;
 };
 
 struct SNetCacheAdminImpl : public CObject
@@ -176,6 +178,18 @@ public:
     bool m_PrimaryServerCheck;
 };
 
+namespace grid {
+namespace netcache {
+namespace search {
+
+NCBI_XCONNECT_EXPORT CExpression operator+(CExpression l, CFields r);
+NCBI_XCONNECT_EXPORT ostream& operator<<(ostream& os, CExpression expression);
+NCBI_XCONNECT_EXPORT void operator<<(CBlobInfo& blob_info, string data);
+
+}
+}
+}
+
 END_NCBI_SCOPE
 
 #endif  /* CONNECT_SERVICES___NETCACHE_API_IMPL__HPP */
diff --git a/c++/src/connect/services/netcache_rw.cpp b/c++/src/connect/services/netcache_rw.cpp
index 466ee4d..0d3bafd 100644
--- a/c++/src/connect/services/netcache_rw.cpp
+++ b/c++/src/connect/services/netcache_rw.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netcache_rw.cpp 496093 2016-03-23 18:15:45Z ivanov $
+/*  $Id: netcache_rw.cpp 495903 2016-03-22 15:17:00Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/connect/services/netcache_search.cpp b/c++/src/connect/services/netcache_search.cpp
new file mode 100644
index 0000000..b4b2bd7
--- /dev/null
+++ b/c++/src/connect/services/netcache_search.cpp
@@ -0,0 +1,556 @@
+/*  $Id: netcache_search.cpp 520437 2016-11-28 18:35:09Z ivanov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author: Rafael Sadyrov
+ *
+ */
+
+
+#include <ncbi_pch.hpp>
+
+#include <corelib/ncbistr.hpp>
+#include <corelib/ncbidbg.hpp>
+#include <connect/services/netcache_search.hpp>
+#include "netcache_api_impl.hpp"
+
+#include <ostream>
+#include <list>
+#include <limits>
+
+
+namespace ncbi {
+namespace grid {
+namespace netcache {
+namespace search {
+
+using namespace chrono;
+
+enum ETerm : size_t
+{
+    eKey,
+    eSubkey,
+    eCreatedAgo,
+    eCreated,
+    eExpiresIn,
+    eExpires,
+    eVersionExpiresIn,
+    eVersionExpires,
+    eSize,
+
+    eNumberOfTerms
+};
+
+enum EComparison : size_t
+{
+    eGreaterOrEqual,
+    eEqual,
+    eLessThan,
+
+    eNumberOfComparisons
+};
+
+struct SCondition
+{
+    SCondition(size_t key) : m_Key(key) {}
+    virtual ~SCondition() {}
+
+    size_t Key() const { return m_Key; }
+
+    virtual ostream& Output(ostream&) const = 0;
+    virtual void Merge(SCondition*) = 0;
+
+    template <ETerm term, EComparison comparison, typename TValue>
+    static SCondition* Create(TValue);
+
+private:
+    size_t m_Key;
+};
+
+ostream& operator<<(ostream& os, const SCondition& c)
+{
+    return c.Output(os);
+}
+
+template <ETerm term, EComparison comparison, typename TValue>
+struct SConditionImpl : SCondition
+{
+    SConditionImpl(TValue value) :
+        SCondition(comparison + term * eNumberOfComparisons),
+        m_Value(value)
+    {
+    }
+
+    ostream& Output(ostream& os) const override;
+    void Merge(SCondition*) override;
+
+private:
+    TValue m_Value;
+};
+
+const char* s_Term(ETerm term)
+{
+    switch (term) {
+    case eKey:              return "key";
+    case eSubkey:           return "subkey";
+    case eCreated:          return "fcr_epoch";
+    case eCreatedAgo:       return "fcr_ago";
+    case eExpires:          return "fexp_epoch";
+    case eExpiresIn:        return "fexp_now";
+    case eVersionExpires:   return "fvexp_epoch";
+    case eVersionExpiresIn: return "fvexp_now";
+    case eSize:             return "fsize";
+    default:                return nullptr;
+    }
+}
+
+const char* s_Comparison(EComparison comparison)
+{
+    switch (comparison) {
+    case eLessThan:         return "_lt";
+    case eEqual:            return "";
+    case eGreaterOrEqual:   return "_ge";
+    default:                return nullptr;
+    }
+}
+
+template <typename TValue>
+string s_Value(TValue value)
+{
+    return to_string(value);
+}
+
+template <>
+string s_Value(string value)
+{
+    return value;
+}
+
+template <ETerm term, EComparison comparison, typename TValue>
+ostream& SConditionImpl<term, comparison, TValue>::Output(ostream& os) const
+{
+    return os << s_Term(term) << s_Comparison(comparison) << "=" << s_Value(m_Value);
+}
+
+template <ETerm term, EComparison comparison, typename TValue>
+struct SMerge;
+
+template <ETerm term, typename TValue>
+struct SMerge<term, eLessThan, TValue>
+{
+    SMerge(TValue& left, const TValue& right)
+    {
+        if (left > right) left = right;
+    }
+};
+
+template <ETerm term, typename TValue>
+struct SMerge<term, eGreaterOrEqual, TValue>
+{
+    SMerge(TValue& left, const TValue& right)
+    {
+        if (left < right) left = right;
+    }
+};
+
+template <>
+struct SMerge<eKey, eEqual, string>
+{
+    SMerge(string&, const string&)
+    {
+        NCBI_THROW_FMT(CNetCacheException, eNotImplemented,
+            "Field '" << s_Term(eKey) << "' cannot be specified more than once");
+    }
+};
+
+template <ETerm term, EComparison comparison, typename TValue>
+void SConditionImpl<term, comparison, TValue>::Merge(SCondition* o)
+{
+    auto other = dynamic_cast<decltype(this)>(o);
+    _ASSERT(other);
+
+    SMerge<term, comparison, TValue>(m_Value, other->m_Value);
+}
+
+template <ETerm term, EComparison comparison, typename TValue>
+SCondition* SCondition::Create(TValue value)
+{
+    return new SConditionImpl<term, comparison, TValue>(value);
+}
+
+struct SExpressionImpl
+{
+    list<shared_ptr<SCondition>> conditions;
+};
+
+SExpression::~SExpression()
+{
+}
+
+template <ETerm term, EComparison comparison, typename TValue>
+SExpression s_CreateBase(TValue value)
+{
+    auto condition = SCondition::Create<term, comparison>(value);
+
+    SExpression result;
+    result.impl.reset(new SExpressionImpl);
+    result.impl->conditions.emplace_back(condition);
+    return result;
+}
+
+template <ETerm term, EComparison comparison, typename TValue>
+CExpression s_Create(TValue value)
+{
+    CExpression result;
+    result.base = s_CreateBase<term, comparison>(value);
+    return result;
+}
+
+chrono::seconds::rep s_GetSeconds(duration d)
+{
+    return duration_cast<chrono::seconds>(d).count();
+}
+
+chrono::seconds::rep s_GetSeconds(time_point p)
+{
+    return s_GetSeconds(p.time_since_epoch());
+}
+
+CExpression operator==(KEY, string v)
+{
+    return s_Create<eKey, eEqual>(v);
+}
+
+CExpression operator>=(CREATED, time_point v)
+{
+    return s_Create<eCreated, eGreaterOrEqual>(s_GetSeconds(v));
+}
+
+CExpression operator< (CREATED, time_point v)
+{
+    return s_Create<eCreated, eLessThan>(s_GetSeconds(v));
+}
+
+CExpression operator>=(CREATED, duration v)
+{
+    return s_Create<eCreatedAgo, eGreaterOrEqual>(s_GetSeconds(v));
+}
+
+CExpression operator< (CREATED, duration v)
+{
+    return s_Create<eCreatedAgo, eLessThan>(s_GetSeconds(v));
+}
+
+CExpression operator>=(EXPIRES, time_point v)
+{
+    return s_Create<eExpires, eGreaterOrEqual>(s_GetSeconds(v));
+}
+
+CExpression operator< (EXPIRES, time_point v)
+{
+    return s_Create<eExpires, eLessThan>(s_GetSeconds(v));
+}
+
+CExpression operator>=(EXPIRES, duration v)
+{
+    return s_Create<eExpiresIn, eGreaterOrEqual>(s_GetSeconds(v));
+}
+
+CExpression operator< (EXPIRES, duration v)
+{
+    return s_Create<eExpiresIn, eLessThan>(s_GetSeconds(v));
+}
+
+CExpression operator>=(VERSION_EXPIRES, time_point v)
+{
+    return s_Create<eVersionExpires, eGreaterOrEqual>(s_GetSeconds(v));
+}
+
+CExpression operator< (VERSION_EXPIRES, time_point v)
+{
+    return s_Create<eVersionExpires, eLessThan>(s_GetSeconds(v));
+}
+
+CExpression operator>=(VERSION_EXPIRES, duration v)
+{
+    return s_Create<eVersionExpiresIn, eGreaterOrEqual>(s_GetSeconds(v));
+}
+
+CExpression operator< (VERSION_EXPIRES, duration v)
+{
+    return s_Create<eVersionExpiresIn, eLessThan>(s_GetSeconds(v));
+}
+
+CExpression operator>=(SIZE, size_t v)
+{
+    return s_Create<eSize, eGreaterOrEqual>(v);
+}
+
+CExpression operator< (SIZE, size_t v)
+{
+    return s_Create<eSize, eLessThan>(v);
+}
+
+void s_Merge(SExpression& l, SExpression& r)
+{
+    if (!l.impl) { l = r; return; }
+    if (!r.impl) return;
+
+    auto& lc = l.impl->conditions;
+    auto& rc = r.impl->conditions;
+    auto li = lc.begin();
+    auto ri = rc.begin();
+
+    while (li != lc.end() && ri != rc.end()) {
+        auto& lp = *li;
+        auto& rp = *ri;
+
+        if (lp->Key() < rp->Key()) {
+            ++li;
+        } else if (lp->Key() > rp->Key()) {
+            auto old_ri = ri;
+            lc.splice(li, rc, old_ri, ++ri);
+        } else {
+            lp->Merge(rp.get());
+            ++li;
+            ++ri;
+        }
+    }
+
+    if (ri != rc.end()) {
+        lc.splice(lc.end(), rc, ri, rc.end());
+    }
+}
+
+CExpression operator&&(CExpression l, CExpression r)
+{
+    s_Merge(l.base, r.base);
+    return l;
+}
+
+CExpression operator+(CExpression l, CFields r)
+{
+    s_Merge(l.base, r.base);
+    return l;
+}
+
+ostream& operator<<(ostream& os, CExpression expression)
+{
+    if (!expression.base.impl) return os;
+
+    for (auto& condition : expression.base.impl->conditions) {
+        os << " " << *condition;
+    }
+
+    return os;
+}
+
+// Mirrored versions
+CExpression operator==(string v, KEY                 t) { return t == v; }
+CExpression operator<=(time_point v, CREATED         t) { return t >= v; }
+CExpression operator> (time_point v, CREATED         t) { return t <  v; }
+CExpression operator<=(duration   v, CREATED         t) { return t >= v; }
+CExpression operator> (duration   v, CREATED         t) { return t <  v; }
+CExpression operator<=(time_point v, EXPIRES         t) { return t >= v; }
+CExpression operator> (time_point v, EXPIRES         t) { return t <  v; }
+CExpression operator<=(duration   v, EXPIRES         t) { return t >= v; }
+CExpression operator> (duration   v, EXPIRES         t) { return t <  v; }
+CExpression operator<=(time_point v, VERSION_EXPIRES t) { return t >= v; }
+CExpression operator> (time_point v, VERSION_EXPIRES t) { return t <  v; }
+CExpression operator<=(duration   v, VERSION_EXPIRES t) { return t >= v; }
+CExpression operator> (duration   v, VERSION_EXPIRES t) { return t <  v; }
+CExpression operator<=(size_t v, SIZE                t) { return t >= v; }
+CExpression operator> (size_t v, SIZE                t) { return t <  v; }
+
+// Cannot use zero, as corresponding condition would be ignored then
+const chrono::seconds::rep kSmallestTimePoint = 1;
+const size_t kLargestSize = numeric_limits<size_t>::max();
+
+CFields::CFields()
+{
+}
+
+CFields::CFields(CREATED)
+    : base(s_CreateBase<eCreated, eGreaterOrEqual>(kSmallestTimePoint))
+{
+}
+
+CFields::CFields(EXPIRES)
+    : base(s_CreateBase<eExpires, eGreaterOrEqual>(kSmallestTimePoint))
+{
+}
+
+CFields::CFields(VERSION_EXPIRES)
+    : base(s_CreateBase<eVersionExpires, eGreaterOrEqual>(kSmallestTimePoint))
+{
+}
+
+CFields::CFields(SIZE)
+    : base(s_CreateBase<eSize, eLessThan>(kLargestSize))
+{
+}
+
+CFields operator|(CFields l, CFields r)
+{
+    s_Merge(l.base, r.base);
+    return l;
+}
+
+struct SBlobInfoImpl
+{
+    string key;
+    string subkey;
+
+    SBlobInfoImpl(string key, string subkey, string data);
+    time_point operator[](CREATED);
+    time_point operator[](EXPIRES);
+    time_point operator[](VERSION_EXPIRES);
+    size_t operator[](SIZE);
+
+    static SBlobInfoImpl* Create(string data);
+
+private:
+    void Parse();
+
+    const string m_Data;
+    bool m_Parsed;
+    CNullable<time_point> m_Created;
+    CNullable<time_point> m_Expires;
+    CNullable<time_point> m_VersionExpires;
+    CNullable<size_t> m_Size;
+};
+
+SBlobInfoImpl::SBlobInfoImpl(string k, string sk, string data)
+    : key(k),
+      subkey(sk),
+      m_Data(data),
+      m_Parsed(false)
+{
+}
+
+time_point SBlobInfoImpl::operator[](CREATED)
+{
+    if (!m_Parsed) Parse();
+    return m_Created.GetValue();
+}
+
+time_point SBlobInfoImpl::operator[](EXPIRES)
+{
+    if (!m_Parsed) Parse();
+    return m_Expires.GetValue();
+}
+
+time_point SBlobInfoImpl::operator[](VERSION_EXPIRES)
+{
+    if (!m_Parsed) Parse();
+    return m_VersionExpires.GetValue();
+}
+
+size_t SBlobInfoImpl::operator[](SIZE)
+{
+    if (!m_Parsed) Parse();
+    return m_Size.GetValue();
+}
+
+const string kSeparator = "\t";
+
+void SBlobInfoImpl::Parse()
+{
+    vector<CTempString> fields;
+
+    NStr::Split(m_Data, kSeparator, fields);
+
+    for (auto& field : fields) {
+        string name, value;
+        NStr::SplitInTwo(field, "=", name, value);
+        if (name == "cr_time") {
+            m_Created = time_point(seconds(stoll(value)));
+        } else if (name == "exp") {
+            m_Expires = time_point(seconds(stoll(value)));
+        } else if (name == "ver_dead") {
+            m_VersionExpires = time_point(seconds(stoll(value)));
+        } else if (name == "size") {
+            m_Size = stoull(value);
+        } else {
+            NCBI_THROW_FMT(CNetCacheException, eInvalidServerResponse,
+                "Unknown field '" << name << "' in response '" << m_Data << "'");
+        }
+    }
+
+    m_Parsed = true;
+}
+
+void operator<<(CBlobInfo& blob_info, string data)
+{
+    string cache, key, subkey, remaining;
+    NStr::SplitInTwo(data, kSeparator, cache, remaining);
+    NStr::SplitInTwo(remaining, kSeparator, key, remaining);
+    NStr::SplitInTwo(remaining, kSeparator, subkey, remaining);
+    blob_info.base.impl.reset(new SBlobInfoImpl(key, subkey, remaining));
+}
+
+SBlobInfo::~SBlobInfo()
+{
+}
+
+string CBlobInfo::operator[](KEY) const
+{
+    if (!base.impl) return string();
+    return base.impl->key;
+}
+
+string CBlobInfo::operator[](SUBKEY) const
+{
+    if (!base.impl) return string();
+    return base.impl->subkey;
+}
+
+time_point CBlobInfo::operator[](CREATED created) const
+{
+    if (!base.impl) return time_point();
+    return (*base.impl)[created];
+}
+
+time_point CBlobInfo::operator[](EXPIRES expires) const
+{
+    if (!base.impl) return time_point();
+    return (*base.impl)[expires];
+}
+
+time_point CBlobInfo::operator[](VERSION_EXPIRES version_expires) const
+{
+    if (!base.impl) return time_point();
+    return (*base.impl)[version_expires];
+}
+
+size_t CBlobInfo::operator[](SIZE size) const
+{
+    if (!base.impl) return size_t();
+    return (*base.impl)[size];
+}
+
+}
+}
+}
+}
diff --git a/c++/src/connect/services/neticache_client.cpp b/c++/src/connect/services/neticache_client.cpp
index 04ff636..3f14c07 100644
--- a/c++/src/connect/services/neticache_client.cpp
+++ b/c++/src/connect/services/neticache_client.cpp
@@ -1,4 +1,4 @@
-/*  $Id: neticache_client.cpp 498373 2016-04-15 17:20:10Z ivanov $
+/*  $Id: neticache_client.cpp 520437 2016-11-28 18:35:09Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -51,6 +51,7 @@
 #include <corelib/ncbi_safe_static.hpp>
 
 #include <memory>
+#include <sstream>
 
 #define MAX_ICACHE_CACHE_NAME_LENGTH 64
 #define MAX_ICACHE_KEY_LENGTH 256
@@ -248,6 +249,7 @@ CNetServerConnection SNetICacheClientImpl::InitiateWriteCmd(
         cmd.append(" confirm=1");
     m_UseNextSubHitID.ProperCommand();
     AppendClientIPSessionIDPasswordAgeHitID(&cmd, parameters);
+    if (!m_ProlongBlobLifetimeOnWrite) cmd.append(" flags=1");
 
     return ChooseServerAndExec(cmd, nc_writer->GetKey(),
             false, parameters).conn;
@@ -1105,6 +1107,37 @@ void CNetICacheClient::SetEventHandler(INetEventHandler* event_handler)
     m_Impl->GetListener()->m_EventHandler = event_handler;
 }
 
+vector<CNetICacheClient::CBlobInfo> CNetICacheClient::Search(
+        CNetICacheClient::CExpression expression,
+        CNetICacheClient::CFields filter)
+{
+    const auto parameters = &m_Impl->m_DefaultParameters;
+    const auto cache_name = NStr::PrintableString(parameters->GetCacheName());
+    string ids;
+    m_Impl->AppendClientIPSessionIDPasswordAgeHitID(&ids, parameters);
+    ostringstream oss;
+    oss << "IC(" << cache_name << ") BLIST2" << expression + filter << ids;
+
+    CNetServerMultilineCmdOutput output(
+            m_Impl->ChooseServerAndExec(
+                oss.str(),
+                kEmptyStr,
+                true,
+                &m_Impl->m_DefaultParameters));
+
+    output->SetNetCacheCompatMode();
+    string line;
+    vector<CNetICacheClient::CBlobInfo> result;
+
+    while (output.ReadLine(line) && !line.empty()) {
+        CBlobInfo blob_info;
+        blob_info << line;
+        result.push_back(blob_info);
+    }
+
+    return result;
+}
+
 void CNetICacheClientExt::ProlongBlobLifetime(const string& key,
         const CTimeout& ttl, const CNamedParameterList* optional)
 {
diff --git a/c++/src/connect/services/netschedule_api.cpp b/c++/src/connect/services/netschedule_api.cpp
index c8b408e..67dbf74 100644
--- a/c++/src/connect/services/netschedule_api.cpp
+++ b/c++/src/connect/services/netschedule_api.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netschedule_api.cpp 498273 2016-04-14 17:59:04Z ivanov $
+/*  $Id: netschedule_api.cpp 514423 2016-09-21 17:22:32Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -687,8 +687,6 @@ void CNetScheduleServerListener::OnInit(
         SNetScheduleAPIImpl::VerifyQueueNameAlphabet(queue_ref);
     }
 
-    ns_impl->m_AffinityPreference = CNetScheduleExecutor::eAnyJob;
-
     const list<string> embedded_synonyms{"use_embedded_input"};
     bool use_affinities_value;
 
@@ -724,43 +722,7 @@ void CNetScheduleServerListener::OnInit(
             embedded.ReadOnce();
 
             if (use_affinities.ReadOnce() && use_affinities_value) {
-                ns_impl->m_AffinityPreference = config->GetBool(module,
-                        "claim_new_affinities", CConfig::eErr_NoThrow, false) ?
-                    CNetScheduleExecutor::eClaimNewPreferredAffs :
-                    config->GetBool(module,
-                        "process_any_job", CConfig::eErr_NoThrow, false) ?
-                            CNetScheduleExecutor::ePreferredAffsOrAnyJob :
-                            CNetScheduleExecutor::ePreferredAffinities;
-
-                string affinity_list = config->GetString(module,
-                        "affinity_list", CConfig::eErr_NoThrow, kEmptyStr);
-
-                if (!affinity_list.empty()) {
-                    NStr::Split(affinity_list, ", ", ns_impl->m_AffinityList,
-                            NStr::fSplit_MergeDelimiters | NStr::fSplit_Truncate);
-                    ITERATE(list<string>, it, ns_impl->m_AffinityList) {
-                        SNetScheduleAPIImpl::VerifyAffinityAlphabet(*it);
-                    }
-                }
-
-                string affinity_ladder = config->GetString(module,
-                        "affinity_ladder", CConfig::eErr_NoThrow, kEmptyStr);
-                list<CTempString> affinities;
-                NStr::Split(affinity_ladder, ", ", affinities,
-                        NStr::fSplit_MergeDelimiters | NStr::fSplit_Truncate);
-
-                if (!affinities.empty()) {
-                    list<CTempString>::const_iterator it = affinities.begin();
-                    affinity_list = *it;
-                    for (;;) {
-                        ns_impl->m_AffinityLadder.push_back(
-                                make_pair(*it, affinity_list));
-                        if (++it == affinities.end())
-                            break;
-                        affinity_list += ',';
-                        affinity_list += *it;
-                    }
-                }
+                ns_impl->InitAffinities(config, module);
             }
 
             job_group.ReadOnce();
@@ -898,10 +860,11 @@ static const char* const s_NetScheduleConfigSections[] = {
 SNetScheduleAPIImpl::SNetScheduleAPIImpl(
         CConfig* config, const string& section,
         const string& service_name, const string& client_name,
-        const string& queue_name) :
+        const string& queue_name, bool wn, bool try_config) :
     m_Service(new SNetServiceImpl("NetScheduleAPI", client_name,
-                new CNetScheduleServerListener)),
+                new CNetScheduleServerListener(wn, try_config))),
     m_Queue(queue_name),
+    m_AffinityPreference(CNetScheduleExecutor::eAnyJob),
     m_JobTtl(0)
 {
     m_Service->Init(this, service_name,
@@ -909,18 +872,6 @@ SNetScheduleAPIImpl::SNetScheduleAPIImpl(
 }
 
 SNetScheduleAPIImpl::SNetScheduleAPIImpl(
-        const string& service_name, const string& client_name,
-        const string& queue_name, bool wn_compatible) :
-    m_Service(new SNetServiceImpl("NetScheduleAPI", client_name,
-                new CNetScheduleServerListener(wn_compatible), wn_compatible)),
-    m_Queue(queue_name),
-    m_JobTtl(0)
-{
-    m_Service->Init(this, service_name,
-        NULL, kEmptyStr, s_NetScheduleConfigSections);
-}
-
-SNetScheduleAPIImpl::SNetScheduleAPIImpl(
         SNetServerInPool* server, SNetScheduleAPIImpl* parent) :
     m_Service(new SNetServiceImpl(server, parent->m_Service)),
     m_Queue(parent->m_Queue),
@@ -1429,6 +1380,75 @@ void SNetScheduleAPIImpl::SetAuthParam(const string& param_name,
     UpdateAuthString();
 }
 
+void SNetScheduleAPIImpl::InitAffinities(CConfig* config, const string& section)
+{
+    const bool claim_new_affinities = config->GetBool(section,
+            "claim_new_affinities", CConfig::eErr_NoThrow, false);
+
+    const bool process_any_job = config->GetBool(section,
+            "process_any_job", CConfig::eErr_NoThrow, false);
+
+    const string affinity_list = config->GetString(section,
+            "affinity_list", CConfig::eErr_NoThrow, kEmptyStr);
+
+    const string affinity_ladder = config->GetString(section,
+            "affinity_ladder", CConfig::eErr_NoThrow, kEmptyStr);
+
+    if (affinity_ladder.empty()) {
+
+        if (claim_new_affinities) {
+            m_AffinityPreference = CNetScheduleExecutor::eClaimNewPreferredAffs;
+
+        } else if (process_any_job) {
+            m_AffinityPreference = CNetScheduleExecutor::ePreferredAffsOrAnyJob;
+
+        } else {
+            m_AffinityPreference = CNetScheduleExecutor::ePreferredAffinities;
+        }
+
+        if (affinity_list.empty()) return;
+
+        NStr::Split(affinity_list, ", ", m_AffinityList,
+                NStr::fSplit_MergeDelimiters | NStr::fSplit_Truncate);
+
+        for (auto& affinity : m_AffinityList) {
+            VerifyAffinityAlphabet(affinity);
+        }
+
+        return;
+    }
+
+    // Sanity checks
+    if (claim_new_affinities) {
+        NCBI_THROW(CConfigException, eInvalidParameter,
+                "'affinity_ladder' cannot be used with 'claim_new_affinities'");
+    }
+    if (!affinity_list.empty()) {
+        NCBI_THROW(CConfigException, eInvalidParameter,
+                "'affinity_ladder' cannot be used with 'affinity_list'");
+    }
+
+    if (!process_any_job) {
+        m_AffinityPreference = CNetScheduleExecutor::eExplicitAffinitiesOnly;
+    }
+
+    list<CTempString> affinities;
+    NStr::Split(affinity_ladder, ", ", affinities,
+            NStr::fSplit_MergeDelimiters | NStr::fSplit_Truncate);
+
+    if (affinities.empty()) return;
+
+    string affinity_step;
+
+    for (auto& affinity : affinities) {
+        VerifyAffinityAlphabet(affinity);
+
+        if (!affinity_step.empty()) affinity_step += ',';
+        affinity_step += affinity;
+        m_AffinityLadder.emplace_back(affinity, affinity_step);
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 /// @internal
@@ -1550,14 +1570,16 @@ CNetScheduleAPI::TInstance
 CNetScheduleAPIExt::CreateWnCompat(const string& service_name,
         const string& client_name)
 {
-    return new SNetScheduleAPIImpl(service_name, client_name, kEmptyStr, true);
+    return new SNetScheduleAPIImpl(nullptr, kEmptyStr,
+            service_name, client_name, kEmptyStr, true, false);
 }
 
 CNetScheduleAPI::TInstance
 CNetScheduleAPIExt::CreateNoCfgLoad(const string& service_name,
         const string& client_name, const string& queue_name)
 {
-    return new SNetScheduleAPIImpl(service_name, client_name, queue_name, false);
+    return new SNetScheduleAPIImpl(nullptr, kEmptyStr,
+            service_name, client_name, queue_name, false, false);
 }
 
 
diff --git a/c++/src/connect/services/netschedule_api_admin.cpp b/c++/src/connect/services/netschedule_api_admin.cpp
index 6f0418a..429b8a9 100644
--- a/c++/src/connect/services/netschedule_api_admin.cpp
+++ b/c++/src/connect/services/netschedule_api_admin.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netschedule_api_admin.cpp 492599 2016-02-18 19:26:29Z ivanov $
+/*  $Id: netschedule_api_admin.cpp 492051 2016-02-11 17:22:40Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/connect/services/netschedule_api_executor.cpp b/c++/src/connect/services/netschedule_api_executor.cpp
index be05cdb..442cca3 100644
--- a/c++/src/connect/services/netschedule_api_executor.cpp
+++ b/c++/src/connect/services/netschedule_api_executor.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netschedule_api_executor.cpp 486255 2015-12-02 17:51:03Z sadyrovr $
+/*  $Id: netschedule_api_executor.cpp 518714 2016-11-07 18:04:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -192,6 +192,8 @@ static bool s_DoParseGetJobResponse(
     return true;
 }
 
+string s_GET2(CNetScheduleExecutor::EJobAffinityPreference affinity_preference);
+
 bool g_ParseGetJobResponse(CNetScheduleJob& job, const string& response)
 {
     if (response.empty())
@@ -354,66 +356,26 @@ bool SNetScheduleExecutorImpl::ExecGET(SNetServerImpl* server,
     return true;
 }
 
-bool SNetScheduleExecutorImpl::x_GetJobWithAffinityList(SNetServerImpl* server,
-        const CDeadline* timeout, CNetScheduleJob& job,
-        CNetScheduleExecutor::EJobAffinityPreference affinity_preference,
-        const string& affinity_list)
-{
-    string cmd(CNetScheduleNotificationHandler::MkBaseGETCmd(
-            affinity_preference, affinity_list));
-
-    m_NotificationHandler.CmdAppendTimeoutGroupAndClientInfo(cmd,
-            timeout, m_JobGroup);
-
-    return ExecGET(server, cmd, job);
-}
-
 bool SNetScheduleExecutorImpl::x_GetJobWithAffinityLadder(
         SNetServerImpl* server, const CDeadline& timeout, 
-        const string& prio_aff_list, CNetScheduleJob& job)
+        const string& prio_aff_list, bool any_affinity, CNetScheduleJob& job)
 {
-    if (prio_aff_list.empty())
-        return x_GetJobWithAffinityList(server, &timeout, job,
-                m_AffinityPreference, kEmptyStr);
+    // Ask for any affinity only when requested and configured
+    // (it's not requested when we have a job already).
+    const auto affinity_preference = any_affinity ? m_AffinityPreference :
+        CNetScheduleExecutor::eExplicitAffinitiesOnly;
 
-    // If prioritized_aff flag is supported (NS v4.22.0+)
-    CRef<SNetScheduleServerProperties> server_props =
-        CNetScheduleServerListener::x_GetServerProperties(server);
+    string cmd(s_GET2(affinity_preference));
+    const bool have_affinities = !prio_aff_list.empty();
 
-    if (server_props->version.IsUpCompatible(CVersionInfo(4, 22, 0))) {
-        string cmd("GET2 wnode_aff=0 any_aff=0 aff=");
-        cmd += prio_aff_list;
+    if (have_affinities) cmd += " aff=" + prio_aff_list;
 
-        m_NotificationHandler.CmdAppendTimeoutGroupAndClientInfo(cmd,
-                &timeout, m_JobGroup);
-
-        cmd.append(" prioritized_aff=1");
-        return ExecGET(server, cmd, job);
-    }
-
-    // XXX: Compatibility mode.
-    // TODO: Can be thrown out after all NS serves are updated to version 4.22.0+
-    list<CTempString> affinity_tokens;
-    NStr::Split(prio_aff_list, ",", affinity_tokens,
-            NStr::fSplit_MergeDelimiters | NStr::fSplit_Truncate);
-
-    string affinity_list;
-    list<CTempString>::const_iterator it = affinity_tokens.begin();
-
-    while (it != affinity_tokens.end()) {
-        affinity_list += *it;
-        const bool last_try = ++it == affinity_tokens.end();
-
-        if (x_GetJobWithAffinityList(server, last_try ? &timeout : NULL,
-                    job, CNetScheduleExecutor::eExplicitAffinitiesOnly,
-                    affinity_list)) {
-            return true;
-        }
+    m_NotificationHandler.CmdAppendTimeoutGroupAndClientInfo(cmd,
+            &timeout, m_JobGroup);
 
-        affinity_list += ',';
-    }
+    if (have_affinities) cmd += " prioritized_aff=1";
 
-    return false;
+    return ExecGET(server, cmd, job);
 }
 
 bool CNetScheduleExecutor::GetJob(CNetScheduleJob& job,
@@ -477,32 +439,31 @@ bool CNetScheduleExecutor::GetJob(CNetScheduleJob& job,
     }
 }
 
-string CNetScheduleNotificationHandler::MkBaseGETCmd(
-    CNetScheduleExecutor::EJobAffinityPreference affinity_preference,
-    const string& affinity_list)
+string s_GET2(CNetScheduleExecutor::EJobAffinityPreference affinity_preference)
 {
-    string cmd;
-
     switch (affinity_preference) {
     case CNetScheduleExecutor::ePreferredAffsOrAnyJob:
-        cmd = "GET2 wnode_aff=1 any_aff=1";
-        break;
+        return "GET2 wnode_aff=1 any_aff=1";
 
     case CNetScheduleExecutor::ePreferredAffinities:
-        cmd = "GET2 wnode_aff=1 any_aff=0";
-        break;
+        return "GET2 wnode_aff=1 any_aff=0";
 
     case CNetScheduleExecutor::eClaimNewPreferredAffs:
-        cmd = "GET2 wnode_aff=1 any_aff=0 exclusive_new_aff=1";
-        break;
+        return "GET2 wnode_aff=1 any_aff=0 exclusive_new_aff=1";
 
     case CNetScheduleExecutor::eAnyJob:
-        cmd = "GET2 wnode_aff=0 any_aff=1";
-        break;
+        return "GET2 wnode_aff=0 any_aff=1";
 
-    case CNetScheduleExecutor::eExplicitAffinitiesOnly:
-        cmd = "GET2 wnode_aff=0 any_aff=0";
+    default:
+        return "GET2 wnode_aff=0 any_aff=0";
     }
+}
+
+string CNetScheduleNotificationHandler::MkBaseGETCmd(
+    CNetScheduleExecutor::EJobAffinityPreference affinity_preference,
+    const string& affinity_list)
+{
+    string cmd(s_GET2(affinity_preference));
 
     if (!affinity_list.empty()) {
         list<CTempString> affinity_tokens;
diff --git a/c++/src/connect/services/netschedule_api_getjob.cpp b/c++/src/connect/services/netschedule_api_getjob.cpp
index 16b5fb5..f6262f8 100644
--- a/c++/src/connect/services/netschedule_api_getjob.cpp
+++ b/c++/src/connect/services/netschedule_api_getjob.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netschedule_api_getjob.cpp 476303 2015-08-17 19:03:16Z sadyrovr $
+/*  $Id: netschedule_api_getjob.cpp 518714 2016-11-07 18:04:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -64,19 +64,6 @@ typedef list<SServerAddress> TServers;
 typedef list<CNetScheduleGetJob::SEntry> TTimeline;
 typedef TTimeline::iterator TIterator;
 
-// TODO: This can be replaced by lambda after we migrate to C++11
-template <class TImpl>
-struct SEntryHasMoreJobs
-{
-    TImpl& impl;
-    SEntryHasMoreJobs(TImpl& i) : impl(i) {}
-
-    bool operator()(const CNetScheduleGetJob::SEntry& entry)
-    {
-        return impl.MoreJobs(entry);
-    }
-};
-
 template <class TImpl>
 class CAnyAffinityJob
 {
@@ -92,7 +79,7 @@ public:
     void Interrupt()                {}
     TIterator Begin()               { return m_Timeline.begin(); }
     TIterator Next(bool)            { return m_Timeline.begin(); }
-    const string& Affinity(bool&) const { return kEmptyStr; }
+    const string& Affinity() const  { return kEmptyStr; }
     bool Done()                     { return true; }
     bool HasJob() const             { return false; }
 
@@ -151,7 +138,7 @@ public:
         return ++ret;
     }
 
-    const string& Affinity(bool& all_affinities) const
+    const string& Affinity() const
     {
         // Must not happen, since otherwise Done() has returned true already
         _ASSERT(m_JobPriority);
@@ -161,11 +148,9 @@ public:
 
         if (HasJob()) {
             // Only affinities that are higher that current job's one
-            all_affinities = false;
             return affinity_ladder[m_JobPriority - 1].second;
         } else {
             // All affinities
-            all_affinities = true;
             return affinity_ladder.back().second;
         }
     }
@@ -196,10 +181,18 @@ public:
             }
         } while (priority-- > 0);
 
-        // Should not happen
-        LOG_POST(Error << "Got a job " << job.job_id <<
-                " with unexpected affinity " << job.affinity);
-        m_JobPriority = numeric_limits<size_t>::max();
+        // Whether affinities not from the ladder are allowed
+        if (m_GetJobImpl.m_API->m_AffinityPreference ==
+                CNetScheduleExecutor::eAnyJob) {
+            // Make it the least-priority
+            m_JobPriority = affinity_ladder.size();
+        } else {
+            // Should not happen
+            LOG_POST(Error << "Got a job " << job.job_id <<
+                    " with unexpected affinity " << job.affinity);
+            m_JobPriority = numeric_limits<size_t>::max();
+        }
+
         return false;
     }
 
@@ -253,11 +246,11 @@ CNetScheduleGetJob::EResult CNetScheduleGetJobImpl<TImpl>::GetJobImmediately(TJo
 
         try {
             // Get prioritized affinity list and
-            // a flag whether the list contains all possible affinities
-            bool all_affinities = true;
-            const string& prio_aff_list(holder.Affinity(all_affinities));
+            // a flag whether any affinity job is appropriate
+            const string& prio_aff_list = holder.Affinity();
+            const bool any_affinity = !holder.HasJob();
 
-            if (m_Impl.CheckEntry(*i, prio_aff_list,
+            if (m_Impl.CheckEntry(*i, prio_aff_list, any_affinity,
                         holder.job, holder.job_status)) {
                 if (i == m_ImmediateActions.begin()) {
                     increment = true;
@@ -280,7 +273,7 @@ CNetScheduleGetJob::EResult CNetScheduleGetJobImpl<TImpl>::GetJobImmediately(TJo
                 // No job has been returned by this server;
                 // query the server later.
                 i->deadline = CDeadline(m_Impl.m_Timeout, 0);
-                i->all_affinities = all_affinities;
+                i->all_affinities_checked = any_affinity;
                 m_ScheduledActions.splice(m_ScheduledActions.end(),
                         m_ImmediateActions, i);
             }
@@ -329,9 +322,13 @@ CNetScheduleGetJob::EResult CNetScheduleGetJobImpl<TImpl>::GetJobImpl(
             return ret;
         }
 
+        auto entry_has_more_jobs = [&](const SEntry& entry) {
+            return m_Impl.MoreJobs(entry);
+        };
+
         // If MoreJobs() returned false for all entries of m_ScheduledActions
         if (find_if(m_ScheduledActions.begin(), m_ScheduledActions.end(),
-                    SEntryHasMoreJobs<TImpl>(m_Impl)) == m_ScheduledActions.end()) {
+                    entry_has_more_jobs) == m_ScheduledActions.end()) {
             return eNoJobs;
         }
 
@@ -444,7 +441,7 @@ void CNetScheduleGetJobImpl<TImpl>::ReturnNotFullyCheckedServers()
     TIterator i = m_ScheduledActions.begin();
 
     while (i != m_ScheduledActions.end()) {
-        if (i->all_affinities) {
+        if (i->all_affinities_checked) {
             ++i;
         } else {
             m_ImmediateActions.splice(m_ImmediateActions.end(),
diff --git a/c++/src/connect/services/netschedule_api_getjob.hpp b/c++/src/connect/services/netschedule_api_getjob.hpp
index 13e68e7..67fafd7 100644
--- a/c++/src/connect/services/netschedule_api_getjob.hpp
+++ b/c++/src/connect/services/netschedule_api_getjob.hpp
@@ -1,7 +1,7 @@
 #ifndef CONN_SERVICES___NETSCHEDULE_API_GETJOB__HPP
 #define CONN_SERVICES___NETSCHEDULE_API_GETJOB__HPP
 
-/*  $Id: netschedule_api_getjob.hpp 476303 2015-08-17 19:03:16Z sadyrovr $
+/*  $Id: netschedule_api_getjob.hpp 518714 2016-11-07 18:04:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -70,13 +70,13 @@ struct CNetScheduleGetJob
     {
         SServerAddress server_address;
         CDeadline deadline;
-        bool all_affinities;
+        bool all_affinities_checked;
         bool more_jobs;
 
         SEntry(const SServerAddress& a, bool j = true) :
             server_address(a),
             deadline(0, 0),
-            all_affinities(true),
+            all_affinities_checked(true),
             more_jobs(j)
         {
         }
diff --git a/c++/src/connect/services/netschedule_api_impl.hpp b/c++/src/connect/services/netschedule_api_impl.hpp
index 52e37db..b3d14ee 100644
--- a/c++/src/connect/services/netschedule_api_impl.hpp
+++ b/c++/src/connect/services/netschedule_api_impl.hpp
@@ -1,7 +1,7 @@
 #ifndef CONN_SERVICES___NETSCHEDULE_API_IMPL__HPP
 #define CONN_SERVICES___NETSCHEDULE_API_IMPL__HPP
 
-/*  $Id: netschedule_api_impl.hpp 498273 2016-04-14 17:59:04Z ivanov $
+/*  $Id: netschedule_api_impl.hpp 518714 2016-11-07 18:04:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -150,20 +150,22 @@ private:
     enum EMode {
         fWnCompatible       = (0 << 0),
         fNonWnCompatible    = (1 << 0),
-        fConfigLoading      = (1 << 1) | fNonWnCompatible,
+        fConfigLoading      = (1 << 1),
+        fWorkerNode         = fWnCompatible,
+        fNetSchedule        = fNonWnCompatible,
     };
     typedef int TMode;
 
-public:
-    CNetScheduleServerListener() :
-        m_ClientType(CNetScheduleAPI::eCT_Auto),
-        m_Mode(fConfigLoading)
+    static TMode GetMode(bool wn, bool try_config)
     {
+        if (wn) return fWorkerNode;
+        if (try_config) return fNetSchedule | fConfigLoading;
+                        return fNetSchedule;
     }
 
-    CNetScheduleServerListener(bool wn_compatible) :
-        m_ClientType(CNetScheduleAPI::eCT_Auto),
-        m_Mode(wn_compatible ? fWnCompatible : fNonWnCompatible)
+public:
+    CNetScheduleServerListener(bool wn, bool try_config) :
+        m_Mode(GetMode(wn, try_config))
     {
     }
 
@@ -194,7 +196,7 @@ public:
     // preferred affinities from two threads.
     CFastMutex m_AffinitySubmissionMutex;
 
-    CNetScheduleAPI::EClientType m_ClientType;
+    CNetScheduleAPI::EClientType m_ClientType = CNetScheduleAPI::eCT_Auto;
 
 private:
     const TMode m_Mode;
@@ -282,10 +284,7 @@ struct SNetScheduleAPIImpl : public CObject
 {
     SNetScheduleAPIImpl(CConfig* config, const string& section,
         const string& service_name, const string& client_name,
-        const string& queue_name);
-
-    SNetScheduleAPIImpl(const string& service_name, const string& client_name,
-        const string& queue_name, bool wn_compatible);
+        const string& queue_name, bool wn = false, bool try_config = true);
 
     // Special constructor for CNetScheduleAPI::GetServer().
     SNetScheduleAPIImpl(SNetServerInPool* server, SNetScheduleAPIImpl* parent);
@@ -362,6 +361,7 @@ struct SNetScheduleAPIImpl : public CObject
     void UseOldStyleAuth();
     void SetAuthParam(const string& param_name, const string& param_value);
     CCompoundIDPool GetCompoundIDPool() { return m_CompoundIDPool; }
+    void InitAffinities(CConfig* config, const string& section);
 
     CNetService m_Service;
 
@@ -399,7 +399,7 @@ struct SNetScheduleSubmitterImpl : public CObject
 {
     SNetScheduleSubmitterImpl(CNetScheduleAPI::TInstance ns_api_impl);
 
-    string SubmitJobImpl(CNetScheduleJob& job, unsigned short udp_port,
+    string SubmitJobImpl(CNetScheduleNewJob& job, unsigned short udp_port,
             unsigned wait_time, CNetServer* server = NULL);
 
     void FinalizeRead(const char* cmd_start,
@@ -440,14 +440,10 @@ struct SNetScheduleExecutorImpl : public CObject
     string MkSETAFFCmd();
     bool ExecGET(SNetServerImpl* server,
             const string& get_cmd, CNetScheduleJob& job);
-    bool x_GetJobWithAffinityList(SNetServerImpl* server,
-            const CDeadline* timeout,
-            CNetScheduleJob& job,
-            CNetScheduleExecutor::EJobAffinityPreference affinity_preference,
-            const string& affinity_list);
     bool x_GetJobWithAffinityLadder(SNetServerImpl* server,
             const CDeadline& timeout,
             const string& prio_aff_list,
+            bool any_affinity,
             CNetScheduleJob& job);
 
     void ExecWithOrWithoutRetry(const CNetScheduleJob& job, const string& cmd);
@@ -537,6 +533,7 @@ private:
         bool CheckEntry(
                 SEntry& entry,
                 const string& prio_aff_list,
+                bool any_affinity,
                 CNetScheduleJob& job,
                 CNetScheduleAPI::EJobStatus* job_status);
         void ReturnJob(CNetScheduleJob& job);
diff --git a/c++/src/connect/services/netschedule_api_reader.cpp b/c++/src/connect/services/netschedule_api_reader.cpp
index 63be99e..36b9e12 100644
--- a/c++/src/connect/services/netschedule_api_reader.cpp
+++ b/c++/src/connect/services/netschedule_api_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netschedule_api_reader.cpp 492591 2016-02-18 19:23:34Z ivanov $
+/*  $Id: netschedule_api_reader.cpp 518714 2016-11-07 18:04:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -102,6 +102,7 @@ static bool s_ParseReadJobResponse(const string& response,
 bool SNetScheduleJobReaderImpl::CImpl::CheckEntry(
         SEntry& entry,
         const string& prio_aff_list,
+        bool any_affinity,
         CNetScheduleJob& job,
         CNetScheduleAPI::EJobStatus* job_status)
 {
@@ -116,7 +117,16 @@ bool SNetScheduleJobReaderImpl::CImpl::CheckEntry(
         cmd.append(m_Affinity);
     } else if (!prio_aff_list.empty()) {
         prioritized_aff = true;
-        cmd.append("any_aff=0 aff=");
+
+        // Ask for any affinity only when requested and configured
+        // (it's not requested when we have a job already).
+        if (any_affinity &&
+                m_API->m_AffinityPreference == CNetScheduleExecutor::eAnyJob) {
+            cmd.append("any_aff=1 aff=");
+        } else {
+            cmd.append("any_aff=0 aff=");
+        }
+
         cmd.append(prio_aff_list);
     } else {
         cmd.append("any_aff=1");
diff --git a/c++/src/connect/services/netschedule_api_submitter.cpp b/c++/src/connect/services/netschedule_api_submitter.cpp
index cbe974a..e1b6640 100644
--- a/c++/src/connect/services/netschedule_api_submitter.cpp
+++ b/c++/src/connect/services/netschedule_api_submitter.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netschedule_api_submitter.cpp 492602 2016-02-18 19:27:34Z ivanov $
+/*  $Id: netschedule_api_submitter.cpp 507304 2016-07-18 16:15:49Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -47,7 +47,7 @@ BEGIN_NCBI_SCOPE
 #define FORCED_SST_INTERVAL_NANOSEC 500 * 1000 * 1000
 
 //////////////////////////////////////////////////////////////////////////////
-static void s_SerializeJob(string& cmd, const CNetScheduleJob& job,
+static void s_SerializeJob(string& cmd, const CNetScheduleNewJob& job,
     unsigned short udp_port, unsigned wait_time)
 {
     cmd.push_back('"');
@@ -82,12 +82,12 @@ void static s_CheckInputSize(const string& input, size_t max_input_size)
     }
 }
 
-string CNetScheduleSubmitter::SubmitJob(CNetScheduleJob& job)
+string CNetScheduleSubmitter::SubmitJob(CNetScheduleNewJob& job)
 {
     return m_Impl->SubmitJobImpl(job, 0, 0);
 }
 
-string SNetScheduleSubmitterImpl::SubmitJobImpl(CNetScheduleJob& job,
+string SNetScheduleSubmitterImpl::SubmitJobImpl(CNetScheduleNewJob& job,
         unsigned short udp_port, unsigned wait_time, CNetServer* server)
 {
     size_t max_input_size = m_API->GetServerParams().max_input_size;
diff --git a/c++/src/connect/services/netservice_api.cpp b/c++/src/connect/services/netservice_api.cpp
index 1fdf3d5..edfbae3 100644
--- a/c++/src/connect/services/netservice_api.cpp
+++ b/c++/src/connect/services/netservice_api.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netservice_api.cpp 497256 2016-04-05 15:59:16Z ivanov $
+/*  $Id: netservice_api.cpp 512527 2016-08-31 18:05:30Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -419,7 +419,8 @@ void SNetServiceImpl::Init(CObject* api_impl, const string& service_name,
     m_ServiceName = service_name;
     NStr::TruncateSpacesInPlace(m_ServiceName);
 
-    if (config) {
+    // Do not override explicitly set client name
+    if (config && m_ClientName.empty()) {
         m_ClientName = config->GetString(section, "client_name",
                 CConfig::eErr_NoThrow);
 
diff --git a/c++/src/connect/services/netservice_api_impl.hpp b/c++/src/connect/services/netservice_api_impl.hpp
index 520a1f3..5c50460 100644
--- a/c++/src/connect/services/netservice_api_impl.hpp
+++ b/c++/src/connect/services/netservice_api_impl.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES___NETSERVICE_API_IMPL__HPP
 #define CONNECT_SERVICES___NETSERVICE_API_IMPL__HPP
 
-/*  $Id: netservice_api_impl.hpp 497257 2016-04-05 15:59:52Z ivanov $
+/*  $Id: netservice_api_impl.hpp 497092 2016-04-04 15:52:44Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/connect/services/netstorage.cpp b/c++/src/connect/services/netstorage.cpp
index 2dc0645..9c3a6c6 100644
--- a/c++/src/connect/services/netstorage.cpp
+++ b/c++/src/connect/services/netstorage.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netstorage.cpp 499028 2016-04-21 15:25:58Z ivanov $
+/*  $Id: netstorage.cpp 505978 2016-06-30 15:57:38Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -159,9 +159,9 @@ CNetStorageObject CNetStorage::Open(const string& object_loc,
 }
 
 string CNetStorage::Relocate(const string& object_loc,
-        TNetStorageFlags flags)
+        TNetStorageFlags flags, TNetStorageProgressCb cb)
 {
-    return m_Impl->Relocate(object_loc, flags);
+    return m_Impl->Relocate(object_loc, flags, cb);
 }
 
 bool CNetStorage::Exists(const string& object_loc)
@@ -189,10 +189,11 @@ CNetStorageObject CNetStorageByKey::Open(const string& unique_key,
 }
 
 string CNetStorageByKey::Relocate(const string& unique_key,
-        TNetStorageFlags flags, TNetStorageFlags old_flags)
+        TNetStorageFlags flags, TNetStorageFlags old_flags,
+        TNetStorageProgressCb cb)
 {
     SNetStorage::SLimits::Check<SNetStorage::SLimits::SUserKey>(unique_key);
-    return m_Impl->Relocate(unique_key, flags, old_flags);
+    return m_Impl->Relocate(unique_key, flags, old_flags, cb);
 }
 
 bool CNetStorageByKey::Exists(const string& key, TNetStorageFlags flags)
diff --git a/c++/src/connect/services/netstorage_direct_nc.cpp b/c++/src/connect/services/netstorage_direct_nc.cpp
index 8bae92f..2a44199 100644
--- a/c++/src/connect/services/netstorage_direct_nc.cpp
+++ b/c++/src/connect/services/netstorage_direct_nc.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netstorage_direct_nc.cpp 493320 2016-02-25 19:43:11Z ivanov $
+/*  $Id: netstorage_direct_nc.cpp 504524 2016-06-15 23:50:37Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -220,7 +220,10 @@ void SNetStorage_NetCacheBlob::SetExpiration(const CTimeout& ttl)
             ": infinite ttl for NetCache blobs is not implemented");
     }
 
-    m_NetCacheAPI.ProlongBlobLifetime(m_BlobKey, (unsigned)ttl.GetAsDouble());
+    try {
+        m_NetCacheAPI.ProlongBlobLifetime(m_BlobKey, (unsigned)ttl.GetAsDouble());
+    }
+    NETSTORAGE_CONVERT_NETCACHEEXCEPTION("on setting ttl " + m_BlobKey)
 }
 
 string SNetStorage_NetCacheBlob::FileTrack_Path()
diff --git a/c++/src/connect/services/netstorage_direct_nc.hpp b/c++/src/connect/services/netstorage_direct_nc.hpp
index 2db4425..146b3da 100644
--- a/c++/src/connect/services/netstorage_direct_nc.hpp
+++ b/c++/src/connect/services/netstorage_direct_nc.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES__NETSTORAGE_DIRECT_NC__HPP
 #define CONNECT_SERVICES__NETSTORAGE_DIRECT_NC__HPP
 
-/*  $Id: netstorage_direct_nc.hpp 493320 2016-02-25 19:43:11Z ivanov $
+/*  $Id: netstorage_direct_nc.hpp 493146 2016-02-24 17:38:53Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/connect/services/netstorage_rpc.cpp b/c++/src/connect/services/netstorage_rpc.cpp
index ed5179d..54f6bfb 100644
--- a/c++/src/connect/services/netstorage_rpc.cpp
+++ b/c++/src/connect/services/netstorage_rpc.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netstorage_rpc.cpp 499028 2016-04-21 15:25:58Z ivanov $
+/*  $Id: netstorage_rpc.cpp 505978 2016-06-30 15:57:38Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -756,7 +756,7 @@ CNetStorageObject SNetStorageRPC::Create(TNetStorageFlags flags)
     m_UseNextSubHitID.ProperCommand();
     CJsonNode request(MkStdRequest("CREATE"));
 
-    x_SetStorageFlags(request, flags);
+    x_SetStorageFlags(request, GetFlags(flags));
 
     CNetServerConnection conn;
 
@@ -765,7 +765,7 @@ CNetStorageObject SNetStorageRPC::Create(TNetStorageFlags flags)
 
     return new SNetStorageObjectRPC(this, request, conn,
             SNetStorageObjectRPC::eByGeneratedID,
-            object_loc, flags, SNetStorageObjectRPC::eWriting);
+            object_loc, 0, SNetStorageObjectRPC::eWriting);
 }
 
 CNetStorageObject SNetStorageRPC::Open(const string& object_loc)
@@ -779,7 +779,7 @@ CNetStorageObject SNetStorageRPC::Open(const string& object_loc)
 }
 
 string SNetStorageRPC::Relocate(const string& object_loc,
-        TNetStorageFlags flags)
+        TNetStorageFlags flags, TNetStorageProgressCb /*cb*/)
 {
     if (x_NetCacheMode(object_loc))
         NCBI_THROW_FMT(CNetStorageException, eNotSupported, object_loc <<
@@ -794,6 +794,8 @@ string SNetStorageRPC::Relocate(const string& object_loc,
 
     request.SetByKey("NewLocation", new_location);
 
+    // TODO: CXX-8302
+
     return Exchange(GetServiceFromLocator(object_loc),
             request).GetString("ObjectLoc");
 }
@@ -808,8 +810,15 @@ bool SNetStorageRPC::Exists(const string& object_loc)
 
     CJsonNode request(MkObjectRequest("EXISTS", object_loc));
 
-    return Exchange(GetServiceFromLocator(object_loc),
-            request).GetBoolean("Exists");
+    try {
+        return Exchange(GetServiceFromLocator(object_loc),
+                request).GetBoolean("Exists");
+    }
+    catch (CNetStorageException& e) {
+        if (e.GetErrCode() != CNetStorageException::eExpired) throw;
+    }
+
+    return false;
 }
 
 ENetStorageRemoveResult SNetStorageRPC::Remove(const string& object_loc)
@@ -828,10 +837,18 @@ ENetStorageRemoveResult SNetStorageRPC::Remove(const string& object_loc)
 
     m_UseNextSubHitID.ProperCommand();
     CJsonNode request(MkObjectRequest("DELETE", object_loc));
-    CJsonNode response(Exchange(GetServiceFromLocator(object_loc), request));
-    CJsonNode not_found(response.GetByKeyOrNull("NotFound"));
 
-    return not_found && not_found.AsBoolean() ? eNSTRR_NotFound : eNSTRR_Removed;
+    try {
+        CJsonNode response(Exchange(GetServiceFromLocator(object_loc), request));
+        CJsonNode not_found(response.GetByKeyOrNull("NotFound"));
+
+        return not_found && not_found.AsBoolean() ? eNSTRR_NotFound : eNSTRR_Removed;
+    }
+    catch (CNetStorageException& e) {
+        if (e.GetErrCode() != CNetStorageException::eExpired) throw;
+    }
+
+    return eNSTRR_NotFound;
 }
 
 class CJsonOverUTTPExecHandler : public INetServerExecHandler
@@ -967,7 +984,7 @@ CJsonNode SNetStorageRPC::MkObjectRequest(const string& request_type,
     user_key.SetString("UniqueID", unique_key);
     new_request.SetByKey("UserKey", user_key);
 
-    x_SetStorageFlags(new_request, flags);
+    x_SetStorageFlags(new_request, GetFlags(flags));
     return new_request;
 }
 
@@ -1416,12 +1433,13 @@ struct SNetStorageByKeyRPC : public SNetStorageByKeyImpl
             TNetStorageFlags default_flags);
 
     virtual CNetStorageObject Open(const string& unique_key,
-            TNetStorageFlags flags = 0);
+            TNetStorageFlags flags);
     virtual string Relocate(const string& unique_key,
-            TNetStorageFlags flags, TNetStorageFlags old_flags = 0);
-    virtual bool Exists(const string& key, TNetStorageFlags flags = 0);
+            TNetStorageFlags flags, TNetStorageFlags old_flags,
+            TNetStorageProgressCb cb);
+    virtual bool Exists(const string& key, TNetStorageFlags flags);
     virtual ENetStorageRemoveResult Remove(const string& key,
-            TNetStorageFlags flags = 0);
+            TNetStorageFlags flags);
 
 #ifdef NCBI_GRID_XSITE_CONN_SUPPORT
     void AllowXSiteConnections() { m_NetStorageRPC->AllowXSiteConnections(); }
@@ -1450,7 +1468,8 @@ CNetStorageObject SNetStorageByKeyRPC::Open(const string& unique_key,
 }
 
 string SNetStorageByKeyRPC::Relocate(const string& unique_key,
-        TNetStorageFlags flags, TNetStorageFlags old_flags)
+        TNetStorageFlags flags, TNetStorageFlags old_flags,
+        TNetStorageProgressCb /*cb*/)
 {
     m_NetStorageRPC->m_UseNextSubHitID.ProperCommand();
     CJsonNode request(m_NetStorageRPC->MkObjectRequest(
@@ -1462,6 +1481,8 @@ string SNetStorageByKeyRPC::Relocate(const string& unique_key,
 
     request.SetByKey("NewLocation", new_location);
 
+    // TODO: CXX-8302
+
     return m_NetStorageRPC->Exchange(m_NetStorageRPC->m_Service,
             request).GetString("ObjectLoc");
 }
@@ -1470,8 +1491,15 @@ bool SNetStorageByKeyRPC::Exists(const string& key, TNetStorageFlags flags)
 {
     CJsonNode request(m_NetStorageRPC->MkObjectRequest("EXISTS", key, flags));
 
-    return m_NetStorageRPC->Exchange(m_NetStorageRPC->m_Service,
-            request).GetBoolean("Exists");
+    try {
+        return m_NetStorageRPC->Exchange(m_NetStorageRPC->m_Service,
+                request).GetBoolean("Exists");
+    }
+    catch (CNetStorageException& e) {
+        if (e.GetErrCode() != CNetStorageException::eExpired) throw;
+    }
+
+    return false;
 }
 
 ENetStorageRemoveResult SNetStorageByKeyRPC::Remove(const string& key,
@@ -1480,12 +1508,19 @@ ENetStorageRemoveResult SNetStorageByKeyRPC::Remove(const string& key,
     m_NetStorageRPC->m_UseNextSubHitID.ProperCommand();
     CJsonNode request(m_NetStorageRPC->MkObjectRequest("DELETE", key, flags));
 
-    CJsonNode response(
-            m_NetStorageRPC->Exchange(m_NetStorageRPC->m_Service, request));
+    try {
+        CJsonNode response(
+                m_NetStorageRPC->Exchange(m_NetStorageRPC->m_Service, request));
+
+        CJsonNode not_found(response.GetByKeyOrNull("NotFound"));
 
-    CJsonNode not_found(response.GetByKeyOrNull("NotFound"));
+        return not_found && not_found.AsBoolean() ? eNSTRR_NotFound : eNSTRR_Removed;
+    }
+    catch (CNetStorageException& e) {
+        if (e.GetErrCode() != CNetStorageException::eExpired) throw;
+    }
 
-    return not_found && not_found.AsBoolean() ? eNSTRR_NotFound : eNSTRR_Removed;
+    return eNSTRR_NotFound;
 }
 
 struct SNetStorageAdminImpl : public CObject
diff --git a/c++/src/connect/services/netstorage_rpc.hpp b/c++/src/connect/services/netstorage_rpc.hpp
index 7903a54..83c2a69 100644
--- a/c++/src/connect/services/netstorage_rpc.hpp
+++ b/c++/src/connect/services/netstorage_rpc.hpp
@@ -1,7 +1,7 @@
 #ifndef CONNECT_SERVICES__NETSTORAGE_RPC__HPP
 #define CONNECT_SERVICES__NETSTORAGE_RPC__HPP
 
-/*  $Id: netstorage_rpc.hpp 499028 2016-04-21 15:25:58Z ivanov $
+/*  $Id: netstorage_rpc.hpp 505978 2016-06-30 15:57:38Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -44,9 +44,10 @@ struct SNetStorageRPC : public SNetStorageImpl
 {
     SNetStorageRPC(const TConfig& config, TNetStorageFlags default_flags);
 
-    virtual CNetStorageObject Create(TNetStorageFlags flags = 0);
+    virtual CNetStorageObject Create(TNetStorageFlags flags);
     virtual CNetStorageObject Open(const string& object_loc);
-    virtual string Relocate(const string& object_loc, TNetStorageFlags flags);
+    virtual string Relocate(const string& object_loc, TNetStorageFlags flags,
+            TNetStorageProgressCb cb);
     virtual bool Exists(const string& object_loc);
     virtual ENetStorageRemoveResult Remove(const string& object_loc);
 
@@ -80,7 +81,15 @@ struct SNetStorageRPC : public SNetStorageImpl
         return service;
     }
 
+    TNetStorageFlags GetFlags(TNetStorageFlags flags) const
+    {
+        return flags ? flags : m_DefaultFlags;
+    }
+
+private:
     TNetStorageFlags m_DefaultFlags;
+
+public:
     CNetService m_Service;
 
     const TConfig m_Config;
diff --git a/c++/src/connect/services/netstorageobjectinfo.cpp b/c++/src/connect/services/netstorageobjectinfo.cpp
index 09d2a75..672d0fe 100644
--- a/c++/src/connect/services/netstorageobjectinfo.cpp
+++ b/c++/src/connect/services/netstorageobjectinfo.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netstorageobjectinfo.cpp 499845 2016-04-28 16:13:50Z ivanov $
+/*  $Id: netstorageobjectinfo.cpp 516423 2016-10-13 14:58:14Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -129,11 +129,22 @@ private:
 template <>
 CTime SLazyInitData::GetTime<eNFL_FileTrack>()
 {
-    const char* const kISO8601TimeFormat = "Y-M-DTh:m:s.ro";
-
     if (st_info) {
         if (CJsonNode ctime = st_info.GetByKeyOrNull("ctime")) {
-            return CTime(ctime.AsString(), kISO8601TimeFormat).ToLocalTime();
+            const string ctime_string = ctime.AsString();
+
+            // TODO:
+            // Remove code related to old format after
+            // all NetStorage servers upgraded to contain CXX-8230.
+            try {
+                return CTime(ctime_string, "Y-M-DTh:m:s.rZ").ToLocalTime();
+            }
+            catch (CTimeException& ex) {
+                if (ex.GetErrCode() != CTimeException::eFormat) throw;
+
+                // Try old format.
+                return CTime(ctime_string, "Y-M-DTh:m:s.ro").ToLocalTime();
+            }
         }
     }
 
diff --git a/c++/src/connect/services/netstorageobjectloc.cpp b/c++/src/connect/services/netstorageobjectloc.cpp
index 11062aa..f3a91cf 100644
--- a/c++/src/connect/services/netstorageobjectloc.cpp
+++ b/c++/src/connect/services/netstorageobjectloc.cpp
@@ -1,4 +1,4 @@
-/*  $Id: netstorageobjectloc.cpp 499845 2016-04-28 16:13:50Z ivanov $
+/*  $Id: netstorageobjectloc.cpp 499705 2016-04-27 17:58:55Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/connect/services/ns_output_parser.cpp b/c++/src/connect/services/ns_output_parser.cpp
index c34c8b3..71777ee 100644
--- a/c++/src/connect/services/ns_output_parser.cpp
+++ b/c++/src/connect/services/ns_output_parser.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ns_output_parser.cpp 479861 2015-09-23 21:07:21Z sadyrovr $
+/*  $Id: ns_output_parser.cpp 502215 2016-05-23 15:27:45Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -36,246 +36,6 @@
 
 BEGIN_NCBI_SCOPE
 
-#define INVALID_FORMAT_ERROR() \
-    NCBI_THROW2(CStringException, eFormat, \
-            (*m_Ch == '\0' ? "Unexpected end of NetSchedule output" : \
-                    "Syntax error in structured NetSchedule output"), \
-            GetPosition())
-
-CJsonNode CNetScheduleStructuredOutputParser::ParseJSON(const string& json)
-{
-    m_Ch = (m_NSOutput = json).c_str();
-
-    while (isspace((unsigned char) *m_Ch))
-        ++m_Ch;
-
-    CJsonNode root;
-
-    switch (*m_Ch) {
-    case '[':
-        ++m_Ch;
-        root = ParseArray(']');
-        break;
-
-    case '{':
-        ++m_Ch;
-        root = ParseObject('}');
-        break;
-
-    default:
-        INVALID_FORMAT_ERROR();
-    }
-
-    while (isspace((unsigned char) *m_Ch))
-        ++m_Ch;
-
-    if (*m_Ch != '\0') {
-        INVALID_FORMAT_ERROR();
-    }
-
-    return root;
-}
-
-string CNetScheduleStructuredOutputParser::ParseString(size_t max_len)
-{
-    size_t len;
-    string val(NStr::ParseQuoted(CTempString(m_Ch, max_len), &len));
-
-    m_Ch += len;
-    return val;
-}
-
-Int8 CNetScheduleStructuredOutputParser::ParseInt(size_t len)
-{
-    Int8 val = NStr::StringToInt8(CTempString(m_Ch, len));
-
-    if (*m_Ch == '-') {
-        ++m_Ch;
-        --len;
-    }
-    if (*m_Ch == '0' && len > 1) {
-        NCBI_THROW2(CStringException, eFormat,
-                "Leading zeros are not allowed", GetPosition());
-    }
-
-    m_Ch += len;
-    return val;
-}
-
-double CNetScheduleStructuredOutputParser::ParseDouble(size_t len)
-{
-    double val = NStr::StringToDouble(CTempString(m_Ch, len));
-
-    m_Ch += len;
-    return val;
-}
-
-bool CNetScheduleStructuredOutputParser::MoreNodes()
-{
-    while (isspace((unsigned char) *m_Ch))
-        ++m_Ch;
-    if (*m_Ch != ',')
-        return false;
-    while (isspace((unsigned char) *++m_Ch))
-        ;
-    return true;
-}
-
-CJsonNode CNetScheduleStructuredOutputParser::ParseObject(char closing_char)
-{
-    CJsonNode result(CJsonNode::NewObjectNode());
-
-    while (isspace((unsigned char) *m_Ch))
-        ++m_Ch;
-
-    if (*m_Ch == closing_char) {
-        ++m_Ch;
-        return result;
-    }
-
-    while (*m_Ch == '\'' || *m_Ch == '"') {
-        // New attribute/value pair
-        string attr_name(ParseString(GetRemainder()));
-
-        while (isspace((unsigned char) *m_Ch))
-            ++m_Ch;
-        if (*m_Ch == ':' || *m_Ch == '=')
-            while (isspace((unsigned char) *++m_Ch))
-                ;
-
-        result.SetByKey(attr_name, ParseValue());
-
-        if (!MoreNodes()) {
-            if (*m_Ch != closing_char)
-                break;
-            ++m_Ch;
-            return result;
-        }
-    }
-
-    INVALID_FORMAT_ERROR();
-}
-
-CJsonNode CNetScheduleStructuredOutputParser::ParseArray(char closing_char)
-{
-    CJsonNode result(CJsonNode::NewArrayNode());
-
-    while (isspace((unsigned char) *m_Ch))
-        ++m_Ch;
-
-    if (*m_Ch == closing_char) {
-        ++m_Ch;
-        return result;
-    }
-
-    do
-        result.Append(ParseValue());
-    while (MoreNodes());
-
-    if (*m_Ch == closing_char) {
-        ++m_Ch;
-        return result;
-    }
-
-    INVALID_FORMAT_ERROR();
-}
-
-CJsonNode CNetScheduleStructuredOutputParser::ParseValue()
-{
-    size_t max_len = GetRemainder();
-    size_t len = 0;
-
-    switch (*m_Ch) {
-    /* Array */
-    case '[':
-        ++m_Ch;
-        return ParseArray(']');
-
-    /* Object */
-    case '{':
-        ++m_Ch;
-        return ParseObject('}');
-
-    /* String */
-    case '\'':
-    case '"':
-        return CJsonNode::NewStringNode(ParseString(max_len));
-
-    /* Number */
-    case '-':
-        // Check that there's at least one digit after the minus sign.
-        if (max_len <= 1 || !isdigit((unsigned char) m_Ch[1])) {
-            ++m_Ch;
-            break;
-        }
-        len = 1;
-
-    case '0': case '1': case '2': case '3': case '4':
-    case '5': case '6': case '7': case '8': case '9':
-        // Skim through the integer part.
-        do
-            if (++len >= max_len)
-                return CJsonNode::NewIntegerNode(ParseInt(len));
-        while (isdigit((unsigned char) m_Ch[len]));
-
-        // Stumbled upon a non-digit character -- check
-        // if it's a fraction part or an exponent part.
-        switch (m_Ch[len]) {
-        case '.':
-            if (++len == max_len || !isdigit((unsigned char) m_Ch[len])) {
-                NCBI_THROW2(CStringException, eFormat,
-                        "At least one digit after the decimal "
-                        "point is required", GetPosition());
-            }
-            for (;;) {
-                if (++len == max_len)
-                    return CJsonNode::NewDoubleNode(ParseDouble(len));
-
-                if (!isdigit((unsigned char) m_Ch[len])) {
-                    if (m_Ch[len] == 'E' || m_Ch[len] == 'e')
-                        break;
-
-                    return CJsonNode::NewDoubleNode(ParseDouble(len));
-                }
-            }
-            /* FALL THROUGH */
-
-        case 'E':
-        case 'e':
-            if (++len == max_len ||
-                    (m_Ch[len] == '-' || m_Ch[len] == '+' ?
-                            ++len == max_len ||
-                                    !isdigit((unsigned char) m_Ch[len]) :
-                            !isdigit((unsigned char) m_Ch[len]))) {
-                m_Ch += len;
-                NCBI_THROW2(CStringException, eFormat,
-                        "Invalid exponent specification", GetPosition());
-            }
-            while (++len < max_len && isdigit((unsigned char) m_Ch[len]))
-                ;
-            return CJsonNode::NewDoubleNode(ParseDouble(len));
-
-        default:
-            return CJsonNode::NewIntegerNode(ParseInt(len));
-        }
-
-    /* Constant */
-    case 'F': case 'f': case 'N': case 'n':
-    case 'T': case 't': case 'Y': case 'y':
-        while (len <= max_len && isalpha((unsigned char) m_Ch[len]))
-            ++len;
-
-        {
-            CTempString val(m_Ch, len);
-            m_Ch += len;
-            return val == "null" ? CJsonNode::NewNullNode() :
-                CJsonNode::NewBooleanNode(NStr::StringToBool(val));
-        }
-    }
-
-    INVALID_FORMAT_ERROR();
-}
-
 CAttrListParser::ENextAttributeType CAttrListParser::NextAttribute(
     CTempString* attr_name, string* attr_value, size_t* attr_column)
 {
diff --git a/c++/src/connect/services/srv_connections.cpp b/c++/src/connect/services/srv_connections.cpp
index 990256b..45f91d9 100644
--- a/c++/src/connect/services/srv_connections.cpp
+++ b/c++/src/connect/services/srv_connections.cpp
@@ -1,4 +1,4 @@
-/*  $Id: srv_connections.cpp 495142 2016-03-15 14:04:30Z ivanov $
+/*  $Id: srv_connections.cpp 494943 2016-03-11 20:01:22Z sadyrovr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/connect/services/tmp_wn_info.cpp b/c++/src/connect/services/tmp_wn_info.cpp
index 13c63c4..1c5762a 100644
--- a/c++/src/connect/services/tmp_wn_info.cpp
+++ b/c++/src/connect/services/tmp_wn_info.cpp
@@ -1,4 +1,4 @@
-/*  $Id: tmp_wn_info.cpp 486255 2015-12-02 17:51:03Z sadyrovr $
+/*  $Id: tmp_wn_info.cpp 504536 2016-06-16 12:42:34Z kazimird $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -124,13 +124,19 @@ CJsonNode g_GetWorkerNodeInfo(CNetScheduleAPI api)
     s_GetWorkerNodes(api, worker_nodes);
 
     ITERATE(list<CNetScheduleAdmin::SWorkerNodeInfo>, wn_info, worker_nodes) {
-        CNetScheduleAPI wn_api(wn_info->host + ':' +
-                NStr::NumericToString(wn_info->port),
-                api->m_Service->GetClientName(),
-                kEmptyStr);
-
-        result.SetByKey(wn_info->prog, s_WorkerNodeInfoToJson(
-                wn_api.GetService().Iterate().GetServer()));
+        string wn_address = wn_info->host + ':' +
+                NStr::NumericToString(wn_info->port);
+        try {
+            CNetScheduleAPI wn_api(wn_address,
+                    api->m_Service->GetClientName(),
+                    kEmptyStr);
+
+            result.SetByKey(wn_info->prog, s_WorkerNodeInfoToJson(
+                    wn_api.GetService().Iterate().GetServer()));
+        }
+        catch (CException& e) {
+            LOG_POST(Error << e);
+        }
     }
 
     return result;
diff --git a/c++/src/connect/services/wn_main_loop.cpp b/c++/src/connect/services/wn_main_loop.cpp
index 37b58f4..1cc2c71 100644
--- a/c++/src/connect/services/wn_main_loop.cpp
+++ b/c++/src/connect/services/wn_main_loop.cpp
@@ -1,4 +1,4 @@
-/*  $Id: wn_main_loop.cpp 489744 2016-01-15 16:50:24Z sadyrovr $
+/*  $Id: wn_main_loop.cpp 518714 2016-11-07 18:04:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -702,12 +702,13 @@ bool CMainLoopThread::CImpl::MoreJobs(const SEntry& /*entry*/)
 bool CMainLoopThread::CImpl::CheckEntry(
         SEntry& entry,
         const string& prio_aff_list,
+        bool any_affinity,
         CNetScheduleJob& job,
         CNetScheduleAPI::EJobStatus* /*job_status*/)
 {
     CNetServer server(m_API.GetService()->GetServer(entry.server_address));
     return m_WorkerNode->m_NSExecutor->x_GetJobWithAffinityLadder(server,
-            m_Timeout, prio_aff_list, job);
+            m_Timeout, prio_aff_list, any_affinity, job);
 }
 
 void CMainLoopThread::CImpl::ReturnJob(CNetScheduleJob& job)
diff --git a/c++/src/corelib/ddumpable.cpp b/c++/src/corelib/ddumpable.cpp
index 12c92d3..7dc2f26 100644
--- a/c++/src/corelib/ddumpable.cpp
+++ b/c++/src/corelib/ddumpable.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ddumpable.cpp 493118 2016-02-24 15:43:33Z ivanov $
+/*  $Id: ddumpable.cpp 493042 2016-02-23 19:38:23Z gouriano $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/corelib/env_reg.cpp b/c++/src/corelib/env_reg.cpp
index a90dc98..ce503b5 100644
--- a/c++/src/corelib/env_reg.cpp
+++ b/c++/src/corelib/env_reg.cpp
@@ -1,4 +1,4 @@
-/*  $Id: env_reg.cpp 495404 2016-03-17 13:28:04Z ivanov $
+/*  $Id: env_reg.cpp 507064 2016-07-14 15:29:09Z elisovdn $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -247,7 +247,7 @@ bool CEnvironmentRegistry::x_Set(const string& section, const string& name,
 
 
 bool CEnvironmentRegistry::x_Unset(const string& section, const string& name,
-                                   TFlags flags)
+                                   TFlags /*flags*/)
 {
     bool result = false;
     ITERATE (TPriorityMap, it, m_PriorityMap) {
@@ -346,6 +346,7 @@ bool CNcbiEnvRegMapper::EnvToReg(const string& env, string& section,
     if (uu_pos == NPOS  ||  uu_pos == env.size() - 2) {
         return false;
     }
+    /* Parse section and entry names from the variable */
     if (env[kPfxLen] == '_') { // regular entry
         section = env.substr(kPfxLen + 1, uu_pos - kPfxLen - 1);
         name    = env.substr(uu_pos + 2);
@@ -355,6 +356,14 @@ bool CNcbiEnvRegMapper::EnvToReg(const string& env, string& section,
         name[0] = '.';
         section = env.substr(uu_pos + 2);
     }
+    if (!IRegistry::IsNameSection(section, 0)) {
+        LOG_POST(Info << "Invalid registry section name in environment "
+                            "variable " << env);
+    }
+    if (!IRegistry::IsNameEntry(name, 0)) {
+        LOG_POST(Info << "Invalid registry entry name in environment "
+                            "variable " << env);
+    }
     NStr::ReplaceInPlace(section, "_DOT_", ".");
     NStr::ReplaceInPlace(name,    "_DOT_", ".");
     return true;
diff --git a/c++/src/corelib/expr.cpp b/c++/src/corelib/expr.cpp
index 69d5056..8fd323c 100644
--- a/c++/src/corelib/expr.cpp
+++ b/c++/src/corelib/expr.cpp
@@ -1,4 +1,4 @@
-/*  $Id: expr.cpp 408848 2013-08-02 13:32:46Z ivanov $
+/*  $Id: expr.cpp 500405 2016-05-04 15:18:35Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -779,7 +779,7 @@ void CExprParser::Parse(const char* str)
             }
         }
 
-        int n_args = 1;
+        n_args = 1;
 
         while (sm_lpr[m_OStack[m_o_sp-1]] >= sm_rpr[oper]) { 
             int cop = m_OStack[--m_o_sp]; 
diff --git a/c++/src/corelib/ncbi_cookies.cpp b/c++/src/corelib/ncbi_cookies.cpp
index b7843d7..03863b6 100644
--- a/c++/src/corelib/ncbi_cookies.cpp
+++ b/c++/src/corelib/ncbi_cookies.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbi_cookies.cpp 486111 2015-12-01 17:17:39Z grichenk $
+/*  $Id: ncbi_cookies.cpp 517040 2016-10-20 11:22:39Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -80,7 +80,6 @@ CHttpCookie::CHttpCookie(const CTempString& name,
                          const CTempString& path)
     : m_Name(name),
       m_Value(value),
-      m_Domain(domain),
       m_Path(path),
       m_Expires(CTime::eEmpty, CTime::eGmt),
       m_Secure(false),
@@ -89,6 +88,7 @@ CHttpCookie::CHttpCookie(const CTempString& name,
       m_Accessed(CTime::eCurrent, CTime::eGmt),
       m_HostOnly(false)
 {
+    SetDomain(domain); // store canonical domain
     if ( m_Name.empty() ) {
         NCBI_THROW(CHttpCookieException, eValue, "Empty cookie name");
     }
@@ -469,9 +469,10 @@ bool CHttpCookie::Parse(const CTempString& str)
     m_Secure = false;
     m_HttpOnly = false;
     m_Extension.clear();
+    m_HostOnly = false;
+    // Update the creation and access time to current.
     m_Created.SetCurrent();
     m_Accessed.SetCurrent();
-    m_HostOnly = false;
 
     string err_msg;
     size_t pos = str.find(';');
@@ -502,10 +503,6 @@ bool CHttpCookie::Parse(const CTempString& str)
         m_Value = m_Value.substr(1, m_Value.size() - 2);
     }
 
-    // Update the creation and access time.
-    m_Created.SetCurrent();
-    m_Accessed.SetCurrent();
-
     if ( attr_str.empty() ) {
         return true;
     }
@@ -525,7 +522,8 @@ bool CHttpCookie::Parse(const CTempString& str)
         // Assume all values are valid. If they are not, exception
         // will be thrown on an attempt to write the cookie.
         if ( NStr::EqualNocase(name, "domain") ) {
-            m_Domain = NStr::ToLower(value);
+            m_Domain = value;
+            NStr::ToLower(m_Domain);
             if ( NStr::EndsWith(m_Domain, '.') ) {
                 // Ignore domain if it ends with '.'
                 m_Domain.clear();
@@ -637,7 +635,7 @@ bool CHttpCookie::MatchDomain(const string& host) const
         return host == m_Domain;
     }
     size_t pos = h.find(m_Domain);
-    // Domain matching: cookie_domain must be identical to host,
+    // Domain matching: cookie domain must be identical to host,
     // or be a suffix of host and the last char before the suffix
     // must be '.'.
     if (pos == NPOS  ||
diff --git a/c++/src/corelib/ncbi_param.cpp b/c++/src/corelib/ncbi_param.cpp
index f585f0b..d9dc474 100644
--- a/c++/src/corelib/ncbi_param.cpp
+++ b/c++/src/corelib/ncbi_param.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbi_param.cpp 468199 2015-05-21 13:10:41Z grichenk $
+/*  $Id: ncbi_param.cpp 500405 2016-05-04 15:18:35Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -164,10 +164,10 @@ bool NCBI_XNCBI_EXPORT g_GetConfigFlag(const char* section,
         CMutexGuard guard(CNcbiApplication::GetInstanceMutex());
         CNcbiApplication* app = CNcbiApplication::Instance();
         if ( app  &&  app->HasLoadedConfig() ) {
-            const string& str = app->GetConfig().Get(section, variable);
-            if ( !str.empty() ) {
+            const string& s = app->GetConfig().Get(section, variable);
+            if ( !s.empty() ) {
                 try {
-                    bool value = s_StringToBool(str);
+                    bool value = s_StringToBool(s);
 #ifdef _DEBUG
                     if ( is_config_dump ) {
                         s_ConfigDump = value;
@@ -228,16 +228,16 @@ int NCBI_XNCBI_EXPORT g_GetConfigInt(const char* section,
             if ( s_CanDumpConfig() ) {
                 if ( section  &&  *section ) {
                     DUMP_CONFIG(11, "NCBI_CONFIG: int variable"
-                                    " [" << section << "]"
-                                    " " << variable <<
-                                    " = " << value <<
-                                    " from env var " <<
+                                    " ["  << section  << "]"
+                                    " "   << variable <<
+                                    " = " << value    <<
+                                    " from env var "  <<
                                     s_GetEnvVarName(section, variable, env_var_name));
                 }
                 else {
                     DUMP_CONFIG(12, "NCBI_CONFIG: int variable "
-                                    " " << variable <<
-                                    " = " << value <<
+                                    " "   << variable <<
+                                    " = " << value    <<
                                     " from env var");
                 }
             }
@@ -253,16 +253,16 @@ int NCBI_XNCBI_EXPORT g_GetConfigInt(const char* section,
         CMutexGuard guard(CNcbiApplication::GetInstanceMutex());
         CNcbiApplication* app = CNcbiApplication::Instance();
         if ( app  &&  app->HasLoadedConfig() ) {
-            const string& str = app->GetConfig().Get(section, variable);
-            if ( !str.empty() ) {
+            const string& s = app->GetConfig().Get(section, variable);
+            if ( !s.empty() ) {
                 try {
-                    int value = NStr::StringToInt(str);
+                    int value = NStr::StringToInt(s);
 #ifdef _DEBUG
                     if ( s_CanDumpConfig() ) {
                         DUMP_CONFIG(10, "NCBI_CONFIG: int variable"
-                                        " [" << section << "]"
-                                        " " << variable <<
-                                        " = " << value <<
+                                        " ["  << section  << "]"
+                                        " "   << variable <<
+                                        " = " << value    <<
                                         " from registry");
                     }
 #endif
@@ -338,18 +338,18 @@ double NCBI_XNCBI_EXPORT g_GetConfigDouble(const char* section,
         CMutexGuard guard(CNcbiApplication::GetInstanceMutex());
         CNcbiApplication* app = CNcbiApplication::Instance();
         if ( app  &&  app->HasLoadedConfig() ) {
-            const string& str = app->GetConfig().Get(section, variable);
-            if ( !str.empty() ) {
+            const string& s = app->GetConfig().Get(section, variable);
+            if ( !s.empty() ) {
                 try {
-                    double value = NStr::StringToDouble(str,
+                    double value = NStr::StringToDouble(s,
                         NStr::fDecimalPosixOrLocal |
                         NStr::fAllowLeadingSpaces | NStr::fAllowTrailingSpaces);
 #ifdef _DEBUG
                     if ( s_CanDumpConfig() ) {
                         DUMP_CONFIG(10, "NCBI_CONFIG: double variable"
-                                        " [" << section << "]"
-                                        " " << variable <<
-                                        " = " << value <<
+                                        " ["  << section  << "]"
+                                        " "   << variable <<
+                                        " = " << value    <<
                                         " from registry");
                     }
 #endif
@@ -417,18 +417,18 @@ string NCBI_XNCBI_EXPORT g_GetConfigString(const char* section,
         CMutexGuard guard(CNcbiApplication::GetInstanceMutex());
         CNcbiApplication* app = CNcbiApplication::Instance();
         if ( app  &&  app->HasLoadedConfig() ) {
-            const string& value = app->GetConfig().Get(section, variable);
-            if ( !value.empty() ) {
+            const string& v = app->GetConfig().Get(section, variable);
+            if ( !v.empty() ) {
 #ifdef _DEBUG
                 if ( s_CanDumpConfig() ) {
                     DUMP_CONFIG(15, "NCBI_CONFIG: str variable"
-                                    " [" << section << "]"
-                                    " " << variable <<
+                                    " [" << section  << "]"
+                                    " "  << variable <<
                                     " = \"" << value << "\""
                                     " from registry");
                 }
 #endif
-                return value;
+                return v;
             }
         }
     }
diff --git a/c++/src/corelib/ncbi_stack.cpp b/c++/src/corelib/ncbi_stack.cpp
index a79b67a..bad71b4 100644
--- a/c++/src/corelib/ncbi_stack.cpp
+++ b/c++/src/corelib/ncbi_stack.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbi_stack.cpp 463583 2015-03-30 18:05:28Z vasilche $
+/*  $Id: ncbi_stack.cpp 500861 2016-05-09 16:32:20Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -58,8 +58,15 @@ BEGIN_NCBI_SCOPE
 
 string CStackTrace::SStackFrameInfo::AsString(void) const
 {
-    return module + " " + file + ":" + NStr::UInt8ToString(line) + " " + func +
-        " offset=0x" + NStr::UInt8ToString(offs, 0, 16);
+    return module + " " + file + ":" + NStr::NumericToString(line) + " " + func +
+        " offset=0x" + NStr::NumericToString(offs, 0, 16) +
+// On Windows PtrToString does not add 0x prefix, while on Linux it does.
+#if defined NCBI_OS_MSWIN
+        " addr=0x" + 
+#else
+        " addr=" + 
+#endif
+        NStr::PtrToString(addr);
 }
 
 
diff --git a/c++/src/corelib/ncbi_stack_linux.cpp b/c++/src/corelib/ncbi_stack_linux.cpp
index bfbe282..c6dafb7 100644
--- a/c++/src/corelib/ncbi_stack_linux.cpp
+++ b/c++/src/corelib/ncbi_stack_linux.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbi_stack_linux.cpp 488254 2015-12-29 13:56:26Z ivanov $
+/*  $Id: ncbi_stack_linux.cpp 500861 2016-05-09 16:32:20Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -80,7 +80,14 @@ void CStackTraceImpl::Expand(CStackTrace::TStack& stack)
         info.offs = 0;
         info.line = 0;
 
-        string::size_type pos = sym.find_first_of("(");
+        string::size_type pos = sym.find_last_of("[");
+        if (pos != string::npos) {
+            string::size_type epos = sym.find_first_of("]", pos + 1);
+            if (epos != string::npos) {
+                info.addr = NStr::StringToPtr(sym.substr(pos + 1, epos - pos - 1));
+            }
+        }
+        pos = sym.find_first_of("(");
         if (pos != string::npos) {
             info.module = sym.substr(0, pos);
             sym.erase(0, pos + 1);
diff --git a/c++/src/corelib/ncbi_stack_solaris.cpp b/c++/src/corelib/ncbi_stack_solaris.cpp
index 2be7535..20a00f9 100644
--- a/c++/src/corelib/ncbi_stack_solaris.cpp
+++ b/c++/src/corelib/ncbi_stack_solaris.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbi_stack_solaris.cpp 104013 2007-05-15 19:27:33Z grichenk $
+/*  $Id: ncbi_stack_solaris.cpp 500861 2016-05-09 16:32:20Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -65,7 +65,7 @@ extern "C"
 int s_StackWalker(uintptr_t int_ptr, int, void* data)
 {
     CStackTrace::TStack* stack_trace = (CStackTrace::TStack*)data;
-    CStackTrace::SStackFrameInfo sf_info;
+    CStackTrace::SStackFrameInfo sf_info((void*)int_ptr);
     Dl_info info;
     if (dladdr((void*)int_ptr, &info)) {
         sf_info.func = info.dli_sname;
diff --git a/c++/src/corelib/ncbi_stack_win32.cpp b/c++/src/corelib/ncbi_stack_win32.cpp
index 234f805..b69b575 100644
--- a/c++/src/corelib/ncbi_stack_win32.cpp
+++ b/c++/src/corelib/ncbi_stack_win32.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbi_stack_win32.cpp 403742 2013-06-18 15:26:09Z grichenk $
+/*  $Id: ncbi_stack_win32.cpp 500861 2016-05-09 16:32:20Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -538,7 +538,7 @@ void CStackTraceImpl::Expand(CStackTrace::TStack& stack)
 
     try {
         ITERATE(TStack, it, m_Stack) {
-            CStackTrace::SStackFrameInfo sf_info;
+            CStackTrace::SStackFrameInfo sf_info((void*)it->AddrPC.Offset);
             sf_info.func = "<cannot get function name for this address>";
 
             if ( !SymGetSymFromAddr(curr_proc,
diff --git a/c++/src/corelib/ncbi_stack_win64.cpp b/c++/src/corelib/ncbi_stack_win64.cpp
index a14ef55..5ce5a55 100644
--- a/c++/src/corelib/ncbi_stack_win64.cpp
+++ b/c++/src/corelib/ncbi_stack_win64.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbi_stack_win64.cpp 456287 2015-01-09 14:29:15Z grichenk $
+/*  $Id: ncbi_stack_win64.cpp 500861 2016-05-09 16:32:20Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -416,7 +416,7 @@ void CStackTraceImpl::Expand(CStackTrace::TStack& stack)
 
     try {
         ITERATE(TStack, it, m_Stack) {
-            CStackTrace::SStackFrameInfo sf_info;
+            CStackTrace::SStackFrameInfo sf_info((void*)it->AddrPC.Offset);
             sf_info.func = "<cannot get function name for this address>";
 
             if ( !SymGetSymFromAddr64(curr_proc, it->AddrPC.Offset, &offs64, pSym) ) {
diff --git a/c++/src/corelib/ncbi_system.cpp b/c++/src/corelib/ncbi_system.cpp
index 2e26c1e..f01663b 100644
--- a/c++/src/corelib/ncbi_system.cpp
+++ b/c++/src/corelib/ncbi_system.cpp
@@ -1,4 +1,4 @@
-/* $Id: ncbi_system.cpp 488254 2015-12-29 13:56:26Z ivanov $
+/* $Id: ncbi_system.cpp 500405 2016-05-04 15:18:35Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1084,7 +1084,12 @@ extern void SuppressSystemMessageBox(TSuppressSystemMessageBox mode)
         SetUnhandledExceptionFilter(_SEH_Handler);
     }
     s_DoneSuppressSystemMessageBox = true;
-#endif //NCBI_OS_MSWIN
+
+#else
+    // dummy, to avoid compilation warning
+    mode = 0;
+
+#endif
 }
 
 
diff --git a/c++/src/corelib/ncbi_url.cpp b/c++/src/corelib/ncbi_url.cpp
index d96e61e..4e9101b 100644
--- a/c++/src/corelib/ncbi_url.cpp
+++ b/c++/src/corelib/ncbi_url.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbi_url.cpp 500588 2016-05-05 17:18:11Z ivanov $
+/*  $Id: ncbi_url.cpp 518082 2016-10-31 17:19:46Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -337,6 +337,8 @@ CUrl& CUrl::operator=(const CUrl& url)
         m_OrigArgs = url.m_OrigArgs;
         if ( url.m_ArgsList.get() ) {
             m_ArgsList.reset(new CUrlArgs(*url.m_ArgsList));
+        } else {
+            m_ArgsList.reset();
         }
     }
     return *this;
diff --git a/c++/src/corelib/ncbiapp.cpp b/c++/src/corelib/ncbiapp.cpp
index 6f67430..6ab34ac 100644
--- a/c++/src/corelib/ncbiapp.cpp
+++ b/c++/src/corelib/ncbiapp.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbiapp.cpp 492326 2016-02-16 19:38:11Z ivanov $
+/*  $Id: ncbiapp.cpp 518670 2016-11-07 15:25:48Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -39,6 +39,9 @@
 #include <corelib/syslog.hpp>
 #include <corelib/error_codes.hpp>
 #include <corelib/ncbi_safe_static.hpp>
+#ifdef HAVE_COMMON_NCBI_BUILD_VER_H
+#  include <common/ncbi_build_ver.h>
+#endif
 #include "ncbisys.hpp"
 
 #if defined(NCBI_OS_MSWIN)
@@ -101,7 +104,8 @@ CNcbiApplication* CNcbiApplication::Instance(void)
 
 CNcbiApplication::CNcbiApplication(const SBuildInfo& build_info)
     : m_ConfigLoaded(false),
-      m_LogFile(0)
+      m_LogFile(0),
+      m_LogOptions(0)
 {
     // Initialize UID and start timer
     GetDiagContext().GetUID();
@@ -328,6 +332,118 @@ void CNcbiApplication::x_TryInit(EAppDiagStream diag,
     }
 }
 
+#define NCBI_LOG_PARAM(type,Name,NAME)                                         \
+/* Logging of environment variables: space separated list of names which       \
+   should be logged after each request start.                                */\
+NCBI_PARAM_DECL  (type, Log, LogApp ## Name);                                  \
+NCBI_PARAM_DEF_EX(type, Log, LogApp ## Name, false,                            \
+                  eParam_NoThread, DIAG_LOG_APP_ ## NAME);                     \
+typedef NCBI_PARAM_TYPE(Log, LogApp ## Name) TLogApp ## Name;
+
+
+NCBI_LOG_PARAM(bool, Environment,        ENVIRONMENT)
+NCBI_LOG_PARAM(bool, EnvironmentOnStop,  ENVIRONMENT_ON_STOP)
+NCBI_LOG_PARAM(bool, Registry,           REGISTRY)
+NCBI_LOG_PARAM(bool, RegistryOnStop,     REGISTRY_ON_STOP)
+NCBI_LOG_PARAM(bool, Arguments,          ARGUMENTS)
+NCBI_LOG_PARAM(bool, Path,               PATH)
+NCBI_LOG_PARAM(bool, RunContext,         RUN_CONTEXT)
+
+
+enum ELogOptionsEvent {
+    eStartEvent = 0x01, ///< right before AppMain()
+    eStopEvent  = 0x02, ///< right after AppMain()
+    eOtherEvent = 0x03  ///< any case is fine
+};
+
+
+/// Flags to switch what to log
+enum ELogOptions {
+    fLogAppEnvironment      = 0x01, ///< log app environment on app start
+    fLogAppEnvironmentStop  = 0x02, ///< log app environment on app stop
+    fLogAppRegistry         = 0x04, ///< log app registry on app start
+    fLogAppRegistryStop     = 0x08, ///< log app registry on app stop
+    fLogAppArguments        = 0x10, ///< log app arguments
+    fLogAppPath             = 0x20, ///< log app executable path
+};
+
+
+void CNcbiApplication::x_ReadLogOptions()
+{
+    /* Log all */
+    if ( TLogAppRunContext::GetDefault() ) {
+        m_LogOptions = 0x7f; // all on
+        return;
+    }
+
+    /* Log registry */
+    m_LogOptions |= TLogAppRegistry::GetDefault() ? fLogAppRegistry : 0;
+    m_LogOptions |= 
+        TLogAppRegistryOnStop::GetDefault() ? fLogAppRegistryStop : 0;
+
+    /* Log environment */
+    m_LogOptions |= TLogAppEnvironment::GetDefault() ? fLogAppEnvironment : 0;
+    m_LogOptions |= 
+        TLogAppEnvironmentOnStop::GetDefault() ? fLogAppEnvironmentStop : 0;
+
+    /* Log arguments */
+    m_LogOptions |= TLogAppArguments::GetDefault() ? fLogAppArguments : 0;
+
+    /* Log path */
+    m_LogOptions |= TLogAppPath::GetDefault() ? fLogAppPath : 0;
+}
+
+
+void CNcbiApplication::x_LogOptions(int /*ELogOptionsEvent*/ event)
+{
+    // Print environment values
+    if ( (m_LogOptions & fLogAppEnvironment  &&  event & eStartEvent) ||
+         (m_LogOptions & fLogAppEnvironmentStop  &&  event & eStopEvent) ) {
+        CDiagContext_Extra extra = GetDiagContext().Extra();
+        extra.Print("LogAppEnvironment", "true");
+        list<string> env_keys;
+        const CNcbiEnvironment& env = GetEnvironment();
+        env.Enumerate(env_keys);
+        ITERATE(list<string>, it, env_keys) {
+            const string& val = env.Get(*it);
+            extra.Print(*it, val);
+        }
+    }
+
+    // Print registry values
+    if ( (m_LogOptions & fLogAppRegistry  &&  event & eStartEvent) ||
+         (m_LogOptions & fLogAppRegistryStop  &&  event & eStopEvent) ) {
+        CDiagContext_Extra extra = GetDiagContext().Extra();
+        extra.Print("LogAppRegistry", "true");
+        list<string> reg_sections;
+        const CNcbiRegistry& reg = GetConfig();
+        reg.EnumerateSections(&reg_sections);
+        ITERATE(list<string>, it, reg_sections) {
+            string section, name;
+            list<string> section_entries;
+            reg.EnumerateEntries(*it, &section_entries);
+            ITERATE(list<string>, it_entry, section_entries) {
+                const string& val = reg.Get(*it, *it_entry);
+                string path = "[" + *it + "]" + *it_entry;
+                extra.Print(path, val);
+            }
+        }
+    }
+    
+    if ( m_LogOptions & fLogAppArguments  &&  event & eStartEvent) {
+        CDiagContext_Extra extra = GetDiagContext().Extra();
+        extra.Print("LogAppArguments", "true");
+        string args_str;
+        extra.Print("Arguments", GetArgs().Print(args_str));
+    }
+
+    if ( m_LogOptions & fLogAppPath  &&  event & eStartEvent) {
+        CDiagContext_Extra extra = GetDiagContext().Extra();
+        extra.Print("LogAppPath", "true");
+        extra.Print("Path", GetProgramExecutablePath());
+    }
+}
+
 
 void CNcbiApplication::x_TryMain(EAppDiagStream diag,
                                  const char*    conf,
@@ -378,7 +494,8 @@ void CNcbiApplication::x_TryMain(EAppDiagStream diag,
         }
         *exit_code = 0;
     }
-
+    x_ReadLogOptions();
+    x_LogOptions(eStartEvent);
     // Run application
     if (*exit_code == 1) {
         GetDiagContext().SetGlobalAppState(eDiagAppState_AppRun);
@@ -405,6 +522,7 @@ void CNcbiApplication::x_TryMain(EAppDiagStream diag,
             *exit_code = m_DryRun ? DryRun() : Run();
         }
     }
+    x_LogOptions(eStopEvent);
     GetDiagContext().SetGlobalAppState(eDiagAppState_AppEnd);
 
     // Close application
@@ -745,6 +863,24 @@ void CNcbiApplication::SetEnvironment(const string& name, const string& value)
     SetEnvironment().Set(name, value);
 }
 
+void CNcbiApplication::SetVersionByBuild(int major)
+{
+    int minor =
+#if defined(NCBI_SC_VERSION)
+        NCBI_SC_VERSION;
+#else
+        0;
+#endif
+    int build_num =
+#if defined(NCBI_TEAMCITY_BUILD_NUMBER)
+        NCBI_TEAMCITY_BUILD_NUMBER;
+#else
+        0;
+#endif
+
+    SetVersion(CVersionInfo(major, minor, build_num));
+}
+
 
 void CNcbiApplication::SetVersion(const CVersionInfo& version)
 {
diff --git a/c++/src/corelib/ncbiargs.cpp b/c++/src/corelib/ncbiargs.cpp
index bc77509..9bb0822 100644
--- a/c++/src/corelib/ncbiargs.cpp
+++ b/c++/src/corelib/ncbiargs.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbiargs.cpp 488569 2015-12-31 21:35:10Z vakatov $
+/*  $Id: ncbiargs.cpp 500405 2016-05-04 15:18:35Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -2396,6 +2396,10 @@ void CArgDescriptions::AddNegatedFlagAlias(const string& alias,
     arg.release();
 }
 
+void CArgDescriptions::AddDependencyGroup(CArgDependencyGroup* dep_group)
+{
+    m_DependencyGroups.insert( CConstRef<CArgDependencyGroup>(dep_group));
+}
 
 void CArgDescriptions::SetConstraint(const string&      name, 
                                      const CArgAllow*   constraint,
@@ -3055,6 +3059,11 @@ void CArgDescriptions::x_PostCheck(CArgs&           args,
         def_args.push_back(&arg);
     }
 
+    for (set< CConstRef<CArgDependencyGroup> >::const_iterator i = m_DependencyGroups.begin();
+        i != m_DependencyGroups.end(); ++i) {
+        i->GetPointer()->Evaluate(args);
+    }
+
     // Set default values (if available) for the arguments not defined
     // in the command line.
     ITERATE (list<const CArgDesc*>, it, def_args) {
@@ -3582,6 +3591,15 @@ void CArgDescriptions::CPrintUsage::AddDetails(list<string>& arr) const
         arr.push_back("OPTIONAL ARGUMENTS");
         arr.splice(arr.end(), opt);
     }
+
+    if (!m_desc.m_DependencyGroups.empty()) {
+        arr.push_back(kEmptyStr);
+        arr.push_back("DEPENDENCY GROUPS");
+        for (set< CConstRef<CArgDependencyGroup> >::const_iterator i = m_desc.m_DependencyGroups.begin();
+            i != m_desc.m_DependencyGroups.end(); ++i) {
+            i->GetPointer()->PrintUsage(arr, 0);
+        }
+    }
 }
 
 string& CArgDescriptions::PrintUsage(string& str, bool detailed) const
@@ -3611,7 +3629,7 @@ string& CArgDescriptions::PrintUsage(string& str, bool detailed) const
 }
 
 CArgDescriptions::CPrintUsageXml::CPrintUsageXml(const CArgDescriptions& desc, CNcbiOstream& out)
-    : m_out(out)
+    : m_desc(desc), m_out(out)
 {
     m_out << "<?xml version=\"1.0\"?>" << endl;
     m_out << "<" << "ncbi_application xmlns=\"ncbi:application\"" << endl
@@ -3713,6 +3731,11 @@ void CArgDescriptions::CPrintUsageXml::PrintArguments(const CArgDescriptions& de
         }
         m_out << "</" << "dependencies" << ">" << endl;
     }
+
+    for (set< CConstRef<CArgDependencyGroup> >::const_iterator i = m_desc.m_DependencyGroups.begin();
+        i != m_desc.m_DependencyGroups.end(); ++i) {
+        i->GetPointer()->PrintUsageXml(m_out);
+    }
     m_out << "</" << "arguments" << ">" << endl;
 }
 
@@ -3973,25 +3996,25 @@ string& CCommandArgDescriptions::PrintUsage(string& str, bool detailed) const
         if ((m_Cmd_req & eNoSortGroups)==0) {
             cmdgroups.sort();
         }
-        ITERATE( list<string>, g, cmdgroups) {
+        ITERATE( list<string>, gi, cmdgroups) {
             string grouptitle;
             bool titleprinted = false;
-            if (g->empty()) {
+            if (gi->empty()) {
                 grouptitle = "Commands";
             } else {
-                grouptitle = *g;
+                grouptitle = *gi;
             }
-            size_t group = x_GetCommandGroupIndex(*g);
-            ITERATE( list<string>, d, cmds) {
-                map<string, size_t >::const_iterator j = m_Groups.find(*d);
+            size_t group = x_GetCommandGroupIndex(*gi);
+            ITERATE( list<string>, di, cmds) {
+                map<string, size_t >::const_iterator j = m_Groups.find(*di);
                 if (j != m_Groups.end() && j->second == group) {
                     if (!titleprinted) {
                         arr.push_back(kEmptyStr);
                         arr.push_back(grouptitle + ":");
                         titleprinted = true;
                     }
-                    CPrintUsage y(*(m_Description.lower_bound(*d)->second));
-                    y.AddCommandDescription(arr, *d, &m_Aliases, max_cmd_len, detailed);
+                    CPrintUsage y(*(m_Description.lower_bound(*di)->second));
+                    y.AddCommandDescription(arr, *di, &m_Aliases, max_cmd_len, detailed);
                 }
             }
             ++group;
@@ -3999,9 +4022,9 @@ string& CCommandArgDescriptions::PrintUsage(string& str, bool detailed) const
     } else {
         arr.push_back(kEmptyStr);
         arr.push_back("AVAILABLE COMMANDS:");
-        ITERATE( list<string>, d, cmds) {
-            CPrintUsage y(*(m_Description.find(*d)->second));
-            y.AddCommandDescription(arr, *d, &m_Aliases, max_cmd_len, detailed);
+        ITERATE( list<string>, di, cmds) {
+            CPrintUsage y(*(m_Description.find(*di)->second));
+            y.AddCommandDescription(arr, *di, &m_Aliases, max_cmd_len, detailed);
         }
     }
 
@@ -4022,6 +4045,7 @@ string& CCommandArgDescriptions::PrintUsage(string& str, bool detailed) const
     return str;
 }
 
+
 void CCommandArgDescriptions::PrintUsageXml(CNcbiOstream& out) const
 {
     CPrintUsageXml x(*this,out);
@@ -4597,6 +4621,236 @@ CArgAllow* CArgAllow_Doubles::Clone(void) const
     return clone;
 }
 
+
+/////////////////////////////////////////////////////////////////////////////
+
+CRef<CArgDependencyGroup> CArgDependencyGroup::Create(
+        const string& name, const string& description)
+{
+    CRef<CArgDependencyGroup> gr(new CArgDependencyGroup());
+    gr->m_Name = name;
+    gr->m_Description = description;
+    return gr;
+}
+
+CArgDependencyGroup::CArgDependencyGroup()
+    : m_MinMembers(0), m_MaxMembers(0)
+{
+}
+
+CArgDependencyGroup::~CArgDependencyGroup(void)
+{
+}
+
+CArgDependencyGroup& CArgDependencyGroup::SetMinMembers(size_t min_members)
+{
+    m_MinMembers = min_members;
+    return *this;
+}
+
+CArgDependencyGroup& CArgDependencyGroup::SetMaxMembers(size_t max_members)
+{
+    m_MaxMembers = max_members;
+    return *this;
+}
+
+CArgDependencyGroup& CArgDependencyGroup::Add(const string& arg_name, EInstantSet  instant_set)
+{
+    m_Arguments[arg_name] = instant_set;
+    return *this;
+}
+
+CArgDependencyGroup& CArgDependencyGroup::Add(
+    CArgDependencyGroup* dep_group, EInstantSet instant_set)
+{
+    m_Groups[ CConstRef<CArgDependencyGroup>(dep_group)] = instant_set;
+    return *this;
+}
+
+void CArgDependencyGroup::Evaluate( const CArgs& args) const
+{
+    x_Evaluate(args, nullptr, nullptr);
+}
+
+bool CArgDependencyGroup::x_Evaluate( const CArgs& args, string* arg_set, string* arg_unset) const
+{
+    bool top_level = !arg_set || !arg_unset;
+    bool has_instant_set = false;
+    size_t count_set = 0;
+    set<string> names_set, names_unset;
+    string args_set, args_unset;
+
+    for (map< CConstRef<CArgDependencyGroup>, EInstantSet>::const_iterator i = m_Groups.begin();
+        i != m_Groups.end(); ++i) {
+        string msg_set, msg_unset;
+        if (i->first.GetPointer()->x_Evaluate(args, &msg_set, &msg_unset)) {
+            ++count_set;
+            has_instant_set = has_instant_set || (i->second == eInstantSet);
+            names_set.insert(msg_set);
+        } else {
+            names_unset.insert(msg_unset);
+        }
+    }
+    for (map<string, EInstantSet>::const_iterator i = m_Arguments.begin();
+        i != m_Arguments.end(); ++i) {
+        if (args.Exist(i->first)) {
+            ++count_set;
+            has_instant_set = has_instant_set || (i->second == eInstantSet);
+            names_set.insert(i->first);
+        } else {
+            names_unset.insert(i->first);
+        }
+    }
+    size_t count_total = m_Groups.size() + m_Arguments.size();
+    size_t count_max = m_MaxMembers != 0 ? m_MaxMembers : count_total;
+
+    if (names_set.size() > 1) {
+        args_set = "(" + NStr::Join(names_set, ", ") + ")";
+    } else if (names_set.size() == 1) {
+        args_set = *names_set.begin();
+    }
+
+    if (names_unset.size() > 1) {
+        args_unset = "(" + NStr::Join(names_unset, m_MinMembers <= 1 ? " | " : ", ") + ")";
+    } else if (names_unset.size() == 1) {
+        args_unset = *names_unset.begin();
+    }
+
+    bool result = count_set != 0 || top_level;
+    if (result) {
+        if (count_set > count_max) {
+            string msg("Argument conflict: ");
+            msg += args_set + " may not be specified simultaneously";
+            NCBI_THROW(CArgException, eConstraint, msg);
+        }
+        if (!has_instant_set && count_set < m_MinMembers) {
+            string msg("Argument has no value: ");
+            if (count_total != count_max) {
+                msg += (m_MinMembers - count_set > 1) ? "some" : "one";                                  
+                msg += " of ";
+            }
+            msg += args_unset + " must be specified";
+            NCBI_THROW(CArgException,eNoValue, msg);
+        }
+    }
+    if (arg_set) {
+        *arg_set = args_set;
+    }
+    if (arg_unset) {
+        *arg_unset = args_unset;
+    }
+    return result;
+}
+
+void CArgDependencyGroup::PrintUsage(list<string>& arr, size_t offset) const
+{
+    arr.push_back(kEmptyStr);
+    string off(2*offset,' ');
+    string msg(off);
+    msg += m_Name + ": {";
+
+    bool first = true;
+    list<string> instant;
+    for (map< CConstRef<CArgDependencyGroup>, EInstantSet>::const_iterator i = m_Groups.begin();
+        i != m_Groups.end(); ++i) {
+        if (!first) {
+            msg += ",";
+        }
+        first = false;
+        msg += i->first.GetPointer()->m_Name;
+        if (i->second == eInstantSet) {
+            instant.push_back(i->first.GetPointer()->m_Name);
+        }
+    }
+    for (map<string, EInstantSet>::const_iterator i = m_Arguments.begin();
+        i != m_Arguments.end(); ++i) {
+        if (!first) {
+            msg += ",";
+        }
+        first = false;
+        msg += i->first;
+        if (i->second == eInstantSet) {
+            instant.push_back(i->first);
+        }
+    }
+    msg += "}";
+    arr.push_back(msg);
+    if (!m_Description.empty()) {
+        msg = off;
+        msg += m_Description;
+        arr.push_back(msg);
+    }
+    size_t count_total = m_Groups.size() + m_Arguments.size();
+    size_t count_max = m_MaxMembers != 0 ? m_MaxMembers : count_total;
+
+    msg = off + "in which ";
+    size_t count = m_MinMembers;
+    if (m_MinMembers == count_max) {
+        msg += "exactly ";
+        msg += NStr::NumericToString(m_MinMembers);
+    } else if (count_max == count_total && m_MinMembers != 0) {
+        msg += "at least ";
+        msg += NStr::NumericToString(m_MinMembers);
+    } else if (count_max != count_total && m_MinMembers == 0) {
+        msg += "no more than ";
+        msg += NStr::NumericToString(m_MaxMembers);
+        count = m_MaxMembers;
+    } else {
+        msg += NStr::NumericToString(m_MinMembers);
+        msg += " to ";
+        msg += NStr::NumericToString(m_MaxMembers);
+        count = m_MaxMembers;
+    }
+    msg += " element";
+    if (count != 1) {
+        msg += "s";
+    }
+    msg += " must be set";
+    arr.push_back(msg);
+
+    if (!instant.empty()) {
+        msg = off;
+        msg += "Instant set: ";
+        msg += NStr::Join(instant, ",");
+        arr.push_back(msg);
+    }
+    for (map< CConstRef<CArgDependencyGroup>, EInstantSet>::const_iterator i = m_Groups.begin();
+        i != m_Groups.end(); ++i) {
+        i->first.GetPointer()->PrintUsage(arr, offset+1);
+    }
+}
+
+void CArgDependencyGroup::PrintUsageXml(CNcbiOstream& out) const
+{
+    out << "<" << "dependencygroup" << ">" << endl;
+    out << "<" << "name" << ">" << m_Name << "</" << "name" << ">" << endl;
+    out << "<" << "description" << ">" << m_Description << "</" << "description" << ">" << endl;
+
+    for (map< CConstRef<CArgDependencyGroup>, EInstantSet>::const_iterator i = m_Groups.begin();
+        i != m_Groups.end(); ++i) {
+        out << "<" << "group";
+        if (i->second == eInstantSet) {
+            out << " instantset=\"true\"";
+        }
+        out << ">" << i->first.GetPointer()->m_Name << "</" << "group" << ">" << endl;
+    }
+    for (map<string, EInstantSet>::const_iterator i = m_Arguments.begin();
+        i != m_Arguments.end(); ++i) {
+        out << "<" << "argument";
+        if (i->second == eInstantSet) {
+            out << " instantset=\"true\"";
+        }
+        out << ">" << i->first << "</" << "argument" << ">" << endl;
+    }
+    out << "<" << "minmembers" << ">" << m_MinMembers << "</" << "minmembers" << ">" << endl;
+    out << "<" << "maxmembers" << ">" << m_MaxMembers << "</" << "maxmembers" << ">" << endl;
+    for (map< CConstRef<CArgDependencyGroup>, EInstantSet>::const_iterator i = m_Groups.begin();
+        i != m_Groups.end(); ++i) {
+        i->first.GetPointer()->PrintUsageXml(out);
+    }
+    out << "</" << "dependencygroup" << ">" << endl;
+}
+
 ///////////////////////////////////////////////////////
 // CArgException
 
diff --git a/c++/src/corelib/ncbidiag.cpp b/c++/src/corelib/ncbidiag.cpp
index 8d43805..617bd3b 100644
--- a/c++/src/corelib/ncbidiag.cpp
+++ b/c++/src/corelib/ncbidiag.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbidiag.cpp 500364 2016-05-04 12:04:46Z ivanov $
+/*  $Id: ncbidiag.cpp 519554 2016-11-16 16:33:59Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -186,8 +186,13 @@ public:
     CTeeDiagHandler(CDiagHandler* orig, bool own_orig);
     virtual void Post(const SDiagMessage& mess);
 
-    // Don't post duplicates to console.
-    virtual void PostToConsole(const SDiagMessage& mess) {}
+    virtual void PostToConsole(const SDiagMessage& mess)
+    {
+        // Console manipulator ignores severity, so we have to always print
+        // the message to console and set NoTee flag to avoid duplicates.
+        CDiagHandler::PostToConsole(mess);
+        const_cast<SDiagMessage&>(mess).m_NoTee = true;
+    }
 
     virtual string GetLogName(void)
     {
@@ -269,9 +274,43 @@ typedef NCBI_PARAM_TYPE(Diag, Log_Size_Limit) TLogSizeLimitParam;
 ///////////////////////////////////////////////////////
 //  Output rate control parameters
 
+class CLogRateLimit
+{
+public:
+    typedef unsigned int TValue;
+    CLogRateLimit(void) : m_Value(kMax_UInt) {}
+    CLogRateLimit(TValue val) : m_Value(val) {}
+
+    operator TValue(void) const
+    {
+        return m_Value;
+    }
+
+    void Set(TValue val)
+    {
+        m_Value = val;
+    }
+
+private:
+    TValue m_Value;
+};
+
+
+CNcbiIstream& operator>>(CNcbiIstream& in, CLogRateLimit& lim)
+{
+    lim.Set(kMax_UInt);
+    string s;
+    getline(in, s);
+    if ( !NStr::EqualNocase(s, "off") ) {
+        lim.Set(NStr::StringToNumeric<CLogRateLimit::TValue>(s));
+    }
+    return in;
+}
+
+
 // AppLog limit per period
-NCBI_PARAM_DECL(unsigned int, Diag, AppLog_Rate_Limit);
-NCBI_PARAM_DEF_EX(unsigned int, Diag, AppLog_Rate_Limit, 50000,
+NCBI_PARAM_DECL(CLogRateLimit, Diag, AppLog_Rate_Limit);
+NCBI_PARAM_DEF_EX(CLogRateLimit, Diag, AppLog_Rate_Limit, CLogRateLimit(50000),
                   eParam_NoThread, DIAG_APPLOG_RATE_LIMIT);
 typedef NCBI_PARAM_TYPE(Diag, AppLog_Rate_Limit) TAppLogRateLimitParam;
 
@@ -282,8 +321,8 @@ NCBI_PARAM_DEF_EX(unsigned int, Diag, AppLog_Rate_Period, 10, eParam_NoThread,
 typedef NCBI_PARAM_TYPE(Diag, AppLog_Rate_Period) TAppLogRatePeriodParam;
 
 // ErrLog limit per period
-NCBI_PARAM_DECL(unsigned int, Diag, ErrLog_Rate_Limit);
-NCBI_PARAM_DEF_EX(unsigned int, Diag, ErrLog_Rate_Limit, 5000,
+NCBI_PARAM_DECL(CLogRateLimit, Diag, ErrLog_Rate_Limit);
+NCBI_PARAM_DEF_EX(CLogRateLimit, Diag, ErrLog_Rate_Limit, CLogRateLimit(5000),
                   eParam_NoThread, DIAG_ERRLOG_RATE_LIMIT);
 typedef NCBI_PARAM_TYPE(Diag, ErrLog_Rate_Limit) TErrLogRateLimitParam;
 
@@ -294,8 +333,8 @@ NCBI_PARAM_DEF_EX(unsigned int, Diag, ErrLog_Rate_Period, 1, eParam_NoThread,
 typedef NCBI_PARAM_TYPE(Diag, ErrLog_Rate_Period) TErrLogRatePeriodParam;
 
 // TraceLog limit per period
-NCBI_PARAM_DECL(unsigned int, Diag, TraceLog_Rate_Limit);
-NCBI_PARAM_DEF_EX(unsigned int, Diag, TraceLog_Rate_Limit, 5000,
+NCBI_PARAM_DECL(CLogRateLimit, Diag, TraceLog_Rate_Limit);
+NCBI_PARAM_DEF_EX(CLogRateLimit, Diag, TraceLog_Rate_Limit, CLogRateLimit(5000),
                   eParam_NoThread, DIAG_TRACELOG_RATE_LIMIT);
 typedef NCBI_PARAM_TYPE(Diag, TraceLog_Rate_Limit) TTraceLogRateLimitParam;
 
@@ -369,8 +408,6 @@ NCBI_PARAM_DEF_EX(string, Log, LogRegistry, kEmptyStr,
 typedef NCBI_PARAM_TYPE(Log, LogRegistry) TLogRegistry;
 
 
-// Are we using applog automatically (set by SetupDiag)?
-static bool s_UsingAutoApplog = false;
 static bool s_FinishedSetupDiag = false;
 static bool s_MergeLinesSetBySetupDiag = false;
 
@@ -1497,14 +1534,28 @@ CDiagContext::TUID CDiagContext::UpdateUID(TUID uid) const
 
 string CDiagContext::GetNextHitID(void) const
 {
+    return x_GetNextHitID(false);
+}
+
+
+string CDiagContext::x_GetNextHitID(bool is_default) const
+{
+    static CAtomicCounter s_HitIdCounter;
+
     Uint8 hi = GetUID();
     Uint4 b3 = Uint4((hi >> 32) & 0xFFFFFFFF);
     Uint4 b2 = Uint4(hi & 0xFFFFFFFF);
 
     CDiagContextThreadData& thr_data = CDiagContextThreadData::GetThreadData();
     Uint8 tid = (thr_data.GetTID() & 0xFFFFFF) << 40;
-    Uint8 rid = Uint8(thr_data.GetRequestContext().GetRequestID() & 0xFFFFFF) << 16;
-    Uint8 us = (GetFastLocalTime().MicroSecond()/16) & 0xFFFF;
+    Uint8 rid;
+    if ( !is_default ) {
+        rid = ((Uint8)thr_data.GetRequestContext().GetRequestID() & 0xFFFFFF) << 16;
+    }
+    else {
+        rid = ((Uint8)0xFFFFFF) << 16;
+    }
+    Uint8 us = (Uint8)(s_HitIdCounter.Add(1) & 0xFFFF);
     Uint8 lo = tid | rid | us;
     Uint4 b1 = Uint4((lo >> 32) & 0xFFFFFFFF);
     Uint4 b0 = Uint4(lo & 0xFFFFFFFF);
@@ -1514,6 +1565,12 @@ string CDiagContext::GetNextHitID(void) const
 }
 
 
+string CDiagContext::GetDefaultHitID(void) const
+{
+    return x_GetDefaultHitID(eHitID_Create).GetHitId();
+}
+
+
 const string& CDiagContext::GetUsername(void) const
 {
     return m_Username->GetOriginalString();
@@ -2473,11 +2530,11 @@ void CDiagContext::x_LogHitID(void) const
 
     // Log the default hit id only when at application level. Otherwise
     // pospone it untill request-stop/app-stop.
-    if (m_LoggedHitId || !m_DefaultHitId.get() || m_DefaultHitId->empty() ||
+    if (m_LoggedHitId || !m_DefaultHitId.get() || m_DefaultHitId->Empty() ||
         !x_DiagAtApplicationLevel()) {
         return;
     }
-    Extra().Print(g_GetNcbiString(eNcbiStrings_PHID), *m_DefaultHitId);
+    Extra().Print(g_GetNcbiString(eNcbiStrings_PHID), m_DefaultHitId->GetHitId());
     m_LoggedHitId = true;
 }
 
@@ -2492,24 +2549,24 @@ void CDiagContext::x_LogHitID_WithLock(void) const
 bool CDiagContext::x_IsSetDefaultHitID(void) const
 {
     CFastMutexGuard guard(s_DefaultHidMutex);
-    return m_DefaultHitId.get() && !m_DefaultHitId->empty();
+    return m_DefaultHitId.get() && !m_DefaultHitId->Empty();
 }
 
 
-string CDiagContext::x_GetDefaultHitID(EDefaultHitIDFlags flag) const
+CSharedHitId CDiagContext::x_GetDefaultHitID(EDefaultHitIDFlags flag) const
 {
     CFastMutexGuard guard(s_DefaultHidMutex);
-    if (m_DefaultHitId.get()  &&  !m_DefaultHitId->empty()) {
+    if (m_DefaultHitId.get()  &&  !m_DefaultHitId->Empty()) {
         return *m_DefaultHitId;
     }
 
     if ( !m_DefaultHitId.get() ) {
-        m_DefaultHitId.reset(new string);
+        m_DefaultHitId.reset(new CSharedHitId());
     }
-    if ( m_DefaultHitId->empty() ) {
-        *m_DefaultHitId = CRequestContext::SelectLastHitID(
-            TParamHttpHitId::GetDefault());
-        if ( m_DefaultHitId->empty() ) {
+    if ( m_DefaultHitId->Empty() ) {
+        m_DefaultHitId->SetHitId(CRequestContext::SelectLastHitID(
+            TParamHttpHitId::GetDefault()));
+        if ( m_DefaultHitId->Empty() ) {
             string phid = CRequestContext::SelectLastHitID(
                 TParamHitId::GetDefault());
             if ( !phid.empty() ) {
@@ -2546,12 +2603,14 @@ string CDiagContext::x_GetDefaultHitID(EDefaultHitIDFlags flag) const
                     }
                 }
             }
-            *m_DefaultHitId = phid;
+            m_DefaultHitId->SetHitId(phid);
         }
-        if (m_DefaultHitId->empty()  &&  (flag == eHitID_Create)) {
-            *m_DefaultHitId = GetNextHitID();
+        if (m_DefaultHitId->Empty()  &&  (flag == eHitID_Create)) {
+            m_DefaultHitId->SetHitId(x_GetNextHitID(true));
         }
     }
+    // Default hit id always uses shared sub-hit counter.
+    m_DefaultHitId->SetShared();
     _ASSERT(!m_LoggedHitId);
     // Log hit id if at application level.
     x_LogHitID();
@@ -2563,9 +2622,11 @@ void CDiagContext::SetDefaultHitID(const string& hit_id)
 {
     CFastMutexGuard guard(s_DefaultHidMutex);
     if ( !m_DefaultHitId.get() ) {
-        m_DefaultHitId.reset(new string);
+        m_DefaultHitId.reset(new CSharedHitId());
     }
-    *m_DefaultHitId = hit_id;
+    m_DefaultHitId->SetHitId(hit_id);
+    // Default hit id always uses shared sub-hit counter.
+    m_DefaultHitId->SetShared();
     // Log new hit id when at application level.
     m_LoggedHitId = false;
     x_LogHitID();
@@ -2904,12 +2965,14 @@ void CDiagContext::DiscardMessages(void)
 
 // Diagnostics setup
 
+static const char* kRootLog = "/log/";
+
 string GetDefaultLogLocation(CNcbiApplication& app)
 {
     static const char* kToolkitRcPath = "/etc/toolkitrc";
     static const char* kWebDirToPort = "Web_dir_to_port";
 
-    string log_path = "/log/";
+    string log_path = kRootLog;
 
     string exe_path = CFile(app.GetProgramExecutablePath()).GetDir();
     CNcbiIfstream is(kToolkitRcPath, ios::binary);
@@ -2989,19 +3052,6 @@ void CDiagContext::x_FinalizeSetupDiag(void)
 }
 
 
-// Helper function to set log file with forced splitting.
-bool SetApplogFile(const string& file_name)
-{
-    bool old_split = s_UsingAutoApplog;
-    s_UsingAutoApplog = true;
-    bool res = SetLogFile(file_name);
-    if ( !res ) {
-        s_UsingAutoApplog = old_split;
-    }
-    return res;
-}
-
-
 // Load string value from config if not null, or from the environment.
 static string s_GetLogConfigString(const CTempString name,
                                    const CTempString defval,
@@ -3045,6 +3095,16 @@ void CDiagContext::SetupDiag(EAppDiagStream       ds,
                              const char*          cmd_logfile)
 {
     CDiagLock lock(CDiagLock::eWrite);
+
+    // Check severity level change status now.
+    // This used to be done in SetDiag(), but if the first logging event is an
+    // Extra(), new post format is enabled and post level is Trace, the initialization
+    // results in infinite recursion. To prevent this, call this as soon as possible,
+    // before any logging is done.
+    if ( CDiagBuffer::sm_PostSeverityChange == eDiagSC_Unknown ) {
+        CDiagBuffer::GetSeverityChangeEnabledFirstTime();
+    }
+
     CDiagContext& ctx = GetDiagContext();
     // Initialize message collecting
     if (collect == eDCM_Init) {
@@ -3053,8 +3113,6 @@ void CDiagContext::SetupDiag(EAppDiagStream       ds,
     else if (collect == eDCM_InitNoLimit) {
         ctx.InitMessages(size_t(-1));
     }
-    bool old_using_applog = s_UsingAutoApplog;
-    s_UsingAutoApplog = false; // Prevent splitting logs unless applog is used.
 
     /*
     The default order of checking possible log locations is:
@@ -3186,6 +3244,12 @@ void CDiagContext::SetupDiag(EAppDiagStream       ds,
         case eDS_ToStdlog:
         case eDS_Default:
             {
+                // When using applog, create separate log file for each
+                // user to avoid permission problems.
+                string euid;
+#if defined(NCBI_OS_UNIX)
+                euid = "." + NStr::NumericToString(geteuid());
+#endif
                 string log_base;
                 string def_log_dir;
                 {{
@@ -3197,12 +3261,12 @@ void CDiagContext::SetupDiag(EAppDiagStream       ds,
                     }
                 }}
                 if ( !log_base.empty() ) {
-                    log_base = CFile(log_base).GetBase() + ".log";
+                    log_base = CFile(log_base).GetBase() + euid + ".log";
                     string log_name;
                     // Try /log/<port>
                     if ( !def_log_dir.empty() ) {
                         log_name = CFile::ConcatPath(def_log_dir, log_base);
-                        if ( SetApplogFile(log_name) ) {
+                        if ( SetLogFile(log_name) ) {
                             log_set = true;
                             new_log_name = log_name;
                             to_applog = true;
@@ -3210,8 +3274,8 @@ void CDiagContext::SetupDiag(EAppDiagStream       ds,
                         }
                     }
                     // Try /log/srv if port is unknown or not writable
-                    log_name = CFile::ConcatPath("/log/srv", log_base);
-                    if ( SetApplogFile(log_name) ) {
+                    log_name = CFile::ConcatPath(CFile::ConcatPath(kRootLog, "srv"), log_base);
+                    if ( SetLogFile(log_name) ) {
                         log_set = true;
                         new_log_name = log_name;
                         to_applog = true;
@@ -3225,8 +3289,8 @@ void CDiagContext::SetupDiag(EAppDiagStream       ds,
                         break;
                     }
                     // Try to switch to /log/fallback/
-                    log_name = CFile::ConcatPath("/log/fallback/", log_base);
-                    if ( SetApplogFile(log_name) ) {
+                    log_name = CFile::ConcatPath(CFile::ConcatPath(kRootLog, "fallback"), log_base);
+                    if ( SetLogFile(log_name) ) {
                         log_set = true;
                         new_log_name = log_name;
                         to_applog = true;
@@ -3234,7 +3298,8 @@ void CDiagContext::SetupDiag(EAppDiagStream       ds,
                     }
                     // Try cwd/ for eDS_ToStdlog only
                     if (ds == eDS_ToStdlog) {
-                        log_name = CFile::ConcatPath(".", log_base);
+                        // Don't include euid in file name when using cwd.
+                        log_name = CFile::ConcatPath(".", CFile(log_base).GetBase() + ".log");
                         if ( SetLogFile(log_name, eDiagFile_All) ) {
                             log_set = true;
                             new_log_name = log_name;
@@ -3253,17 +3318,17 @@ void CDiagContext::SetupDiag(EAppDiagStream       ds,
                     }
                 }
                 // No command line and no base name.
-                // Try to switch to /log/fallback/UNKNOWN
+                // Try to switch to /log/fallback/UNKNOWN.<euid>
                 if (!log_set  &&  log_base.empty()) {
-                    static const char* kDefaultFallback = "/log/fallback/UNKNOWN";
-                    if ( SetApplogFile(kDefaultFallback) ) {
+                    string default_fallback = CFile::ConcatPath(kRootLog, "fallback/UNKNOWN.log");
+                    if ( SetLogFile(default_fallback + euid) ) {
                         log_set = true;
-                        new_log_name = kDefaultFallback;
+                        new_log_name = default_fallback;
                         to_applog = true;
                         break;
                     }
                     _TRACE_X(4, "Failed to set log file to " <<
-                        CFile::NormalizePath(kDefaultFallback));
+                        CFile::NormalizePath(default_fallback));
                 }
                 const char* log_name = TTeeToStderr::GetDefault() ?
                     kLogName_Tee : kLogName_Stderr;
@@ -3285,7 +3350,6 @@ void CDiagContext::SetupDiag(EAppDiagStream       ds,
     // Unlock severity level
     SetApplogSeverityLocked(false);
     if ( to_applog ) {
-        _ASSERT(s_UsingAutoApplog);
         ctx.SetOldPostFormat(false);
         SetDiagPostFlag(eDPF_MergeLines);
         s_MergeLinesSetBySetupDiag = true;
@@ -3295,7 +3359,6 @@ void CDiagContext::SetupDiag(EAppDiagStream       ds,
         SetApplogSeverityLocked(true);
     }
     else {
-        s_UsingAutoApplog = old_using_applog;
         if ( s_MergeLinesSetBySetupDiag ) {
             UnsetDiagPostFlag(eDPF_MergeLines);
         }
@@ -3346,7 +3409,7 @@ CDiagContext::TCount CDiagContext::GetProcessPostNumber(EPostNumberIncrement inc
 
 bool CDiagContext::IsUsingRootLog(void)
 {
-    return GetLogFile().substr(0, 5) == "/log/";
+    return GetLogFile().substr(0, 5) == kRootLog;
 }
 
 
@@ -3610,11 +3673,6 @@ bool CDiagBuffer::SetDiag(const CNcbiDiag& diag)
         return false;
     }
 
-    // Check severity level change status
-    if ( sm_PostSeverityChange == eDiagSC_Unknown ) {
-        GetSeverityChangeEnabledFirstTime();
-    }
-
     EDiagSev sev = diag.GetSeverity();
     bool is_console = (diag.GetPostFlags() & eDPF_IsConsole) > 0;
     if (!is_console  &&  SeverityDisabled(sev)) {
@@ -3762,7 +3820,6 @@ bool CDiagBuffer::GetTraceEnabledFirstTime(void)
 
 bool CDiagBuffer::GetSeverityChangeEnabledFirstTime(void)
 {
-    CDiagLock lock(CDiagLock::eWrite);
     if ( sm_PostSeverityChange != eDiagSC_Unknown ) {
         return sm_PostSeverityChange == eDiagSC_Enable;
     }
@@ -5536,7 +5593,9 @@ extern void SetDiagHandler(CDiagHandler* handler, bool can_delete)
             ctx.Extra().Print("switch_diag_to", new_name);
         }
     }
-    if ( CDiagBuffer::sm_CanDeleteHandler )
+    // Do not delete old handler if it's reinstalled (possibly just to change
+    // the ownership).
+    if (CDiagBuffer::sm_CanDeleteHandler  &&  CDiagBuffer::sm_Handler != handler)
         delete CDiagBuffer::sm_Handler;
     if ( TTeeToStderr::GetDefault() ) {
         // Need to tee?
@@ -5558,9 +5617,13 @@ extern bool IsSetDiagHandler(void)
     return (CDiagBuffer::sm_Handler != s_DefaultHandler);
 }
 
-extern CDiagHandler* GetDiagHandler(bool take_ownership)
+extern CDiagHandler* GetDiagHandler(bool take_ownership,
+                                    bool* current_ownership)
 {
     CDiagLock lock(CDiagLock::eRead);
+    if ( current_ownership ) {
+        *current_ownership = CDiagBuffer::sm_CanDeleteHandler;
+    }
     if (take_ownership) {
         _ASSERT(CDiagBuffer::sm_CanDeleteHandler);
         CDiagBuffer::sm_CanDeleteHandler = false;
@@ -5891,7 +5954,7 @@ string CFileHandleDiagHandler::ComposeMessage(const SDiagMessage& msg,
 
 void CFileHandleDiagHandler::WriteMessage(const char*   buf,
                                           size_t        len,
-                                          EDiagFileType file_type)
+                                          EDiagFileType /*file_type*/)
 {
     // Period is longer than for CFileDiagHandler to prevent double-reopening
     // In async mode only one thread is writing messages and there's no need
@@ -6121,19 +6184,33 @@ bool CFileDiagHandler::SetLogFile(const string& file_name,
             string trace_name = special ? adj_name : adj_name + ".trace";
             string perf_name = special ? adj_name : adj_name + ".perf";
 
-            if (!s_CreateHandler(err_name, err_handler))
-                return false;
-            if (!s_CreateHandler(log_name, log_handler))
-                return false;
-            if (!s_CreateHandler(trace_name, trace_handler))
-                return false;
-            if (!s_CreateHandler(perf_name, perf_handler))
-                return false;
+            if ( s_SplitLogFile ) {
+                if (!s_CreateHandler(err_name, err_handler))
+                    return false;
+                if (!s_CreateHandler(log_name, log_handler))
+                    return false;
+                if (!s_CreateHandler(trace_name, trace_handler))
+                    return false;
+                if (!s_CreateHandler(perf_name, perf_handler))
+                    return false;
+
+                x_SetHandler(&m_Err, &m_OwnErr, err_handler.release(), true);
+                x_SetHandler(&m_Log, &m_OwnLog, log_handler.release(), true);
+                x_SetHandler(&m_Trace, &m_OwnTrace, trace_handler.release(), true);
+                x_SetHandler(&m_Perf, &m_OwnPerf, perf_handler.release(), true);
+            }
+            else {
+                if (!s_CreateHandler(file_name, err_handler))
+                    return false;
+                if (!s_CreateHandler(perf_name, perf_handler))
+                    return false;
+
+                x_SetHandler(&m_Err, &m_OwnErr, err_handler.get(), true);
+                x_SetHandler(&m_Log, &m_OwnLog, err_handler.get(), true);
+                x_SetHandler(&m_Trace, &m_OwnTrace, err_handler.release(), true);
+                x_SetHandler(&m_Perf, &m_OwnPerf, perf_handler.release(), true);
+            }
 
-            x_SetHandler(&m_Err, &m_OwnErr, err_handler.release(), true);
-            x_SetHandler(&m_Log, &m_OwnLog, log_handler.release(), true);
-            x_SetHandler(&m_Trace, &m_OwnTrace, trace_handler.release(), true);
-            x_SetHandler(&m_Perf, &m_OwnPerf, perf_handler.release(), true);
             m_ReopenTimer->Restart();
             break;
         }
@@ -6248,10 +6325,10 @@ void CFileDiagHandler::Reopen(TReopenFlags flags)
     if ( m_Err ) {
         m_Err->Reopen(flags);
     }
-    if ( m_Log ) {
+    if ( m_Log  &&  m_Log != m_Err ) {
         m_Log->Reopen(flags);
     }
-    if ( m_Trace ) {
+    if ( m_Trace  &&  m_Trace != m_Log  &&  m_Trace != m_Err ) {
         m_Trace->Reopen(flags);
     }
     if ( m_Perf ) {
@@ -6744,8 +6821,7 @@ extern bool SetLogFile(const string& file_name,
         // Auto-split log file
         SetSplitLogFile(true);
     }
-    bool no_split = !(s_SplitLogFile  ||  s_UsingAutoApplog);
-    if ( no_split ) {
+    if ( !s_SplitLogFile ) {
         if (file_type != eDiagFile_All) {
             ERR_POST_X(8, Info <<
                 "Failed to set log file for the selected event type: "
@@ -6763,9 +6839,8 @@ extern bool SetLogFile(const string& file_name,
         }
         else {
             // output to file
-            auto_ptr<CFileHandleDiagHandler> fhandler(
-                new CFileHandleDiagHandler(file_name));
-            if ( !fhandler->Valid() ) {
+            auto_ptr<CFileDiagHandler> fhandler(new CFileDiagHandler());
+            if ( !fhandler->SetLogFile(file_name, eDiagFile_All, quick_flush) ) {
                 ERR_POST_X(9, Info << "Failed to initialize log: " << file_name);
                 return false;
             }
@@ -6776,22 +6851,33 @@ extern bool SetLogFile(const string& file_name,
         CFileDiagHandler* handler =
             dynamic_cast<CFileDiagHandler*>(GetDiagHandler());
         if ( !handler ) {
+            bool old_ownership = false;
             CStreamDiagHandler_Base* sub_handler =
-                dynamic_cast<CStreamDiagHandler_Base*>(GetDiagHandler());
+                dynamic_cast<CStreamDiagHandler_Base*>(GetDiagHandler(false, &old_ownership));
+            if ( !sub_handler ) {
+                old_ownership = false;
+            }
             // Install new handler, try to re-use the old one
             auto_ptr<CFileDiagHandler> fhandler(new CFileDiagHandler());
-            // If we are going to set all three handlers, no need to save
-            // the old one.
             if ( sub_handler  &&  file_type != eDiagFile_All) {
-                GetDiagHandler(true); // Take ownership!
+                // If we are going to set all handlers, no need to save the old one.
+                if ( old_ownership ) {
+                    GetDiagHandler(true); // Take ownership!
+                }
                 // Set all three handlers to the old one.
-                fhandler->SetSubHandler(sub_handler, eDiagFile_All, false);
+                fhandler->SetSubHandler(sub_handler, eDiagFile_All, old_ownership);
             }
             if ( fhandler->SetLogFile(file_name, file_type, quick_flush) ) {
+                // This will delete the old handler in case of eDiagFile_All.
+                // Otherwise the new handler will remember the ownership.
                 SetDiagHandler(fhandler.release());
                 return true;
             }
             else {
+                // Restore the old handler's ownership if necessary.
+                if ( old_ownership ) {
+                    SetDiagHandler(sub_handler, true);
+                }
                 return false;
             }
         }
diff --git a/c++/src/corelib/ncbidiag_p.hpp b/c++/src/corelib/ncbidiag_p.hpp
index 28de813..047e8f5 100644
--- a/c++/src/corelib/ncbidiag_p.hpp
+++ b/c++/src/corelib/ncbidiag_p.hpp
@@ -1,7 +1,7 @@
 #ifndef CORELIB___NCBIDIAG_P__HPP
 #define CORELIB___NCBIDIAG_P__HPP
 
-/*  $Id: ncbidiag_p.hpp 456643 2015-01-14 13:08:34Z ivanov $
+/*  $Id: ncbidiag_p.hpp 505891 2016-06-29 17:58:41Z gouriano $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -37,7 +37,7 @@
 ///   classes, and macros.
 ///
 ///   More elaborate documentation could be found in:
-///     http://www.ncbi.nlm.nih.gov/toolkit/doc/book/ch_core/#ch_core.diag
+///     http://ncbi.github.io/cxx-toolkit/pages/ch_log
 
 #include <corelib/ncbiutil.hpp>
 #include <deque>
diff --git a/c++/src/corelib/ncbienv.cpp b/c++/src/corelib/ncbienv.cpp
index b13d6c0..65d6254 100644
--- a/c++/src/corelib/ncbienv.cpp
+++ b/c++/src/corelib/ncbienv.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbienv.cpp 477588 2015-08-31 18:03:35Z ucko $
+/*  $Id: ncbienv.cpp 500965 2016-05-10 14:33:08Z elisovdn $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -100,7 +100,7 @@ void CNcbiEnvironment::Reset(const char* const* envp)
             ERR_POST_X(3, "CNcbiEnvironment: bad string '" << s << "'");
             continue;
         }
-        m_Cache[string(s, eq)] = SEnvValue(eq + 1, kEmptyXCStr);
+        m_Cache[string(s, (size_t)(eq - s))] = SEnvValue(eq + 1, kEmptyXCStr);
     }
 }
 
diff --git a/c++/src/corelib/ncbierror.cpp b/c++/src/corelib/ncbierror.cpp
index 2cc2af9..dbf1215 100644
--- a/c++/src/corelib/ncbierror.cpp
+++ b/c++/src/corelib/ncbierror.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbierror.cpp 373165 2012-08-27 14:27:55Z gouriano $
+/*  $Id: ncbierror.cpp 511430 2016-08-22 15:25:37Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -139,44 +139,193 @@ CNcbiError::ECode CNcbiError::Code(void) const
     return m_Code;
 }
 
-void  CNcbiError::Set(ECode code, const CTempString& extra)
+
+CNcbiError* CNcbiError::x_Init(int err_code)
 {
     CNcbiError* e = NcbiError_GetOrCreate();
-    e->m_Code     = code;
-    e->m_Category = code < eUnknown ? eGeneric : eNcbi;
-    e->m_Native   = code;
-    e->m_Extra    = extra;
+    e->m_Code     = ECode(err_code);
+    e->m_Category = err_code < eUnknown ? eGeneric : eNcbi;
+    e->m_Native   = err_code;
+    e->m_Extra.clear();
+    return e;
 }
 
-void  CNcbiError::SetErrno(int native_err_code, const CTempString& extra)
+
+template<class Ty>
+CNcbiError* CNcbiError::x_Init(int err_code, Ty extra)
 {
     CNcbiError* e = NcbiError_GetOrCreate();
-    e->m_Code     = ECode(native_err_code);
-    e->m_Category = e->m_Code < eUnknown ? eGeneric : eNcbi;
-    e->m_Native   = native_err_code;
+    e->m_Code     = ECode(err_code);
+    e->m_Category = err_code < eUnknown ? eGeneric : eNcbi;
+    e->m_Native   = err_code;
     e->m_Extra    = extra;
+    return e;
+}
+
+
+void  CNcbiError::Set(ECode code)
+{
+    x_Init((int)code);
+}
+
+
+void  CNcbiError::Set(ECode code, const CTempString extra)
+{
+    x_Init((int)code, extra);
+}
+
+
+void  CNcbiError::Set(ECode code, string&& extra)
+{
+    x_Init((int)code, extra);
+}
+
+
+void CNcbiError::Set(ECode code, const string& extra)
+{
+    x_Init((int)code, extra);
+}
+
+
+void CNcbiError::Set(ECode code, const char* extra)
+{
+    x_Init((int)code, extra);
+}
+
+
+void  CNcbiError::SetErrno(int native_err_code)
+{
+    x_Init(native_err_code);
+}
+
+
+void  CNcbiError::SetErrno(int native_err_code, const CTempString extra)
+{
+    x_Init(native_err_code, extra);
+}
+
+
+void  CNcbiError::SetErrno(int native_err_code, string&& extra)
+{
+    x_Init(native_err_code, extra);
+}
+
+
+void CNcbiError::SetErrno(int native_err_code, const string& extra)
+{
+    x_Init(native_err_code, extra);
+}
+
+
+void CNcbiError::SetErrno(int native_err_code, const char* extra)
+{
+    x_Init(native_err_code, extra);
+}
+
+
+void  CNcbiError::SetFromErrno(void)
+{
+    SetErrno(errno);
 }
-void  CNcbiError::SetFromErrno(const CTempString& extra)
+
+
+void  CNcbiError::SetFromErrno(const CTempString extra)
 {
-    SetErrno(errno,extra);
+    SetErrno(errno, extra);
 }
 
+
+void  CNcbiError::SetFromErrno(string&& extra)
+{
+    SetErrno(errno, extra);
+}
+
+
+void CNcbiError::SetFromErrno(const string& extra)
+{
+    SetErrno(errno, extra);
+}
+
+
+void CNcbiError::SetFromErrno(const char* extra)
+{
+    SetErrno(errno, extra);
+}
+
+
+
 #if defined(NCBI_OS_MSWIN)
-void  CNcbiError::SetWindowsError( int native_err_code, const CTempString& extra)
+
+void CNcbiError::x_SetWindowsCodeCategory(CNcbiError* e)
 {
-    CNcbiError* e = NcbiError_GetOrCreate();
-    e->m_Code     = eNotSet;
+    e->m_Code = eNotSet;
     e->m_Category = eMsWindows;
-    e->m_Native   = native_err_code;
-    e->m_Extra    = extra;
 }
 
-void  CNcbiError::SetFromWindowsError( const CTempString& extra)
+
+void  CNcbiError::SetWindowsError(int native_err_code)
+{
+    x_SetWindowsCodeCategory( x_Init(native_err_code) );
+}
+
+
+void  CNcbiError::SetWindowsError(int native_err_code, const CTempString extra)
+{
+    x_SetWindowsCodeCategory( x_Init(native_err_code, extra) );
+}
+
+
+void  CNcbiError::SetWindowsError(int native_err_code, string&& extra)
+{
+    x_SetWindowsCodeCategory( x_Init(native_err_code, extra) );
+}
+
+
+void CNcbiError::SetWindowsError(int native_err_code, const string& extra)
+{
+    x_SetWindowsCodeCategory( x_Init(native_err_code, extra) );
+}
+
+
+void CNcbiError::SetWindowsError(int native_err_code, const char* extra)
+{
+    x_SetWindowsCodeCategory( x_Init(native_err_code, extra) );
+}
+
+
+void  CNcbiError::SetFromWindowsError(void)
+{
+    SetWindowsError( GetLastError() );
+}
+
+
+void  CNcbiError::SetFromWindowsError(const CTempString extra)
+{
+    SetWindowsError( GetLastError(), extra );
+}
+
+
+void  CNcbiError::SetFromWindowsError(string&& extra)
 {
     SetWindowsError( GetLastError(), extra );
 }
+
+
+void CNcbiError::SetFromWindowsError(const string& extra)
+{
+    SetWindowsError( GetLastError(), extra );
+}
+
+
+void CNcbiError::SetFromWindowsError(const char* extra)
+{
+    SetWindowsError( GetLastError(), extra );
+}
+
 #endif
 
+
+
 /////////////////////////////////////////////////////////////////////////////
 
 CNcbiOstream& operator<< (CNcbiOstream& str, const CNcbiError& err)
diff --git a/c++/src/corelib/ncbifile.cpp b/c++/src/corelib/ncbifile.cpp
index f7062b2..d5ac7ce 100644
--- a/c++/src/corelib/ncbifile.cpp
+++ b/c++/src/corelib/ncbifile.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbifile.cpp 488254 2015-12-29 13:56:26Z ivanov $
+/*  $Id: ncbifile.cpp 515654 2016-10-04 18:38:59Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -186,7 +186,7 @@ NCBI_PARAM_DEF_EX(bool, NCBI, FileAPILogging, DEFAULT_LOGGING_VALUE,
         int saved_error = errno; \
         if (NCBI_PARAM_TYPE(NCBI, FileAPILogging)::GetDefault()) { \
             ERR_POST(log_message << ": " << _T_STDSTRING(NcbiSys_strerror(saved_error))); \
-        } \
+                } \
         errno = saved_error; \
     }
 
@@ -194,7 +194,7 @@ NCBI_PARAM_DEF_EX(bool, NCBI, FileAPILogging, DEFAULT_LOGGING_VALUE,
     { \
         if (NCBI_PARAM_TYPE(NCBI, FileAPILogging)::GetDefault()) { \
             ERR_POST(log_message); \
-        } \
+                } \
         return false; \
     }
 
@@ -202,7 +202,7 @@ NCBI_PARAM_DEF_EX(bool, NCBI, FileAPILogging, DEFAULT_LOGGING_VALUE,
     { \
         if (NCBI_PARAM_TYPE(NCBI, FileAPILogging)::GetDefault()) { \
             ERR_POST(log_message); \
-        } \
+                } \
         CNcbiError::Set(ncbierr, log_message); \
         return false; \
     }
@@ -211,7 +211,7 @@ NCBI_PARAM_DEF_EX(bool, NCBI, FileAPILogging, DEFAULT_LOGGING_VALUE,
     { \
         if (NCBI_PARAM_TYPE(NCBI, FileAPILogging)::GetDefault()) { \
             ERR_POST(log_message); \
-        } \
+                } \
         CNcbiError::SetFromWindowsError(log_message); \
         return false; \
     }
@@ -698,6 +698,40 @@ string CDirEntry::CreateAbsolutePath(const string& path, ERelativeToWhat rtw)
 }
 
 
+string CDirEntry::CreateAbsolutePath(const string& path, const string& rtw)
+{
+    if (IsAbsolutePath(path)) {
+        return path;
+    }
+
+#if defined(NCBI_OS_MSWIN)
+    if ( path.find(DISK_SEPARATOR) != NPOS ) {
+        NCBI_THROW(CFileException, eRelativePath, 
+                   "Path must not contain disk separator: " + path);
+    }
+    // Path started with slash
+    if (!path.empty() && (path[0] == '/' || path[0] == '\\')) {
+        // network path ?
+        if ( s_Win_IsNetworkPath(path) ) {
+            NCBI_THROW(CFileException, eRelativePath,
+                       "Cannot use network path: " + path);
+        }
+        // relative to current drive only -- error
+        NCBI_THROW(CFileException, eRelativePath,
+                    "Path can be used as relative to current drive only: " + path);
+    }
+#endif
+
+    if (!IsAbsolutePath(rtw)) {
+        NCBI_THROW(CFileException, eRelativePath,
+                   "2nd parameter must represent absolute path: " + rtw);
+    }
+    return NormalizePath(ConcatPath(rtw, path));
+
+
+}
+
+
 string CDirEntry::ConvertToOSPath(const string& path)
 {
     // Not process empty or absolute path
@@ -1908,6 +1942,10 @@ bool CDirEntry::SetTime(const CTime* modification,
     return true;
 
 #else // NCBI_OS_UNIX
+
+    // Creation time doesn't used on Unix
+    creation = NULL;  /* DUMMY, to avoid warnings */
+
     if ( !modification  &&  !last_access  /*&&  !creation*/ ) {
         return true;
     }
@@ -1917,9 +1955,9 @@ bool CDirEntry::SetTime(const CTime* modification,
     CTime x_modification, x_last_access;
 
     if ( !modification  ||  !last_access ) {
-        if ( !GetTime(modification ? 0 : &x_modification,
-                      last_access  ? 0 : &x_last_access,
-                      0 /* creation */) ) {
+        if ( !GetTime(modification ? NULL : &x_modification,
+                      last_access  ? NULL : &x_last_access,
+                      NULL /* creation */) ) {
             return false;
         }
         if (!modification) {
@@ -1957,7 +1995,7 @@ bool CDirEntry::SetTime(const CTime* modification,
     if ((!modification  ||  !last_access)
         &&  !GetTimeT(&x_modification,
                       &x_last_access,
-                      0 /* creation */)) {
+                      NULL /* creation */)) {
         return false;
     }
 
@@ -2044,6 +2082,10 @@ bool CDirEntry::SetTimeT(const time_t* modification,
     return true;
 
 #else // NCBI_OS_UNIX
+
+    // Creation time doesn't used on Unix
+    creation = NULL;  /* DUMMY, to avoid warnings */
+
     if ( !modification  &&  !last_access  /*&&  !creation*/ )
         return true;
 
@@ -2051,7 +2093,7 @@ bool CDirEntry::SetTimeT(const time_t* modification,
     if ((!modification  ||  !last_access)
         &&  !GetTimeT(&x_modification,
                       &x_last_access,
-                      0 /* creation */)) {
+                      NULL /* creation */) ) {
         return false;
     }
 
@@ -2464,16 +2506,17 @@ bool CDirEntry::Rename(const string& newname, TRenameFlags flags)
         // Can rename entries with different types?
         if ( F_ISSET(flags, fRF_EqualTypes)  &&  (src_type != dst_type) ) {
             LOG_ERROR_AND_RETURN_NCBI("CDirEntry::Rename():"
-                                 " Both source and destination exist"
-                                 " and have different types: "
-                                 + src.GetPath() + " and " + dst.GetPath(),
-                                 CNcbiError::eOperationNotPermitted);
+                                      " Both source and destination exist"
+                                      " and have different types: "
+                                      + src.GetPath() + " and " + dst.GetPath(),
+                                      CNcbiError::eOperationNotPermitted);
         }
         // Can overwrite entry?
         if ( !F_ISSET(flags, fRF_Overwrite) ) {
             LOG_ERROR_AND_RETURN_NCBI("CDirEntry::Rename():"
-                                 " Destination path already exists: "
-                                 + dst.GetPath(), CNcbiError::eOperationNotPermitted);
+                                      " Destination path already exists: "
+                                      + dst.GetPath(), 
+                                      CNcbiError::eOperationNotPermitted);
         }
         // Rename only if destination is older, otherwise just remove source
         if ( F_ISSET(flags, fRF_Update)  &&  !src.IsNewer(dst.GetPath(), 0)) {
@@ -2927,7 +2970,7 @@ fstream* CDirEntry::CreateTmpFile(const string& filename,
 #if defined(NCBI_OS_MSWIN)
     // Open file manually, because we cannot say to fstream
     // to use some specific flags for file opening.
-    // MS Windows should delete created file automaticaly
+    // MS Windows should delete created file automatically
     // after closing all opened file descriptors.
 
     // We cannot enable "only write" mode here,
@@ -3606,6 +3649,18 @@ string CDir::GetTmpDir(void)
 }
 
 
+string CDir::GetAppTmpDir(void)
+{
+    // Get application specific temporary directory name
+    string tmp = NCBI_PARAM_TYPE(NCBI, TmpDir)::GetThreadDefault();
+    if (!tmp.empty()) {
+        return tmp;
+    }
+    // Use default TMP directory specified by OS
+    return CDir::GetTmpDir();
+}
+
+
 string CDir::GetCwd(void)
 {
     TXChar buf[4096];
@@ -5029,20 +5084,16 @@ Uint8 CFileUtil::GetTotalDiskSpace(const string& path)
 
 CFileDeleteList::~CFileDeleteList()
 {
-    ITERATE (TNames, name, m_Names) {
-        CDirEntry entry(*name);
-        if ( entry.IsDir()) {
-            CDir(*name).Remove(CDir::eRecursiveIgnoreMissing);
-        } else {
-            entry.Remove();
+    ITERATE (TList, path, m_Paths) {
+        if (!CDirEntry(*path).Remove(CDirEntry::eRecursiveIgnoreMissing)) {
+            ERR_POST(Warning << "CFileDeleteList: failed to remove path: " << *path);
         }
     }
 }
 
-
-void CFileDeleteAtExit::Add(const string& entryname)
+void CFileDeleteAtExit::Add(const string& path)
 {
-    s_DeleteAtExitFileList->Add(entryname);
+    s_DeleteAtExitFileList->Add(path);
 }
 
 const CFileDeleteList& CFileDeleteAtExit::GetDeleteList(void)
@@ -5309,7 +5360,7 @@ string s_LastErrorMessage(void)
 
 CMemoryFileSegment::CMemoryFileSegment(SMemoryFileHandle& handle,
                                        SMemoryFileAttrs&  attrs,
-                                       off_t              offset,
+                                       TOffsetType        offset,
                                        size_t             length)
     : m_DataPtr(0), m_Offset(offset), m_Length(length),
       m_DataPtrReal(0), m_OffsetReal(offset), m_LengthReal(length)
@@ -5488,7 +5539,7 @@ CMemoryFileMap::~CMemoryFileMap(void)
 }
 
 
-void* CMemoryFileMap::Map(off_t offset, size_t length)
+void* CMemoryFileMap::Map(TOffsetType offset, size_t length)
 {
     if ( !m_Handle  ||  (m_Handle->hMap == kInvalidHandle) ) {
         // Special case.
@@ -5801,7 +5852,7 @@ CMemoryFileMap::x_GetMemoryFileSegment(void* ptr) const
 CMemoryFile::CMemoryFile(const string&  file_name,
                          EMemMapProtect protect,
                          EMemMapShare   share,
-                         off_t          offset,
+                         TOffsetType    offset,
                          size_t         length,
                          EOpenMode      mode,
                          Uint8          max_file_len)
@@ -5816,7 +5867,7 @@ CMemoryFile::CMemoryFile(const string&  file_name,
 }
 
 
-void* CMemoryFile::Map(off_t offset, size_t length)
+void* CMemoryFile::Map(TOffsetType offset, size_t length)
 {
     // Unmap if already mapped
     if ( m_Ptr ) {
@@ -5844,7 +5895,7 @@ void* CMemoryFile::Extend(size_t length)
 
     // Get current mapped segment
     CMemoryFileSegment* segment = x_GetMemoryFileSegment(m_Ptr);
-    off_t offset = segment->GetOffset();
+    TOffsetType offset = segment->GetOffset();
 
     // Get file size
     Int8 file_size = GetFileSize();
@@ -6163,8 +6214,8 @@ void CFileIO::Open(const string& filename,
         default:
             _TROUBLE;
     };
-    // -- Ignore 'share_mode' on UNIX.
-    //share_mode = eShare;
+    // Dummy, ignore 'share_mode' on UNIX
+    share_mode = eShare;
 
     // Try to open/create file
     m_Handle = open(filename.c_str(), flags, mode);
@@ -6187,12 +6238,8 @@ void CFileIO::CreateTemporary(const string& dir,
 #if defined(NCBI_OS_MSWIN)  ||  defined(NCBI_OS_UNIX)
     string x_dir = dir;
     if (x_dir.empty()) {
-        // Get application specific temporary directory name (see CParam)
-        x_dir = NCBI_PARAM_TYPE(NCBI, TmpDir)::GetThreadDefault();
-        if (x_dir.empty()) {
-            // Use default TMP directory specified by OS
-            x_dir = CDir::GetTmpDir();
-        }
+        // Get application specific temporary directory name
+        x_dir = CDir::GetAppTmpDir();
     }
     if (!x_dir.empty()) {
         x_dir = CDirEntry::AddTrailingPathSeparator(x_dir);
@@ -6774,11 +6821,11 @@ ERW_Result CFileReaderWriter::Flush(void)
 // Platform-dependent structure to store file locking information
 struct SLock {
     SLock(void) {};
-    SLock(off_t off, size_t len) {
+    SLock(CFileLock::TOffsetType off, size_t len) {
         Reset(off, len);
     }
 #if defined(NCBI_OS_MSWIN)
-    void Reset(off_t off, size_t len) 
+    void Reset(CFileLock::TOffsetType off, size_t len) 
     {
         offset_lo = (DWORD)(off & 0xFFFFFFFF);
         offset_hi = (DWORD)((Int8(off) >> 32) & 0xFFFFFFFF);
@@ -6798,7 +6845,7 @@ struct SLock {
     DWORD length_lo;
     DWORD length_hi;
 #elif defined(NCBI_OS_UNIX)
-    void Reset(off_t off, size_t len) {
+    void Reset(CFileLock::TOffsetType off, size_t len) {
         offset = off;
         length = len;
     }
@@ -6809,7 +6856,7 @@ struct SLock {
 
 
 CFileLock::CFileLock(const string& filename, TFlags flags, EType type,
-                     off_t offset, size_t length)
+                     TOffsetType offset, size_t length)
     : m_Handle(kInvalidHandle), m_CloseHandle(false), m_Flags(flags),
       m_IsLocked(false), m_Lock(0)
 {
@@ -6818,7 +6865,7 @@ CFileLock::CFileLock(const string& filename, TFlags flags, EType type,
 
 
 CFileLock::CFileLock(const char* filename, TFlags flags, EType type,
-                     off_t offset, size_t length)
+                     TOffsetType offset, size_t length)
     : m_Handle(kInvalidHandle), m_CloseHandle(false), m_Flags(flags),
       m_IsLocked(false), m_Lock(0)
 {
@@ -6827,7 +6874,7 @@ CFileLock::CFileLock(const char* filename, TFlags flags, EType type,
 
 
 CFileLock::CFileLock(TFileHandle handle, TFlags flags, EType type,
-                     off_t offset, size_t length)
+                     TOffsetType offset, size_t length)
     : m_Handle(handle), m_CloseHandle(false), m_Flags(flags),
       m_IsLocked(false), m_Lock(0)
 {
@@ -6836,7 +6883,7 @@ CFileLock::CFileLock(TFileHandle handle, TFlags flags, EType type,
 
 
 void CFileLock::x_Init(const char* filename, EType type,
-                       off_t offset, size_t length)
+                       TOffsetType offset, size_t length)
 {
     // Reset redundant flags
     F_CLEAN_REDUNDANT(fLockNow | fLockLater);
@@ -6894,7 +6941,7 @@ CFileLock::~CFileLock()
 }
 
 
-void CFileLock::Lock(EType type, off_t offset, size_t length)
+void CFileLock::Lock(EType type, TOffsetType offset, size_t length)
 {
     // Remove previous lock
     if (m_IsLocked) {
diff --git a/c++/src/corelib/ncbimtx.cpp b/c++/src/corelib/ncbimtx.cpp
index 90365b1..8e5614c 100644
--- a/c++/src/corelib/ncbimtx.cpp
+++ b/c++/src/corelib/ncbimtx.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbimtx.cpp 469575 2015-06-05 16:41:20Z elisovdn $
+/*  $Id: ncbimtx.cpp 505546 2016-06-27 13:14:02Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1650,12 +1650,8 @@ void CSemaphore::Post(unsigned int count)
                        "CSemaphore::Post() - "
                        "attempt to exceed max_count and "
                        "pthread_mutex_unlock() failed");
-        xncbi_Validate(m_Sem->count <= kMax_UInt - count,
-                       "CSemaphore::Post() - "
-                       "would result in counter > MAX_UINT");
-        xncbi_Validate(m_Sem->count + count <= m_Sem->max_count,
+        xncbi_Validate(false,
                        "CSemaphore::Post() - attempt to exceed max_count");
-        _TROUBLE;
     }
 
     // Signal some (or all) of the threads waiting on this semaphore
@@ -2227,10 +2223,10 @@ void CConditionVariable::SignalSome(void)
         switch (res) {
         case EINVAL:
             NCBI_THROW(CConditionVariableException, eInvalidValue,
-                       "WaitForSignal failed: invalid paramater");
+                       "SignalSome failed: invalid paramater");
         default:
             NCBI_THROW(CConditionVariableException, eInvalidValue,
-                       "WaitForSignal failed: unknown error");
+                       "SignalSome failed: unknown error");
         }
     }
 #endif
@@ -2247,10 +2243,10 @@ void CConditionVariable::SignalAll(void)
         switch (res) {
         case EINVAL:
             NCBI_THROW(CConditionVariableException, eInvalidValue,
-                       "WaitForSignal failed: invalid paramater");
+                       "SignalAll failed: invalid paramater");
         default:
             NCBI_THROW(CConditionVariableException, eInvalidValue,
-                       "WaitForSignal failed: unknown error");
+                       "SignalAll failed: unknown error");
         }
     }
 #endif
diff --git a/c++/src/corelib/ncbireg.cpp b/c++/src/corelib/ncbireg.cpp
index 635d911..30d547f 100644
--- a/c++/src/corelib/ncbireg.cpp
+++ b/c++/src/corelib/ncbireg.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbireg.cpp 495404 2016-03-17 13:28:04Z ivanov $
+/*  $Id: ncbireg.cpp 507290 2016-07-18 15:24:29Z elisovdn $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -65,9 +65,7 @@ inline bool s_IsNameSectionSymbol(char ch, IRegistry::TFlags flags)
 }
 
 
-// Check if "str" consists of alphanumeric and '_' only
-// Treat the case of set fSectionlessEntries separately
-static bool s_IsNameSection(const string& str, IRegistry::TFlags flags)
+bool IRegistry::IsNameSection(const string& str, TFlags flags)
 {
     // Allow empty section name in case of fSectionlessEntries set
     if (str.empty() && !(flags & IRegistry::fSectionlessEntries) ) {
@@ -82,22 +80,13 @@ static bool s_IsNameSection(const string& str, IRegistry::TFlags flags)
     return true;
 }
 
-// Check if "str" consists of alphanumeric and '_' only
-static bool s_IsNameEntry(const string& str, IRegistry::TFlags flags)
-{
-    // Do not allow empty entry name regardless of fSectionlessEntries
-    if (str.empty()) {
-        return false;
-    }
 
-    ITERATE (string, it, str) {
-        if (!s_IsNameSectionSymbol(*it, flags)) {
-            return false;
-        }
-    }
-    return true;
+bool IRegistry::IsNameEntry(const string& str, TFlags flags)
+{
+    return IsNameSection(str, flags & ~IRegistry::fSectionlessEntries);
 }
 
+
 // Convert "comment" from plain text to comment
 static const string s_ConvertComment(const string& comment,
                                      bool is_file_comment = false)
@@ -279,13 +268,13 @@ const string& IRegistry::Get(const string& section, const string& name,
         flags |= fTPFlags;
     }
     string clean_section = NStr::TruncateSpaces(section);
-    if ( !s_IsNameSection(clean_section, flags) ) {
+    if ( !IsNameSection(clean_section, flags) ) {
         _TRACE("IRegistry::Get: bad section name \""
                << NStr::PrintableString(section) << '\"');
         return kEmptyStr;
     }
     string clean_name = NStr::TruncateSpaces(name);
-    if ( !s_IsNameEntry(clean_name, flags) ) {
+    if ( !IsNameEntry(clean_name, flags) ) {
         _TRACE("IRegistry::Get: bad entry name \""
                << NStr::PrintableString(name) << '\"');
         return kEmptyStr;
@@ -306,7 +295,7 @@ bool IRegistry::HasEntry(const string& section, const string& name,
         flags |= fTPFlags;
     }
     string clean_section = NStr::TruncateSpaces(section);
-    if ( !s_IsNameSection(clean_section, flags) ) {
+    if ( !IsNameSection(clean_section, flags) ) {
         _TRACE("IRegistry::HasEntry: bad section name \""
                << NStr::PrintableString(section) << '\"');
         return false;
@@ -314,7 +303,7 @@ bool IRegistry::HasEntry(const string& section, const string& name,
     string clean_name = NStr::TruncateSpaces(name);
     bool is_special_name = clean_name.empty() || 
                             clean_name == sm_InSectionCommentName;
-    if ( !is_special_name  &&  !s_IsNameEntry(clean_name, flags) ) {
+    if ( !is_special_name  &&  !IsNameEntry(clean_name, flags) ) {
         _TRACE("IRegistry::HasEntry: bad entry name \""
                << NStr::PrintableString(name) << '\"');
         return false;
@@ -459,7 +448,7 @@ const string& IRegistry::GetComment(const string& section, const string& name,
     x_CheckFlags("IRegistry::GetComment", flags,
                  (TFlags)fLayerFlags | fInternalSpaces | fSectionlessEntries);
     string clean_section = NStr::TruncateSpaces(section);
-    if ( !clean_section.empty()  &&  !s_IsNameSection(clean_section, flags) ) {
+    if ( !clean_section.empty()  &&  !IsNameSection(clean_section, flags) ) {
         _TRACE("IRegistry::GetComment: bad section name \""
                << NStr::PrintableString(section) << '\"');
         return kEmptyStr;
@@ -467,7 +456,7 @@ const string& IRegistry::GetComment(const string& section, const string& name,
     string clean_name = NStr::TruncateSpaces(name);
     bool is_special_name = clean_name.empty() || 
                             clean_name == sm_InSectionCommentName;
-    if ( !is_special_name  &&  !s_IsNameSection(clean_name, flags) ) {
+    if ( !is_special_name  &&  !IsNameSection(clean_name, flags) ) {
         _TRACE("IRegistry::GetComment: bad entry name \""
                << NStr::PrintableString(name) << '\"');
         return kEmptyStr;
@@ -490,7 +479,7 @@ void IRegistry::EnumerateInSectionComments(const string& section,
     _ASSERT(comments);
     comments->clear();
     string clean_section = NStr::TruncateSpaces(section);
-    if (clean_section.empty() || !s_IsNameSection(clean_section, flags)) {
+    if (clean_section.empty() || !IsNameSection(clean_section, flags)) {
         _TRACE("IRegistry::EnumerateInSectionComments: bad section name \""
             << NStr::PrintableString(section) << '\"');
         return;
@@ -530,7 +519,7 @@ void IRegistry::EnumerateEntries(const string& section, list<string>* entries,
     _ASSERT(entries);
     entries->clear();
     string clean_section = NStr::TruncateSpaces(section);
-    if ( !clean_section.empty()  &&  !s_IsNameSection(clean_section, flags) ) {
+    if ( !clean_section.empty()  &&  !IsNameSection(clean_section, flags) ) {
         _TRACE("IRegistry::EnumerateEntries: bad section name \""
                << NStr::PrintableString(section) << '\"');
         return;
@@ -710,7 +699,7 @@ IRWRegistry* IRWRegistry::x_Read(CNcbiIstream& is, TFlags flags,
                     NCBI_THROW2(CRegistryException, eSection,
                                 "Unnamed registry section" + in_path + ": `"
                                 + str + "'", line);
-                } else if ( !s_IsNameSection(section, flags) ) {
+                } else if ( !IsNameSection(section, flags) ) {
                     NCBI_THROW2(CRegistryException, eSection,
                                 "Invalid registry section name" + in_path
                                 + ": `" + str + "'", line);
@@ -730,7 +719,7 @@ IRWRegistry* IRWRegistry::x_Read(CNcbiIstream& is, TFlags flags,
                                 + ": '" + str + "'", line);
                 }
                 NStr::TruncateSpacesInPlace(name);
-                if ( !s_IsNameSection(name, flags) ) {
+                if ( !IsNameEntry(name, flags) ) {
                     NCBI_THROW2(CRegistryException, eEntry,
                                 "Invalid registry entry name" + in_path + ": '"
                                 + str + "'", line);
@@ -837,13 +826,13 @@ bool IRWRegistry::Set(const string& section, const string& name,
                  fPersistent | fNoOverride | fTruncate | fInternalSpaces
                  | fCountCleared | fSectionlessEntries);
     string clean_section = NStr::TruncateSpaces(section);
-    if ( !s_IsNameSection(clean_section, flags) ) {
+    if ( !IsNameSection(clean_section, flags) ) {
         _TRACE("IRWRegistry::Set: bad section name \""
                << NStr::PrintableString(section) << '\"');
         return false;
     }
     string clean_name = NStr::TruncateSpaces(name);
-    if ( !s_IsNameEntry(clean_name, flags) ) {
+    if ( !IsNameEntry(clean_name, flags) ) {
         _TRACE("IRWRegistry::Set: bad entry name \""
                << NStr::PrintableString(name) << '\"');
         return false;
@@ -876,13 +865,13 @@ bool IRWRegistry::Unset(const string& section, const string& name,
     x_CheckFlags("IRWRegistry::Unset", flags,
                  fTPFlags | fCountCleared | fSectionlessEntries);
     string clean_section = NStr::TruncateSpaces(section);
-    if ( !s_IsNameSection(clean_section, flags) ) {
+    if ( !IsNameSection(clean_section, flags) ) {
         _TRACE("IRWRegistry::Unset: bad section name \""
                << NStr::PrintableString(section) << '\"');
         return false;
     }
     string clean_name = NStr::TruncateSpaces(name);
-    if ( !s_IsNameEntry(clean_name, flags) ) {
+    if ( !IsNameEntry(clean_name, flags) ) {
         _TRACE("IRWRegistry::Unset: bad entry name \""
                << NStr::PrintableString(name) << '\"');
         return false;
@@ -903,7 +892,7 @@ bool IRWRegistry::SetComment(const string& comment, const string& section,
     x_CheckFlags("IRWRegistry::SetComment", flags,
                  fTransient | fNoOverride | fInternalSpaces | fCountCleared);
     string clean_section = NStr::TruncateSpaces(section);
-    if ( !clean_section.empty()  &&  !s_IsNameSection(clean_section, flags) ) {
+    if ( !clean_section.empty()  &&  !IsNameSection(clean_section, flags) ) {
         _TRACE("IRWRegistry::SetComment: bad section name \""
                << NStr::PrintableString(section) << '\"');
         return false;
@@ -911,7 +900,7 @@ bool IRWRegistry::SetComment(const string& comment, const string& section,
     string clean_name = NStr::TruncateSpaces(name);
     bool is_special_name = clean_name.empty()  || 
                             clean_name == sm_InSectionCommentName;
-    if ( !is_special_name && !s_IsNameEntry(clean_name, flags) )  {
+    if ( !is_special_name && !IsNameEntry(clean_name, flags) )  {
         _TRACE("IRWRegistry::SetComment: bad entry name \""
                << NStr::PrintableString(name) << '\"');
         return false;
@@ -1030,7 +1019,7 @@ void CMemoryRegistry::x_Enumerate(const string& section, list<string>& entries,
                    " but with no fSections flag set");
 
         ITERATE (TSections, it, m_Sections) {
-            if (s_IsNameSection(it->first, flags)
+            if (IsNameSection(it->first, flags)
                 &&  HasEntry(it->first, kEmptyStr, flags)) {
                 entries.push_back(it->first);
             }
@@ -1046,7 +1035,7 @@ void CMemoryRegistry::x_Enumerate(const string& section, list<string>& entries,
         TSections::const_iterator sit = m_Sections.find(section);
         if (sit != m_Sections.end()) {
             ITERATE (TEntries, it, sit->second.entries) {
-                if (s_IsNameSection(it->first, flags)
+                if (IsNameSection(it->first, flags)
                     &&  ((flags & fCountCleared) != 0
                          ||  !it->second.value.empty() )) {
                     entries.push_back(it->first);
@@ -1974,7 +1963,8 @@ void CCompoundRWRegistry::x_Enumerate(const string& section,
                                       list<string>& entries,
                                       TFlags flags) const
 {
-    set<string> accum;
+    typedef set<string, PNocase> SetNoCase;
+    SetNoCase accum;
     REVERSE_ITERATE (CCompoundRegistry::TPriorityMap, it,
                      m_AllRegistries->m_PriorityMap) {
         if ((flags & fJustCore)  &&  (it->first < GetCoreCutoff())) {
@@ -2001,7 +1991,7 @@ void CCompoundRWRegistry::x_Enumerate(const string& section,
             }
         }
     }
-    ITERATE (set<string>, it, accum) {
+    ITERATE(SetNoCase, it, accum) {
         entries.push_back(*it);
     }
 }
@@ -2031,7 +2021,7 @@ bool CCompoundRWRegistry::x_Set(const string& section, const string& name,
     TFlags flags2 = (flags & fPersistent) ? flags : (flags | fTransient);
     flags2 &= fLayerFlags;
     _TRACE('[' << section << ']' << name << " = " << value);
-    if ((flags & fNoOverride)  &&  HasEntry(section, name, flags)) {
+    if ((flags & fNoOverride) && HasEntry(section, name, flags)) {
         return false;
     }
     if (value.empty()) {
diff --git a/c++/src/corelib/ncbistr.cpp b/c++/src/corelib/ncbistr.cpp
index 68e3336..b85d0a4 100644
--- a/c++/src/corelib/ncbistr.cpp
+++ b/c++/src/corelib/ncbistr.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbistr.cpp 491918 2016-02-10 14:52:43Z ivanov $
+/*  $Id: ncbistr.cpp 511434 2016-08-22 15:26:41Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -347,36 +347,55 @@ bool NStr::IsUpper(const CTempString str)
 }
 
 
-int NStr::StringToNonNegativeInt(const string& str)
+int NStr::StringToNonNegativeInt(const CTempString str, TStringToNumFlags flags)
 {
-    int& errno_ref = errno;
-    if ( str.empty() ) {
-        CNcbiError::SetErrno(errno_ref = EINVAL, str);
-        return -1;
-    }
-    char ch = str[0];
-    if ( !isdigit((unsigned char)ch) &&  (ch != '+') ) {
-        CNcbiError::SetErrno(errno_ref = EINVAL, str);
-        return -1;
-    }
-    char* endptr = 0;
-    const char* begptr = str.c_str();
-    errno_ref = 0;
-    unsigned long value = strtoul(begptr, &endptr, 10);
-    if ( errno_ref ) {
-        CNcbiError::SetErrno(errno_ref, str);
-        return -1;
+    int error = 0, ret = -1;
+    size_t len = str.size();
+
+    if (!len) {
+        error = EINVAL;
+    } else {
+        size_t i = 0;
+        // skip leading '+' if any
+        if (str.data()[0] == '+'  &&  len > 1) {
+            ++i;
+        }
+        unsigned v = 0;
+        for (; i < len; ++i) {
+            unsigned d = str.data()[i] - '0';
+            if (d > 9) {
+                error = EINVAL;
+                break;
+            }
+            unsigned nv = v * 10 + d;
+            const unsigned kOverflowLimit = (INT_MAX - 9) / 10 + 1;
+            if (v >= kOverflowLimit) {
+                // possible overflow
+                if (v > kOverflowLimit || nv > INT_MAX) {
+                    error = ERANGE;
+                    break;
+                }
+            }
+            v = nv;
+        }
+        if (!error) {
+            ret = static_cast<int>(v);
+        }
     }
-    else if ( !endptr  ||  endptr == begptr  ||  *endptr ) {
-        CNcbiError::SetErrno(errno_ref = EINVAL, str);
-        return -1;
+/*
+    if (flags & fConvErr_NoErrno) {
+        return ret;
     }
-    else if ( value > (unsigned long) kMax_Int ) {
-        CNcbiError::SetErrno(errno_ref = ERANGE, str);
-        return -1;
+*/
+    errno = error;
+    if (error) {
+        if (flags & fConvErr_NoErrMessage) {
+            CNcbiError::SetErrno(error);
+        } else {
+            CNcbiError::SetErrno(error, str);
+        }
     }
-    errno_ref = 0;
-    return (int) value;
+    return ret;
 }
 
 
@@ -388,15 +407,18 @@ class CS2N_Guard
 {
 public:
     CS2N_Guard(NStr::TStringToNumFlags flags, bool skip_if_zero) :
+        m_NoErrno(false),     // m_NoErrno((flags & NStr::fConvErr_NoErrno) > 0),
         m_NoThrow((flags & NStr::fConvErr_NoThrow) > 0), 
         m_SkipIfZero(skip_if_zero), 
         m_Errno(0)
     {}
     ~CS2N_Guard(void)  {
-        // Does the guard is used against the code that already set an errno?
-        // If the error code is not defined here, do not even try to check/set it.
-        if (!m_SkipIfZero  ||  m_Errno) {
-            errno = m_Errno;
+        if (!m_NoErrno) {
+            // Does the guard is used against the code that already set an errno?
+            // If the error code is not defined here, do not even try to check/set it.
+            if (!m_SkipIfZero  ||  m_Errno) {
+                errno = m_Errno;
+            }
         }
     }
     void Set(int errcode)    { m_Errno = errcode; }
@@ -410,6 +432,7 @@ public:
     string Message(const CTempString str, const char* to_type, const CTempString msg);
 
 private:
+    bool m_NoErrno;    // do not set errno at all
     bool m_NoThrow;    // do not throw an exception if TRUE
     bool m_SkipIfZero; // do not set errno if TRUE and m_Errno == 0
     int  m_Errno;      // errno value to set
@@ -447,8 +470,18 @@ string CS2N_Guard::Message(const CTempString str, const char* to_type, const CTe
             NCBI_THROW2(CStringException, eConvert,                   \
                         err_guard.Message(str, #to_type, msg), pos);  \
         } else {                                                      \
-            CNcbiError::SetErrno(err_guard.Errno(),                   \
-                err_guard.Message(str, #to_type, msg));               \
+/* \
+            if (flags & NStr::fConvErr_NoErrno) {                     \
+                / Error, but forced to return 0 /                   \
+                return 0;                                             \
+            }                                                         \
+*/ \
+            if (flags & NStr::fConvErr_NoErrMessage) {              \
+                CNcbiError::SetErrno(err_guard.Errno());              \
+            } else {                                                  \
+                CNcbiError::SetErrno(err_guard.Errno(),               \
+                            err_guard.Message(str, #to_type, msg));   \
+            }                                                         \
             return 0;                                                 \
         }                                                             \
     } while (false)
@@ -495,7 +528,7 @@ string CS2N_Guard::Message(const CTempString str, const char* to_type, const CTe
     }
 
 
-int NStr::StringToInt(const CTempString str, TStringToNumFlags flags,int base)
+int NStr::StringToInt(const CTempString str, TStringToNumFlags flags, int base)
 {
     S2N_CONVERT_GUARD_EX(flags);
     Int8 value = StringToInt8(str, flags, base);
@@ -518,8 +551,7 @@ NStr::StringToUInt(const CTempString str, TStringToNumFlags flags, int base)
 }
 
 
-long NStr::StringToLong(const CTempString str, TStringToNumFlags flags,
-                        int base)
+long NStr::StringToLong(const CTempString str, TStringToNumFlags flags, int base)
 {
     S2N_CONVERT_GUARD_EX(flags);
     Int8 value = StringToInt8(str, flags, base);
@@ -626,7 +658,6 @@ void s_SkipAllowedSymbols(const CTempString  str,
 // Check radix base. If it is zero, determine base using first chars
 // of the string. Update 'base' value.
 // Update 'ptr' to current position in the string.
-
 static inline
 bool s_CheckRadix(const CTempString str, SIZE_TYPE& pos, int& base)
 {
@@ -660,10 +691,8 @@ bool s_CheckRadix(const CTempString str, SIZE_TYPE& pos, int& base)
 }
 
 
-Int8 NStr::StringToInt8(const CTempString str, TStringToNumFlags flags,
-                        int base)
+Int8 NStr::StringToInt8(const CTempString str, TStringToNumFlags flags, int base)
 {
-    _ASSERT(flags == 0  ||  flags > 32);
     S2N_CONVERT_GUARD(flags);
 
     // Current position in the string
@@ -737,6 +766,7 @@ Int8 NStr::StringToInt8(const CTempString str, TStringToNumFlags flags,
     // Assign sign before the end pointer check
     n = sign ? -n : n;
     CHECK_ENDPTR(Int8);
+
     return n;
 }
 
@@ -744,13 +774,12 @@ Int8 NStr::StringToInt8(const CTempString str, TStringToNumFlags flags,
 Uint8 NStr::StringToUInt8(const CTempString str,
                           TStringToNumFlags flags, int base)
 {
-    _ASSERT(flags == 0  ||  flags > 32);
     S2N_CONVERT_GUARD(flags);
 
     const TStringToNumFlags slow_flags =
         fMandatorySign|fAllowCommas|fAllowLeadingSymbols|fAllowTrailingSymbols;
 
-    if ( base == 10 && (flags & slow_flags) == 0 ) {
+    if ( base == 10  &&  (flags & slow_flags) == 0 ) {
         // fast conversion
 
         // Current position in the string
@@ -1154,7 +1183,6 @@ double NStr::StringToDoublePosix(const char* ptr, char** endptr, TStringToNumFla
 static double s_StringToDouble(const char* str, size_t size,
                                NStr::TStringToNumFlags flags)
 {
-    _ASSERT(flags == 0  ||  flags > 32);
     _ASSERT(str[size] == '\0');
     if ((flags & NStr::fDecimalPosix) && (flags & NStr::fDecimalPosixOrLocal)) {
         NCBI_THROW2(CStringException, eBadArgs,
@@ -1336,7 +1364,6 @@ Uint8 NStr::StringToUInt8_DataSize(const CTempString str,
                                    int               base)
 {
     // We have a limited base range here
-    _ASSERT(flags == 0  ||  flags > 20);
     if ( base < 2  ||  base > 16 ) {
         NCBI_THROW2(CStringException, eConvert,  
                     "Bad numeric base '" + NStr::IntToString(base)+ "'", 0);
@@ -1713,7 +1740,6 @@ static void s_SignedToString(string&                 out_str,
 void NStr::IntToString(string& out_str, int svalue,
                        TNumToStringFlags flags, int base)
 {
-    _ASSERT(flags == 0  ||  flags > 32);
     if ( base < 2  ||  base > 36 ) {
         CNcbiError::SetErrno(errno = EINVAL);
         return;
@@ -1731,7 +1757,6 @@ void NStr::IntToString(string& out_str, int svalue,
 void NStr::LongToString(string& out_str, long svalue,
                        TNumToStringFlags flags, int base)
 {
-    _ASSERT(flags == 0  ||  flags > 32);
     if ( base < 2  ||  base > 36 ) {
         CNcbiError::SetErrno(errno = EINVAL);
         return;
@@ -1751,12 +1776,10 @@ void NStr::ULongToString(string&          out_str,
                         TNumToStringFlags flags,
                         int               base)
 {
-    _ASSERT(flags == 0  ||  flags > 32);
     if ( base < 2  ||  base > 36 ) {
         CNcbiError::SetErrno(errno = EINVAL);
         return;
     }
-
     const SIZE_TYPE kBufSize = CHAR_BIT * sizeof(value);
     char  buffer[kBufSize];
     char* pos = buffer + kBufSize;
@@ -1912,7 +1935,6 @@ static char* s_PrintUint8(char*                   pos,
 void NStr::Int8ToString(string& out_str, Int8 svalue,
                         TNumToStringFlags flags, int base)
 {
-    _ASSERT(flags == 0  ||  flags > 32);
     if ( base < 2  ||  base > 36 ) {
         CNcbiError::SetErrno(errno = EINVAL);
         return;
@@ -1942,7 +1964,6 @@ void NStr::Int8ToString(string& out_str, Int8 svalue,
 void NStr::UInt8ToString(string& out_str, Uint8 value,
                          TNumToStringFlags flags, int base)
 {
-    _ASSERT(flags == 0  ||  flags > 32);
     if ( base < 2  ||  base > 36 ) {
         CNcbiError::SetErrno(errno = EINVAL);
         return;
@@ -2234,7 +2255,6 @@ void NStr::DoubleToString(string& out_str, double value,
 }
 
 
-
 SIZE_TYPE NStr::DoubleToString(double value, unsigned int precision,
                                char* buf, SIZE_TYPE buf_size,
                                TNumToStringFlags flags)
@@ -2653,10 +2673,9 @@ void NStr::PtrToString(string& out_str, const void* value)
 }
 
 
-const void* NStr::StringToPtr(const CTempStringEx str)
+const void* NStr::StringToPtr(const CTempStringEx str, TConvErrFlags flags)
 {
-    int& errno_ref = errno;
-    errno_ref = 0;
+    errno = 0;
     void *ptr = NULL;
     int res;
     if ( str.HasZeroAtEnd() ) {
@@ -2665,7 +2684,11 @@ const void* NStr::StringToPtr(const CTempStringEx str)
         res = ::sscanf(string(str).c_str(), "%p", &ptr);
     }
     if (res != 1) {
-        CNcbiError::SetErrno(errno_ref = EINVAL, str);
+        if (flags & fConvErr_NoErrMessage) {
+            CNcbiError::SetErrno(errno = EINVAL);
+        } else {
+            CNcbiError::SetErrno(errno = EINVAL, str);
+        }
         return NULL;
     }
     return ptr;
@@ -3658,7 +3681,7 @@ string NStr::Join(const set<CTempString>& arr, const CTempString delim)
         out.reset(new CNcbiOstrstream); \
     } \
     SIZE_TYPE n = (flags & fSS_NoMerge) ? n_spaces : 1; \
-    for (SIZE_TYPE i = n; i > 0; i--) { \
+    for (SIZE_TYPE j = n; j > 0; j--) { \
         out->put(' '); \
     } 
 
@@ -4763,7 +4786,7 @@ string NStr::ParseEscapes(const CTempString str, EEscSeqRange mode, char user_ch
                                 "' is out of range [0-255]", pos2);
                             break;
                         case eEscSeqRange_Errno:
-                            CNcbiError::SetErrno(errno = ERANGE,str);
+                            CNcbiError::SetErrno(errno = ERANGE, str);
                             is_error = true;
                             continue;
                         case eEscSeqRange_User:
diff --git a/c++/src/corelib/ncbitime.cpp b/c++/src/corelib/ncbitime.cpp
index 689667f..e378fd9 100644
--- a/c++/src/corelib/ncbitime.cpp
+++ b/c++/src/corelib/ncbitime.cpp
@@ -1,4 +1,4 @@
-/*  $Id: ncbitime.cpp 493937 2016-03-02 16:38:06Z ivanov $
+/*  $Id: ncbitime.cpp 500405 2016-05-04 15:18:35Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -817,15 +817,15 @@ bool CTime::x_Init(const string& str, const CTimeFormat& format, EErrAction err_
             SET_SEC(value);
             if ( *sss == '.' ) {
                 ++sss;
-                char* s = value_str;
+                s = value_str;
                 // Limit fraction of second to 9 digits max,
                 // ignore all other digits in string if any.
-                for (size_t len = 9;
-                    len  &&  *sss  &&  isdigit((unsigned char)(*sss));  --len) {
+                for (size_t n = 9;
+                    n  &&  *sss  &&  isdigit((unsigned char)(*sss));  --n) {
                     *s++ = *sss++;
                 }
                 *s = '\0';
-                long value = NStr::StringToLong(value_str);
+                value = NStr::StringToLong(value_str);
                 size_t n = strlen(value_str);
                 // 'n' cannot have more then 9 (max for nanoseconds) - see above.
                 _ASSERT(n <= 9);
@@ -2433,8 +2433,8 @@ CTimeSpan::CTimeSpan(const string& str, const CTimeFormat& fmt)
         // if global format has not set.
         CTimeFormat* ptr = s_TlsFormatSpan.GetValue();
         if (!ptr) {
-            CTimeFormat fmt(kDefaultFormatSpanIn);
-            x_Init(str, fmt);
+            CTimeFormat default_fmt(kDefaultFormatSpanIn);
+            x_Init(str, default_fmt);
         } else {
             x_Init(str, *ptr);
         }
@@ -3965,7 +3965,7 @@ retry:
         int x_daylight = Daylight();
         {{
             // MT-Safe protect: use CTime locking mutex
-            CFastMutexGuard LOCK(s_TimeMutex);
+            CFastMutexGuard LOCK_TM(s_TimeMutex);
             x_timezone = TimeZone();
             x_daylight = Daylight();
         }}
diff --git a/c++/src/corelib/request_ctx.cpp b/c++/src/corelib/request_ctx.cpp
index 6c37235..5178b2f 100644
--- a/c++/src/corelib/request_ctx.cpp
+++ b/c++/src/corelib/request_ctx.cpp
@@ -1,4 +1,4 @@
-/*  $Id: request_ctx.cpp 493379 2016-02-26 15:41:32Z ivanov $
+/*  $Id: request_ctx.cpp 508783 2016-08-01 16:05:01Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -53,7 +53,6 @@ CRequestContext::CRequestContext(TContextFlags flags)
     : m_RequestID(0),
       m_AppState(eDiagAppState_NotSet),
       m_LoggedHitID(false),
-      m_SubHitID(0),
       m_ReqStatus(0),
       m_ReqTimer(CStopWatch::eStop),
       m_BytesRd(0),
@@ -81,7 +80,7 @@ CRequestContext::TCount CRequestContext::GetNextRequestID(void)
 
 void CRequestContext::x_LogHitID(bool ignore_app_state) const
 {
-    if (m_LoggedHitID || m_HitID.empty()) return;
+    if (m_LoggedHitID || m_HitID.Empty()) return;
 
     // ignore_app_state can be set by CDiagContext in case if hit-id
     // was set for request context only (no default one), but request
@@ -93,7 +92,8 @@ void CRequestContext::x_LogHitID(bool ignore_app_state) const
         m_AppState != eDiagAppState_Request  &&
         m_AppState != eDiagAppState_RequestBegin  &&
         m_AppState != eDiagAppState_RequestEnd) return;
-    GetDiagContext().Extra().Print(g_GetNcbiString(eNcbiStrings_PHID), m_HitID);
+    GetDiagContext().Extra().Print(g_GetNcbiString(eNcbiStrings_PHID),
+        m_HitID.GetHitId());
     m_LoggedHitID = true;
 }
 
@@ -101,7 +101,7 @@ void CRequestContext::x_LogHitID(bool ignore_app_state) const
 const string& CRequestContext::SetHitID(void)
 {
     SetHitID(GetDiagContext().GetNextHitID());
-    return m_HitID;
+    return m_HitID.GetHitId();
 }
 
 
@@ -109,12 +109,12 @@ string CRequestContext::x_GetHitID(CDiagContext::EDefaultHitIDFlags flag) const
 {
     if ( x_IsSetProp(eProp_HitID) ) {
         x_LogHitID();
-        return m_HitID;
+        return m_HitID.GetHitId();
     }
-    string phid = GetDiagContext().x_GetDefaultHitID(CDiagContext::eHitID_NoCreate);
-    if (!phid.empty()) {
-        const_cast<CRequestContext*>(this)->SetHitID(phid);
-        return phid;
+    CSharedHitId phid = GetDiagContext().x_GetDefaultHitID(CDiagContext::eHitID_NoCreate);
+    if (!phid.Empty()) {
+        const_cast<CRequestContext*>(this)->x_SetHitID(phid);
+        return phid.GetHitId();
     }
     if (flag != CDiagContext::eHitID_NoCreate) {
         // If there's no hit id available, create (and log) a new one.
@@ -291,6 +291,9 @@ static bool IsValidHitID(const string& hit) {
             return false;
         }
     }
+    // Hit id must be present before the first separator.
+    // Note that empty hit id is still allowed if there are no sub-hit ids.
+    if (sep_pos == 0) return false;
     if (sep_pos == NPOS) return true;
     // Separator found - make sure the rest of the id contains only separators
     // and valid sub-hit ids: a prefix consisting of allowed chars and some
@@ -316,24 +319,26 @@ static bool IsValidHitID(const string& hit) {
 }
 
 
-void CRequestContext::SetHitID(const string& hit)
+void CRequestContext::x_SetHitID(const CSharedHitId& hit_id)
 {
+    const string& hit = hit_id.GetHitId();
     if ( m_LoggedHitID ) {
         // Show warning when changing hit id after is has been logged.
         ERR_POST_X(28, Warning << "Changing hit ID after one has been logged. "
             "New hit id is: " << hit);
     }
+    if (m_HitID.GetHitId() == hit) return;
+
     static CSafeStatic<TOnBadHitId> action;
     if ( !IsValidHitID(hit) ) {
         switch ( action->Get() ) {
         case eOnBadPHID_Ignore:
             return;
         case eOnBadPHID_AllowAndReport:
-            // Use Warning if bad hit id is acceptable.
             ERR_POST_X(27, Warning << "Bad hit ID format: " << hit);
             break;
         case eOnBadPHID_IgnoreAndReport:
-            ERR_POST_X(27, "Bad hit ID format: " << hit);
+            ERR_POST_X(27, Warning << "Bad hit ID format: " << hit);
             return;
         case eOnBadPHID_Throw:
             NCBI_THROW(CRequestContextException, eBadHit,
@@ -344,38 +349,33 @@ void CRequestContext::SetHitID(const string& hit)
         }
     }
     x_SetProp(eProp_HitID);
-    if (m_HitID != hit) {
-        m_SubHitID = 0;
-        m_SubHitIDCache.clear();
-    }
-    m_HitID = hit;
+
+    m_SubHitIDCache.clear();
+    m_HitID = hit_id;
     m_LoggedHitID = false;
     x_LogHitID();
 }
 
 
-void CRequestContext::x_UpdateSubHitID(bool increment)
+void CRequestContext::SetHitID(const string& hit)
 {
-    static CAtomicCounter s_DefaultSubHitCounter;
+    x_SetHitID(CSharedHitId(hit));
+}
+
 
+void CRequestContext::x_UpdateSubHitID(bool increment, CTempString prefix)
+{
     _ASSERT(IsSetHitID());
 
     // Use global sub-hit counter for default hit id to prevent
     // duplicate phids in different threads.
     m_SubHitIDCache = GetHitID();
 
-    unsigned int sub_hit_id;
-    if (m_SubHitIDCache == GetDiagContext().GetDefaultHitID()) {
-        sub_hit_id = (unsigned int)(increment ? s_DefaultSubHitCounter.Add(1) :
-            s_DefaultSubHitCounter.Get());
-    }
-    else {
-        if ( increment ) ++m_SubHitID;
-        sub_hit_id = m_SubHitID;
-    }
+    unsigned int sub_hit_id = increment ?
+        m_HitID.GetNextSubHitId() : m_HitID.GetCurrentSubHitId();
 
     // Cache the string so that C code can use it.
-    m_SubHitIDCache += "." + NStr::NumericToString(sub_hit_id);
+    m_SubHitIDCache += "." + prefix + NStr::NumericToString(sub_hit_id);
 }
 
 
@@ -387,12 +387,11 @@ void CRequestContext::SetSessionID(const string& session)
         case eOnBadSID_Ignore:
             return;
         case eOnBadSID_AllowAndReport:
-        case eOnBadSID_IgnoreAndReport:
-            ERR_POST_X(26, "Bad session ID format: " << session);
-            if (action == eOnBadSID_IgnoreAndReport) {
-                return;
-            }
+            ERR_POST_X(26, Warning << "Bad session ID format: " << session);
             break;
+        case eOnBadSID_IgnoreAndReport:
+            ERR_POST_X(26, Warning << "Bad session ID format: " << session);
+            return;
         case eOnBadSID_Throw:
             NCBI_THROW(CRequestContextException, eBadSession,
                 "Bad session ID format: " + session);
@@ -505,9 +504,9 @@ CRef<CRequestContext> CRequestContext::Clone(void) const
     ret->m_AppState = m_AppState;
     ret->m_ClientIP = m_ClientIP;
     ret->m_SessionID.SetString(m_SessionID.GetOriginalString());
+    m_HitID.SetShared();
     ret->m_HitID = m_HitID;
     ret->m_LoggedHitID = m_LoggedHitID;
-    ret->m_SubHitID = m_SubHitID;
     ret->m_SubHitIDCache = m_SubHitIDCache;
     ret->m_Dtab = m_Dtab;
     ret->m_ReqStatus = m_ReqStatus;
diff --git a/c++/src/corelib/stream_utils.cpp b/c++/src/corelib/stream_utils.cpp
index 8489cac..4fa623f 100644
--- a/c++/src/corelib/stream_utils.cpp
+++ b/c++/src/corelib/stream_utils.cpp
@@ -1,4 +1,4 @@
-/* $Id: stream_utils.cpp 463570 2015-03-30 16:29:21Z lavr $
+/* $Id: stream_utils.cpp 504923 2016-06-20 20:21:48Z lavr $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -525,6 +525,13 @@ static streamsize s_Readsome(CNcbiIstream& is,
     return count;
 #else
     // Try to read data
+#  ifdef __llvm__
+    // https://llvm.org/bugs/show_bug.cgi?id=28217
+    if ( !is.good() ) {
+        is.setstate(is.rdstate() | NcbiFailbit);
+        return 0; // simulate construction of sentry in standard readsome()
+    }
+#  endif //__llvm__
     streamsize n = x_Readsome(is, buf, buf_size);
     if (n != 0  ||  !is.good())
         return n;
diff --git a/c++/src/corelib/teamcity_boost.cpp b/c++/src/corelib/teamcity_boost.cpp
index 45e1370..0578c0d 100644
--- a/c++/src/corelib/teamcity_boost.cpp
+++ b/c++/src/corelib/teamcity_boost.cpp
@@ -1,83 +1,106 @@
 /* Copyright 2011 JetBrains s.r.o.
- *
+ * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- *
+ * 
  *     http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- *
- * $Id: teamcity_boost.cpp 488254 2015-12-29 13:56:26Z ivanov $
+ * 
+ * $Id: teamcity_boost.cpp 500448 2016-05-04 18:16:16Z ucko $
 */
 
 #include <sstream>
 
-#include <boost/test/unit_test_suite_impl.hpp>
 #include <boost/test/results_collector.hpp>
 #include <boost/test/utils/basic_cstring/io.hpp>
 #include <boost/test/unit_test_log.hpp>
-#include <boost/test/included/unit_test.hpp>
+#include <boost/test/execution_monitor.hpp>
+#include <boost/test/unit_test_log_formatter.hpp>
+#include <boost/test/unit_test.hpp>
+
+// In 1.59.0, they changed the name of this enum value, so we have to this hacky thing...
+#include <boost/version.hpp>
+#if BOOST_VERSION >= 105900
+    #define TUT_CASE_IDENTIFIER boost::unit_test::TUT_CASE
+    #define CURRENT_TEST_NAME   boost::unit_test_framework::framework::current_test_case().full_name()
+#else
+    #define TUT_CASE_IDENTIFIER boost::unit_test::tut_case
+    #define CURRENT_TEST_NAME   boost::unit_test_framework::framework::current_test_case().p_name
+#endif
 
 #include "teamcity_messages.h"
 
-///
-// NOTE: Using namespace boost::unit_test breaks GPIPE Static build!!
-///
-//using namespace boost::unit_test;
-using namespace std;
-
-namespace JetBrains {
+namespace jetbrains { namespace teamcity {
+const std::string ASSERT_CTX = "Assertion occurred in a following context:";
+const std::string FAILURE_CTX = "Failure occurred in a following context:";
 
 // Custom formatter for TeamCity messages
 class TeamcityBoostLogFormatter: public boost::unit_test::unit_test_log_formatter {
     TeamcityMessages messages;
     std::string currentDetails;
+    std::string currentContextDetails;
     std::string flowId;
 
 public:
     TeamcityBoostLogFormatter(const std::string &_flowId);
     TeamcityBoostLogFormatter();
 
-    void log_start(std::ostream&, boost::unit_test::counter_t test_cases_amount);
-    void log_finish(std::ostream&);
-    void log_build_info(std::ostream&);
+    virtual ~TeamcityBoostLogFormatter() {}
+
+    virtual void log_start(std::ostream&, boost::unit_test::counter_t test_cases_amount);
+    virtual void log_finish(std::ostream&);
+    virtual void log_build_info(std::ostream&);
 
-    void test_unit_start(std::ostream&, boost::unit_test::test_unit const& tu);
-    void test_unit_finish(std::ostream&,
+    virtual void test_unit_start(std::ostream&, boost::unit_test::test_unit const& tu);
+    virtual void test_unit_finish(std::ostream&,
         boost::unit_test::test_unit const& tu,
         unsigned long elapsed);
-    void test_unit_skipped(std::ostream&, boost::unit_test::test_unit const& tu);
+    virtual void test_unit_skipped(std::ostream&, boost::unit_test::test_unit const& tu);
+    virtual void test_unit_skipped(std::ostream&,
+        boost::unit_test::test_unit const& tu,
+        boost::unit_test::const_string reason);
 
-    void log_exception(std::ostream&,
+    virtual void log_exception(std::ostream&,
         boost::unit_test::log_checkpoint_data const&,
         boost::unit_test::const_string explanation);
+    virtual void log_exception_start(std::ostream&,
+        boost::unit_test::log_checkpoint_data const&,
+        const boost::execution_exception&);
+    virtual void log_exception_finish(std::ostream&);
 
-    void log_entry_start(std::ostream&,
-        boost::unit_test::log_entry_data const&,
+    virtual void log_entry_start(std::ostream & out,
+        boost::unit_test::log_entry_data const & entry_data,
         log_entry_types let);
-    void log_entry_value(std::ostream&, boost::unit_test::const_string value);
-    void log_entry_finish(std::ostream&);
+    virtual void log_entry_value(std::ostream&, boost::unit_test::const_string value);
+    virtual void log_entry_finish(std::ostream&);
+
+    virtual void entry_context_start(std::ostream&, boost::unit_test::log_level);
+    virtual void log_entry_context(std::ostream&, boost::unit_test::const_string);
+    virtual void entry_context_finish(std::ostream&);
 };
 
 // Fake fixture to register formatter
 struct TeamcityFormatterRegistrar {
     TeamcityFormatterRegistrar() {
-        if (JetBrains::underTeamcity()) {
-            boost::unit_test::unit_test_log.set_formatter(new JetBrains::TeamcityBoostLogFormatter());
-            boost::unit_test::unit_test_log.set_threshold_level(boost::unit_test::runtime_config::log_level());
+        if (underTeamcity()) {
+            boost::unit_test::unit_test_log.set_formatter(new TeamcityBoostLogFormatter());
+            boost::unit_test::unit_test_log.set_threshold_level
+                (RTCFG(but::log_level, LOG_LEVEL, log_level));
         }
     }
 };
+
 BOOST_GLOBAL_FIXTURE(TeamcityFormatterRegistrar);
 
 // Formatter implementation
-string toString(boost::unit_test::const_string bstr) {
-    stringstream ss;
+static std::string toString(boost::unit_test::const_string bstr) {
+    std::stringstream ss;
 
     ss << bstr;
 
@@ -92,19 +115,19 @@ TeamcityBoostLogFormatter::TeamcityBoostLogFormatter()
 : flowId(getFlowIdFromEnvironment())
 {}
 
-void TeamcityBoostLogFormatter::log_start(ostream &out, boost::unit_test::counter_t test_cases_amount)
+void TeamcityBoostLogFormatter::log_start(std::ostream &/*out*/, boost::unit_test::counter_t /*test_cases_amount*/)
 {}
 
-void TeamcityBoostLogFormatter::log_finish(ostream &out)
+void TeamcityBoostLogFormatter::log_finish(std::ostream &/*out*/)
 {}
 
-void TeamcityBoostLogFormatter::log_build_info(ostream &out)
+void TeamcityBoostLogFormatter::log_build_info(std::ostream &/*out*/)
 {}
 
-void TeamcityBoostLogFormatter::test_unit_start(ostream &out, boost::unit_test::test_unit const& tu) {
+void TeamcityBoostLogFormatter::test_unit_start(std::ostream &out, boost::unit_test::test_unit const& tu) {
     messages.setOutput(out);
 
-    if (tu.p_type == boost::unit_test::tut_case) {
+    if (tu.p_type == TUT_CASE_IDENTIFIER) {
         messages.testStarted(tu.p_name, flowId);
     } else {
         messages.suiteStarted(tu.p_name, flowId);
@@ -113,11 +136,11 @@ void TeamcityBoostLogFormatter::test_unit_start(ostream &out, boost::unit_test::
     currentDetails.clear();
 }
 
-void TeamcityBoostLogFormatter::test_unit_finish(ostream &out, boost::unit_test::test_unit const& tu, unsigned long elapsed) {
+void TeamcityBoostLogFormatter::test_unit_finish(std::ostream &out, boost::unit_test::test_unit const& tu, unsigned long elapsed) {
     messages.setOutput(out);
 
     boost::unit_test::test_results const& tr = boost::unit_test::results_collector.results(tu.p_id);
-    if (tu.p_type == boost::unit_test::tut_case) {
+    if (tu.p_type == TUT_CASE_IDENTIFIER) {
         if(!tr.passed()) {
             if(tr.p_skipped) {
                 messages.testIgnored(tu.p_name, "ignored", flowId);
@@ -134,27 +157,62 @@ void TeamcityBoostLogFormatter::test_unit_finish(ostream &out, boost::unit_test:
     }
 }
 
-void TeamcityBoostLogFormatter::test_unit_skipped(ostream &out, boost::unit_test::test_unit const& tu)
+void TeamcityBoostLogFormatter::test_unit_skipped(std::ostream &/*out*/, boost::unit_test::test_unit const& /*tu*/)
 {}
 
-void TeamcityBoostLogFormatter::log_exception(ostream &out, boost::unit_test::log_checkpoint_data const&, boost::unit_test::const_string explanation) {
-    string what = toString(explanation);
+void TeamcityBoostLogFormatter::test_unit_skipped(std::ostream &out, boost::unit_test::test_unit const& tu, boost::unit_test::const_string reason)
+{
+    messages.testIgnored(tu.p_name, toString(reason), flowId);
+}
+
+void TeamcityBoostLogFormatter::log_exception(std::ostream &out, boost::unit_test::log_checkpoint_data const &, boost::unit_test::const_string explanation) {
+    std::string what = toString(explanation);
 
-    out << what << endl;
+    out << what << std::endl;
     currentDetails += what + "\n";
 }
 
-void TeamcityBoostLogFormatter::log_entry_start(ostream&, boost::unit_test::log_entry_data const&, log_entry_types let)
-{}
+void TeamcityBoostLogFormatter::log_exception_start(std::ostream &out, boost::unit_test::log_checkpoint_data const &data, const boost::execution_exception& excpt) {
+    log_exception(out, data, excpt.what());
+}
+
+void TeamcityBoostLogFormatter::log_exception_finish(std::ostream &/*out*/) {}
 
-void TeamcityBoostLogFormatter::log_entry_value(ostream &out, boost::unit_test::const_string value) {
+
+void TeamcityBoostLogFormatter::log_entry_start(std::ostream & out, boost::unit_test::log_entry_data const & entry_data, log_entry_types /*let*/)
+{
+    std::stringstream ss(std::ios_base::out);
+
+    out << entry_data.m_file_name << "(" << entry_data.m_line_num << "): ";
+    ss  << entry_data.m_file_name << "(" << entry_data.m_line_num << "): ";
+
+    currentDetails += ss.str();
+}
+
+void TeamcityBoostLogFormatter::log_entry_value(std::ostream &out, boost::unit_test::const_string value) {
     out << value;
     currentDetails += toString(value);
 }
 
-void TeamcityBoostLogFormatter::log_entry_finish(ostream &out) {
-    out << endl;
+void TeamcityBoostLogFormatter::log_entry_finish(std::ostream &out) {
+    out << std::endl;
     currentDetails += "\n";
 }
 
+void TeamcityBoostLogFormatter::entry_context_start(std::ostream &out, boost::unit_test::log_level l) {
+    const std::string& initial_msg = (l == boost::unit_test::log_successful_tests ? ASSERT_CTX : FAILURE_CTX);
+    out << initial_msg;
+    currentContextDetails = initial_msg;
 }
+
+void TeamcityBoostLogFormatter::log_entry_context(std::ostream &out, boost::unit_test::const_string ctx) {
+    out << "\n " << ctx;
+    currentContextDetails += "\n " + toString(ctx);
+}
+
+void TeamcityBoostLogFormatter::entry_context_finish(std::ostream &out) {
+    out.flush();
+    messages.testOutput(CURRENT_TEST_NAME, currentContextDetails, flowId, TeamcityMessages::StdErr);
+}
+
+}}                                                          // namespace teamcity, jetbrains
diff --git a/c++/src/corelib/teamcity_messages.cpp b/c++/src/corelib/teamcity_messages.cpp
index 83dbbb5..85977ec 100644
--- a/c++/src/corelib/teamcity_messages.cpp
+++ b/c++/src/corelib/teamcity_messages.cpp
@@ -12,43 +12,66 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * $Id: teamcity_messages.cpp 435791 2014-05-20 18:47:58Z camacho $
+ * $Id: teamcity_messages.cpp 500881 2016-05-09 17:50:16Z ucko $
 */
 
 #include <ncbi_pch.hpp>
 
-#include <stdlib.h>
-#include <sstream>
-
 #include "teamcity_messages.h"
 
-using namespace std;
+#include <cstdlib>
+#include <sstream>
 
-namespace JetBrains {
+namespace jetbrains {
+namespace teamcity {
 
 std::string getFlowIdFromEnvironment() {
+#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)) && 0
+    char *flowId = NULL;
+    size_t sz = 0;
+    std::string result;
+    if(!_dupenv_s(&flowId, &sz,"TEAMCITY_PROCESS_FLOW_ID")) {
+        result = flowId != NULL ? flowId : "";
+        free(flowId);
+    }
+
+    return result;
+#else
     const char *flowId = getenv("TEAMCITY_PROCESS_FLOW_ID");
     return flowId == NULL ? "" : flowId;
+#endif
 }
 
 bool underTeamcity() {
+#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)) && 0
+    char *teamCityProjectName = 0;
+    size_t sz = 0;
+    bool result = false;
+    if(!_dupenv_s(&teamCityProjectName, &sz, "TEAMCITY_PROJECT_NAME")) {
+        result = teamCityProjectName != NULL;
+        free(teamCityProjectName);
+    }
+
+    return result;
+#else
     return getenv("TEAMCITY_PROJECT_NAME") != NULL;
+#endif
 }
 
 TeamcityMessages::TeamcityMessages()
-: m_out(&cout)
+: m_out(&std::cout)
 {}
 
-void TeamcityMessages::setOutput(ostream &out) {
+void TeamcityMessages::setOutput(std::ostream &out) {
     m_out = &out;
 }
 
-string TeamcityMessages::escape(string s) {
-    string result;
-    
+std::string TeamcityMessages::escape(std::string s) {
+    std::string result;
+
     for (size_t i = 0; i < s.length(); i++) {
         char c = s[i];
-        
+
         switch (c) {
         case '\n': result.append("|n"); break;
         case '\r': result.append("|r"); break;
@@ -58,56 +81,60 @@ string TeamcityMessages::escape(string s) {
         default:   result.append(&c, 1);
         }
     }
-    
+
     return result;
 }
 
-void TeamcityMessages::openMsg(const string &name) {
-    *m_out << "##teamcity[" << name;
+void TeamcityMessages::openMsg(const std::string &name) {
+    // endl for http://jetbrains.net/tracker/issue/TW-4412
+    *m_out << std::endl << "##teamcity[" << name;
 }
 
 void TeamcityMessages::closeMsg() {
     *m_out << "]";
     // endl for http://jetbrains.net/tracker/issue/TW-4412
-    *m_out << endl;
-    m_out->flush();
+    *m_out << std::endl;
 }
 
-void TeamcityMessages::writeProperty(string name, string value) {
+void TeamcityMessages::writeProperty(std::string name, std::string value) {
     *m_out << " " << name << "='" << escape(value) << "'";
 }
 
-void TeamcityMessages::suiteStarted(string name, string flowid) {
+void TeamcityMessages::suiteStarted(std::string name, std::string flowid) {
     openMsg("testSuiteStarted");
     writeProperty("name", name);
     if(flowid.length() > 0) {
         writeProperty("flowId", flowid);
     }
-    
+
     closeMsg();
 }
 
-void TeamcityMessages::suiteFinished(string name, string flowid) {
+void TeamcityMessages::suiteFinished(std::string name, std::string flowid) {
     openMsg("testSuiteFinished");
     writeProperty("name", name);
     if(flowid.length() > 0) {
         writeProperty("flowId", flowid);
     }
-    
+
     closeMsg();
 }
 
-void TeamcityMessages::testStarted(string name, string flowid) {
+void TeamcityMessages::testStarted(std::string name, std::string flowid, bool captureStandardOutput) {
     openMsg("testStarted");
     writeProperty("name", name);
     if(flowid.length() > 0) {
         writeProperty("flowId", flowid);
     }
-    
+
+    if(captureStandardOutput) {
+        writeProperty("captureStandardOutput", "true"); // false by default
+    }
+
     closeMsg();
 }
 
-void TeamcityMessages::testFinished(string name, int durationMs, string flowid) {
+void TeamcityMessages::testFinished(std::string name, int durationMs, std::string flowid) {
     openMsg("testFinished");
 
     writeProperty("name", name);
@@ -117,15 +144,15 @@ void TeamcityMessages::testFinished(string name, int durationMs, string flowid)
     }
 
     if(durationMs >= 0) {
-        stringstream out;
+        std::stringstream out(std::ios_base::out);
         out << durationMs;
         writeProperty("duration", out.str());
     }
-    
+
     closeMsg();
 }
 
-void TeamcityMessages::testFailed(string name, string message, string details, string flowid) {
+void TeamcityMessages::testFailed(std::string name, std::string message, std::string details, std::string flowid) {
     openMsg("testFailed");
     writeProperty("name", name);
     writeProperty("message", message);
@@ -133,19 +160,31 @@ void TeamcityMessages::testFailed(string name, string message, string details, s
     if(flowid.length() > 0) {
         writeProperty("flowId", flowid);
     }
-    
+
     closeMsg();
 }
 
-void TeamcityMessages::testIgnored(std::string name, std::string message, string flowid) {
+void TeamcityMessages::testIgnored(std::string name, std::string message, std::string flowid) {
     openMsg("testIgnored");
     writeProperty("name", name);
     writeProperty("message", message);
     if(flowid.length() > 0) {
         writeProperty("flowId", flowid);
     }
-    
+
     closeMsg();
 }
 
+void TeamcityMessages::testOutput(std::string name, std::string output, std::string flowid, bool isStdError) {
+    openMsg(isStdError ? "testStdErr" : "testStdOut");
+    writeProperty("name", name);
+    writeProperty("out", output);
+    if(flowid.length() > 0) {
+        writeProperty("flowId", flowid);
+    }
+
+    closeMsg();
+}
+
+}
 }
diff --git a/c++/src/corelib/teamcity_messages.h b/c++/src/corelib/teamcity_messages.h
index 88dd5c0..e4326e3 100644
--- a/c++/src/corelib/teamcity_messages.h
+++ b/c++/src/corelib/teamcity_messages.h
@@ -12,23 +12,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * $Id: teamcity_messages.h 422318 2013-12-19 17:48:09Z satskyse $
+ * $Id: teamcity_messages.h 500448 2016-05-04 18:16:16Z ucko $
 */
 
 #ifndef H_TEAMCITY_MESSAGES
 #define H_TEAMCITY_MESSAGES
 
-#include <string>
 #include <iostream>
+#include <string>
 
-namespace JetBrains {
+namespace jetbrains {
+namespace teamcity {
 
 std::string getFlowIdFromEnvironment();
 bool underTeamcity();
 
 class TeamcityMessages {
     std::ostream *m_out;
-    
+
 protected:
     std::string escape(std::string s);
 
@@ -37,19 +38,24 @@ protected:
     void closeMsg();
 
 public:
+    static const bool StdErr = true;
+    static const bool StdOut = false;
+
     TeamcityMessages();
-    
+
     void setOutput(std::ostream &);
-    
-    void suiteStarted(std::string name, std::string flowid = "");
-    void suiteFinished(std::string name, std::string flowid = "");
-    
-    void testStarted(std::string name, std::string flowid = "");
-    void testFailed(std::string name, std::string message, std::string details, std::string flowid = "");
-    void testIgnored(std::string name, std::string message, std::string flowid = "");
-    void testFinished(std::string name, int durationMs = -1, std::string flowid = "");    
+
+    void suiteStarted(std::string name, std::string flowid =  std::string());
+    void suiteFinished(std::string name, std::string flowid =  std::string());
+
+    void testStarted(std::string name, std::string flowid =  std::string(), bool captureStandardOutput = false);
+    void testFailed(std::string name, std::string message, std::string details, std::string flowid =  std::string());
+    void testIgnored(std::string name, std::string message, std::string flowid =  std::string());
+    void testOutput(std::string name, std::string output, std::string flowid, bool isStdErr = StdOut);
+    void testFinished(std::string name, int durationMs = -1, std::string flowid = std::string());
 };
 
 }
+}
 
 #endif /* H_TEAMCITY_MESSAGES */
diff --git a/c++/src/corelib/test_boost.cpp b/c++/src/corelib/test_boost.cpp
index 174758c..6e8914b 100644
--- a/c++/src/corelib/test_boost.cpp
+++ b/c++/src/corelib/test_boost.cpp
@@ -1,4 +1,4 @@
-/*  $Id: test_boost.cpp 497436 2016-04-06 17:56:51Z ivanov $
+/*  $Id: test_boost.cpp 520770 2016-12-01 15:44:45Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -301,7 +301,7 @@ public:
     virtual ~CNcbiTestsObserver(void) {}
 
     /// Method called before execution of all tests
-    virtual void test_start(but::counter_t /* test_cases_amount */);
+    // virtual void test_start(but::counter_t /* test_cases_amount */);
 
     /// Method called after execution of all tests
     virtual void test_finish(void);
@@ -630,9 +630,9 @@ CNcbiBoostReporter::CNcbiBoostReporter()
 {}
 
 inline void
-CNcbiBoostReporter::SetOutputFormat(but::output_format format)
+CNcbiBoostReporter::SetOutputFormat(but::output_format fmt)
 {
-    if (format == but::OF_XML) {
+    if (fmt == but::OF_XML) {
         m_IsXML = true;
         m_Upper = new but::output::xml_report_formatter();
     }
@@ -897,7 +897,9 @@ CNcbiTestsTreeBuilder::EnsureDep(but::test_unit* tu, but::test_unit* tu_from)
 inline void
 CNcbiTestsTreeBuilder::FixUnitsOrder(void)
 {
-    m_RootElem->FixUnitsOrder();
+    if (m_RootElem) {
+        m_RootElem->FixUnitsOrder();
+    }
 }
 
 
@@ -1079,6 +1081,13 @@ CNcbiTestApplication::x_EnsureAllDeps(void)
 inline void
 CNcbiTestApplication::x_ActualizeDeps(void)
 {
+#if BOOST_VERSION >= 105900
+    // Expedite run status initialization so s_IsEnabled will work.
+    auto  master_id = but::framework::master_test_suite().p_id;
+    auto& state     = but::framework::impl::s_frk_state();
+    state.finalize_default_run_status(master_id, but::test_unit::RS_INVALID);
+    state.deduce_run_status(master_id);
+#endif
     ITERATE(TUnitToManyMap, it, m_TestDeps) {
         but::test_unit* test = it->first;
         if (!m_DisabledTests.count(test) && !s_IsEnabled(*test)) {
@@ -1565,10 +1574,13 @@ CNcbiTestApplication::AdjustTestTimeout(but::test_unit* tu)
             CNcbiEnvironment env;
             printf("Maximum execution time of %s seconds is exceeded",
                    m_TimeoutStr.c_str());
-#if BOOST_VERSION >= 105900
+#if BOOST_VERSION < 105900
+            throw but::test_being_aborted();
+#elif defined(SIGALRM)
             raise(SIGALRM);
 #else
-            throw but::test_being_aborted();
+            throw runtime_error("Maximum execution time of " + m_TimeoutStr +
+                                " seconds is exceeded");
 #endif
         }
         new_timeout = (unsigned int)(m_Timeout - elapsed);
@@ -1850,13 +1862,6 @@ CNcbiTestsCollector::test_suite_start(but::test_suite const& suite)
     return true;
 }
 
-
-void
-CNcbiTestsObserver::test_start(but::counter_t /* test_cases_amount */)
-{
-    s_GetTestApp().InitTestsBeforeRun();
-}
-
 void
 CNcbiTestsObserver::test_finish(void)
 {
@@ -1994,6 +1999,10 @@ CNcbiBoostReporter::do_confirmation_report(but::test_unit const&  tu,
                 ostr << "*** Skipped some tests\n";
             }
         }
+        // Boost.Test 3.x (from Boost 1.59+) treats skipped tests as errors.
+        // Override that treatment both here (to avoid a claim that errors
+        // occurred) and in main (to yield a sane exit code regardless of
+        // report level).
         const_cast<bool&>(tr.p_skipped.get()) = false;
         const_cast<but::counter_t&>(tr.p_test_cases_skipped.get()) = 0;
     }
@@ -2229,6 +2238,8 @@ main(int argc, char* argv[])
         framework::init( &init_unit_test_suite, argc, argv );
 #endif
 
+        ncbi::s_GetTestApp().InitTestsBeforeRun();
+
 #if BOOST_VERSION >= 105900
         if( RTCFG(bool, WAIT_FOR_DEBUGGER, wait_for_debugger) ) {
             results_reporter::get_stream() << "Press any key to continue..." << std::endl;
@@ -2288,6 +2299,18 @@ main(int argc, char* argv[])
             !runtime_config::no_result_code()
 #endif
             ) {
+#if BOOST_VERSION >= 105900
+            // Boost.Test 3.x (from Boost 1.59+) treats skipped tests
+            // as errors.  Override that treatment both here (to yield
+            // a sane exit code regardless of report level) and in
+            // CNcbiBoostReporter::do_confirmation_report (to avoid a
+            // claim that errors occurred).
+            but::test_results const& tr
+                = but::results_collector.results(
+                    framework::master_test_suite().p_id);
+            const_cast<bool&>(tr.p_skipped.get()) = false;
+            const_cast<but::counter_t&>(tr.p_test_cases_skipped.get()) = 0;
+#endif
             result_code = results_collector.results( framework::master_test_suite().p_id ).result_code();
             if (!NCBI_NS_NCBI::s_GetTestApp().HasTestErrors()
                 &&  NCBI_NS_NCBI::s_GetTestApp().HasTestTimeouts())
diff --git a/c++/src/corelib/version.cpp b/c++/src/corelib/version.cpp
index ec7250e..2cdc97e 100644
--- a/c++/src/corelib/version.cpp
+++ b/c++/src/corelib/version.cpp
@@ -1,4 +1,4 @@
-/*  $Id: version.cpp 492326 2016-02-16 19:38:11Z ivanov $
+/*  $Id: version.cpp 508166 2016-07-26 15:59:33Z elisovdn $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -33,6 +33,7 @@
 #include <ncbi_pch.hpp>
 #include <corelib/version.hpp>
 #include <common/ncbi_package_ver.h>
+#include <common/ncbi_source_ver.h>
 
 
 BEGIN_NCBI_SCOPE
@@ -595,6 +596,13 @@ string CVersion::Print(const string& appname, TPrintFlags flags) const
         }
     }
 
+#ifdef NCBI_TEAMCITY_BUILD_NUMBER
+    if (flags & fTCBuildNumber) {
+            os << " TeamCity-Build-Number:  " << NCBI_TEAMCITY_BUILD_NUMBER
+               << endl;
+    }
+#endif /* NCBI_TEAMCITY_BUILD_NUMBER */
+
     return CNcbiOstrstreamToString(os);
 }
 
diff --git a/c++/src/dbapi/blobstream.cpp b/c++/src/dbapi/blobstream.cpp
index 8b599df..442510f 100644
--- a/c++/src/dbapi/blobstream.cpp
+++ b/c++/src/dbapi/blobstream.cpp
@@ -1,4 +1,4 @@
-/* $Id: blobstream.cpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: blobstream.cpp 497635 2016-04-08 13:52:30Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE                          
@@ -23,7 +23,7 @@
 *
 * ===========================================================================
 *
-* File Name:  $Id: blobstream.cpp 498367 2016-04-15 17:18:04Z ivanov $
+* File Name:  $Id: blobstream.cpp 497635 2016-04-08 13:52:30Z ucko $
 *
 * Author:  Michael Kholodov
 *   
diff --git a/c++/src/dbapi/blobstream.hpp b/c++/src/dbapi/blobstream.hpp
index 44943b9..54dc8c1 100644
--- a/c++/src/dbapi/blobstream.hpp
+++ b/c++/src/dbapi/blobstream.hpp
@@ -1,7 +1,7 @@
 #ifndef _BLOBSTREAM_HPP_
 #define _BLOBSTREAM_HPP_
 
-/* $Id: blobstream.hpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: blobstream.hpp 497635 2016-04-08 13:52:30Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE                          
@@ -26,7 +26,7 @@
 *
 * ===========================================================================
 *
-* File Name:  $Id: blobstream.hpp 498367 2016-04-15 17:18:04Z ivanov $
+* File Name:  $Id: blobstream.hpp 497635 2016-04-08 13:52:30Z ucko $
 *
 * Author:  Michael Kholodov
 *   
diff --git a/c++/src/dbapi/conn_impl.cpp b/c++/src/dbapi/conn_impl.cpp
index 4342dc7..a450230 100644
--- a/c++/src/dbapi/conn_impl.cpp
+++ b/c++/src/dbapi/conn_impl.cpp
@@ -1,4 +1,4 @@
-/* $Id: conn_impl.cpp 451412 2014-11-06 16:54:28Z ucko $
+/* $Id: conn_impl.cpp 507084 2016-07-14 16:04:41Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -23,7 +23,7 @@
 *
 * ===========================================================================
 *
-* File Name:  $Id: conn_impl.cpp 451412 2014-11-06 16:54:28Z ucko $
+* File Name:  $Id: conn_impl.cpp 507084 2016-07-14 16:04:41Z ucko $
 *
 * Author:  Michael Kholodov
 *
@@ -64,7 +64,7 @@ CConnection::CConnection(CDataSource* ds, EOwnership ownership)
 CConnection::CConnection(CDB_Connection *conn, CDataSource* ds)
     : m_ds(ds), m_connection(conn), m_connCounter(-1), m_connUsed(false),
       m_modeMask(0), m_forceSingle(false), m_multiExH(0),
-      m_msgToEx(false)
+      m_msgToEx(false), m_ownership(eNoOwnership)
 {
     _TRACE("Auxiliary connection " << (void *)this << " created...");
     SetIdent("CConnection");
diff --git a/c++/src/dbapi/dbapi.cpp b/c++/src/dbapi/dbapi.cpp
index a9facd3..84fb2a7 100644
--- a/c++/src/dbapi/dbapi.cpp
+++ b/c++/src/dbapi/dbapi.cpp
@@ -1,4 +1,4 @@
-/* $Id: dbapi.cpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: dbapi.cpp 497635 2016-04-08 13:52:30Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE                          
@@ -23,7 +23,7 @@
 *
 * ===========================================================================
 *
-* File Name:  $Id: dbapi.cpp 498367 2016-04-15 17:18:04Z ivanov $
+* File Name:  $Id: dbapi.cpp 497635 2016-04-08 13:52:30Z ucko $
 *
 * Author:  Michael Kholodov
 *   
diff --git a/c++/src/dbapi/driver/dbapi_conn_factory.cpp b/c++/src/dbapi/driver/dbapi_conn_factory.cpp
index b02e455..5cda0b5 100644
--- a/c++/src/dbapi/driver/dbapi_conn_factory.cpp
+++ b/c++/src/dbapi/driver/dbapi_conn_factory.cpp
@@ -1,4 +1,4 @@
-/*  $Id: dbapi_conn_factory.cpp 470851 2015-06-19 16:29:01Z ucko $
+/*  $Id: dbapi_conn_factory.cpp 507218 2016-07-15 19:45:42Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -65,6 +65,7 @@ m_TryServerToo(false)
 
 CDBConnectionFactory::~CDBConnectionFactory(void)
 {
+    CDB_UserHandler::ClearExceptions(m_Errors);
 }
 
 void
@@ -315,7 +316,7 @@ CDBConnectionFactory::MakeDBConnection(
 
     CDB_UserHandler::ClearExceptions(m_Errors);
 
-    CDB_Connection* t_con = NULL;
+    unique_ptr<CDB_Connection> t_con;
     CRuntimeData& rt_data = GetRuntimeData(params.GetConnValidator());
     TSvrRef dsp_srv = rt_data.GetDispatchedServer(params.GetServerName());
 
@@ -350,7 +351,7 @@ CDBConnectionFactory::MakeDBConnection(
         // because a named connection pool has been used before.
         // Dispatch server name ...
 
-        t_con = DispatchServerName(opening_ctx, params);
+        t_con.reset(DispatchServerName(opening_ctx, params));
     } else {
         // Server name is already dispatched ...
         string single_server(params.GetParam("single_server"));
@@ -361,8 +362,9 @@ CDBConnectionFactory::MakeDBConnection(
             // We definitely need to re-dispatch it ...
 
             // Clean previous info ...
+            rt_data.CleanExcluded(params.GetServerName());
             rt_data.SetDispatchedServer(params.GetServerName(), TSvrRef());
-            t_con = DispatchServerName(opening_ctx, params);
+            t_con.reset(DispatchServerName(opening_ctx, params));
         } else {
             // We do not need to re-dispatch it ...
 
@@ -379,9 +381,9 @@ CDBConnectionFactory::MakeDBConnection(
 
                 // MakeValidConnection may return NULL here because a newly
                 // created connection may not pass validation.
-                t_con = MakeValidConnection(opening_ctx,
-                                            // cur_conn_attr,
-                                            cur_params);
+                t_con.reset(MakeValidConnection(opening_ctx,
+                                                // cur_conn_attr,
+                                                cur_params));
 
             } catch (CDB_Exception& ex) {
                 // m_Errors.push_back(ex.Clone());
@@ -392,7 +394,7 @@ CDBConnectionFactory::MakeDBConnection(
                 }
             }
 
-            if (!t_con) {
+            if (t_con.get() == NULL) {
                 // We couldn't connect ...
                 if (single_server != "true") {
                     // Server might be temporarily unavailable ...
@@ -404,7 +406,7 @@ CDBConnectionFactory::MakeDBConnection(
                     }
 
                     // Re-dispatch ...
-                    t_con = DispatchServerName(opening_ctx, params);
+                    t_con.reset(DispatchServerName(opening_ctx, params));
                 }
             } else {
                 // Dispatched server is already set, but calling of this method
@@ -418,14 +420,14 @@ CDBConnectionFactory::MakeDBConnection(
     ctx.SetTimeout(query_timeout);
 
     // Restore original query timeout ...
-    if (t_con) {
+    if (t_con.get() != NULL) {
         t_con->SetTimeout(query_timeout);
     }
 
-    x_LogConnection(opening_ctx, t_con, params);
-    handler->Flush((t_con == NULL) ? eDiagSevMax : eDiag_Warning);
+    x_LogConnection(opening_ctx, t_con.get(), params);
+    handler->Flush((t_con.get() == NULL) ? eDiagSevMax : eDiag_Warning);
 
-    return t_con;
+    return t_con.release();
 }
 
 CDB_Connection*
@@ -611,6 +613,10 @@ CDBConnectionFactory::MakeValidConnection(
 
     if (conn.get())
     {
+        if (conn->Host() == 0) {
+            GetRuntimeData(params.GetConnValidator()).GetDBServiceMapper()
+                .RecordServer(conn->GetExtraFeatures());
+        }
         CTrivialConnValidator use_db_validator(
             params.GetDatabaseName(),
             CTrivialConnValidator::eKeepModifiedConnection
@@ -759,8 +765,11 @@ void CDBConnectionFactory::x_LogConnection(const SOpeningContext& ctx,
     }}
 
     extra.Print(prefix + "resource", service);
+
     if ( !dsp_srv->GetName().empty() ) {
         extra.Print(prefix + "server_name", dsp_srv->GetName());
+    } else if (connection != NULL  &&  !connection->ServerName().empty()) {
+        extra.Print(prefix + "server_name", connection->ServerName());
     }
 
     if (dsp_srv->GetHost() != 0) {
@@ -768,12 +777,17 @@ void CDBConnectionFactory::x_LogConnection(const SOpeningContext& ctx,
                     impl::ConvertN2A(dsp_srv->GetHost()));
     } else if (params.GetHost() != 0) {
         extra.Print(prefix + "server_ip", impl::ConvertN2A(params.GetHost()));
+    } else if (connection != NULL  &&  connection->Host() != 0) {
+        extra.Print(prefix + "server_ip",
+                    impl::ConvertN2A(connection->Host()));
     }
 
     if (dsp_srv->GetPort() != 0) {
         extra.Print(prefix + "server_port", dsp_srv->GetPort());
     } else if (params.GetPort() != 0) {
         extra.Print(prefix + "server_port", params.GetPort());
+    } else if (connection != NULL  &&  connection->Port() != 0) {
+        extra.Print(prefix + "server_port", connection->Port());
     }
 
     if ( !params.GetUserName().empty() ) {
diff --git a/c++/src/dbapi/driver/dbapi_driver_conn_mgr.cpp b/c++/src/dbapi/driver/dbapi_driver_conn_mgr.cpp
index 9a420db..4d57b0a 100644
--- a/c++/src/dbapi/driver/dbapi_driver_conn_mgr.cpp
+++ b/c++/src/dbapi/driver/dbapi_driver_conn_mgr.cpp
@@ -1,4 +1,4 @@
-/* $Id: dbapi_driver_conn_mgr.cpp 494592 2016-03-08 17:55:58Z ivanov $
+/* $Id: dbapi_driver_conn_mgr.cpp 494417 2016-03-07 15:06:35Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/dbapi/driver/dbapi_driver_conn_params.cpp b/c++/src/dbapi/driver/dbapi_driver_conn_params.cpp
index 2b76a0a..f0ab89e 100644
--- a/c++/src/dbapi/driver/dbapi_driver_conn_params.cpp
+++ b/c++/src/dbapi/driver/dbapi_driver_conn_params.cpp
@@ -1,4 +1,4 @@
-/*  $Id: dbapi_driver_conn_params.cpp 488796 2016-01-05 20:20:40Z ucko $
+/*  $Id: dbapi_driver_conn_params.cpp 515776 2016-10-05 17:33:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -729,6 +729,7 @@ CCPPToolkitConnParams::GetServerType(const CTempString& server_name)
     if (NStr::CompareNocase(server_name, 0, 8, "DBAPI_MS") == 0
         || NStr::CompareNocase(server_name, 0, 5, "MSSQL") == 0
         || NStr::CompareNocase(server_name, 0, 5, "MSDEV") == 0
+        || NStr::CompareNocase(server_name, 0, 9, "MS2008DEV") == 0
         || NStr::CompareNocase(server_name, 0, 7, "OAMSDEV") == 0
         || NStr::CompareNocase(server_name, 0, 6, "QMSSQL") == 0
         || NStr::CompareNocase(server_name, 0, 6, "BLASTQ") == 0
diff --git a/c++/src/dbapi/driver/dbapi_driver_utils.cpp b/c++/src/dbapi/driver/dbapi_driver_utils.cpp
index 20ae4dd..be70dd6 100644
--- a/c++/src/dbapi/driver/dbapi_driver_utils.cpp
+++ b/c++/src/dbapi/driver/dbapi_driver_utils.cpp
@@ -1,4 +1,4 @@
-/* $Id: dbapi_driver_utils.cpp 487444 2015-12-17 18:38:53Z ucko $
+/* $Id: dbapi_driver_utils.cpp 503691 2016-06-07 15:44:43Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -99,6 +99,37 @@ SIZE_TYPE GetValidUTF8Len(const CTempString& ts)
     return len;
 }
 
+size_t binary_to_hex_string(char* buffer, size_t buffer_size,
+                            const void* value, size_t value_size,
+                            TBinaryToHexFlags flags)
+{
+    static const char s_HexDigits[] = "0123456789ABCDEF";
+
+    const unsigned char* c = (const unsigned char*) value;
+    size_t i = 0, margin = 0;
+    if ((flags & fB2H_NoFinalNul) == 0) {
+        margin += 1;
+    }
+    if ((flags & fB2H_NoPrefix) == 0) {
+        margin += 2;
+    }
+    if (value_size * 2 + margin > buffer_size) {
+        return 0;
+    }
+    if ((flags & fB2H_NoPrefix) == 0) {
+        buffer[i++] = '0';
+        buffer[i++] = 'x';
+    }
+    for (size_t j = 0;  j < value_size;  j++) {
+        buffer[i++] = s_HexDigits[c[j] >> 4];
+        buffer[i++] = s_HexDigits[c[j] & 0x0F];
+    }
+    if ((flags & fB2H_NoFinalNul) == 0) {
+        buffer[i + 1] = '\0';
+    }
+    return i;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 CDBBindedParams::CDBBindedParams(CDB_Params& bindings, EOwnership ownership) 
 : m_Bindings(&bindings, ownership)
diff --git a/c++/src/dbapi/driver/dbapi_impl_cmd.cpp b/c++/src/dbapi/driver/dbapi_impl_cmd.cpp
index 7c1eb81..e6d8e8e 100644
--- a/c++/src/dbapi/driver/dbapi_impl_cmd.cpp
+++ b/c++/src/dbapi/driver/dbapi_impl_cmd.cpp
@@ -1,4 +1,4 @@
-/*  $Id: dbapi_impl_cmd.cpp 498367 2016-04-15 17:18:04Z ivanov $
+/*  $Id: dbapi_impl_cmd.cpp 497635 2016-04-08 13:52:30Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/dbapi/driver/dbapi_impl_connection.cpp b/c++/src/dbapi/driver/dbapi_impl_connection.cpp
index b8f6298..254f5cb 100644
--- a/c++/src/dbapi/driver/dbapi_impl_connection.cpp
+++ b/c++/src/dbapi/driver/dbapi_impl_connection.cpp
@@ -1,4 +1,4 @@
-/*  $Id: dbapi_impl_connection.cpp 498367 2016-04-15 17:18:04Z ivanov $
+/*  $Id: dbapi_impl_connection.cpp 512261 2016-08-29 17:14:32Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -98,6 +98,7 @@ CConnection::CConnection(CDriverContext& dc,
 , m_ExceptionContext(new TDbgInfo(params))
 , m_ServerType(params.GetServerType())
 , m_ServerTypeIsKnown(false)
+, m_RequestedServer(params.GetServerName())
 , m_Host(params.GetHost())
 , m_Port(params.GetPort())
 , m_Passwd(params.GetPassword())
@@ -397,6 +398,16 @@ string CConnection::GetDriverName(void) const
     return GetCDriverContext().GetDriverName();
 }
 
+void CConnection::x_RecordServer(const CDBServer& server)
+{
+    string new_name = ServerName().substr(0, ServerName().find(':'))
+        + '@' + server.GetName();
+    _TRACE("Updating server metadata from " << ServerName() << '@'
+           << ConvertN2A(m_Host) << ':' << m_Port << " to " << new_name);
+    m_ExceptionContext->server_name = new_name;
+    m_Host = server.GetHost();
+    m_Port = server.GetPort();
+}
 
 } // namespace impl
 
diff --git a/c++/src/dbapi/driver/dbapi_impl_context.cpp b/c++/src/dbapi/driver/dbapi_impl_context.cpp
index c0da2cb..7fabedb 100644
--- a/c++/src/dbapi/driver/dbapi_impl_context.cpp
+++ b/c++/src/dbapi/driver/dbapi_impl_context.cpp
@@ -1,4 +1,4 @@
-/*  $Id: dbapi_impl_context.cpp 498367 2016-04-15 17:18:04Z ivanov $
+/*  $Id: dbapi_impl_context.cpp 516380 2016-10-13 11:32:10Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -63,9 +63,7 @@ namespace impl
 //
 
 CDriverContext::CDriverContext(void) :
-#ifdef NCBI_THREADS
     m_PoolSem(0, 1),
-#endif
     m_LoginTimeout(0),
     m_Timeout(0),
     m_CancelTimeout(0),
@@ -78,7 +76,9 @@ CDriverContext::CDriverContext(void) :
 
 CDriverContext::~CDriverContext(void)
 {
-    return;
+    try {
+        DeleteAllConn();
+    } STD_CATCH_ALL("CDriverContext::DeleteAllConn");
 }
 
 void
@@ -270,7 +270,7 @@ void CDriverContext::ResetEnvSybase(void)
 
 void CDriverContext::x_Recycle(CConnection* conn, bool conn_reusable)
 {
-    CMutexGuard mg(x_GetCtxMtx());
+    CMutexGuard mg(m_PoolMutex);
 
     TConnPool::iterator it = find(m_InUse.begin(), m_InUse.end(), conn);
 
@@ -310,7 +310,7 @@ void CDriverContext::x_Recycle(CConnection* conn, bool conn_reusable)
 void CDriverContext::CloseUnusedConnections(const string&   srv_name,
                                              const string&   pool_name)
 {
-    CMutexGuard mg(x_GetCtxMtx());
+    CMutexGuard mg(m_PoolMutex);
 
     TConnPool::value_type con;
 
@@ -318,7 +318,9 @@ void CDriverContext::CloseUnusedConnections(const string&   srv_name,
     NON_CONST_ITERATE(TConnPool, it, m_NotInUse) {
         con = *it;
 
-        if((!srv_name.empty()) && srv_name.compare(con->ServerName())) continue;
+        if ( !srv_name.empty()  && srv_name != con->ServerName()
+            &&  srv_name != con->GetRequestedServer() )
+            continue;
         if((!pool_name.empty()) && pool_name.compare(con->PoolName())) continue;
 
         it = m_NotInUse.erase(it);
@@ -330,7 +332,7 @@ void CDriverContext::CloseUnusedConnections(const string&   srv_name,
 unsigned int CDriverContext::NofConnections(const TSvrRef& svr_ref,
                                             const string& pool_name) const
 {
-    CMutexGuard mg(x_GetCtxMtx());
+    CMutexGuard mg(m_PoolMutex);
 
     if ((!svr_ref  ||  !svr_ref->IsValid())  &&  pool_name.empty()) {
         return static_cast<unsigned int>(m_InUse.size() + m_NotInUse.size());
@@ -352,7 +354,8 @@ unsigned int CDriverContext::NofConnections(const TSvrRef& svr_ref,
         ITERATE(TConnPool, it, (*pools[i])) {
             TConnPool::value_type con = *it;
             if(!server.empty()) {
-                if (server.compare(con->ServerName()))
+                if (server != con->ServerName()
+                    &&  server != con->GetRequestedServer())
                     continue;
             }
             else if (host != 0) {
@@ -377,6 +380,7 @@ unsigned int CDriverContext::NofConnections(const string& srv_name,
 CDB_Connection* CDriverContext::MakeCDBConnection(CConnection* connection)
 {
     connection->m_CleanupTime.Clear();
+    CMutexGuard mg(m_PoolMutex);
     m_InUse.push_back(connection);
 
     return new CDB_Connection(connection);
@@ -403,7 +407,7 @@ CDB_Connection*
 CDriverContext::MakePooledConnection(const CDBConnParams& params)
 {
     if (params.GetParam("is_pooled") == "true") {
-        CMutexGuard mg(x_GetCtxMtx());
+        CMutexGuard mg(m_PoolMutex);
 
         string pool_name(params.GetParam("pool_name"));
         if (!m_NotInUse.empty()) {
@@ -434,8 +438,8 @@ CDriverContext::MakePooledConnection(const CDBConnParams& params)
                 }
             }
             else {
-
-                if ( params.GetServerName().empty() ) {
+                string server_name = params.GetServerName();
+                if ( server_name.empty() ) {
                     return NULL;
                 }
 
@@ -443,7 +447,8 @@ CDriverContext::MakePooledConnection(const CDBConnParams& params)
                 ERASE_ITERATE(TConnPool, it, m_NotInUse) {
                     CConnection* t_con(*it);
 
-                    if (params.GetServerName() == t_con->ServerName()) {
+                    if (server_name == t_con->ServerName()
+                        ||  server_name == t_con->GetRequestedServer()) {
                         it = m_NotInUse.erase(it);
                         if (t_con->Refresh()) {
                             /* Future development ...
@@ -487,7 +492,7 @@ CDriverContext::MakePooledConnection(const CDBConnParams& params)
                     m_PoolSemSubject = pool_name;
                     mg.Release();
                     if (m_PoolSem.TryWait(timeout)) {
-                        mg.Guard(x_GetCtxMtx());
+                        mg.Guard(m_PoolMutex);
                         CConnection* t_con = NULL;
                         NON_CONST_REVERSE_ITERATE(TConnPool, it, m_NotInUse) {
                             if (*it == m_PoolSemConn) {
@@ -546,6 +551,7 @@ CDriverContext::MakePooledConnection(const CDBConnParams& params)
 void
 CDriverContext::CloseAllConn(void)
 {
+    CMutexGuard mg(m_PoolMutex);
     // close all connections first
     ITERATE(TConnPool, it, m_NotInUse) {
         delete *it;
@@ -560,6 +566,7 @@ CDriverContext::CloseAllConn(void)
 void
 CDriverContext::DeleteAllConn(void)
 {
+    CMutexGuard mg(m_PoolMutex);
     // close all connections first
     ITERATE(TConnPool, it, m_NotInUse) {
         delete *it;
@@ -867,6 +874,12 @@ CDriverContext::ReadDBConfParams(const string&  service_name,
         params->pool_allow_temp_overflow
             = reg.Get(section_name, "conn_pool_allow_temp_overflow");
     }
+    if (reg.HasEntry(section_name, "continue_after_raiserror",
+                     IRegistry::fCountCleared)) {
+        params->flags += SDBConfParams::fContRaiserrorSet;
+        params->continue_after_raiserror
+            = reg.Get(section_name, "continue_after_raiserror");
+    }
     if (reg.HasEntry(section_name, "args", IRegistry::fCountCleared)) {
         params->flags += SDBConfParams::fArgsSet;
         params->args = reg.Get(section_name, "args");
@@ -876,7 +889,7 @@ CDriverContext::ReadDBConfParams(const string&  service_name,
 bool
 CDriverContext::SatisfyPoolMinimum(const CDBConnParams& params)
 {
-    CMutexGuard mg(x_GetCtxMtx());
+    CMutexGuard mg(m_PoolMutex);
 
     string pool_min_str = params.GetParam("pool_minsize");
     if (pool_min_str.empty()  ||  pool_min_str == "default")
@@ -930,7 +943,7 @@ CDriverContext::MakeConnection(const CDBConnParams& params)
 
     int was_timeout = GetTimeout();
     int was_login_timeout = GetLoginTimeout();
-    CDB_Connection* t_con = NULL;
+    unique_ptr<CDB_Connection> t_con;
     try {
         string server_name = (conf_params.IsServerSet()?   conf_params.server:
                                                            params.GetServerName());
@@ -1053,6 +1066,21 @@ CDriverContext::MakeConnection(const CDBConnParams& params)
         else if (params.GetParam("pool_allow_temp_overflow") == "default") {
             act_params.SetParam("pool_allow_temp_overflow", "false");
         }
+        if (conf_params.IsContinueAfterRaiserrorSet()) {
+            if (conf_params.continue_after_raiserror.empty()) {
+                act_params.SetParam("continue_after_raiserror", "false");
+            }
+            else {
+                act_params.SetParam
+                    ("continue_after_raiserror", 
+                     NStr::BoolToString(
+                         NStr::StringToBool(
+                             conf_params.continue_after_raiserror)));
+            }
+        }
+        else if (params.GetParam("continue_after_raiserror") == "default") {
+            act_params.SetParam("continue_after_raiserror", "false");
+        }
 
         s_TransformLoginData(server_name, user_name, db_name, password);
         act_params.SetServerName(server_name);
@@ -1061,13 +1089,13 @@ CDriverContext::MakeConnection(const CDBConnParams& params)
         act_params.SetPassword(password);
 
         CRef<IDBConnectionFactory> factory = CDbapiConnMgr::Instance().GetConnectionFactory();
-        t_con = factory->MakeDBConnection(*this, act_params);
+        t_con.reset(factory->MakeDBConnection(*this, act_params));
 
-        if((!t_con && act_params.GetParam("do_not_connect") == "true")) {
-            return NULL;
-        }
+        if (t_con.get() == NULL) {
+            if (act_params.GetParam("do_not_connect") == "true") {
+                return NULL;
+            }
 
-        if (!t_con) {
             string err;
             err += "Cannot connect to the server '" + act_params.GetServerName();
             err += "' as user '" + act_params.GetUserName() + "'";
@@ -1094,12 +1122,12 @@ CDriverContext::MakeConnection(const CDBConnParams& params)
     SetTimeout(was_timeout);
     SetLoginTimeout(was_login_timeout);
 
-    return t_con;
+    return t_con.release();
 }
 
 void CDriverContext::CloseConnsForPool(const string& pool_name)
 {
-    CMutexGuard mg(x_GetCtxMtx());
+    CMutexGuard mg(m_PoolMutex);
 
     ITERATE(TConnPool, it, m_InUse) {
         CConnection* t_con(*it);
@@ -1120,6 +1148,7 @@ void CDriverContext::CloseConnsForPool(const string& pool_name)
 void CDriverContext::CloseOldIdleConns(unsigned int max_closings,
                                        const string& pool_name)
 {
+    CMutexGuard mg(m_PoolMutex);
     if (max_closings == 0) {
         return;
     }
diff --git a/c++/src/dbapi/driver/dbapi_object_convert.cpp b/c++/src/dbapi/driver/dbapi_object_convert.cpp
index ad50f70..aaee44b 100644
--- a/c++/src/dbapi/driver/dbapi_object_convert.cpp
+++ b/c++/src/dbapi/driver/dbapi_object_convert.cpp
@@ -1,4 +1,4 @@
-/* $Id: dbapi_object_convert.cpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: dbapi_object_convert.cpp 498292 2016-04-14 19:07:55Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/dbapi/driver/dbapi_svc_mapper.cpp b/c++/src/dbapi/driver/dbapi_svc_mapper.cpp
index ecd741c..7b2fa0a 100644
--- a/c++/src/dbapi/driver/dbapi_svc_mapper.cpp
+++ b/c++/src/dbapi/driver/dbapi_svc_mapper.cpp
@@ -1,4 +1,4 @@
-/*  $Id: dbapi_svc_mapper.cpp 485360 2015-11-20 17:03:34Z ucko $
+/*  $Id: dbapi_svc_mapper.cpp 506715 2016-07-11 16:01:42Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -254,6 +254,19 @@ CDBServiceMapperCoR::GetServersList(const string& service, list<string>* serv_li
 }
 
 
+bool
+CDBServiceMapperCoR::RecordServer(I_ConnectionExtra& extra) const
+{
+    CFastMutexGuard mg(m_Mtx);
+    REVERSE_ITERATE (TDelegates, dg_it, m_Delegates) {
+        if ((*dg_it)->RecordServer(extra)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+
 void
 CDBServiceMapperCoR::ConfigureFromRegistry(const IRegistry* registry)
 {
@@ -721,7 +734,8 @@ CDBUDPriorityMapper::Exclude(const string& service,
 void
 CDBUDPriorityMapper::CleanExcluded(const string& service)
 {
-    CNcbiDiag::DiagTrouble(DIAG_COMPILE_INFO, "Not implemented");
+    CFastMutexGuard mg(m_Mtx);
+    m_ServiceUsageMap[service] = m_OrigServiceUsageMap[service];
 }
 
 void
@@ -753,6 +767,7 @@ CDBUDPriorityMapper::Add(const string&    service,
 {
     TSvrMap& server_list = m_ServerMap[service];
     TServerUsageMap& usage_map = m_ServiceUsageMap[service];
+    TServerUsageMap& usage_map2 = m_OrigServiceUsageMap[service];
 
     if (preference < 0) {
         preference = 0;
@@ -763,10 +778,9 @@ CDBUDPriorityMapper::Add(const string&    service,
     server_list.insert(
         TSvrMap::value_type(server, preference)
         );
-    usage_map.insert(TServerUsageMap::value_type(
-        100 - preference,
-        server)
-        );
+    TServerUsageMap::value_type usage(100 - preference, server);
+    usage_map.insert(usage);
+    usage_map2.insert(usage);
 }
 
 
diff --git a/c++/src/dbapi/driver/interfaces.cpp b/c++/src/dbapi/driver/interfaces.cpp
index 2f73e97..3c134c5 100644
--- a/c++/src/dbapi/driver/interfaces.cpp
+++ b/c++/src/dbapi/driver/interfaces.cpp
@@ -1,4 +1,4 @@
-/* $Id: interfaces.cpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: interfaces.cpp 501779 2016-05-18 19:36:43Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -343,10 +343,6 @@ I_Connection::~I_Connection(void)
 }
 
 
-I_ConnectionExtra::~I_ConnectionExtra(void)
-{}
-
-
 END_NCBI_SCOPE
 
 
diff --git a/c++/src/dbapi/driver/memory_store.cpp b/c++/src/dbapi/driver/memory_store.cpp
index ecdf9e9..4192f61 100644
--- a/c++/src/dbapi/driver/memory_store.cpp
+++ b/c++/src/dbapi/driver/memory_store.cpp
@@ -1,4 +1,4 @@
-/*  $Id: memory_store.cpp 498375 2016-04-15 17:20:50Z ivanov $
+/*  $Id: memory_store.cpp 498292 2016-04-14 19:07:55Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/dbapi/driver/memory_store.hpp b/c++/src/dbapi/driver/memory_store.hpp
index f5e8923..2e2c7c2 100644
--- a/c++/src/dbapi/driver/memory_store.hpp
+++ b/c++/src/dbapi/driver/memory_store.hpp
@@ -1,7 +1,7 @@
 #ifndef DBAPI_DRIVER___MEMORY_STORE__HPP
 #define DBAPI_DRIVER___MEMORY_STORE__HPP
 
-/*  $Id: memory_store.hpp 498375 2016-04-15 17:20:50Z ivanov $
+/*  $Id: memory_store.hpp 498292 2016-04-14 19:07:55Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/dbapi/driver/odbc/bcp.cpp b/c++/src/dbapi/driver/odbc/bcp.cpp
index bee0c8e..a518c01 100644
--- a/c++/src/dbapi/driver/odbc/bcp.cpp
+++ b/c++/src/dbapi/driver/odbc/bcp.cpp
@@ -1,4 +1,4 @@
-/* $Id: bcp.cpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: bcp.cpp 498292 2016-04-14 19:07:55Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/dbapi/driver/odbc/connection.cpp b/c++/src/dbapi/driver/odbc/connection.cpp
index b141ca3..6288984 100644
--- a/c++/src/dbapi/driver/odbc/connection.cpp
+++ b/c++/src/dbapi/driver/odbc/connection.cpp
@@ -1,4 +1,4 @@
-/* $Id: connection.cpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: connection.cpp 499728 2016-04-27 19:40:54Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1504,6 +1504,27 @@ CStatementBase::x_GetData(const CDB_Object& param,
         }
         break;
     case eDB_VarCharMax:
+#ifdef UNICODE
+        if( !param.IsNULL() ) {
+            CDB_Stream& par = static_cast<CDB_Stream&>
+                (const_cast<CDB_Object&>(param));
+            size_t n = par.Size();
+            AutoArray<char> raw_data(n);
+            par.MoveTo(0);
+            _VERIFY(par.Read(raw_data.get(), n) == n);
+            CStringUTF8 utf_data
+                = CUtf8::AsUTF8(CTempString(raw_data.get(), n),
+                                GetClientEncoding());
+            raw_data.reset();
+            wstring wdata = CUtf8::AsBasicString<TSqlChar>(utf_data);
+            utf_data.clear();
+            n = wdata.size() * sizeof(TSqlChar);
+            data = bind_guard.Alloc(n);
+            memcpy(data, wdata.data(), n);
+        }
+        break;
+// else fall through
+#endif
     case eDB_VarBinaryMax:
         if( !param.IsNULL() ) {
             CDB_Stream& par = static_cast<CDB_Stream&>
diff --git a/c++/src/dbapi/driver/odbc/cursor.cpp b/c++/src/dbapi/driver/odbc/cursor.cpp
index 209e793..a27fb3a 100644
--- a/c++/src/dbapi/driver/odbc/cursor.cpp
+++ b/c++/src/dbapi/driver/odbc/cursor.cpp
@@ -1,4 +1,4 @@
-/* $Id: cursor.cpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: cursor.cpp 498292 2016-04-14 19:07:55Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/dbapi/driver/odbc/result.cpp b/c++/src/dbapi/driver/odbc/result.cpp
index 7de91be..c31d424 100644
--- a/c++/src/dbapi/driver/odbc/result.cpp
+++ b/c++/src/dbapi/driver/odbc/result.cpp
@@ -1,4 +1,4 @@
-/* $Id: result.cpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: result.cpp 498292 2016-04-14 19:07:55Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/dbapi/driver/public.cpp b/c++/src/dbapi/driver/public.cpp
index 88cdd15..258f9a2 100644
--- a/c++/src/dbapi/driver/public.cpp
+++ b/c++/src/dbapi/driver/public.cpp
@@ -1,4 +1,4 @@
-/* $Id: public.cpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: public.cpp 497635 2016-04-08 13:52:30Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/dbapi/driver/types.cpp b/c++/src/dbapi/driver/types.cpp
index 7bbbb67..2a98f49 100644
--- a/c++/src/dbapi/driver/types.cpp
+++ b/c++/src/dbapi/driver/types.cpp
@@ -1,4 +1,4 @@
-/* $Id: types.cpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: types.cpp 498292 2016-04-14 19:07:55Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/dbapi/driver_mgr.cpp b/c++/src/dbapi/driver_mgr.cpp
index 5399a64..a284b42 100644
--- a/c++/src/dbapi/driver_mgr.cpp
+++ b/c++/src/dbapi/driver_mgr.cpp
@@ -1,4 +1,4 @@
-/* $Id: driver_mgr.cpp 497437 2016-04-06 17:56:55Z ivanov $
+/* $Id: driver_mgr.cpp 497217 2016-04-05 11:37:33Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -23,7 +23,7 @@
 *
 * ===========================================================================
 *
-* File Name:  $Id: driver_mgr.cpp 497437 2016-04-06 17:56:55Z ivanov $
+* File Name:  $Id: driver_mgr.cpp 497217 2016-04-05 11:37:33Z ivanov $
 *
 * Author:  Michael Kholodov, Denis Vakatov
 *
diff --git a/c++/src/dbapi/rs_impl.cpp b/c++/src/dbapi/rs_impl.cpp
index 5dbee97..59770e0 100644
--- a/c++/src/dbapi/rs_impl.cpp
+++ b/c++/src/dbapi/rs_impl.cpp
@@ -1,4 +1,4 @@
-/* $Id: rs_impl.cpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: rs_impl.cpp 498292 2016-04-14 19:07:55Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -23,7 +23,7 @@
 *
 * ===========================================================================
 *
-* File Name:  $Id: rs_impl.cpp 498375 2016-04-15 17:20:50Z ivanov $
+* File Name:  $Id: rs_impl.cpp 498292 2016-04-14 19:07:55Z ucko $
 *
 * Author:  Michael Kholodov
 *
diff --git a/c++/src/dbapi/rw_impl.cpp b/c++/src/dbapi/rw_impl.cpp
index dcb00d4..8d0e7e2 100644
--- a/c++/src/dbapi/rw_impl.cpp
+++ b/c++/src/dbapi/rw_impl.cpp
@@ -1,4 +1,4 @@
-/* $Id: rw_impl.cpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: rw_impl.cpp 497635 2016-04-08 13:52:30Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE                          
diff --git a/c++/src/dbapi/rw_impl.hpp b/c++/src/dbapi/rw_impl.hpp
index 020ba6f..2ccbe88 100644
--- a/c++/src/dbapi/rw_impl.hpp
+++ b/c++/src/dbapi/rw_impl.hpp
@@ -1,7 +1,7 @@
 #ifndef _RW_IMPL_HPP_
 #define _RW_IMPL_HPP_
 
-/* $Id: rw_impl.hpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: rw_impl.hpp 497635 2016-04-08 13:52:30Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE                          
diff --git a/c++/src/dbapi/stmt_impl.cpp b/c++/src/dbapi/stmt_impl.cpp
index 64d2062..4f468ca 100644
--- a/c++/src/dbapi/stmt_impl.cpp
+++ b/c++/src/dbapi/stmt_impl.cpp
@@ -1,4 +1,4 @@
-/* $Id: stmt_impl.cpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: stmt_impl.cpp 497635 2016-04-08 13:52:30Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -23,7 +23,7 @@
 *
 * ===========================================================================
 *
-* File Name:  $Id: stmt_impl.cpp 498367 2016-04-15 17:18:04Z ivanov $
+* File Name:  $Id: stmt_impl.cpp 497635 2016-04-08 13:52:30Z ucko $
 *
 * Author:  Michael Kholodov
 *
diff --git a/c++/src/dbapi/stmt_impl.hpp b/c++/src/dbapi/stmt_impl.hpp
index fde06c5..282be16 100644
--- a/c++/src/dbapi/stmt_impl.hpp
+++ b/c++/src/dbapi/stmt_impl.hpp
@@ -1,7 +1,7 @@
 #ifndef _STMT_IMPL_HPP_
 #define _STMT_IMPL_HPP_
 
-/* $Id: stmt_impl.hpp 498367 2016-04-15 17:18:04Z ivanov $
+/* $Id: stmt_impl.hpp 497635 2016-04-08 13:52:30Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE                          
@@ -26,7 +26,7 @@
 *
 * ===========================================================================
 *
-* File Name:  $Id: stmt_impl.hpp 498367 2016-04-15 17:18:04Z ivanov $
+* File Name:  $Id: stmt_impl.hpp 497635 2016-04-08 13:52:30Z ucko $
 *
 * Author:  Michael Kholodov
 *   
diff --git a/c++/src/dbapi/variant.cpp b/c++/src/dbapi/variant.cpp
index 3d4025f..f3558f4 100644
--- a/c++/src/dbapi/variant.cpp
+++ b/c++/src/dbapi/variant.cpp
@@ -1,4 +1,4 @@
-/* $Id: variant.cpp 498375 2016-04-15 17:20:50Z ivanov $
+/* $Id: variant.cpp 498292 2016-04-14 19:07:55Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -23,7 +23,7 @@
 *
 * ===========================================================================
 *
-* File Name:  $Id: variant.cpp 498375 2016-04-15 17:20:50Z ivanov $
+* File Name:  $Id: variant.cpp 498292 2016-04-14 19:07:55Z ucko $
 *
 * Author:  Michael Kholodov
 *
diff --git a/c++/src/html/indentstream.cpp b/c++/src/html/indentstream.cpp
index a6f9cb1..e2d4d8b 100644
--- a/c++/src/html/indentstream.cpp
+++ b/c++/src/html/indentstream.cpp
@@ -1,4 +1,4 @@
-/*  $Id: indentstream.cpp 103491 2007-05-04 17:18:18Z kazimird $
+/*  $Id: indentstream.cpp 501456 2016-05-16 15:12:46Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -190,7 +190,7 @@ CT_INT_TYPE CIndentingStreambuf::uflow(void)
 
 CT_INT_TYPE CIndentingStreambuf::pbackfail(CT_INT_TYPE c)
 {
-    return (CT_EQ_INT_TYPE(c, CT_EOF) ? CT_EOF : m_Buf->sputbackc(c));
+    return (CT_EQ_INT_TYPE(c, CT_EOF) ? CT_EOF : m_Buf->sputbackc((char)c));
 }
 
 
diff --git a/c++/src/html/selection.cpp b/c++/src/html/selection.cpp
index ce999dd..030c6a0 100644
--- a/c++/src/html/selection.cpp
+++ b/c++/src/html/selection.cpp
@@ -1,4 +1,4 @@
-/*  $Id: selection.cpp 367926 2012-06-29 14:04:54Z ivanov $
+/*  $Id: selection.cpp 501456 2016-05-16 15:12:46Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -55,7 +55,7 @@ CSelection::CSelection(const CCgiRequest& request,
     found = values.find(checkboxName);
     if ( found != values.end() ) {
         for ( TCgiEntriesCI i = values.lower_bound(checkboxName),
-              end = values.upper_bound(checkboxName); i != end; ++i ) {
+              iend = values.upper_bound(checkboxName); i != iend; ++i ) {
             AddID(NStr::StringToInt(string(i->second)));
         }
     }
diff --git a/c++/src/misc/CMakeLists.txt b/c++/src/misc/CMakeLists.txt
new file mode 100644
index 0000000..087ff6a
--- /dev/null
+++ b/c++/src/misc/CMakeLists.txt
@@ -0,0 +1,22 @@
+##############################################################################
+# CMakeLists.txt autogenerated from /export/home/dicuccio/cpp-cmake/cpp-cmake/src/misc/Makefile.in
+#
+
+# Include projects from this directory
+
+# Recurse subdirectories
+add_subdirectory_optional(third_party)
+add_subdirectory_optional(third_party_static)
+add_subdirectory_optional(clog)
+add_subdirectory_optional(grid_cgi)
+add_subdirectory_optional(xmlwrapp)
+add_subdirectory_optional(eutils_client)
+add_subdirectory_optional(hydra_client)
+add_subdirectory_optional(discrepancy_report)
+add_subdirectory_optional(discrepancy)
+add_subdirectory_optional(xmlreaders)
+add_subdirectory_optional(hgvs)
+add_subdirectory_optional(netstorage)
+add_subdirectory_optional(jsonwrapp)
+add_subdirectory_optional(biosample_util)
+add_subdirectory_optional(data_loaders_util)
diff --git a/c++/src/misc/Makefile.in b/c++/src/misc/Makefile.in
new file mode 100644
index 0000000..933d731
--- /dev/null
+++ b/c++/src/misc/Makefile.in
@@ -0,0 +1,10 @@
+# $Id: Makefile.in 506528 2016-07-08 11:48:54Z dicuccio $
+
+SUB_PROJ            = third_party third_party_static clog grid_cgi xmlwrapp \
+                      eutils_client hydra_client discrepancy_report discrepancy xmlreaders \
+                      hgvs netstorage jsonwrapp biosample_util \
+                      data_loaders_util lapackwrapp
+EXPENDABLE_SUB_PROJ = cgi_redirect
+
+srcdir = @srcdir@
+include @builddir@/Makefile.meta
diff --git a/c++/src/misc/third_party/CMakeLists.txt b/c++/src/misc/third_party/CMakeLists.txt
new file mode 100644
index 0000000..de7e224
--- /dev/null
+++ b/c++/src/misc/third_party/CMakeLists.txt
@@ -0,0 +1,6 @@
+##############################################################################
+# CMakeLists.txt autogenerated from /export/home/dicuccio/cpp-cmake/cpp-cmake.2015-01-24/src/misc/third_party/Makefile.in
+#
+
+# Include projects from this directory
+
diff --git a/c++/src/misc/third_party/Makefile.in b/c++/src/misc/third_party/Makefile.in
new file mode 100644
index 0000000..f4ab5fe
--- /dev/null
+++ b/c++/src/misc/third_party/Makefile.in
@@ -0,0 +1,10 @@
+#################################
+# $Id: Makefile.in 107069 2007-07-11 13:46:21Z gouriano $
+# Author:  Viatcheslav Gorelenkov
+#################################
+
+MSVC_PROJ = third_party_dll_install third_party_msvcdll_install
+REQUIRES = DLL
+
+srcdir = @srcdir@
+include @builddir@/Makefile.meta
diff --git a/c++/src/misc/third_party/Makefile.third_party_dll_install.msvcproj b/c++/src/misc/third_party/Makefile.third_party_dll_install.msvcproj
new file mode 100644
index 0000000..c456640
--- /dev/null
+++ b/c++/src/misc/third_party/Makefile.third_party_dll_install.msvcproj
@@ -0,0 +1,11 @@
+# $Id: Makefile.third_party_dll_install.msvcproj 216394 2010-12-09 16:54:20Z gouriano $
+
+MSVC_PROJ = third_party_dll_install
+
+APP_DEP   = 
+
+DLL_DEP   = 
+
+VCPROJ    = $(msvc_prj)\dll\third_party_dll_install.vcproj
+VCXPROJ   = $(msvc_prj)\dll\third_party_dll_install.vcxproj
+
diff --git a/c++/src/misc/third_party/Makefile.third_party_dll_install.msvcproj.msvc b/c++/src/misc/third_party/Makefile.third_party_dll_install.msvcproj.msvc
new file mode 100644
index 0000000..b14ca76
--- /dev/null
+++ b/c++/src/misc/third_party/Makefile.third_party_dll_install.msvcproj.msvc
@@ -0,0 +1,4 @@
+# $Id: Makefile.third_party_dll_install.msvcproj.msvc 107885 2007-07-30 15:34:21Z kazimird $
+
+[Common]
+ProjectGUID = {9E4B5381-9B6C-4867-BF8A-F1AAA1FD580F}
\ No newline at end of file
diff --git a/c++/src/misc/third_party/Makefile.third_party_msvcdll_install.msvcproj b/c++/src/misc/third_party/Makefile.third_party_msvcdll_install.msvcproj
new file mode 100644
index 0000000..6caaba9
--- /dev/null
+++ b/c++/src/misc/third_party/Makefile.third_party_msvcdll_install.msvcproj
@@ -0,0 +1,11 @@
+# $Id: Makefile.third_party_msvcdll_install.msvcproj 216394 2010-12-09 16:54:20Z gouriano $
+
+MSVC_PROJ = third_party_msvcdll_install
+
+APP_DEP   = 
+
+DLL_DEP   = 
+
+VCPROJ    = $(msvc_prj)\dll\third_party_msvcdll_install.vcproj
+VCXPROJ   = $(msvc_prj)\dll\third_party_msvcdll_install.vcxproj
+
diff --git a/c++/src/misc/third_party_static/CMakeLists.txt b/c++/src/misc/third_party_static/CMakeLists.txt
new file mode 100644
index 0000000..fbec35c
--- /dev/null
+++ b/c++/src/misc/third_party_static/CMakeLists.txt
@@ -0,0 +1,6 @@
+##############################################################################
+# CMakeLists.txt autogenerated from /export/home/dicuccio/cpp-cmake/cpp-cmake.2015-01-24/src/misc/third_party_static/Makefile.in
+#
+
+# Include projects from this directory
+
diff --git a/c++/src/misc/third_party_static/Makefile.in b/c++/src/misc/third_party_static/Makefile.in
new file mode 100644
index 0000000..4440e88
--- /dev/null
+++ b/c++/src/misc/third_party_static/Makefile.in
@@ -0,0 +1,10 @@
+#################################
+# $Id: Makefile.in 107069 2007-07-11 13:46:21Z gouriano $
+# Author:  Viatcheslav Gorelenkov
+#################################
+
+MSVC_PROJ = third_party_static_install third_party_msvcstatic_install
+REQUIRES = -DLL
+
+srcdir = @srcdir@
+include @builddir@/Makefile.meta
diff --git a/c++/src/misc/third_party_static/Makefile.third_party_msvcstatic_install.msvcproj b/c++/src/misc/third_party_static/Makefile.third_party_msvcstatic_install.msvcproj
new file mode 100644
index 0000000..9c6ebf3
--- /dev/null
+++ b/c++/src/misc/third_party_static/Makefile.third_party_msvcstatic_install.msvcproj
@@ -0,0 +1,11 @@
+# $Id: Makefile.third_party_msvcstatic_install.msvcproj 196847 2010-07-09 13:40:18Z gouriano $
+
+MSVC_PROJ = third_party_msvcstatic_install
+
+APP_DEP   = 
+
+DLL_DEP   = 
+
+VCPROJ    = $(msvc_prj)\static\third_party_msvcstatic_install.vcproj
+VCXPROJ   = $(msvc_prj)\static\third_party_msvcstatic_install.vcxproj
+
diff --git a/c++/src/misc/third_party_static/Makefile.third_party_static_install.msvcproj b/c++/src/misc/third_party_static/Makefile.third_party_static_install.msvcproj
new file mode 100644
index 0000000..c68b712
--- /dev/null
+++ b/c++/src/misc/third_party_static/Makefile.third_party_static_install.msvcproj
@@ -0,0 +1,11 @@
+# $Id: Makefile.third_party_static_install.msvcproj 196847 2010-07-09 13:40:18Z gouriano $
+
+MSVC_PROJ = third_party_static_install
+
+APP_DEP   = 
+
+DLL_DEP   = 
+
+VCPROJ    = $(msvc_prj)\static\third_party_static_install.vcproj
+VCXPROJ   = $(msvc_prj)\static\third_party_static_install.vcxproj
+
diff --git a/c++/src/misc/third_party_static/Makefile.third_party_static_install.msvcproj.msvc b/c++/src/misc/third_party_static/Makefile.third_party_static_install.msvcproj.msvc
new file mode 100644
index 0000000..5a45729
--- /dev/null
+++ b/c++/src/misc/third_party_static/Makefile.third_party_static_install.msvcproj.msvc
@@ -0,0 +1,4 @@
+# $Id: Makefile.third_party_static_install.msvcproj.msvc 107885 2007-07-30 15:34:21Z kazimird $
+
+[Common]
+ProjectGUID = {9E4B5381-9B6C-4867-BF8A-F1AAA1FD580E}
\ No newline at end of file
diff --git a/c++/src/objects/Makefile.in b/c++/src/objects/Makefile.in
index 78a9c4d..128cbc0 100644
--- a/c++/src/objects/Makefile.in
+++ b/c++/src/objects/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in 437784 2014-06-10 14:26:24Z fongah2 $
+# $Id: Makefile.in 497130 2016-04-04 18:01:02Z foleyjp $
 
 # Meta-makefile("objects" project)
 #################################
@@ -11,7 +11,7 @@ SUB_PROJ = general biblio medline pub seqcode seq seqset submit \
            pcsubstance pcassay gbseq insdseq tinyseq biotree entrezgene \
            omssa remap seqtest taxon1 taxon3 gbproj trackmgr valerr valid \
            access docsum featdef genomecoll homologene mim objprt \
-           variation macro genesbyloc coords
+           variation macro genesbyloc coords varrep
 
 REQUIRES = objects
 
diff --git a/c++/src/objects/biblio/Auth_list.cpp b/c++/src/objects/biblio/Auth_list.cpp
index aead49d..9dd9fa3 100644
--- a/c++/src/objects/biblio/Auth_list.cpp
+++ b/c++/src/objects/biblio/Auth_list.cpp
@@ -1,4 +1,4 @@
-/* $Id: Auth_list.cpp 452468 2014-11-20 13:44:46Z bollin $
+/* $Id: Auth_list.cpp 498903 2016-04-20 15:50:10Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -223,7 +223,7 @@ void CAuth_list::ConvertMlToStandard(void)
         if (!NStr::IsBlank(*it)) {
             CRef<CAuthor> new_auth(new CAuthor());
             vector<string> tokens;
-            NStr::Tokenize(*it, " ", tokens);
+            NStr::Split(*it, " ", tokens, NStr::fSplit_NoMergeDelims);
             string suffix = "";
             string init = s_GetInitials(tokens);
             if (NStr::IsBlank(init) && tokens.size() > 1) {
@@ -239,7 +239,7 @@ void CAuth_list::ConvertMlToStandard(void)
             if (!NStr::IsBlank(init)) {                
                 new_auth->SetName().SetName().SetFirst(init.substr(0, 1));
                 vector<string> letters;
-                NStr::Tokenize(init, "", letters);
+                NStr::Split(init, "", letters, NStr::fSplit_NoMergeDelims);
                 string initials = NStr::Join(letters, ".");
                 new_auth->SetName().SetName().SetInitials(initials);
             }
diff --git a/c++/src/objects/biblio/Cit_gen.cpp b/c++/src/objects/biblio/Cit_gen.cpp
index 92352e8..7279509 100644
--- a/c++/src/objects/biblio/Cit_gen.cpp
+++ b/c++/src/objects/biblio/Cit_gen.cpp
@@ -1,4 +1,4 @@
-/* $Id: Cit_gen.cpp 272691 2011-04-10 03:51:54Z ucko $
+/* $Id: Cit_gen.cpp 498027 2016-04-12 18:56:44Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -61,7 +61,7 @@ bool CCit_gen::GetLabelV1(string* label, TLabelFlags flags) const
         *label += "[" + NStr::IntToString(GetSerial_number()) + "]";
     }
     if (IsSetMuid()) {
-        *label += "NLM" + NStr::IntToString(GetMuid());
+        *label += "NLM" + NStr::NumericToString(GetMuid());
     }
 
     string date;
diff --git a/c++/src/objects/biblio/biblio.def b/c++/src/objects/biblio/biblio.def
index 411bd02..1d64723 100644
--- a/c++/src/objects/biblio/biblio.def
+++ b/c++/src/objects/biblio/biblio.def
@@ -3,3 +3,16 @@ _export = NCBI_BIBLIO_EXPORT
 
 [Auth-list]
 names._delay = 1
+
+[PubMedId]
+_type = ncbi::TEntrezId
+
+[MedlineUID]
+_type = ncbi::TEntrezId
+
+[PmcID]
+_type = ncbi::TEntrezId
+
+[Cit-gen]
+muid._type = ncbi::TEntrezId
+muid._storage_type = ncbi::TIntId
diff --git a/c++/src/objects/biotree/DistanceMatrix.cpp b/c++/src/objects/biotree/DistanceMatrix.cpp
index 604674f..7c83ac1 100644
--- a/c++/src/objects/biotree/DistanceMatrix.cpp
+++ b/c++/src/objects/biotree/DistanceMatrix.cpp
@@ -1,4 +1,4 @@
-/* $Id: DistanceMatrix.cpp 103491 2007-05-04 17:18:18Z kazimird $
+/* $Id: DistanceMatrix.cpp 498903 2016-04-20 15:50:10Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -159,7 +159,7 @@ void CDistanceMatrix::Read(istream &istr, EFormat format) {
                 line = line.substr(10);
             }
             list<string> fields;
-            NStr::Split(line, " \t\n\r", fields);
+            NStr::Split(line, " \t\n\r", fields, NStr::fSplit_Tokenize);
             ITERATE (list<string>, field, fields) {
                 line_values.push_back(NStr::StringToDouble(*field));
             }
diff --git a/c++/src/objects/blast/doc/blast.htm b/c++/src/objects/blast/doc/blast.htm
index 06e87c9..58f1b59 100644
--- a/c++/src/objects/blast/doc/blast.htm
+++ b/c++/src/objects/blast/doc/blast.htm
@@ -17,7 +17,7 @@ Center for Biotechnology Information provides free BLAST services to the public
 using this interface (over HTTP) and others. NCBI's BLAST source code is in the 
 public domain, so other organizations may choose to run their own BLAST servers.</p>
 <p>The functionality provided by this interface is similar to that provided by 
-the <a href="http://www.ncbi.nlm.nih.gov/BLAST/Doc/urlapi.html">URL API</a>. 
+the <a href="https://www.ncbi.nlm.nih.gov/BLAST/Doc/urlapi.html">URL API</a>. 
 Either interface will work for many applications, but application programmers 
 may find this interface to be more convenient.</p>
 <p>For more information on using NCBI's public BLAST servers using this 
@@ -493,31 +493,31 @@ from each other, by spaces. Default values are shown in parentheses.</p>
 <h1 id="references">References</h1>
 <ul>
   <li id="basic-local-alignment-search-tool" class="ref">
-  <a href="http://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=2231712&dopt=Abstract">
+  <a href="https://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=2231712&dopt=Abstract">
   Basic local alignment search tool</a><br>
   Altschul SF, Gish W, Miller W, Myers EW, Lipman DJ<br>
   J Mol Biol. 1990 Oct 5;215(3):403-10.<br>
-  http://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=2231712&dopt=Abstract</li>
+  https://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=2231712&dopt=Abstract</li>
   </li>
   <li id="gapped-blast-and-psi-blast" class="ref">
-  <a href="http://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=9254694&dopt=Abstract">
+  <a href="https://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=9254694&dopt=Abstract">
   Gapped BLAST and PSI-BLAST: a new generation of protein database search 
   programs</a><br>
   Altschul SF, Madden TL, Schaffer AA, Zhang J, Zhang Z, Miller W, Lipman DJ<br>
   Nucleic Acids Res. 1997 Sep 1;25(17):3389-402.<br>
-  http://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=9254694&dopt=Abstract</li>
+  https://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=9254694&dopt=Abstract</li>
   <li id="improving-the-accuracy-of-psi-blast" class="ref">
-  <a href="http://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=11452024&dopt=Abstract">
+  <a href="https://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=11452024&dopt=Abstract">
   Improving the accuracy of PSI-BLAST protein database searches with 
   composition-based statistics and other refinements</a><br>
   Schaffer AA, Aravind L, Madden TL, Shavirin S, Spouge JL, Wolf YI, Koonin EV, 
   Altschul SF<br>
   Nucleic Acids Res. 2001 Jul 15;29(14):2994-3005.<br>
-  http://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=11452024&dopt=Abstract</li>
+  https://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=11452024&dopt=Abstract</li>
   <li id class="ref">
-  <a href="http://www.ncbi.nlm.nih.gov/Taxonomy/Utils/wprintgc.cgi?mode=c">Table 
+  <a href="https://www.ncbi.nlm.nih.gov/Taxonomy/Utils/wprintgc.cgi?mode=c">Table 
   of Genetic Codes</a><br>
-  http://www.ncbi.nlm.nih.gov/Taxonomy/Utils/wprintgc.cgi?mode=c</li>
+  https://www.ncbi.nlm.nih.gov/Taxonomy/Utils/wprintgc.cgi?mode=c</li>
   <li id="table-of-genetic-codes" class="ref">
   <a href="ftp://ftp.ncbi.nih.gov/blast/matrices/">Substitution Scoring Matrices
 —Data</a><br>
diff --git a/c++/src/objects/entrez2/entrez2.def b/c++/src/objects/entrez2/entrez2.def
index 614fee2..bd41fd5 100644
--- a/c++/src/objects/entrez2/entrez2.def
+++ b/c++/src/objects/entrez2/entrez2.def
@@ -4,6 +4,22 @@ clients = entrez2_client
 
 [entrez2_client]
 class   = CEntrez2Client
-service = ENTREZ2
+service = ENTREZ2S
 request = Entrez2-request.request
 reply   = Entrez2-reply.reply
+
+[Entrez2-id]
+uid._type = ncbi::TEntrezId
+uid._storage_type = ncbi::TIntId
+
+[Entrez2-hier-query]
+txid._type = ncbi::TEntrezId
+txid._storage_type = ncbi::TIntId
+
+[Entrez2-docsum]
+uid._type = ncbi::TEntrezId
+uid._storage_type = ncbi::TIntId
+
+[Entrez2-term]
+txid._type = ncbi::TEntrezId
+txid._storage_type = ncbi::TIntId
diff --git a/c++/src/objects/general/Dbtag.cpp b/c++/src/objects/general/Dbtag.cpp
index 3b93b33..c4d2aa8 100644
--- a/c++/src/objects/general/Dbtag.cpp
+++ b/c++/src/objects/general/Dbtag.cpp
@@ -1,4 +1,4 @@
-/* $Id: Dbtag.cpp 497059 2016-04-04 14:45:02Z ivanov $
+/* $Id: Dbtag.cpp 512465 2016-08-31 11:24:52Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -68,6 +68,7 @@ static const TDbxrefPair kApprovedDbXrefs[] = {
     { "ApiDB_CryptoDB", CDbtag::eDbtagType_ApiDB_CryptoDB },
     { "ApiDB_PlasmoDB", CDbtag::eDbtagType_ApiDB_PlasmoDB },
     { "ApiDB_ToxoDB", CDbtag::eDbtagType_ApiDB_ToxoDB },
+    { "Araport", CDbtag::eDbtagType_Araport },
     { "Axeldb", CDbtag::eDbtagType_axeldb },
     { "BDGP_EST", CDbtag::eDbtagType_BDGP_EST },
     { "BDGP_INS", CDbtag::eDbtagType_BDGP_INS },
@@ -160,6 +161,7 @@ static const TDbxrefPair kApprovedDbXrefs[] = {
     { "UniProtKB/TrEMBL", CDbtag::eDbtagType_UniProt_TrEMBL },
     { "UniSTS", CDbtag::eDbtagType_UniSTS },
     { "VBASE2", CDbtag::eDbtagType_VBASE2 },
+    { "VGNC", CDbtag::eDbtagType_VGNC },
     { "VISTA", CDbtag::eDbtagType_VISTA },
     { "VectorBase", CDbtag::eDbtagType_VectorBase },
     { "Vega", CDbtag::eDbtagType_Vega },
@@ -542,153 +544,156 @@ void CDbtag::InvalidateType(void)
 //=========================================================================//
 
 // special case URLs
-static const char kFBan[] = "http://www.fruitfly.org/cgi-bin/annot/fban?";
-static const char kHInvDbHIT[] = "http://www.jbirc.aist.go.jp/hinv/hinvsys/servlet/ExecServlet?KEN_INDEX=0&KEN_TYPE=30&KEN_STR=";
-static const char kHInvDbHIX[] = "http://www.jbirc.aist.go.jp/hinv/hinvsys/servlet/ExecServlet?KEN_INDEX=0&KEN_TYPE=31&KEN_STR=";
-static const char kDictyPrim[] = "http://dictybase.org/db/cgi-bin/gene_page.pl?primary_id=";
-static const char kMiRBaseMat[] = "http://www.mirbase.org/cgi-bin/mature.pl?mature_acc=";
-static const char kMaizeGDBInt[] = "http://www.maizegdb.org/cgi-bin/displaylocusrecord.cgi?id=";
-static const char kMaizeGDBStr[] = "http://www.maizegdb.org/cgi-bin/displaylocusrecord.cgi?term=";
-static const char kHomdTax[] = "http://www.homd.org/taxon=";
-static const char kHomdSeq[] = "http://www.homd.org/seq=";
+static const char kFBan[] = "http://www.fruitfly.org/cgi-bin/annot/fban?";  // url not found �Internal Server Error� tested 7/13/2016
+static const char kHInvDbHIT[] = "http://www.jbirc.aist.go.jp/hinv/hinvsys/servlet/ExecServlet?KEN_INDEX=0&KEN_TYPE=30&KEN_STR="; // access forbidden 7/13/2016
+static const char kHInvDbHIX[] = "http://www.jbirc.aist.go.jp/hinv/hinvsys/servlet/ExecServlet?KEN_INDEX=0&KEN_TYPE=31&KEN_STR=";  // �Internal Server Error� tested 7/13/2016
+static const char kDictyPrim[] = "http://dictybase.org/db/cgi-bin/gene_page.pl?primary_id=";  // url not found tested 7/13/2016
+static const char kMiRBaseMat[] = "http://www.mirbase.org/cgi-bin/mature.pl?mature_acc="; // https not available tested 7/13/2016 
+static const char kMaizeGDBInt[] = "https://www.maizegdb.org/cgi-bin/displaylocusrecord.cgi?id=";
+static const char kMaizeGDBStr[] = "https://www.maizegdb.org/cgi-bin/displaylocusrecord.cgi?term=";
+static const char kHomdTax[] = "http://www.homd.org/taxon="; // https not available tested 7/13/2016                                                                                                      
+static const char kHomdSeq[] = "http://www.homd.org/seq="; // https not available tested 7/13/2016 
+
 
 // mapping of DB to its URL; please sort these by tag value (mostly,
 // but NOT entirely, in case-sensitive ASCII-betical order as above)
 typedef SStaticPair<CDbtag::EDbtagType, const char*>    TDbtUrl;
 static const TDbtUrl sc_url_prefix[] = {
-    { CDbtag::eDbtagType_AFTOL, "http://wasabi.lutzonilab.net/pub/displayTaxonInfo?aftol_id=" },
-    { CDbtag::eDbtagType_APHIDBASE, "http://bipaa.genouest.org/apps/grs-2.3/grs?reportID=aphidbase_transcript_report&objectID=" },
+    { CDbtag::eDbtagType_AFTOL, "https://wasabi.lutzonilab.net/pub/displayTaxonInfo?aftol_id=" },
+    { CDbtag::eDbtagType_APHIDBASE, "http://bipaa.genouest.org/apps/grs-2.3/grs?reportID=aphidbase_transcript_report&objectID=" }, // �Service Unavailable� tested 7/13/2016  
     { CDbtag::eDbtagType_ASAP, "https://asap.genetics.wisc.edu/asap/feature_info.php?FeatureID=" },
-    { CDbtag::eDbtagType_ATCC, "http://www.atcc.org/Products/All/" },
-    { CDbtag::eDbtagType_AceView_WormGenes, "http://www.ncbi.nlm.nih.gov/IEB/Research/Acembly/av.cgi?db=worm&c=gene&q=" },
-    { CDbtag::eDbtagType_AntWeb, "http://www.antweb.org/specimen.do?name=" },
-    { CDbtag::eDbtagType_ApiDB, "http://www.apidb.org/apidb/showRecord.do?name=GeneRecordClasses.ApiDBGeneRecordClass&primary_key=" },
-    { CDbtag::eDbtagType_ApiDB_CryptoDB, "http://cryptodb.org/cryptodb/showRecord.do?name=GeneRecordClasses.GeneRecordClass&project_id=CryptoDB&source_id=" },
-    { CDbtag::eDbtagType_ApiDB_PlasmoDB, "http://plasmodb.org/plasmo/showRecord.do?name=GeneRecordClasses.GeneRecordClass&project_id=PlasmoDB&source_id=" },
-    { CDbtag::eDbtagType_ApiDB_ToxoDB, "http://toxodb.org/toxo/showRecord.do?name=GeneRecordClasses.GeneRecordClass&project_id=ToxoDB&source_id=" },
-    { CDbtag::eDbtagType_BB, "http://beetlebase.org/cgi-bin/cmap/feature_search?features=" },
-    { CDbtag::eDbtagType_BEETLEBASE, "http://www.beetlebase.org/cgi-bin/report.cgi?name=" },
-    { CDbtag::eDbtagType_BGD, "http://bovinegenome.org/genepages/btau40/genes/" },
-    { CDbtag::eDbtagType_BoLD, "http://www.boldsystems.org/connectivity/specimenlookup.php?processid=" },
-    { CDbtag::eDbtagType_CCDS, "http://www.ncbi.nlm.nih.gov/CCDS/CcdsBrowse.cgi?REQUEST=CCDS&DATA=" },
-    { CDbtag::eDbtagType_CDD, "http://www.ncbi.nlm.nih.gov/Structure/cdd/cddsrv.cgi?uid=" },
-    { CDbtag::eDbtagType_CGNC, "http://birdgenenames.org/cgnc/GeneReport?id=" },
-    { CDbtag::eDbtagType_CK, "http://flybane.berkeley.edu/cgi-bin/cDNA/CK_clone.pl?db=CK&dbid=" },
-    { CDbtag::eDbtagType_COG, "http://www.ncbi.nlm.nih.gov/COG/new/release/cow.cgi?cog=" },
-    { CDbtag::eDbtagType_CollecTF, "http://collectf.umbc.edu/" },
-    { CDbtag::eDbtagType_ECOCYC, "http://biocyc.org/ECOLI/new-image?type=GENE&object=" },
-    { CDbtag::eDbtagType_ENSEMBL, "http://www.ensembl.org/id/" },
-    { CDbtag::eDbtagType_EcoGene, "http://www.ecogene.org/gene/" },
-    { CDbtag::eDbtagType_FANTOM_DB, "http://fantom.gsc.riken.jp/db/annotate/main.cgi?masterid=" },
-    { CDbtag::eDbtagType_FBOL, "http://www.fungalbarcoding.org/BioloMICS.aspx?Table=Fungal%20barcodes&Fields=All&Rec=" },
-    { CDbtag::eDbtagType_FLYBASE, "http://flybase.bio.indiana.edu/.bin/fbidq.html?" },
-    { CDbtag::eDbtagType_Fungorum, "http://www.indexfungorum.org/Names/NamesRecord.asp?RecordID=" },
-    { CDbtag::eDbtagType_GABI, "http://www.gabipd.org/database/cgi-bin/GreenCards.pl.cgi?Mode=ShowSequence&App=ncbi&SequenceId=" },
-    { CDbtag::eDbtagType_GEO, "http://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=" },
+    { CDbtag::eDbtagType_ATCC, "https://www.atcc.org/Products/All/" },
+    { CDbtag::eDbtagType_AceView_WormGenes, "https://www.ncbi.nlm.nih.gov/IEB/Research/Acembly/av.cgi?db=worm&c=gene&q=" },
+    { CDbtag::eDbtagType_AntWeb, "https://www.antweb.org/specimen.do?name=" },
+    { CDbtag::eDbtagType_ApiDB, "http://www.apidb.org/apidb/showRecord.do?name=GeneRecordClasses.ApiDBGeneRecordClass&primary_key=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_ApiDB_CryptoDB, "http://cryptodb.org/cryptodb/showRecord.do?name=GeneRecordClasses.GeneRecordClass&project_id=CryptoDB&source_id=" },  // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_ApiDB_PlasmoDB, "http://plasmodb.org/plasmo/showRecord.do?name=GeneRecordClasses.GeneRecordClass&project_id=PlasmoDB&source_id=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_ApiDB_ToxoDB, "http://toxodb.org/toxo/showRecord.do?name=GeneRecordClasses.GeneRecordClass&project_id=ToxoDB&source_id=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_BB, "https://beetlebase.org/cgi-bin/cmap/feature_search?features=" },
+    { CDbtag::eDbtagType_BEETLEBASE, "https://www.beetlebase.org/cgi-bin/report.cgi?name=" },
+    { CDbtag::eDbtagType_BGD, "http://bovinegenome.org/genepages/btau40/genes/" }, // https not available tested 7/13/2016                                                                           
+    { CDbtag::eDbtagType_BoLD, "http://www.boldsystems.org/connectivity/specimenlookup.php?processid=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_CCDS, "https://www.ncbi.nlm.nih.gov/CCDS/CcdsBrowse.cgi?REQUEST=CCDS&DATA=" },
+    { CDbtag::eDbtagType_CDD, "https://www.ncbi.nlm.nih.gov/Structure/cdd/cddsrv.cgi?uid=" },
+    { CDbtag::eDbtagType_CGNC, "http://birdgenenames.org/cgnc/GeneReport?id=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_CK, "http://flybane.berkeley.edu/cgi-bin/cDNA/CK_clone.pl?db=CK&dbid=" }, // url not found tested 7/13/2016
+    { CDbtag::eDbtagType_COG, "http://www.ncbi.nlm.nih.gov/COG/new/release/cow.cgi?cog=" }, // url not found tested 7/13/2016
+    { CDbtag::eDbtagType_CollecTF, "https://collectf.umbc.edu/" },
+    { CDbtag::eDbtagType_ECOCYC, "http://biocyc.org/ECOLI/new-image?type=GENE&object=" }, // https does not result in security cert warning, but �page can�t be displayed�, tested 7/13/2016  
+    { CDbtag::eDbtagType_ENSEMBL, "http://www.ensembl.org/id/" }, // url seems incorrect, includes msg user has been redirected and  �Error 404 Page not found� tested 7/13/2016  
+    { CDbtag::eDbtagType_EcoGene, "https://www.ecogene.org/gene/" },
+    { CDbtag::eDbtagType_FANTOM_DB, "https://fantom.gsc.riken.jp/db/annotate/main.cgi?masterid=" },
+    { CDbtag::eDbtagType_FBOL, "http://www.fungalbarcoding.org/BioloMICS.aspx?Table=Fungal%20barcodes&Fields=All&Rec=" }, // https not available tested 7/13/2016                               
+    { CDbtag::eDbtagType_FLYBASE, "http://flybase.bio.indiana.edu/.bin/fbidq.html?" }, // https not available, http site �experiencing problems� tested 7/13/2016
+    { CDbtag::eDbtagType_Fungorum, "http://www.indexfungorum.org/Names/NamesRecord.asp?RecordID=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_GABI, "https://www.gabipd.org/database/cgi-bin/GreenCards.pl.cgi?Mode=ShowSequence&App=ncbi&SequenceId=" },
+    { CDbtag::eDbtagType_GEO, "https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=" },
     { CDbtag::eDbtagType_GO, "http://amigo.geneontology.org/amigo/term/GO:" },
-    { CDbtag::eDbtagType_GOA, "http://www.ebi.ac.uk/ego/GProtein?ac=" },
-    { CDbtag::eDbtagType_GRIN, "http://www.ars-grin.gov/cgi-bin/npgs/acc/display.pl?" },
-    { CDbtag::eDbtagType_GeneDB, "http://old.genedb.org/genedb/Search?organism=All%3A*&name=" },
-    { CDbtag::eDbtagType_GeneID, "http://www.ncbi.nlm.nih.gov/gene/" },
-    { CDbtag::eDbtagType_GrainGenes, "http://wheat.pw.usda.gov/cgi-bin/graingenes/report.cgi?class=marker&name=" },
-    { CDbtag::eDbtagType_Greengenes, "http://greengenes.lbl.gov/cgi-bin/show_one_record_v2.pl?prokMSA_id=" },
-    { CDbtag::eDbtagType_HGNC, "http://www.genenames.org/cgi-bin/gene_symbol_report?hgnc_id=HGNC:" },
-    { CDbtag::eDbtagType_HMP, "http://www.hmpdacc.org/catalog/grid.php?dataset=genomic&hmp_id=" },
-    { CDbtag::eDbtagType_HOMD, "http://www.homd.org/" },
-    { CDbtag::eDbtagType_HPM, "http://www.humanproteomemap.org/protein.php?hpm_id=" },
-    { CDbtag::eDbtagType_HPRD, "http://www.hprd.org/protein/" },
-    { CDbtag::eDbtagType_HSSP, "http://mrs.cmbi.ru.nl/m6/search?db=all&q=" },
-    { CDbtag::eDbtagType_H_InvDB, "http://www.h-invitational.jp" },
-    { CDbtag::eDbtagType_IFO, "http://www.nbrc.nite.go.jp/NBRC2/NBRCCatalogueDetailServlet?ID=NBRC&CAT=" },
-    { CDbtag::eDbtagType_IMGT_GENEDB, "http://www.imgt.org/IMGT_GENE-DB/GENElect?species=Homo+sapiens&query=2+" },
-    { CDbtag::eDbtagType_IMGT_HLA, "http://www.ebi.ac.uk/cgi-bin/ipd/imgt/hla/get_allele.cgi?" },
-    { CDbtag::eDbtagType_IMGT_LIGM, "http://www.imgt.org/cgi-bin/IMGTlect.jv?query=201+" },
-    { CDbtag::eDbtagType_IRD, "http://www.fludb.org/brc/fluSegmentDetails.do?irdSubmissionId=" },
-    { CDbtag::eDbtagType_ISD, "http://www.flu.lanl.gov/search/view_record.html?accession=" },
-    { CDbtag::eDbtagType_ISFinder, "http://www-is.biotoul.fr/scripts/is/is_spec.idc?name=" },
-    { CDbtag::eDbtagType_InterimID, "http://www.ncbi.nlm.nih.gov/gene/" },
-    { CDbtag::eDbtagType_Interpro, "http://www.ebi.ac.uk/interpro/ISearch?mode=ipr&query=" },
-    { CDbtag::eDbtagType_IntrepidBio, "http://server1.intrepidbio.com/FeatureBrowser/gene/browse/" },
-    { CDbtag::eDbtagType_JCM, "http://www.jcm.riken.go.jp/cgi-bin/jcm/jcm_number?JCM=" },
-    { CDbtag::eDbtagType_JGIDB, "http://genome.jgi-psf.org/cgi-bin/jgrs?id=" },
-    { CDbtag::eDbtagType_LocusID, "http://www.ncbi.nlm.nih.gov/gene/" },
-    { CDbtag::eDbtagType_MGI, "http://www.informatics.jax.org/marker/MGI:" },
-    { CDbtag::eDbtagType_MIM, "http://www.ncbi.nlm.nih.gov/omim/" },
-    { CDbtag::eDbtagType_MaizeGDB, "http://www.maizegdb.org/cgi-bin/displaylocusrecord.cgi?" },
-    { CDbtag::eDbtagType_MycoBank, "http://www.mycobank.org/MycoTaxo.aspx?Link=T&Rec=" },
-    { CDbtag::eDbtagType_NMPDR, "http://www.nmpdr.org/linkin.cgi?id=" },
-    { CDbtag::eDbtagType_NRESTdb, "http://genome.ukm.my/nrestdb/db/single_view_est.php?id=" },
-    { CDbtag::eDbtagType_NextDB, "http://nematode.lab.nig.ac.jp/cgi-bin/db/ShowGeneInfo.sh?celk=" },
-    { CDbtag::eDbtagType_OrthoMCL, "http://orthomcl.org/orthomcl/showRecord.do?name=GroupRecordClasses.GroupRecordClass&group_name=" },
-    { CDbtag::eDbtagType_Osa1, "http://rice.plantbiology.msu.edu/cgi-bin/gbrowse/rice/?name=" },
-    { CDbtag::eDbtagType_PBR, "http://www.poxvirus.org/query.asp?web_id=" },
-    { CDbtag::eDbtagType_PBmice, "http://www.idmshanghai.cn/PBmice/DetailedSearch.do?type=insert&id=" },
-    { CDbtag::eDbtagType_PDB, "http://www.rcsb.org/pdb/cgi/explore.cgi?pdbId=" },
-    { CDbtag::eDbtagType_PFAM, "http://pfam.sanger.ac.uk/family?acc=" },
-    { CDbtag::eDbtagType_PGN, "http://pgn.cornell.edu/cgi-bin/search/seq_search_result.pl?identifier=" },
-    { CDbtag::eDbtagType_Phytozome, "http://www.phytozome.net/genePage.php?db=Phytozome&crown&method=0&search=1&detail=1&searchText=locusname:" },
-    { CDbtag::eDbtagType_PomBase, "http://www.pombase.org/spombe/result/" },
-    { CDbtag::eDbtagType_PseudoCap, "http://www.pseudomonas.com/getAnnotation.do?locusID=" },
-    { CDbtag::eDbtagType_RAP_DB, "http://rapdb.dna.affrc.go.jp/cgi-bin/gbrowse_details/latest?name=" },
-    { CDbtag::eDbtagType_RATMAP, "http://ratmap.gen.gu.se/ShowSingleLocus.htm?accno=" },
-    { CDbtag::eDbtagType_RBGE_garden, "http://data.rbge.org.uk/living/" },
-    { CDbtag::eDbtagType_RBGE_herbarium, "http://data.rbge.org.uk/herb/" },
-    { CDbtag::eDbtagType_REBASE, "http://rebase.neb.com/rebase/enz/" },
-    { CDbtag::eDbtagType_RFAM, "http://rfam.xfam.org/family/" },
-    { CDbtag::eDbtagType_RGD, "http://rgd.mcw.edu/rgdweb/search/search.html?term=" },
-    { CDbtag::eDbtagType_RiceGenes, "http://ars-genome.cornell.edu/cgi-bin/WebAce/webace?db=ricegenes&class=Marker&object=" },
-    { CDbtag::eDbtagType_SEED, "http://www.theseed.org/linkin.cgi?id=" },
-    { CDbtag::eDbtagType_SGD, "http://www.yeastgenome.org/cgi-bin/locus.fpl?sgdid=" },
-    { CDbtag::eDbtagType_SGN, "http://www.sgn.cornell.edu/search/est.pl?request_type=7&request_id=" },
-    { CDbtag::eDbtagType_SK_FST, "http://aafc-aac.usask.ca/fst/" },
-    { CDbtag::eDbtagType_SRPDB, "http://rnp.uthscsa.edu/rnp/SRPDB/rna/sequences/fasta/" },
-    { CDbtag::eDbtagType_SubtiList, "http://genolist.pasteur.fr/SubtiList/genome.cgi?external_query+" },
-    { CDbtag::eDbtagType_TAIR, "http://www.arabidopsis.org/servlets/TairObject?type=locus&name=" },
-    { CDbtag::eDbtagType_TIGRFAM, "http://www.jcvi.org/cgi-bin/tigrfams/HmmReportPage.cgi?acc=" },
-    { CDbtag::eDbtagType_UNITE, "http://unite.ut.ee/bl_forw.php?nimi=" },
-    { CDbtag::eDbtagType_UniGene, "http://www.ncbi.nlm.nih.gov/unigene?term=" },
-    { CDbtag::eDbtagType_UniProt_SwissProt, "http://www.uniprot.org/uniprot/" },
-    { CDbtag::eDbtagType_UniProt_TrEMBL, "http://www.uniprot.org/uniprot/" },
-    { CDbtag::eDbtagType_UniSTS, "http://www.ncbi.nlm.nih.gov/probe?term=" },
-    { CDbtag::eDbtagType_VBASE2, "http://www.dnaplot.de/vbase2/vgene.php?id=" },
-    { CDbtag::eDbtagType_VBRC, "http://vbrc.org/query.asp?web_view=curation&web_id=" },
-    { CDbtag::eDbtagType_VectorBase, "http://www.vectorbase.org/Genome/BRCGene/?feature=" },
+    { CDbtag::eDbtagType_GOA, "https://www.ebi.ac.uk/ego/GProtein?ac=" },
+    { CDbtag::eDbtagType_GRIN, "https://www.ars-grin.gov/cgi-bin/npgs/acc/display.pl?" },
+    { CDbtag::eDbtagType_GeneDB, "http://old.genedb.org/genedb/Search?organism=All%3A*&name=" }, // https not available tested 7/13/2016                                                                                            
+    { CDbtag::eDbtagType_GeneID, "https://www.ncbi.nlm.nih.gov/gene/" },
+    { CDbtag::eDbtagType_GrainGenes, "http://wheat.pw.usda.gov/cgi-bin/graingenes/report.cgi?class=marker&name=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_Greengenes, "http://greengenes.lbl.gov/cgi-bin/show_one_record_v2.pl?prokMSA_id=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_HGNC, "http://www.genenames.org/cgi-bin/gene_symbol_report?hgnc_id=HGNC:" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_HMP, "https://www.hmpdacc.org/catalog/grid.php?dataset=genomic&hmp_id=" },
+    { CDbtag::eDbtagType_HOMD, "http://www.homd.org/" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_HPM, "http://www.humanproteomemap.org/protein.php?hpm_id=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_HPRD, "http://www.hprd.org/protein/" }, // https not available, http returns �Service Temporarily Unavailable� tested 7/13/2016
+    { CDbtag::eDbtagType_HSSP, "http://mrs.cmbi.ru.nl/m6/search?db=all&q=" }, // not sure this points to a useful URL tested 7/13/2016  
+    { CDbtag::eDbtagType_H_InvDB, "https://www.h-invitational.jp" },
+    { CDbtag::eDbtagType_IFO, "https://www.nbrc.nite.go.jp/NBRC2/NBRCCatalogueDetailServlet?ID=NBRC&CAT=" },
+    { CDbtag::eDbtagType_IMGT_GENEDB, "http://www.imgt.org/IMGT_GENE-DB/GENElect?species=Homo+sapiens&query=2+" }, // https not available, http �detected an unhandled exception� tested 7/13/2016
+    { CDbtag::eDbtagType_IMGT_HLA, "https://www.ebi.ac.uk/cgi-bin/ipd/imgt/hla/get_allele.cgi?" },
+    { CDbtag::eDbtagType_IMGT_LIGM, "http://www.imgt.org/cgi-bin/IMGTlect.jv?query=201+" }, // https not available, http �detected an unhandled exception� tested 7/13/2016
+    { CDbtag::eDbtagType_IRD, "https://www.fludb.org/brc/fluSegmentDetails.do?irdSubmissionId=" },
+    { CDbtag::eDbtagType_ISD, "http://www.flu.lanl.gov/search/view_record.html?accession=" }, // http �page can�t be displayed� tested 7/13/2016  
+    { CDbtag::eDbtagType_ISFinder, "http://www-is.biotoul.fr/scripts/is/is_spec.idc?name=" }, // url not found tested 7/13/2016
+    { CDbtag::eDbtagType_InterimID, "https://www.ncbi.nlm.nih.gov/gene/" },
+    { CDbtag::eDbtagType_Interpro, "https://www.ebi.ac.uk/interpro/ISearch?mode=ipr&query=" },
+    { CDbtag::eDbtagType_IntrepidBio, "http://server1.intrepidbio.com/FeatureBrowser/gene/browse/" }, // http request shows �Database is down for maint� tested 7/13/2016  
+    { CDbtag::eDbtagType_JCM, "https://www.jcm.riken.go.jp/cgi-bin/jcm/jcm_number?JCM=" },
+    { CDbtag::eDbtagType_JGIDB, "http://genome.jgi-psf.org/cgi-bin/jgrs?id=" }, // https page �can�t be displayed� tested 7/13/2016  
+    { CDbtag::eDbtagType_LocusID, "https://www.ncbi.nlm.nih.gov/gene/" },
+    { CDbtag::eDbtagType_MGI, "http://www.informatics.jax.org/marker/MGI:" }, // https page �can�t be displayed� tested 7/13/2016  
+    { CDbtag::eDbtagType_MIM, "https://www.ncbi.nlm.nih.gov/omim/" },
+    { CDbtag::eDbtagType_MaizeGDB, "https://www.maizegdb.org/cgi-bin/displaylocusrecord.cgi?" },
+    { CDbtag::eDbtagType_MycoBank, "http://www.mycobank.org/MycoTaxo.aspx?Link=T&Rec=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_NMPDR, "http://www.nmpdr.org/linkin.cgi?id=" }, // https not available, http �Internal Server Error� tested 7/13/2016                                                                                            
+    { CDbtag::eDbtagType_NRESTdb, "http://genome.ukm.my/nrestdb/db/single_view_est.php?id=" }, //  http �page can�t be displayed� tested 7/13/2016  
+    { CDbtag::eDbtagType_NextDB, "http://nematode.lab.nig.ac.jp/cgi-bin/db/ShowGeneInfo.sh?celk=" }, // url not found tested 7/13/2016
+    { CDbtag::eDbtagType_OrthoMCL, "http://orthomcl.org/orthomcl/showRecord.do?name=GroupRecordClasses.GroupRecordClass&group_name=" }, // https not available                                                                                            
+    { CDbtag::eDbtagType_Osa1, "http://rice.plantbiology.msu.edu/cgi-bin/gbrowse/rice/?name=" }, // https �page can�t be displayed� tested 7/13/2016
+    { CDbtag::eDbtagType_PBR, "https://www.poxvirus.org/query.asp?web_id=" },
+    { CDbtag::eDbtagType_PBmice, "http://www.idmshanghai.cn/PBmice/DetailedSearch.do?type=insert&id=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_PDB, "http://www.rcsb.org/pdb/cgi/explore.cgi?pdbId=" }, // https �page can�t be displayed� tested 7/13/2016
+    { CDbtag::eDbtagType_PFAM, "http://pfam.sanger.ac.uk/family?acc=" }, // http page states info no longer avail at this website, includes links to look for a new location tested 7/13/2016
+    { CDbtag::eDbtagType_PGN, "http://pgn.cornell.edu/cgi-bin/search/seq_search_result.pl?identifier=" }, // http page states info no longer avail at this website, includes links to look for a new location tested 7/13/2016
+    { CDbtag::eDbtagType_Phytozome, "http://www.phytozome.net/genePage.php?db=Phytozome&crown&method=0&search=1&detail=1&searchText=locusname:" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_PomBase, "http://www.pombase.org/spombe/result/" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_PseudoCap, "http://www.pseudomonas.com/getAnnotation.do?locusID=" }, // url not found tested 7/13/2016
+    { CDbtag::eDbtagType_RAP_DB, "http://rapdb.dna.affrc.go.jp/cgi-bin/gbrowse_details/latest?name=" }, // https appears available, domain appears to exist but http �page not found� with note about release of a major update tested 7/13/2016  
+    { CDbtag::eDbtagType_RATMAP, "https://ratmap.gen.gu.se/ShowSingleLocus.htm?accno=" },
+    { CDbtag::eDbtagType_RBGE_garden, "https://data.rbge.org.uk/living/" },
+    { CDbtag::eDbtagType_RBGE_herbarium, "https://data.rbge.org.uk/herb/" },
+    { CDbtag::eDbtagType_REBASE, "https://rebase.neb.com/rebase/enz/" },
+    { CDbtag::eDbtagType_RFAM, "http://rfam.xfam.org/family/" }, // https not available tested 7/13/2016                                                                                            
+    { CDbtag::eDbtagType_RGD, "https://rgd.mcw.edu/rgdweb/search/search.html?term=" },
+    { CDbtag::eDbtagType_RiceGenes, "http://ars-genome.cornell.edu/cgi-bin/WebAce/webace?db=ricegenes&class=Marker&object=" }, // http �page can�t be displayed� tested 7/13/2016  
+    { CDbtag::eDbtagType_SEED, "http://www.theseed.org/linkin.cgi?id=" }, // https not available, http Service Temporarily Unavailable tested 7/13/2016                                                                                            
+    { CDbtag::eDbtagType_SGD, "http://www.yeastgenome.org/cgi-bin/locus.fpl?sgdid=" }, // url not found tested 7/13/2016
+    { CDbtag::eDbtagType_SGN, "http://www.sgn.cornell.edu/search/est.pl?request_type=7&request_id=" }, // https not available, http automatically redirects to https, then shows security cert issue, tested 7/13/2016
+    { CDbtag::eDbtagType_SK_FST, "http://aafc-aac.usask.ca/fst/" }, // https not available tested 7/13/2016                                                                                            
+    { CDbtag::eDbtagType_SRPDB, "http://rnp.uthscsa.edu/rnp/SRPDB/rna/sequences/fasta/" }, // https not available tested 7/13/2016                                                                       
+    { CDbtag::eDbtagType_SubtiList, "http://genolist.pasteur.fr/SubtiList/genome.cgi?external_query+" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_TAIR, "https://www.arabidopsis.org/servlets/TairObject?type=locus&name=" },
+    { CDbtag::eDbtagType_TIGRFAM, "http://www.jcvi.org/cgi-bin/tigrfams/HmmReportPage.cgi?acc=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_UNITE, "https://unite.ut.ee/bl_forw.php?nimi=" },
+    { CDbtag::eDbtagType_UniGene, "https://www.ncbi.nlm.nih.gov/unigene?term=" }, 
+    { CDbtag::eDbtagType_UniProt_SwissProt, "http://www.uniprot.org/uniprot/" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_UniProt_TrEMBL, "http://www.uniprot.org/uniprot/" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_UniSTS, "https://www.ncbi.nlm.nih.gov/probe?term=" },
+    { CDbtag::eDbtagType_VBASE2, "http://www.vbase2.org/vgene.php?id=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_VBRC, "http://vbrc.org/query.asp?web_view=curation&web_id=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_VectorBase, "https://www.vectorbase.org/Genome/BRCGene/?feature=" },
     { CDbtag::eDbtagType_Vega, "http://vega.sanger.ac.uk/id/"  },
     { CDbtag::eDbtagType_WorfDB, "http://worfdb.dfci.harvard.edu/search.pl?form=1&search=" },
-    { CDbtag::eDbtagType_WormBase, "http://www.wormbase.org/search/gene/" },
-    { CDbtag::eDbtagType_Xenbase, "http://www.xenbase.org/gene/showgene.do?method=display&geneId=" },
-    { CDbtag::eDbtagType_ZFIN, "http://zfin.org/cgi-bin/webdriver?MIval=aa-markerview.apg&OID=" },
-    { CDbtag::eDbtagType_axeldb, "http://www.dkfz-heidelberg.de/tbi/services/axeldb/clone/xenopus?name=" },
-    { CDbtag::eDbtagType_dbClone, "http://www.ncbi.nlm.nih.gov/sites/entrez?db=clone&cmd=Retrieve&list_uids=" },
-    { CDbtag::eDbtagType_dbCloneLib, "http://www.ncbi.nlm.nih.gov/sites/entrez?db=clonelib&cmd=Retrieve&list_uids=" },
-    { CDbtag::eDbtagType_dbEST, "http://www.ncbi.nlm.nih.gov/nucest/" },
-    { CDbtag::eDbtagType_dbProbe, "http://www.ncbi.nlm.nih.gov/sites/entrez?db=probe&cmd=Retrieve&list_uids=" },
-    { CDbtag::eDbtagType_dbSNP, "http://www.ncbi.nlm.nih.gov/SNP/snp_ref.cgi?type=rs&rs=" },
-    { CDbtag::eDbtagType_dbSTS, "http://www.ncbi.nlm.nih.gov/nuccore/" },
-    { CDbtag::eDbtagType_dictyBase, "http://dictybase.org/db/cgi-bin/gene_page.pl?dictybaseid=" },
-    { CDbtag::eDbtagType_miRBase, "http://www.mirbase.org/cgi-bin/mirna_entry.pl?acc=" },
-    { CDbtag::eDbtagType_niaEST, "http://lgsun.grc.nia.nih.gov/cgi-bin/pro3?sname1=" },
+    { CDbtag::eDbtagType_WormBase, "https://www.wormbase.org/search/gene/" },
+    { CDbtag::eDbtagType_Xenbase, "https://www.xenbase.org/gene/showgene.do?method=display&geneId=" },
+    { CDbtag::eDbtagType_ZFIN, "https://zfin.org/cgi-bin/webdriver?MIval=aa-markerview.apg&OID=" },
+    { CDbtag::eDbtagType_axeldb, "http://www.dkfz-heidelberg.de/tbi/services/axeldb/clone/xenopus?name=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_dbClone, "https://www.ncbi.nlm.nih.gov/sites/entrez?db=clone&cmd=Retrieve&list_uids=" },
+    { CDbtag::eDbtagType_dbCloneLib, "https://www.ncbi.nlm.nih.gov/sites/entrez?db=clonelib&cmd=Retrieve&list_uids=" },
+    { CDbtag::eDbtagType_dbEST, "https://www.ncbi.nlm.nih.gov/nucest/" },
+    { CDbtag::eDbtagType_dbProbe, "https://www.ncbi.nlm.nih.gov/sites/entrez?db=probe&cmd=Retrieve&list_uids=" },
+    { CDbtag::eDbtagType_dbSNP, "https://www.ncbi.nlm.nih.gov/SNP/snp_ref.cgi?type=rs&rs=" },
+    { CDbtag::eDbtagType_dbSTS, "https://www.ncbi.nlm.nih.gov/nuccore/" },
+    { CDbtag::eDbtagType_dictyBase, "https://dictybase.org/db/cgi-bin/gene_page.pl?dictybaseid=" },
+    { CDbtag::eDbtagType_miRBase, "http://www.mirbase.org/cgi-bin/mirna_entry.pl?acc=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_niaEST, "http://lgsun.grc.nia.nih.gov/cgi-bin/pro3?sname1=" }, // https not available tested 7/13/2016
     { CDbtag::eDbtagType_taxon, "https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?" },
-    { CDbtag::eDbtagType_BEEBASE, "http://hymenopteragenome.org/cgi-bin/gb2/gbrowse/bee_genome45/?name=" },
-    { CDbtag::eDbtagType_NASONIABASE, "http://hymenopteragenome.org/cgi-bin/gbrowse/nasonia10_scaffold/?name=" },
-    { CDbtag::eDbtagType_BioProject, "http://www.ncbi.nlm.nih.gov/bioproject/" },
-    { CDbtag::eDbtagType_IKMC, "http://www.knockoutmouse.org/martsearch/project/" },
-    { CDbtag::eDbtagType_ViPR, "http://www.viprbrc.org/brc/viprStrainDetails.do?viprSubmissionId=" },
-    { CDbtag::eDbtagType_SRA, "http://www.ncbi.nlm.nih.gov/sra/" },
-    { CDbtag::eDbtagType_RefSeq, "http://www.ncbi.nlm.nih.gov/nuccore/" },
-    { CDbtag::eDbtagType_EnsemblGenomes, "http://ensemblgenomes.org/id/" },
-    { CDbtag::eDbtagType_EnsemblGenomes_Gn, "http://ensemblgenomes.org/id/" },
-    { CDbtag::eDbtagType_EnsemblGenomes_Tr, "http://ensemblgenomes.org/id/" },
-    { CDbtag::eDbtagType_TubercuList, "http://tuberculist.epfl.ch/quicksearch.php?gene+name=" },
-    { CDbtag::eDbtagType_MedGen, "http://www.ncbi.nlm.nih.gov/medgen/" },
-    { CDbtag::eDbtagType_CGD, "http://www.candidagenome.org/cgi-bin/locus.pl?locus=" },
-    { CDbtag::eDbtagType_Assembly, "http://www.ncbi.nlm.nih.gov/assembly/" },
-    { CDbtag::eDbtagType_GenBank, "http://www.ncbi.nlm.nih.gov/nuccore/" },
-    { CDbtag::eDbtagType_BioSample, "http://www.ncbi.nlm.nih.gov/biosample/" },
-    { CDbtag::eDbtagType_ISHAM_ITS, "http://its.mycologylab.org/BioloMICS.aspx?Table=Sequences&ExactMatch=T&Name=MITS" },
+    { CDbtag::eDbtagType_BEEBASE, "http://hymenopteragenome.org/cgi-bin/gb2/gbrowse/bee_genome45/?name=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_NASONIABASE, "http://hymenopteragenome.org/cgi-bin/gbrowse/nasonia10_scaffold/?name=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_BioProject, "https://www.ncbi.nlm.nih.gov/bioproject/" },
+    { CDbtag::eDbtagType_IKMC, "https://www.mousephenotype.org/data/alleles/project_id?ikmc_project_id=" }, 
+    { CDbtag::eDbtagType_ViPR, "https://www.viprbrc.org/brc/viprStrainDetails.do?viprSubmissionId=" },
+    { CDbtag::eDbtagType_SRA, "https://www.ncbi.nlm.nih.gov/sra/" },
+    { CDbtag::eDbtagType_RefSeq, "https://www.ncbi.nlm.nih.gov/nuccore/" },
+    { CDbtag::eDbtagType_EnsemblGenomes, "http://ensemblgenomes.org/id/" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_EnsemblGenomes_Gn, "http://ensemblgenomes.org/id/" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_EnsemblGenomes_Tr, "http://ensemblgenomes.org/id/" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_TubercuList, "http://tuberculist.epfl.ch/quicksearch.php?gene+name=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_MedGen, "https://www.ncbi.nlm.nih.gov/medgen/" },
+    { CDbtag::eDbtagType_CGD, "http://www.candidagenome.org/cgi-bin/locus.pl?locus=" }, // https not available tested 7/13/2016
+    { CDbtag::eDbtagType_Assembly, "https://www.ncbi.nlm.nih.gov/assembly/" },
+    { CDbtag::eDbtagType_GenBank, "https://www.ncbi.nlm.nih.gov/nuccore/" },
+    { CDbtag::eDbtagType_BioSample, "https://www.ncbi.nlm.nih.gov/biosample/" },
+    { CDbtag::eDbtagType_ISHAM_ITS, "http://its.mycologylab.org/BioloMICS.aspx?Table=Sequences&ExactMatch=T&Name=MITS" }, // https not available tested 7/13/2016
     { CDbtag::eDbtagType_I5KNAL, "https://i5k.nal.usda.gov/" },
-    { CDbtag::eDbtagType_VISTA, "http://enhancer.lbl.gov/cgi-bin/dbxref.pl?id=" },
+    { CDbtag::eDbtagType_VISTA, "http://enhancer.lbl.gov/cgi-bin/dbxref.pl?id=" }, // https not available tested 7/13/2016
     { CDbtag::eDbtagType_BEI, "https://www.beiresources.org/Catalog/animalViruses/" },
+    { CDbtag::eDbtagType_Araport, "https://www.araport.org/locus/" },
+    { CDbtag::eDbtagType_VGNC, "http://vertebrate.genenames.org/data/gene-symbol-report/#!/vgnc_id/VGNC:" }, // https not available tested 7/13/2016
 };
 
 typedef CStaticPairArrayMap<CDbtag::EDbtagType, const char*> TUrlPrefixMap;
@@ -737,7 +742,7 @@ string CDbtag::GetUrl(const string & taxname_arg ) const
     // extract genus, species, subspeces
 
     vector<string> taxname_parts;
-    NStr::Tokenize( taxname, " ", taxname_parts, NStr::eMergeDelims );
+    NStr::Split(taxname, " ", taxname_parts, NStr::fSplit_Tokenize);
 
     if( taxname_parts.size() == 2 || taxname_parts.size() == 3 ) {
         string genus;
@@ -818,6 +823,12 @@ string CDbtag::GetUrl(const string & genus,
         }
         break;
 
+    case eDbtagType_VGNC:
+        if (NStr::StartsWith(tag, "VGNC:", NStr::eNocase)) {
+            tag = tag.substr(5);
+        }
+        break;
+
     case eDbtagType_RGD:
         if (NStr::StartsWith(tag, "RGD:", NStr::eNocase)) {
             tag = tag.substr(4);
diff --git a/c++/src/objects/general/Name_std.cpp b/c++/src/objects/general/Name_std.cpp
index ba2c3c2..8308ae1 100644
--- a/c++/src/objects/general/Name_std.cpp
+++ b/c++/src/objects/general/Name_std.cpp
@@ -1,4 +1,4 @@
-/* $Id: Name_std.cpp 415406 2013-10-15 12:05:26Z bollin $
+/* $Id: Name_std.cpp 509242 2016-08-04 14:12:34Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -61,6 +61,67 @@ const CName_std::TSuffixes& CName_std::GetStandardSuffixes(void)
 }
 
 
+bool CName_std::ExtractSuffixFromLastName()
+{
+    if ((IsSetSuffix() && !NStr::IsBlank(GetSuffix()))
+        || !IsSetLast()) {
+        // bail if already have non-empty suffix or if no last name
+        return false;
+    }
+    string& last = SetLast();
+    size_t pos = NStr::Find(last, " ");
+    if (pos == string::npos) {
+        return false;
+    }
+    size_t npos = NStr::Find(last, " ", pos + 1);
+    while (npos != string::npos) {
+        pos = npos;
+        npos = NStr::Find(last, " ", pos + 1);
+    }
+
+    string suffix = last.substr(pos + 1);
+    if (NStr::Equal(suffix, "Jr.") ||
+        NStr::Equal(suffix, "Jr") ||
+        NStr::Equal(suffix, "Sr.") ||
+        NStr::Equal(suffix, "Sr") ||
+        NStr::Equal(suffix, "II") ||
+        NStr::Equal(suffix, "III") ||
+        NStr::Equal(suffix, "IV")) {
+        SetSuffix(suffix);
+        FixSuffix(SetSuffix());
+        last = last.substr(0, pos);
+        return true;
+    }
+    return false;
+}
+
+
+void CName_std::FixSuffix(string& suffix)
+{
+    // remove spaces
+    NStr::ReplaceInPlace(suffix, " ", "");
+
+    if (!suffix.empty()) {
+        // remove any period, if any, on the end
+        if (NStr::EndsWith(suffix, ".")) {
+            suffix.resize(suffix.length() - 1);
+        }
+
+        if (NStr::EqualNocase(suffix, "1d")) {
+            suffix = "1st";
+        } else if (NStr::EqualNocase(suffix, "2d")) {
+            suffix = "2nd";
+        } else if (NStr::EqualNocase(suffix, "3d")) {
+            suffix = "3rd";
+        } else if (NStr::EqualNocase(suffix, "Sr")) {
+            suffix = "Sr.";
+        } else if (NStr::EqualNocase(suffix, "Jr")) {
+            suffix = "Jr.";
+        }
+    }
+}
+
+
 END_objects_SCOPE // namespace ncbi::objects::
 
 END_NCBI_SCOPE
diff --git a/c++/src/objects/general/User_field.cpp b/c++/src/objects/general/User_field.cpp
index 2dde71e..5de9393 100644
--- a/c++/src/objects/general/User_field.cpp
+++ b/c++/src/objects/general/User_field.cpp
@@ -1,4 +1,4 @@
-/* $Id: User_field.cpp 490266 2016-01-22 16:40:57Z kornbluh $
+/* $Id: User_field.cpp 498903 2016-04-20 15:50:10Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -228,7 +228,7 @@ CConstRef<CUser_field> CUser_field::GetFieldRef(const string& str,
                                                 NStr::ECase use_case) const
 {
     list<string> toks;
-    NStr::Split(str, delim, toks);
+    NStr::Split(str, delim, toks, NStr::fSplit_Tokenize);
 
     CConstRef<CUser_field> f(this);
     if ( !f->GetData().IsFields() ) {
@@ -344,7 +344,7 @@ CRef<CUser_field> CUser_field::SetFieldRef(const string& str,
                                            NStr::ECase use_case)
 {
     list<string> toks;
-    NStr::Split(str, delim, toks);
+    NStr::Split(str, delim, toks, NStr::fSplit_Tokenize);
 
     CRef<CUser_field> f(this);
     if ( ! f->GetData().IsFields()  &&  f->GetData().Which() != CUser_field::TData::e_not_set ) {
@@ -403,7 +403,7 @@ bool CUser_field::DeleteField(const string& str,
                               NStr::ECase use_case)
 {
     list<string> toks;
-    NStr::Split(str, delim, toks);
+    NStr::Split(str, delim, toks, NStr::fSplit_Tokenize);
 
     CRef<CUser_field> f(this);
     list<string>::const_iterator last = toks.end();
diff --git a/c++/src/objects/general/User_object.cpp b/c++/src/objects/general/User_object.cpp
index d9789f2..f3f73e3 100644
--- a/c++/src/objects/general/User_object.cpp
+++ b/c++/src/objects/general/User_object.cpp
@@ -1,4 +1,4 @@
-/* $Id: User_object.cpp 490266 2016-01-22 16:40:57Z kornbluh $
+/* $Id: User_object.cpp 501123 2016-05-11 17:29:51Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -82,7 +82,7 @@ CConstRef<CUser_field> CUser_object::GetFieldRef(const string& str,
                                                  NStr::ECase use_case) const
 {
     list<string> toks;
-    NStr::Split(str, delim, toks);
+    NStr::Split(str, delim, toks, NStr::fSplit_Tokenize);
     if ( !toks.size() ) {
         return CConstRef<CUser_field>();
     }
@@ -158,7 +158,7 @@ CRef<CUser_field> CUser_object::SetFieldRef(const string& str,
                                             NStr::ECase use_case)
 {
     list<string> toks;
-    NStr::Split(str, delim, toks);
+    NStr::Split(str, delim, toks, NStr::fSplit_Tokenize);
 
     CRef<CUser_field>  field_ref;
 
@@ -597,6 +597,7 @@ static const char* kUnverified            = "Unverified";
 static const char* kValidationSuppression = "ValidationSuppression";
 static const char* kNcbiCleanup           = "NcbiCleanup";
 static const char* kAutoDefOptions        = "AutodefOptions";
+static const char* kFileTrack             = "FileTrack";
 
 CUser_object::EObjectType CUser_object::GetObjectType() const
 {
@@ -622,6 +623,8 @@ CUser_object::EObjectType CUser_object::GetObjectType() const
         rval = eObjectType_Cleanup;
     } else if (NStr::Equal(label, kAutoDefOptions)) {
         rval = eObjectType_AutodefOptions;
+    } else if (NStr::Equal(label, kFileTrack)) {
+        rval = eObjectType_FileTrack;
     }
     return rval;
 }
@@ -651,6 +654,9 @@ void CUser_object::SetObjectType(EObjectType obj_type)
         case eObjectType_AutodefOptions:
             SetType().SetStr(kAutoDefOptions);
             break;
+        case eObjectType_FileTrack:
+            SetType().SetStr(kFileTrack);
+            break;
         case eObjectType_Unknown:
             ResetType();
             break;
@@ -797,6 +803,21 @@ void CUser_object::UpdateNcbiCleanup(int version)
 }
 
 
+void CUser_object::SetFileTrackURL(const string& url)
+{
+    SetObjectType(eObjectType_FileTrack);
+    CRef<CUser_field> fturl = SetFieldRef("BaseModification-FileTrackURL");
+    fturl->SetData().SetStr(url);
+}
+
+
+void CUser_object::SetFileTrackUploadId(const string& upload_id)
+{
+    string url = "https://submit.ncbi.nlm.nih.gov/ft/byid/" + upload_id;
+    SetFileTrackURL(url);
+}
+
+
 END_objects_SCOPE // namespace ncbi::objects::
 
 END_NCBI_SCOPE
diff --git a/c++/src/objects/genomecoll/GCClient_GetAssemblyBySequ.cpp b/c++/src/objects/genomecoll/GCClient_GetAssemblyBySequ.cpp
new file mode 100644
index 0000000..67a1679
--- /dev/null
+++ b/c++/src/objects/genomecoll/GCClient_GetAssemblyBySequ.cpp
@@ -0,0 +1,81 @@
+/* $Id: GCClient_GetAssemblyBySequ.cpp 500855 2016-05-09 16:12:34Z zherikov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  .......
+ *
+ * File Description:
+ *   .......
+ *
+ * Remark:
+ *   This code was originally generated by application DATATOOL
+ *   using the following specifications:
+ *   'gencoll_client.asn'.
+ */
+
+// standard includes
+#include <ncbi_pch.hpp>
+
+#include <serial/enumvalues.hpp>
+
+// generated includes
+#include <objects/genomecoll/GCClient_GetAssemblyBySequ.hpp>
+
+// generated classes
+
+BEGIN_NCBI_SCOPE
+
+BEGIN_objects_SCOPE // namespace ncbi::objects::
+
+// destructor
+CGCClient_GetAssemblyBySequenceRequest::~CGCClient_GetAssemblyBySequenceRequest(void)
+{
+}
+
+string CGCClient_GetAssemblyBySequenceRequest::GetFilterDisplayName(int filter)
+{
+    string s = ENUM_METHOD_NAME(EGCClient_GetAssemblyBySequenceFilter)()->FindName(filter, true);
+    if(!s.empty())
+        return s;
+
+    list<string> res;
+    ITERATE(CEnumeratedTypeValues::TValueToName, it, ENUM_METHOD_NAME(EGCClient_GetAssemblyBySequenceFilter)()->ValueToName())
+        if(it->first && (it->first & filter) == it->first)
+        {
+            res.push_back(*it->second);
+            filter &= ~it->first;
+        }
+
+    if(filter)
+        res.push_back(NStr::NumericToString(filter));
+
+    return NStr::Join(res, ",");
+}
+
+
+END_objects_SCOPE // namespace ncbi::objects::
+
+END_NCBI_SCOPE
+
+/* Original file checksum: lines: 57, chars: 1807, CRC32: 7a2cd229 */
diff --git a/c++/src/objects/genomecoll/GC_Assembly.cpp b/c++/src/objects/genomecoll/GC_Assembly.cpp
index 06afb16..f71fd88 100644
--- a/c++/src/objects/genomecoll/GC_Assembly.cpp
+++ b/c++/src/objects/genomecoll/GC_Assembly.cpp
@@ -1,4 +1,4 @@
-/* $Id: GC_Assembly.cpp 467805 2015-05-18 12:53:53Z zherikov $
+/* $Id: GC_Assembly.cpp 504372 2016-06-14 18:01:03Z shchekot $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -73,31 +73,23 @@ CGC_Assembly::~CGC_Assembly(void)
 {
 }
 
+const list<CRef<CDbtag>>& CGC_Assembly::x_GetId() const
+{
+    if (IsAssembly_set()) return GetAssembly_set().GetId();
+    if (IsUnit()) return GetUnit().GetId();
+    NCBI_THROW(CException, eUnknown, "unhandled GC-Assembly choice");
+}
 
 int CGC_Assembly::GetReleaseId() const
 {
     int release_id = 0;
-    CGC_AssemblyUnit::TId ids;
-    if (IsAssembly_set()) {
-        ITERATE (CGC_AssemblySet::TId, id_it, GetAssembly_set().GetId()) {
-
-            if ((*id_it)->GetDb() == "GenColl"  &&
-                (*id_it)->GetTag().IsId()) {
-                release_id = (*id_it)->GetTag().GetId();
-                break;
-            }
-        }
-    } else if (IsUnit()) {
-        ITERATE (CGC_AssemblyUnit::TId, id_it, GetUnit().GetId()) {
-            if ((*id_it)->GetDb() == "GenColl"  &&
-                (*id_it)->GetTag().IsId()) {
-                release_id = (*id_it)->GetTag().GetId();
-                break;
-            }
+    typedef list<CRef<CDbtag>> TId;
+    ITERATE (TId, id_it, x_GetId()) {
+        if ((*id_it)->GetDb() == "GenColl"  &&
+            (*id_it)->GetTag().IsId()) {
+            release_id = (*id_it)->GetTag().GetId();
+            break;
         }
-    } else {
-        NCBI_THROW(CException, eUnknown,
-                   "unhandled GC-Assembly choice");
     }
     return release_id;
 }
@@ -106,30 +98,36 @@ int CGC_Assembly::GetReleaseId() const
 string CGC_Assembly::GetAccession() const
 {
     string accession;
-    CGC_AssemblyUnit::TId ids;
-    if (IsAssembly_set()) {
-        ITERATE (CGC_AssemblySet::TId, id_it, GetAssembly_set().GetId()) {
-            if ((*id_it)->GetDb() == "GenColl"  &&
-                (*id_it)->GetTag().IsStr()) {
-                accession = (*id_it)->GetTag().GetStr();
-                break;
-            }
-        }
-    } else if (IsUnit()) {
-        ITERATE (CGC_AssemblyUnit::TId, id_it, GetUnit().GetId()) {
-            if ((*id_it)->GetDb() == "GenColl"  &&
-                (*id_it)->GetTag().IsStr()) {
-                accession = (*id_it)->GetTag().GetStr();
-                break;
-            }
+    typedef list<CRef<CDbtag>> TId;
+    ITERATE (TId, id_it, x_GetId()) {
+        if ((*id_it)->GetDb() == "GenColl"  &&
+            (*id_it)->GetTag().IsStr()) {
+            accession = (*id_it)->GetTag().GetStr();
+            break;
         }
-    } else {
-        NCBI_THROW(CException, eUnknown,
-                   "unhandled GC-Assembly choice");
     }
     return accession;
 }
 
+string CGC_Assembly::GetBestIdentifier() const
+{
+    const string acc = GetAccession();
+    return !acc.empty() ? acc : x_GetSubmitterId();
+}
+
+string CGC_Assembly::x_GetSubmitterId() const
+{
+    string submitter_id;
+    typedef list<CRef<CDbtag>> TId;
+    ITERATE (TId, id_it, x_GetId()) {
+        if ((*id_it)->GetDb() == "submitter"  &&
+            (*id_it)->GetTag().IsStr()) {
+            submitter_id = (*id_it)->GetTag().GetStr();
+            break;
+        }
+    }
+    return submitter_id;
+}
 
 const CGC_AssemblyDesc& CGC_Assembly::GetDesc() const
 {
@@ -488,36 +486,6 @@ void CGC_Assembly::x_Index(CGC_Assembly& root)
             }
         }
     }
-
-    ///
-    /// we also maintain a map of objects for fast look-ups
-    ///
-    m_SequenceMap.clear();
-    CTypeConstIterator<CGC_Sequence> seq_it(*this);
-    for ( ;  seq_it;  ++seq_it) {
-        const CGC_Sequence& this_seq = *seq_it;
-        m_SequenceMap[CSeq_id_Handle::GetHandle(this_seq.GetSeq_id())]
-            .push_back(CConstRef<CGC_Sequence>(&this_seq));
-
-        // don't forget to index aliases
-        if (this_seq.IsSetSeq_id_synonyms()) {
-            set<CSeq_id_Handle> these_ids;
-            these_ids.insert(CSeq_id_Handle::GetHandle(seq_it->GetSeq_id()));
-
-            ITERATE (CGC_Sequence::TSeq_id_synonyms, syn_it,
-                     this_seq.GetSeq_id_synonyms()) {
-                for (CTypeConstIterator<CSeq_id> id_it(**syn_it);
-                     id_it;  ++id_it) {
-                    CSeq_id_Handle idh =
-                        CSeq_id_Handle::GetHandle(*id_it);
-                    if (these_ids.insert(idh).second) {
-                        m_SequenceMap[CSeq_id_Handle::GetHandle(*id_it)]
-                            .push_back(CConstRef<CGC_Sequence>(&*seq_it));
-                    }
-                }
-            }
-        }
-    }
 }
 
 
diff --git a/c++/src/objects/genomecoll/cached_assembly.cpp b/c++/src/objects/genomecoll/cached_assembly.cpp
index 64bcc31..28ed2f6 100644
--- a/c++/src/objects/genomecoll/cached_assembly.cpp
+++ b/c++/src/objects/genomecoll/cached_assembly.cpp
@@ -57,7 +57,7 @@ CRef<CGC_Assembly> UncomressAndCreate(const string& blob, CCompressStream::EMeth
                 >> (*m_assembly);
 
     sw.Stop();
-    LOG_POST(Info << "Assebmly uncomressed and created in (sec): " << sw.Elapsed());
+    LOG_POST(Info << "Assembly uncomressed and created in (sec): " << sw.Elapsed());
     GetDiagContext().Extra().Print("Create-assembly-from-blob-time", sw.Elapsed() * 1000) // need millisecond
                             .Print("compress-method", method)
                             .Print("blob-size", blob.size());
@@ -80,8 +80,7 @@ CRef<CGC_Assembly> UncomressAndCreate(const string& blob, CCompressStream::EMeth
 //    LOG_POST(Info << "Assebmly uncomressed in (sec): " << g.Elapsed());
 //}
 
-static
-CCompressStream::EMethod Compression(const string& blob)
+CCompressStream::EMethod CCachedAssembly::Compression(const string& blob)
 {
     if (!CCachedAssembly::ValidBlob(blob.size()))
         NCBI_THROW(CCoreException, eCore, "Invalid blob size detected: " + blob.size());
@@ -112,7 +111,6 @@ void CompressAssembly(string& blob, CRef<CGC_Assembly> assembly, CCompressStream
     CStopWatch sw(CStopWatch::eStart);
 
     LOG_POST(Info << "Creating blob with compression: " << method);
-    _ASSERT(blob.empty());
 
     CNcbiOstrstream out;
     CCompressOStream compress(out, method);
@@ -129,47 +127,65 @@ void CompressAssembly(string& blob, CRef<CGC_Assembly> assembly, CCompressStream
 }
 
 static
-string ChangeCompression(const string& blob,
-                         CCompressStream::EMethod from, CCompressStream::EMethod to)
+const string& EnsureCompression(string& blob, CCompressStream::EMethod cur_method, CCompressStream::EMethod new_method)
 {
+    if(cur_method == new_method)
+        return blob;
+
     CStopWatch sw(CStopWatch::eStart);
 
-    LOG_POST(Info << "Changing compression from " << from << " to " << to);
-    _ASSERT(from != to);
+    LOG_POST(Info << "Changing compression from " << cur_method << " to " << new_method);
 
     CNcbiIstrstream in(blob.data(), blob.size());
-    CDecompressIStream from_stream(in, from);
+    CDecompressIStream from_stream(in, cur_method);
     CNcbiOstrstream out;
-    CCompressOStream to_stream(out, to);
+    CCompressOStream to_stream(out, new_method);
 
     to_stream << from_stream.rdbuf();
     to_stream.Finalize();
 
-    string new_blob = CNcbiOstrstreamToString(out);
+    const string new_blob = CNcbiOstrstreamToString(out);
 
     sw.Stop();
     LOG_POST(Info << "Compression done - processed: " << to_stream.GetProcessedSize() << ", old size:" << blob.size() << ", new size: " << to_stream.GetOutputSize());
 
     GetDiagContext().Extra().Print("Change-assembly-compression-time", sw.Elapsed() * 1000) // need millisecond
-                            .Print("compress-method-old", from)
-                            .Print("compress-method-new", to)
+                            .Print("compress-method-old", cur_method)
+                            .Print("compress-method-new", new_method)
                             .Print("blob-size-old",       blob.size())
                             .Print("blob-size-new",   new_blob.size());
 
-    return new_blob;
+    blob = new_blob;
+
+    return blob;
 }
 
 const string& CCachedAssembly::Blob(CCompressStream::EMethod neededCompression)
 {
     _ASSERT(neededCompression == CCompressStream::eBZip2 || neededCompression == CCompressStream::eZip);
     LOG_POST(Info << "Requested blob with compression: " << neededCompression);
-    if (m_blob.empty()) {
+
+    if (ValidBlob(m_blob.size()))
+        return EnsureCompression(m_blob, Compression(m_blob), neededCompression); //TODO: remove it once all be switched to new gc_access (conversion will be done inside CGencollCache)
+
+    if (m_assembly)
         CompressAssembly(m_blob, m_assembly, neededCompression);
-    }
-    else if (neededCompression != Compression(m_blob)) {
-        //TODO: remove it once all be switched to new gc_access (conversion will be done inside CGencollCache)
-        m_blob = ChangeCompression(m_blob, Compression(m_blob), neededCompression);
-    }
+    else
+        m_blob.clear();
+
+    return m_blob;
+}
+
+const string& CCachedAssembly::Blob()
+{
+    if (ValidBlob(m_blob.size()))
+        return m_blob;
+
+    if (m_assembly)
+        CompressAssembly(m_blob, m_assembly, CCompressStream::eZip);
+    else
+        m_blob.clear();
+
     return m_blob;
 }
 
diff --git a/c++/src/objects/genomecoll/gencoll_client.asn b/c++/src/objects/genomecoll/gencoll_client.asn
index 6047cf6..e722b70 100755
--- a/c++/src/objects/genomecoll/gencoll_client.asn
+++ b/c++/src/objects/genomecoll/gencoll_client.asn
@@ -1,4 +1,4 @@
--- $Id: gencoll_client.asn 486883 2015-12-11 13:03:03Z zherikov $
+-- $Id: gencoll_client.asn 500701 2016-05-06 17:36:05Z zherikov $
 -- **********************************************************************
 --
 --  NCBI Genome Collections Statistics
@@ -20,7 +20,8 @@ GCClientRequest ::= CHOICE {
     get-chrtype-valid  GCClient-ValidateChrTypeLocRequest,
     get-best-assembly GCClient-FindBestAssemblyRequest,
     get-equivalent-assemblies GCClient-GetEquivalentAssembliesRequest,
-    get-assembly-blob GCClient-GetAssemblyBlobRequest
+    get-assembly-blob GCClient-GetAssemblyBlobRequest,
+    get-assembly-by-sequence GCClient-GetAssemblyBySequenceRequest
 }
 
 
@@ -32,7 +33,8 @@ GCClientResponse ::= CHOICE {
     
     --  errors encountered at the server side.
     srvr-error GCClient-Error,
-    get-assembly-blob OCTET STRING
+    get-assembly-blob OCTET STRING,
+    get-assembly-by-sequence GCClient-AssembliesForSequences
 }
 
 GCClient-Error ::= SEQUENCE {
@@ -171,11 +173,39 @@ GCClient-FindBestAssemblyRequest ::= SEQUENCE {
     assembly-return-limit INTEGER OPTIONAL
 }
 
+-- This is a bitfield.  All values are powers of two.
+GCClient-GetAssemblyBySequenceFilter ::= INTEGER {
+    all(0),
+    latest(1),
+    major(2),
+    genbank(4),
+    refseq(8)
+}
+
+GCClient-GetAssemblyBySequenceRequest ::= SEQUENCE {
+    sequence-acc SET OF VisibleString,
+
+    filter GCClient-GetAssemblyBySequenceFilter DEFAULT all,
+
+    sort INTEGER {
+        default(0),
+        latest(1),
+        major(2)
+    } DEFAULT default,
+
+    top-assembly-only INTEGER DEFAULT 0
+}
+
+
 GCClient-AssemblyInfo ::= SEQUENCE {
     accession VisibleString,
     latest    BOOLEAN,
     major     BOOLEAN,
-    annotated BOOLEAN
+    annotated BOOLEAN OPTIONAL,
+    type INTEGER {
+        genbank(1),
+        refseq(2)
+    } OPTIONAL
 }
 
 GCClient-AssemblySequenceInfo ::= SEQUENCE {
diff --git a/c++/src/objects/genomecoll/gencoll_client.def b/c++/src/objects/genomecoll/gencoll_client.def
index 572ff0d..3d4b397 100644
--- a/c++/src/objects/genomecoll/gencoll_client.def
+++ b/c++/src/objects/genomecoll/gencoll_client.def
@@ -4,6 +4,6 @@ clients        = genomic_collections_cli
 
 [genomic_collections_cli]
 class   = CGenomicCollectionsService
-service = GC_GetAssembly_v3
+service = GC_GetAssembly_v3s
 request = GCClientRequest
 reply   = GCClientResponse
diff --git a/c++/src/objects/genomecoll/genome_collection.asn b/c++/src/objects/genomecoll/genome_collection.asn
index 6c0040a..db2b1ec 100644
--- a/c++/src/objects/genomecoll/genome_collection.asn
+++ b/c++/src/objects/genomecoll/genome_collection.asn
@@ -1,4 +1,4 @@
--- $Id: genome_collection.asn 469353 2015-06-03 16:18:27Z smithrg $
+-- $Id: genome_collection.asn 507583 2016-07-20 14:23:26Z xiangcha $
 -- **********************************************************************
 --
 --  NCBI Genome Collections
@@ -524,6 +524,7 @@ GC-Scaf-stats ::= SEQUENCE {
         count-real-scaffolds (112), -- number of scaffolds with gb_is_skipped = 0.
         top-level-count (113), -- Number of chromosomes or plasmids, unplaced/unlocalized scaffolds, alt-loci scaffolds, and patch scaffolds
         total-gap-length (114), -- Total length of gaps
+        count-replicons-without-ordered-scaf (115), -- count of replicons without ordered scaffold
 
         other (255) -- catch all
     },
diff --git a/c++/src/objects/genomecoll/genomic_collections_cli.cpp b/c++/src/objects/genomecoll/genomic_collections_cli.cpp
index 083f2b8..da9c1c7 100644
--- a/c++/src/objects/genomecoll/genomic_collections_cli.cpp
+++ b/c++/src/objects/genomecoll/genomic_collections_cli.cpp
@@ -1,4 +1,4 @@
-/* $Id: genomic_collections_cli.cpp 499302 2016-04-25 15:35:38Z ivanov $
+/* $Id: genomic_collections_cli.cpp 512198 2016-08-29 14:17:45Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -311,6 +311,63 @@ CRef<CGCClient_AssembliesForSequences> CGenomicCollectionsService::FindAllAssemb
 }
 
 
+CRef<CGCClient_AssemblyInfo> CGenomicCollectionsService::FindOneAssemblyBySequences(const string& sequence_acc, int filter, CGCClient_GetAssemblyBySequenceRequest::ESort sort)
+{
+    CRef<CGCClient_AssemblySequenceInfo> asmseq_info(FindOneAssemblyBySequences(list<string>(1, sequence_acc), filter, sort));
+
+    return asmseq_info ? CRef<CGCClient_AssemblyInfo>(&asmseq_info->SetAssembly()) : CRef<CGCClient_AssemblyInfo>();
+}
+
+CRef<CGCClient_AssemblySequenceInfo> CGenomicCollectionsService::FindOneAssemblyBySequences(const list<string>& sequence_acc, int filter, CGCClient_GetAssemblyBySequenceRequest::ESort sort)
+{
+    CRef<CGCClient_AssembliesForSequences> assm(FindAssembliesBySequences(sequence_acc, filter, sort, true));
+
+    return assm->CanGetAssemblies() && !assm->GetAssemblies().empty() ?
+           CRef<CGCClient_AssemblySequenceInfo>(assm->SetAssemblies().front()) :
+           CRef<CGCClient_AssemblySequenceInfo>();
+}
+
+CRef<CGCClient_AssembliesForSequences> CGenomicCollectionsService::FindAssembliesBySequences(const string& sequence_acc, int filter, CGCClient_GetAssemblyBySequenceRequest::ESort sort)
+{
+    return FindAssembliesBySequences(list<string>(1, sequence_acc), filter, sort);
+}
+
+CRef<CGCClient_AssembliesForSequences> CGenomicCollectionsService::FindAssembliesBySequences(const list<string>& sequence_acc, int filter, CGCClient_GetAssemblyBySequenceRequest::ESort sort)
+{
+    return FindAssembliesBySequences(sequence_acc, filter, sort, false);
+}
+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_EquivalentAssemblies> CGenomicCollectionsService::GetEquivalentAssemblies(const string& acc, int equivalency)
 {
     CGCClient_GetEquivalentAssembliesRequest req;
diff --git a/c++/src/objects/macro/String_constraint.cpp b/c++/src/objects/macro/String_constraint.cpp
index f9d75d6..f42881e 100644
--- a/c++/src/objects/macro/String_constraint.cpp
+++ b/c++/src/objects/macro/String_constraint.cpp
@@ -1,4 +1,4 @@
-/* $Id: String_constraint.cpp 494819 2016-03-10 18:53:49Z ivanov $
+/* $Id: String_constraint.cpp 510214 2016-08-11 15:06:21Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -61,7 +61,7 @@ bool CString_constraint :: Empty() const
        GetIs_first_cap() ||
        GetIs_first_each_cap()) {
       return false;
-   } else if (!CanGetMatch_text() || NStr::IsBlank(GetMatch_text())) {
+   } else if (!CanGetMatch_text() || GetMatch_text().empty()) {
         return true;
    }
 
@@ -579,7 +579,7 @@ bool CString_constraint :: x_IsStringInSpanInList (const string& str, const stri
 
 bool CString_constraint :: x_DoesSingleStringMatchConstraint(const string& str) const
 {
-    if (NStr::IsBlank(str)) {
+    if (str.empty()) {
         return false;
     }
 
@@ -619,7 +619,7 @@ bool CString_constraint :: x_DoesSingleStringMatchConstraint(const string& str)
             
             NStr::ECase case_sens = GetCase_sensitive() ? NStr::eCase : NStr::eNocase;
             SIZE_TYPE pFound;
-            if (NStr::IsBlank(pattern)) {
+            if (pattern.empty()) {
                 pFound = 0;
             } else {
                 pFound = NStr::Find(search, pattern, 0, NPOS, NStr::eFirst, case_sens);
diff --git a/c++/src/objects/macro/Suspect_rule.cpp b/c++/src/objects/macro/Suspect_rule.cpp
index 17e8190..1d29ac0 100644
--- a/c++/src/objects/macro/Suspect_rule.cpp
+++ b/c++/src/objects/macro/Suspect_rule.cpp
@@ -1,4 +1,4 @@
-/* $Id: Suspect_rule.cpp 439103 2014-06-25 16:31:44Z chenj $
+/* $Id: Suspect_rule.cpp 513456 2016-09-12 14:18:13Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -83,8 +83,377 @@ bool CSuspect_rule::ApplyToString(string& val) const
 }
 
 
-END_objects_SCOPE // namespace ncbi::objects::
+string CSuspect_rule::SummarizeReplaceRule(const CReplace_rule& repl) const
+{
+    string str = "Unknown replacement function";
+    const CReplace_func& func = repl.GetReplace_func();
+    if (func.Which() == CReplace_func::e_Simple_replace) {
+        const CSimple_replace& simple = func.GetSimple_replace();
+        str = "replace ";
+        str += simple.GetWhole_string() ? "entire name with " : "with ";
+        str += simple.CanGetReplace() ? "'" + simple.GetReplace() + "'": "''";
+        str += simple.GetWeasel_to_putative() ? ", retain and normalize 'putative' synonym" : kEmptyStr;
+    }
+    else if (func.Which() == CReplace_func::e_Haem_replace) {
+        str = "replace '" + func.GetHaem_replace() + "' with 'heme' if whole word, 'hem' otherwise";
+    }
+    str += repl.GetMove_to_note() ? ", move original to note" : kEmptyStr;
+    return str;
+}
 
-END_NCBI_SCOPE
 
-/* Original file checksum: lines: 57, chars: 1729, CRC32: 243f48c6 */
+string CSuspect_rule::SummarizeStringConstraint(const CString_constraint& cons) const
+{
+    if (cons.CanGetMatch_text()) {
+        string loc_word;
+        switch (cons.GetMatch_location()) {
+            case eString_location_contains:
+                loc_word = cons.GetNot_present() ? "does not contain" : "contains";
+                break;
+            case eString_location_equals:
+                loc_word = cons.GetNot_present() ? "does not equal" : "equals";
+                break;
+            case eString_location_starts:
+                loc_word = cons.GetNot_present() ? "does not start with" : "starts with";
+                break;
+            case eString_location_ends:
+                loc_word = cons.GetNot_present() ? "does not end with" : "ends with";
+                break;
+            case eString_location_inlist:
+                loc_word = cons.GetNot_present() ? "is not one of" : "is one of";
+                break;
+        }
+        string sub_words;
+        if (cons.CanGetIgnore_words()) {
+            ITERATE (list<CRef<CWord_substitution> >, it, cons.GetIgnore_words().Get()) {
+                string syns;
+                if ((*it)->CanGetSynonyms() && !(*it)->GetSynonyms().empty()) {
+                    const CWord_substitution::TSynonyms& synonyms = (*it)->GetSynonyms();
+                    ITERATE (CWord_substitution::TSynonyms, sn, synonyms) {
+                        if (!syns.empty()) {
+                            CWord_substitution::TSynonyms::const_iterator z = sn;
+                            syns += (++z == synonyms.end()) ? " and " : ", ";
+                        }
+                        syns += "\'" + *sn + "\'";
+                    }
+                    sub_words += sub_words.empty() ? "" : ", ";
+                    sub_words += "allow '" + ((*it)->CanGetWord() ? (*it)->GetWord() : "") + "' to be replaced by " + syns;
+                    if ((*it)->GetCase_sensitive()) sub_words += ", case-sensitive";
+                    if ((*it)->GetWhole_word()) sub_words += ", whole word";
+                }
+            }
+        }
+        string params;
+        params += cons.GetCase_sensitive() ? "case-sensitive" : kEmptyStr;
+        params += cons.GetWhole_word() ? params.empty() ? "whole word" : ", whole word" : kEmptyStr;
+        params += cons.GetIgnore_space() ? params.empty() ? "ignore spaces" : ", ignore spaces" : kEmptyStr;
+        params += cons.GetIgnore_punct() ? params.empty() ? "ignore punctuation" : ", ignore punctuation" : kEmptyStr;
+        params += cons.GetIgnore_weasel() ? params.empty() ? "ignore \'putative\' synonyms" : ", ignore \'putative\' synonyms" : kEmptyStr;
+
+        string str = loc_word + " '" + cons.GetMatch_text() + "'";
+        str += params.empty() ? kEmptyStr : " (" + params + ")";
+        str += cons.GetIs_all_caps() ? ", all letters are uppercase" : kEmptyStr;
+        str += cons.GetIs_all_lower() ? ", all letters are lowercase" : kEmptyStr;
+        str += cons.GetIs_all_punct() ? ", all characters are punctuation" : kEmptyStr;
+        return str;
+    }
+    return kEmptyStr;
+}
+
+
+string CSuspect_rule::SummarizeSearchFunc(const CSearch_func& func) const
+{
+    string summ;
+    switch (func.Which()) {
+        case CSearch_func::e_String_constraint:
+            return SummarizeStringConstraint(func.GetString_constraint());
+        case CSearch_func::e_Contains_plural:
+            return "may contain plural";
+        case CSearch_func::e_N_or_more_brackets_or_parentheses:
+            return "contains " + NStr::IntToString(func.GetN_or_more_brackets_or_parentheses()) + " or more brackets or parentheses";
+        case CSearch_func::e_Three_numbers:
+            return "Three or more numbers together";
+        case CSearch_func::e_Underscore:
+            return "contains underscore";
+        case CSearch_func::e_Prefix_and_numbers:
+            return "is '" + func.GetPrefix_and_numbers() + "' followed by numbers";
+        case CSearch_func::e_All_caps:
+            return "is all capital letters";
+        case CSearch_func::e_Unbalanced_paren:
+            return "contains unbalanced brackets or parentheses";
+        case CSearch_func::e_Too_long:
+            return "is longer than " + NStr::IntToString(func.GetToo_long()) + " characters";
+        case CSearch_func::e_Has_term:
+            //if (short_version) summ = "contains " + strtmp;
+            return "contains \'" + func.GetHas_term() + "\' at start or separated from other letters by numbers, spaces, or punctuation, but does not also contain 'domain'";
+    }
+    return "Unknown search function";
+}
+
+
+string CSuspect_rule::SummarizeEndDistance(const CLocation_pos_constraint& pos) const
+{
+    switch (pos.Which()) {
+        case CLocation_pos_constraint::e_Dist_from_end:
+            return "exactly " + NStr::IntToString(pos.GetDist_from_end());
+        case CLocation_pos_constraint::e_Max_dist_from_end:
+            return "no more than " + NStr::IntToString(pos.GetMax_dist_from_end());
+        case CLocation_pos_constraint::e_Min_dist_from_end:
+            return "no less than " + NStr::IntToString(pos.GetMin_dist_from_end());
+    }
+    return kEmptyStr;
+}
+
+
+string CSuspect_rule::SummarizeLocationConstraint(const CLocation_constraint& loc) const
+{
+    string partial;
+    EPartial_constraint partial5 = loc.GetPartial5();
+    EPartial_constraint partial3 = loc.GetPartial3();
+    if (partial5 == ePartial_constraint_either && partial3 != ePartial_constraint_either) {
+        partial = partial3 == ePartial_constraint_partial ? " that are 3\' partial" : " that are 3\' complete";
+    }
+    else if (partial3 == ePartial_constraint_either && partial5 != ePartial_constraint_either) {
+        partial = partial5 == ePartial_constraint_partial ? " that are 5\' partial" : " that are 5\' complete";
+    }
+    else if (partial5 == ePartial_constraint_partial && partial3 == ePartial_constraint_partial) {
+        partial = " that are partial on both ends";
+    }
+    else if (partial5 == ePartial_constraint_complete && partial3 == ePartial_constraint_complete) {
+        partial = " that are complete on both ends";
+    }
+    else if (partial5 == ePartial_constraint_complete && partial3 == ePartial_constraint_partial) {
+        partial = " that are 5' complete and 3' partial";
+    }
+    else if (partial5 == ePartial_constraint_partial && partial3 == ePartial_constraint_complete) {
+        partial = " that are 5' partial and 3' complete";
+    }
+    string location_type;
+    if (loc.GetLocation_type() == eLocation_type_constraint_single_interval) {
+        location_type = " with single interval";
+    }
+    else if (loc.GetLocation_type() == eLocation_type_constraint_joined) {
+        location_type = " with joined intervals";
+    }
+    else if (loc.GetLocation_type() == eLocation_type_constraint_ordered) {
+        location_type = " with ordered intervals";
+    }
+    string dist5;
+    if (loc.CanGetEnd5()) {
+        dist5 = SummarizeEndDistance(loc.GetEnd5());
+        dist5 = dist5.empty() ? dist5 : " with 5\' end " + dist5;
+    }
+    string dist3;
+    if (loc.CanGetEnd3()) {
+        dist3 = SummarizeEndDistance(loc.GetEnd3());
+        dist3 = dist3.empty() ? dist3 : " with 3\' end " + dist3;
+    }
+    string seq_word;
+    if (loc.GetSeq_type() == eSeqtype_constraint_nuc) {
+        seq_word = "nucleotide sequences"; 
+    }
+    else if (loc.GetSeq_type() == eSeqtype_constraint_prot) {
+        seq_word = "protein sequences"; 
+    }
+    string strand;
+    if (loc.GetStrand() == eStrand_constraint_plus) {
+        strand = " on plus strands"; 
+    }
+    else if (loc.GetStrand() == eStrand_constraint_minus) {
+        strand = " on minus strands"; 
+    }
+    if (partial.empty() && location_type.empty() && dist5.empty() && dist3.empty() && seq_word.empty() && strand.empty()) {
+        return kEmptyStr;
+    }
+    string str = "only objects";
+
+    if (strand.empty() && !seq_word.empty()) {
+        str += " on " + seq_word;
+    }
+    else if (!strand.empty()) {
+        str += strand;
+        str += seq_word.empty() ? kEmptyStr : " of " + seq_word;
+    }
+    str += partial;
+    str += location_type;
+    str += dist5;
+    str += dist3;
+    return str;
+}
+
+
+string CSuspect_rule::SummarizeFieldType(const CField_type& vnp) const
+{
+    string str = "Invalid field type";
+    switch (vnp.Which()) {
+        case CField_type::e_not_set: return "missing field";
+        case CField_type::e_Source_qual:
+return "e_Source_qual";
+            //return SummarizeSourceQual (vnp.GetSource_qual());
+        case CField_type::e_Feature_field:
+            {
+                const CFeature_field& ff = vnp.GetFeature_field();
+                if (ff.GetField().Which() == CFeat_qual_choice::e_not_set) {
+                    return "missing field";
+                }
+                else {
+                    string label = ENUM_METHOD_NAME(EMacro_feature_type)()->FindName(ff.GetType(), false);
+                    //string label = thisInfo.feattype_name[ff.GetType()];
+                    //if (label.empty()) {
+                    //    return "Unknown feature";
+                    //}
+                    //else str = FeatureFieldLabel (label, ff.GetField());
+                    return label.empty() ? "Unknown feature" : label;
+                }
+
+            }
+        case CField_type::e_Cds_gene_prot:
+return "e_Cds_gene_prot";
+	        //str = thisInfo.cgp_field_name[vnp.GetCds_gene_prot()];
+            //if (str.empty()) str = "Invalid CDS-Gene-Prot Field";
+        case CField_type::e_Molinfo_field:
+return "e_Molinfo_field";
+            //str = GetSequenceQualName (vnp.GetMolinfo_field());
+            //if (str.empty()) str = "Invalid Sequence Qual Field";
+        case CField_type::e_Pub:
+return "e_Pub";
+            //str = thisInfo.pubfield_label[vnp.GetPub()];
+            //if (str.empty()) str = "Invalid field type";
+        case CField_type::e_Rna_field:
+return "e_Rna_field";
+            //str = SummarizeRnaQual (vnp.GetRna_field());
+        case CField_type::e_Struc_comment_field:
+return "e_Struc_comment_field";
+            //str = SummarizeStructuredCommentField (vnp.GetStruc_comment_field());
+        case CField_type::e_Dblink:
+return "e_Dblink";
+            //str = thisInfo.dblink_names[(int)vnp.GetDblink()];
+        case CField_type::e_Misc:
+return "e_Misc";
+            //str = thisInfo.miscfield_names[(int)vnp.GetMisc()];
+    }
+    return str;
+}
+
+
+string CSuspect_rule::SummarizeFieldConstraint(const CField_constraint& field) const
+{
+    string summ = SummarizeStringConstraint(field.GetString_constraint());
+    string label = SummarizeFieldType(field.GetField());
+    return summ.empty() || label.empty() ? kEmptyStr : "where " + label + " " + summ;
+}
+
+
+string CSuspect_rule::SummarizeSourceConstraint(const CSource_constraint& cons) const
+{
+        return kEmptyStr;
+}
+
+
+string CSuspect_rule::SummarizeConstraint(const CConstraint_choice& choice) const
+{
+    switch (choice.Which()) {
+        case CConstraint_choice::e_String:
+            {   string tmp = SummarizeStringConstraint(choice.GetString());
+                return tmp.empty() ? kEmptyStr : "where object text " + tmp;
+            }
+        case CConstraint_choice::e_Location:
+            return SummarizeLocationConstraint(choice.GetLocation()) + " [[LOCATION CONSTRAINT]]";
+        case CConstraint_choice::e_Source:
+            return SummarizeSourceConstraint (choice.GetSource()) + " [[SOURCE CONSTRAINT]]";
+        case CConstraint_choice::e_Cdsgeneprot_qual:
+            //phrase = SummarizeCDSGeneProtQualConstraint (cons_choice.GetCdsgeneprot_qual());
+            return "[[CDS Gene Prot QUAL CONSTRAINT]]";
+        case CConstraint_choice::e_Cdsgeneprot_pseudo:
+            return "[[CDS Gene Prot PSEUDO CONSTRAINT]]";
+            //phrase = SummarizeCDSGeneProtPseudoConstraint (cons_choice.GetCdsgeneprot_pseudo());
+        case CConstraint_choice::e_Sequence:
+            return "[[SEQUENCE CONSTRAINT]]";
+            //phrase = SummarizeSequenceConstraint (cons_choice.GetSequence());
+        case CConstraint_choice::e_Pub:
+            return "[[PUB CONSTRAINT]]";
+            //phrase = SummarizePublicationConstraint (cons_choice.GetPub());
+        case CConstraint_choice::e_Field:
+            return SummarizeFieldConstraint(choice.GetField());
+        case CConstraint_choice::e_Molinfo:
+            return "[[MOLINFO CONSTRAINT]]";
+            //phrase = SummarizeMolinfoFieldConstraint (cons_choice.GetMolinfo());
+        case CConstraint_choice::e_Field_missing:
+            return "[[FIELD MISSING CONSTRAINT]]";
+            //phrase = SummarizeMissingFieldConstraint (cons_choice.GetField_missing());
+        case CConstraint_choice::e_Translation:
+            return "[[TRANSLATION CONSTRAINT]]";
+            //phrase = SummarizeTranslationConstraint (cons_choice.GetTranslation());
+            break;
+    }
+    return kEmptyStr;
+}
+
+
+string CSuspect_rule::SummarizeConstraintSet(const CConstraint_choice_set& cons) const
+{
+    string str;
+    ITERATE (list<CRef<CConstraint_choice> >, it, cons.Get()) {
+        string tmp = SummarizeConstraint(**it);
+        str += tmp.empty() || str.empty() ? kEmptyStr : " and ";
+        str += tmp;
+    }
+    return str;
+}
+
+
+string CSuspect_rule::GetRuleTypeName() const
+{
+    static const char* rule_type[] = {
+        "None",
+        "Typo",
+        "Putative Typo",
+        "Quick fix",
+        "Organelles not appropriate in prokaryote",
+        "Suspicious phrase; should this be nonfunctional?",
+        "May contain database identifier more appropriate in note; remove from product name",
+        "Remove organism from product name",
+        "Possible parsing error or incorrect formatting; remove inappropriate symbols",
+        "Implies evolutionary relationship; change to -like protein",
+        "Consider adding 'protein' to the end of the product name",
+        "Correct the name or use 'hypothetical protein'",
+        "Use American spelling",
+        "Use short product name instead of descriptive phrase",
+        "use protein instead of gene as appropriate"
+    };
+    return rule_type[GetRule_type()];
+}
+
+
+string CSuspect_rule::SummarizeRule() const
+{
+    string type = GetRuleTypeName();
+    string descr = IsSetDescription() ? GetDescription() : kEmptyStr;
+    string find = SummarizeSearchFunc(GetFind());
+    string except = CanGetExcept() ? SummarizeSearchFunc(GetExcept()) : kEmptyStr;
+    string replace = CanGetReplace() ? SummarizeReplaceRule(GetReplace()) : kEmptyStr;
+    string feat_constraint = CanGetFeat_constraint() ? SummarizeConstraintSet(GetFeat_constraint()) : kEmptyStr;
+
+    string out = find;
+    if (!except.empty()) out += " but not " + except;
+    if (!feat_constraint.empty()) out += ", " + feat_constraint;
+    if (!replace.empty()) out += ", " + replace;
+    if (!type.empty()) out += " (" + type + ")";
+    if (!descr.empty()) out += " Description: " + descr;
+    return out;
+
+// debug output
+/*
+    string out = "Type: " + GetRuleTypeName();
+    out += descr.empty() ? kEmptyStr : "\n\t\tDescr: " + descr;
+    out += find.empty() ? kEmptyStr : "\n\t\tFind: " + find;
+    out += except.empty() ? kEmptyStr : "\n\t\tExcept: " + except;
+    out += feat_constraint.empty() ? kEmptyStr : "\n\t\tFeat-Constr: " + feat_constraint;
+    out += replace.empty() ? kEmptyStr : "\n\t\tReplace: " + replace;
+    return out;
+*/
+}
+
+
+END_objects_SCOPE // namespace ncbi::objects::
+END_NCBI_SCOPE
diff --git a/c++/src/objects/macro/product_rules.inc b/c++/src/objects/macro/product_rules.inc
index a5ee216..d4b53f1 100644
--- a/c++/src/objects/macro/product_rules.inc
+++ b/c++/src/objects/macro/product_rules.inc
@@ -1,4 +1,4 @@
-/*  $Id: product_rules.inc 425423 2014-01-29 13:53:42Z bollin $
+/*  $Id: product_rules.inc 507924 2016-07-22 15:32:29Z kachalos $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -23,10 +23,10 @@
  *
  * ===========================================================================
  *
- * Author:  Jonathan Kans et al.
+ * Author:  NCBI developers
  *
  * File Description:
- *   Built-in copy of product_rules.txt.
+ *   Built-in copy of product_rules.prt.
  *
  */
 
@@ -34,74 +34,147 @@ static const char* const s_Defaultproductrules[] = {
     "Suspect-rule-set ::= {",
     "  {",
     "    find",
+    "      contains-plural NULL ,",
+    "    rule-type putative-typo ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      three-numbers NULL ,",
+    "    except",
     "      string-constraint {",
-    "        match-text \" citochrome\" ,",
+    "        match-text \"methyltransferas\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            word \"methyltransferas\" ,",
+    "            synonyms {",
+    "              \"F420\" ,",
+    "              \"FK506\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word FALSE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"cytochrome\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"16S rRNA pseudouridine(516) synthase\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \" 23S rRNA pseudouridine(955/2504/2580) synthase\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"23S rRNA pseudouridine(1911/1915/1917) synthase\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type database ,",
+    "    description \"contains three or more numbers together that may be",
+    " identifiers more appropriate in note\" ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
-    "      string-constraint {",
-    "        match-text \" cytochome\" ,",
+    "      all-caps NULL ,",
+    "    rule-type putative-typo ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      unbalanced-paren NULL ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      too-long 100 ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"multifunctional\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"cytochrome\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \" cytochorme\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"bifunctional\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"cytochrome\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"acetylglucosamine\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type description ,",
+    "    description \"Is longer than 100 characters. Remove descriptive phrases or",
+    " synonyms from product names. Keep valid long product names, eg long enzyme",
+    " names\" ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"accessroy\" ,",
+    "        match-text \" Anopheles\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -111,19 +184,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"accessory\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"aceytltranferase\" ,",
+    "        match-text \" citochrome\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -133,19 +209,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"acetyltransferase\" ,",
+    "          replace \"cytochrome\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"adenylattransferase\" ,",
+    "        match-text \" cytochome\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -155,19 +234,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"adenylate transferase\" ,",
+    "          replace \"cytochrome\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"adenylytransferase\" ,",
+    "        match-text \" cytochorme\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -177,107 +259,94 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"adenylyltransferase\" ,",
+    "          replace \"cytochrome\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"alchohol\" ,",
+    "        match-text \"#\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"alcohol\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"aminomutaseaminotransferase\" ,",
+    "        match-text \"%\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"aminomutase aminotransferase\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"aminotransferasee\" ,",
+    "        match-text \"&apos\" ,",
     "        match-location contains ,",
-    "        case-sensitive FALSE ,",
+    "        case-sensitive TRUE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"aminotransferase\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type database ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"aminotransferease\" ,",
-    "        match-location contains ,",
+    "        match-text \"'\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"aminotransferase\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"aparaginase\" ,",
+    "        match-text \"()\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -287,64 +356,52 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"asparaginase\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"archael\" ,",
+    "        match-text \"(TC \" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"archaeal\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type database ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"arginin \" ,",
-    "        match-location contains ,",
+    "        match-text \",\" ,",
+    "        match-location ends ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"arginine \" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"argininte\" ,",
-    "        match-location contains ,",
+    "        match-text \",\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -353,20 +410,16 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"arginine\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"asparate\" ,",
-    "        match-location contains ,",
+    "        match-text \"-\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -375,64 +428,52 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"aspartate\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"assemby\" ,",
-    "        match-location contains ,",
+    "        match-text \"-\" ,",
+    "        match-location ends ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"assembly\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"assessory\" ,",
-    "        match-location contains ,",
+    "        match-text \".\" ,",
+    "        match-location ends ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"accessory\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"bifunctionnal\" ,",
-    "        match-location contains ,",
+    "        match-text \".\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -441,19 +482,15 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"bifunctional\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"bigenesis\" ,",
+    "        match-text \". \" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -463,43 +500,35 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"biogenesis\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"bioin\" ,",
+    "        match-text \".,\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"biotin\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"biosyntesis\" ,",
+    "        match-text \"./\" ,",
     "        match-location contains ,",
-    "        case-sensitive FALSE ,",
+    "        case-sensitive TRUE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
@@ -507,20 +536,16 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"biosynthesis\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"biosythesis\" ,",
-    "        match-location contains ,",
+    "        match-text \"/\" ,",
+    "        match-location ends ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -529,64 +554,90 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"biosynthesis\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"bnding\" ,",
-    "        match-location contains ,",
+    "        match-text \"16S ribosomal RNA\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            word \"16S\" ,",
+    "            synonyms {",
+    "              \"18S\" ,",
+    "              \"28S\" ,",
+    "              \"5S\" ,",
+    "              \"5.8S\" ,",
+    "              \"23S\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"binding\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    description \"equals ribosomal RNA\" ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"calchone\" ,",
-    "        match-location contains ,",
+    "        match-text \"16S rRNA\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            word \"16S\" ,",
+    "            synonyms {",
+    "              \"18S\" ,",
+    "              \"28S\" ,",
+    "              \"5S\" ,",
+    "              \"5.8S\" ,",
+    "              \"23S\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"chalcone\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    description \"equals rRNA\" ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"candidate\" ,",
-    "        match-location starts ,",
+    "        match-text \":\" ,",
+    "        match-location ends ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -595,34 +646,35 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"candidate protein\" ,",
-    "        match-location equals ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \":\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"carboxilic\" ,",
+    "        match-text \";\" ,",
     "        match-location contains ,",
-    "        case-sensitive FALSE ,",
+    "        case-sensitive TRUE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
@@ -630,19 +682,15 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"carboxylic\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"cell divisionFtsK/SpoIIIE\" ,",
+    "        match-text \"=\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -652,19 +700,15 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"cell division FtsK/SpoIIIE\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"characteris\" ,",
+    "        match-text \"?\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -674,21 +718,17 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"characteriz\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"charateriz\" ,",
+    "        match-text \"@\" ,",
     "        match-location contains ,",
-    "        case-sensitive FALSE ,",
+    "        case-sensitive TRUE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
@@ -696,85 +736,83 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"characteriz\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"CHC2 zinc finger\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
+    "        match-text \"a \" ,",
+    "        match-location starts ,",
+    "        case-sensitive TRUE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"CHC2 zinc finger protein\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative TRUE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"chelatin\" ,",
-    "        match-location contains ,",
+    "        match-text \"ABC-type polysaccharide\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"chelating\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"chroamtid\" ,",
+    "        match-text \"accessroy\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"chromatid\" ,",
+    "          replace \"accessory\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"coantaining\" ,",
+    "        match-text \"aceytltranferase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -784,41 +822,55 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"containing\" ,",
+    "          replace \"acetyltransferase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"coenzye\" ,",
-    "        match-location contains ,",
+    "        match-text \"adenine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"coenzyme\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"compnent\" ,",
+    "        match-text \"adenylattransferase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -828,19 +880,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"component\" ,",
+    "          replace \"adenylate transferase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"componenet\" ,",
+    "        match-text \"adenylytransferase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -850,20 +905,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"component\" ,",
+    "          replace \"adenylyltransferase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"componnent\" ,",
-    "        match-location contains ,",
+    "        match-text \"ADP\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -872,108 +930,131 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"component\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserv\" ,",
+    "        match-text \"Agrobacterium\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"conserved\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Conservd\" ,",
-    "        match-location contains ,",
+    "        match-text \"Alanine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"conserved\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"consevered\" ,",
+    "        match-text \"alchohol\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"conserved\" ,",
+    "          replace \"alcohol\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"contain\" ,",
-    "        match-location contains ,",
+    "        match-text \"alpha\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"containing\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"containg\" ,",
-    "        match-location contains ,",
+    "        match-text \"alpha-1\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -982,41 +1063,40 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"containing\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"containinging\" ,",
+    "        match-text \"alternate gene name\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"containing\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"converved\" ,",
+    "        match-text \"alternate name\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1026,41 +1106,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"conserved\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"coserved\" ,",
-    "        match-location contains ,",
+    "        match-text \"alternate protein name\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"conserved\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"cotaining\" ,",
+    "        match-text \"alternate protein name\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1070,19 +1157,30 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"containing\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"alternative protein name\" ,",
+    "        match-location equals ,",
+    "        case-sensitive TRUE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"degration\" ,",
+    "        match-text \"aluminium\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1092,41 +1190,55 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"degradation\" ,",
+    "          replace \"aluminum\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"dependant\" ,",
-    "        match-location contains ,",
+    "        match-text \"amino acid\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"dependent\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"deulfurase\" ,",
+    "        match-text \"aminomutaseaminotransferase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1136,19 +1248,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"desulfurase\" ,",
+    "          replace \"aminomutase aminotransferase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"deydrogenase\" ,",
+    "        match-text \"aminotransferasee\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1158,19 +1273,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"dehydrogenase\" ,",
+    "          replace \"aminotransferase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"diacyglycerol\" ,",
+    "        match-text \"aminotransferease\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1180,64 +1298,66 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"diacylglycerol\" ,",
+    "          replace \"aminotransferase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"dioxyenase\" ,",
+    "        match-text \"aminotransferease\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"dioxygenase\" ,",
+    "          replace \"aminotransferase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"disulphide\" ,",
+    "        match-text \"analog\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"disulfide\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type evolutionary-relationship ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"divison\" ,",
-    "        match-location contains ,",
+    "        match-text \"and related enzyme\" ,",
+    "        match-location ends ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -1246,42 +1366,46 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"division\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domain domain\" ,",
-    "        match-location contains ,",
+    "        match-text \"and related enzymes\" ,",
+    "        match-location ends ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"domain\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domain of unknown function\" ,",
-    "        match-location starts ,",
+    "        match-text \"and related protein\" ,",
+    "        match-location ends ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -1290,78 +1414,45 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"domain of unknown function\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "      string {",
-    "        match-text \"domain of unknown function family protein\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "      string {",
-    "        match-text \"domain of unknown function protein\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein of unknown function\" ,",
     "          whole-string FALSE ,",
-    "          weasel-to-putative TRUE } ,",
-    "      move-to-note FALSE } } ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domain protein domain protein\" ,",
-    "        match-location contains ,",
+    "        match-text \"and related proteins\" ,",
+    "        match-location ends ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"domain protein\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domainl\" ,",
+    "        match-text \"animal\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1371,20 +1462,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"domain\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domian\" ,",
-    "        match-location contains ,",
+    "        match-text \"anion\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -1393,19 +1487,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"domain\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"dyhydrogenase\" ,",
+    "        match-text \"aparaginase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1415,42 +1512,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"dehydrogenase\" ,",
+    "          replace \"asparaginase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"dyhydrogenase\" ,",
+    "        match-text \"Arabidopsis\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"dihydrogenase\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"enentioselective\" ,",
-    "        match-location contains ,",
+    "        match-text \"Archaeal\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -1459,41 +1562,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"enantioselective\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"enzymye\" ,",
+    "        match-text \"archael\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"enzyme\" ,",
+    "          replace \"archaeal\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ErfKYbiSYcfSYnhG\" ,",
+    "        match-text \"arginin \" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1503,41 +1612,55 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"ErfK/YbiS/YcfS/YnhG\" ,",
+    "          replace \"arginine \" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"exporte\" ,",
-    "        match-location contains ,",
+    "        match-text \"Arginine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"exported\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"facotr\" ,",
+    "        match-text \"argininte\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1547,86 +1670,114 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"factor\" ,",
+    "          replace \"arginine\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"fagella\" ,",
-    "        match-location contains ,",
+    "        match-text \"Asparagine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"flagella\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"familie\" ,",
+    "        match-text \"asparate\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"family\" ,",
+    "          replace \"aspartate\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"family family\" ,",
-    "        match-location contains ,",
+    "        match-text \"Aspartic acid\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"family\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"flageller\" ,",
-    "        match-location contains ,",
+    "        match-text \"aspartyl\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -1635,107 +1786,130 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"flagellar\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"gIycerol\" ,",
+    "        match-text \"Aspergillus\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"glycerol\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"glcosyl\" ,",
+    "        match-text \"assemby\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"glycosyl\" ,",
+    "          replace \"assembly\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"glucosainyl\" ,",
+    "        match-text \"assessory\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"glucosaminyl\" ,",
+    "          replace \"accessory\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"glutaminne\" ,",
-    "        match-location contains ,",
+    "        match-text \"ATP\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"glutamine\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"glycin\" ,",
+    "        match-text \"ATPas\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1745,19 +1919,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"glycine\" ,",
+    "          replace \"ATPase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"glycosy\" ,",
+    "        match-text \"aureus\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1767,19 +1944,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"glucosyl\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"heam\" ,",
+    "        match-text \"authentic point mutation\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1789,16 +1969,15 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        haem-replace \"haem\" ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal TRUE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"heavychain\" ,",
+    "        match-text \"B.subtilis\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1808,49 +1987,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"heavy chain\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"helix-turn-helix\" ,",
-    "        match-location equals ,",
+    "        match-text \"Bacilllus\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"helix-turn-helix protein\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative TRUE } ,",
-    "      move-to-note FALSE } } ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hemaggltinin\" ,",
+    "        match-text \"Bacillus\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1860,19 +2037,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hemagglutinin\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hemelysin\" ,",
+    "        match-text \"Bacterioides\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -1882,130 +2062,164 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hemolysin\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hemoglobine\" ,",
-    "        match-location contains ,",
+    "        match-text \"bacteriophage\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hemoglobin\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hexapaptide\" ,",
+    "        match-text \"Bacteroides\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hexapeptide\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hexpeptide\" ,",
-    "        match-location contains ,",
+    "        match-text \"barrel\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hexapeptide\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"histadine\" ,",
-    "        match-location contains ,",
+    "        match-text \"believed\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"histidine\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"histide\" ,",
+    "        match-text \"bifuctional\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"histidine\" ,",
+    "          replace \"bifunctional\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"homeserine\" ,",
-    "        match-location contains ,",
+    "        match-text \"bifunctional\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -2014,107 +2228,122 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"homoserine\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"homlog\" ,",
+    "        match-text \"bifunctionnal\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"homolog\" ,",
+    "          replace \"bifunctional\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"homocystein\" ,",
+    "        match-text \"bigenesis\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"homocysteine\" ,",
+    "          replace \"biogenesis\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hpothetical\" ,",
-    "        match-location contains ,",
+    "        match-text \"binds\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hydrolases of the alpha/beta superfamily\" ,",
-    "        match-location equals ,",
+    "        match-text \"bioin\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hydrolase of the alpha/beta superfamily\" ,",
+    "          replace \"biotin\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hyopothetical\" ,",
+    "        match-text \"biosyntesis\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -2124,19 +2353,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"biosynthesis\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hyopthetical\" ,",
+    "        match-text \"biosythesis\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -2146,20 +2378,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"biosynthesis\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hyothetical\" ,",
-    "        match-location contains ,",
+    "        match-text \"bis\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -2168,19 +2403,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hyperthetical\" ,",
+    "        match-text \"bnding\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -2190,41 +2428,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"binding\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hyphotetical\" ,",
+    "        match-text \"Bombyx\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hyphotheical\" ,",
+    "        match-text \"bos taurus\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -2234,20 +2478,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypohetical\" ,",
-    "        match-location contains ,",
+    "        match-text \"c-terminal domain protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -2256,64 +2503,73 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypot\" ,",
-    "        match-location contains ,",
+    "        match-text \"C-terminus\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypotehtical\" ,",
+    "        match-text \"calchone\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"chalcone\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypotethical\" ,",
-    "        match-location contains ,",
+    "        match-text \"Calcium\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -2322,41 +2578,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypotetical\" ,",
+    "        match-text \"Campylobacter\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypoth\" ,",
+    "        match-text \"Candida\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -2366,63 +2628,95 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypothe\" ,",
-    "        match-location contains ,",
+    "        match-text \"candidate\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"candidate protein\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"putative\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypotheical\" ,",
-    "        match-location contains ,",
+    "        match-text \"carbon\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypotheitcal\" ,",
+    "        match-text \"carboxilic\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -2432,63 +2726,90 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"carboxylic\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypotherical\" ,",
+    "        match-text \"catalize\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"catalyze\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypothet\" ,",
-    "        match-location contains ,",
+    "        match-text \"CBS domain pair\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypothetcial\" ,",
+    "        match-text \"CDS\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"cell divisionFtsK/SpoIIIE\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -2498,291 +2819,273 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"cell division FtsK/SpoIIIE\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypothethical\" ,",
+    "        match-text \"cerevisiae\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypotheti\" ,",
-    "        match-location contains ,",
+    "        match-text \"Changed start to match that seen in other orgs\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypothetic\" ,",
-    "        match-location contains ,",
+    "        match-text \"Changed start to match that seen in other orgs\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypothetica\" ,",
+    "        match-text \"characteris\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"characteriz\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypothetical\" ,",
-    "        match-location starts ,",
+    "        match-text \"charateriz\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"hypothetical protein\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"characteriz\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"CHC2 zinc finger\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "      string {",
-    "        match-text \"hypothetical domain protein\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "      string {",
-    "        match-text \"hypothetical ORF\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "      string {",
-    "        match-text \"hypothetical\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "      string {",
-    "        match-text \"Hypothetical conserved protein\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "      string {",
-    "        match-text \"hypothetical protein\" ,",
-    "        match-location starts ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"CHC2 zinc finger protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative TRUE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"chelatin\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word TRUE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "      string {",
-    "        match-text \"UPF\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            word \"UPF\" ,",
-    "            synonyms {",
-    "              \"UCP\" ,",
-    "              \"DUF\" ,",
-    "              \"PUF\" ,",
-    "              \"CHP\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word FALSE } } ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
+    "          replace \"chelating\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypotheticalprotein\" ,",
+    "        match-text \"Chlamydial\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
-    "          whole-string FALSE ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypothteical\" ,",
+    "        match-text \"Chlamydomonas\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypothtical\" ,",
+    "        match-text \"chlorAMPhenicol\" ,",
     "        match-location contains ,",
-    "        case-sensitive FALSE ,",
+    "        case-sensitive TRUE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"chloramphenicol \" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypthetical\" ,",
-    "        match-location contains ,",
+    "        match-text \"chloroplastic\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -2791,86 +3094,106 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hyptothetical\" ,",
+    "        match-text \"chroamtid\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"chromatid\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hyputhetical\" ,",
-    "        match-location contains ,",
+    "        match-text \"citrate\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"incolved\" ,",
+    "        match-text \"claster\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"involved\" ,",
+    "          replace \"cluster\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"inductible\" ,",
-    "        match-location contains ,",
+    "        match-text \"clustered with\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -2879,19 +3202,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"inducible\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"initation\" ,",
+    "        match-text \"coantaining\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -2901,64 +3227,63 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"initiation\" ,",
+    "          replace \"containing\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"insitol\" ,",
+    "        match-text \"coenzye\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"inositol\" ,",
+    "          replace \"coenzyme\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Intiation\" ,",
+    "        match-text \"COG\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"initiation\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    except",
     "      string-constraint {",
-    "        match-text \"invertion\" ,",
-    "        match-location contains ,",
+    "        match-text \"COG\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -2967,19 +3292,15 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"inversion\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type database ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"IS ORF\" ,",
+    "        match-text \"COG\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -2989,19 +3310,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"IS protein\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative TRUE } ,",
-    "      move-to-note FALSE } } ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"isomaerase\" ,",
+    "        match-text \"COGnitor\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3011,63 +3335,55 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"isomerase\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"isomerse\" ,",
+    "        match-text \"coli\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"isomerase\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"K potassium\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"adenomatous polyposis coli \" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"potassium\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"K+ potassium\" ,",
+    "        match-text \"colour\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3077,41 +3393,40 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"potassium\" ,",
+    "          replace \"color\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mambrane\" ,",
+    "        match-text \"complete\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"membrane\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"meausure\" ,",
+    "        match-text \"compnent\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3121,41 +3436,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"measure\" ,",
+    "          replace \"component\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"medated\" ,",
+    "        match-text \"componenet\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"mediated\" ,",
+    "          replace \"component\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"membraneprotein\" ,",
+    "        match-text \"componnent\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3165,63 +3486,80 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"membrane protein\" ,",
+    "          replace \"component\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"membranetransport\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
+    "        match-text \"conser\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"membrane transport\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"membranne\" ,",
+    "        match-text \"conserv\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"membrane\" ,",
+    "          replace \"conserved\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"membtrane\" ,",
+    "        match-text \"Conservd\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3231,64 +3569,89 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"membrane\" ,",
+    "          replace \"conserved\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"memebrane\" ,",
-    "        match-location contains ,",
+    "        match-text \"conserve\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"membrane\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"methlytransferase\" ,",
-    "        match-location contains ,",
+    "        match-text \"conserved\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"methyltransferase\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"metylase\" ,",
-    "        match-location contains ,",
+    "        match-text \"conserved domain protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -3297,42 +3660,56 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"methylase\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mitchondrial\" ,",
-    "        match-location contains ,",
+    "        match-text \"conserved hypothetical\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"mitochondrial\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"molibdenum\" ,",
-    "        match-location contains ,",
+    "        match-text \"conserved hypothetical domain protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -3341,20 +3718,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"molybdenum\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"molybopterin\" ,",
-    "        match-location contains ,",
+    "        match-text \"conserved hypothetical family protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -3363,42 +3743,56 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"molybdopterin\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"molydopterin\" ,",
-    "        match-location contains ,",
+    "        match-text \"conserved hypothetical protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"molybdopterin\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"monooxigenase\" ,",
-    "        match-location contains ,",
+    "        match-text \"conserved predicted domain protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -3407,20 +3801,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"monooxygenase\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"monoxyde\" ,",
-    "        match-location contains ,",
+    "        match-text \"conserved predicted protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -3429,20 +3826,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"monoxide\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"monoxygenase\" ,",
-    "        match-location contains ,",
+    "        match-text \"conserved protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -3451,20 +3851,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"monooxygenase\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mulitdrug\" ,",
-    "        match-location contains ,",
+    "        match-text \"conserved protein of unknown function\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -3473,20 +3876,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"multidrug\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mulitfunction\" ,",
-    "        match-location contains ,",
+    "        match-text \"conserved putative protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -3495,42 +3901,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"multifunction\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mutatrotase\" ,",
-    "        match-location contains ,",
+    "        match-text \"Conserved subname: full\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"mutarotase\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mutlifunction\" ,",
-    "        match-location contains ,",
+    "        match-text \"Conserved with\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -3539,19 +3951,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"multifunction\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mypothetical\" ,",
+    "        match-text \"consevered\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3561,19 +3976,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"conserved\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mythylglyoxyl \" ,",
+    "        match-text \"contain\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3583,120 +4001,122 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"methylglyoxyl\" ,",
+    "          replace \"containing\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ncharacterized\" ,",
+    "        match-text \"containg\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"uncharacterized\" ,",
+    "          replace \"containing\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ndoribonuclease\" ,",
-    "        match-location contains ,",
+    "        match-text \"containing\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"endoribonuclease\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"nickle\" ,",
+    "        match-text \"containinging\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"nickel\" ,",
+    "          replace \"containing\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"novel\" ,",
+    "        match-text \"contains\" ,",
     "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"novel protein\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ntegral \" ,",
+    "        match-text \"contig\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3706,41 +4126,40 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"integral \" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"nucear\" ,",
+    "        match-text \"converved\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"nuclear\" ,",
+    "          replace \"conserved\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"nucelar\" ,",
+    "        match-text \"coserved\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3750,19 +4169,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"nuclear\" ,",
+    "          replace \"conserved\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"nucleotydyl\" ,",
+    "        match-text \"cotaining\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3772,19 +4194,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"nucleotidyl\" ,",
+    "          replace \"containing\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"nucletide\" ,",
+    "        match-text \"Critica\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3794,19 +4219,15 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"nucleotide\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"nulcear\" ,",
+    "        match-text \"Crystal Structure\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3816,129 +4237,139 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"nuclear\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"nulceotide\" ,",
-    "        match-location contains ,",
+    "        match-text \"CTP\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"nucleotide\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"obalt\" ,",
-    "        match-location contains ,",
+    "        match-text \"Cysteine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"cobalt\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"odule\" ,",
-    "        match-location contains ,",
+    "        match-text \"cytosine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"module\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Outative\" ,",
+    "        match-text \"database\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"outers\" ,",
-    "        match-location contains ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"no significant database hits\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"outer\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type database ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"oxidoreducatse\" ,",
+    "        match-text \"degration\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3948,41 +4379,40 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"oxidoreductase\" ,",
+    "          replace \"degradation\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"oxidoreductasee\" ,",
+    "        match-text \"deletion\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"oxidoreductase\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"oxidoreductasse\" ,",
+    "        match-text \"dependant\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -3992,64 +4422,73 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"oxidoreductase\" ,",
+    "          replace \"dependent\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"oxidoredutase\" ,",
+    "        match-text \"deulfurase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"oxidoreductase\" ,",
+    "          replace \"desulfurase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"oxidoreduxtase\" ,",
+    "        match-text \"deydrogenase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"oxidoreductase\" ,",
+    "          replace \"dehydrogenase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"oxigenase\" ,",
-    "        match-location contains ,",
+    "        match-text \"di\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -4058,101 +4497,97 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"oxygenase\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"oxydase\" ,",
+    "        match-text \"diacyglycerol\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"oxidase\" ,",
+    "          replace \"diacylglycerol\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"p-loop\" ,",
-    "        match-location equals ,",
+    "        match-text \"dimerisation\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"p-loop protein\" ,",
+    "          replace \"dimerization\" ,",
     "          whole-string FALSE ,",
-    "          weasel-to-putative TRUE } ,",
-    "      move-to-note FALSE } } ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"PASTA\" ,",
-    "        match-location equals ,",
+    "        match-text \"dimerising\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"PASTA protein\" ,",
+    "          replace \"dimerizing\" ,",
     "          whole-string FALSE ,",
-    "          weasel-to-putative TRUE } ,",
-    "      move-to-note FALSE } } ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"peptidodoglycan\" ,",
+    "        match-text \"dioxyenase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -4162,20 +4597,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"peptidoglycan\" ,",
+    "          replace \"dioxygenase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"periplamic\" ,",
-    "        match-location contains ,",
+    "        match-text \"dipeptide\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -4184,19 +4622,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"periplasmic\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"periplasmc\" ,",
+    "        match-text \"disulphide\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -4206,19 +4647,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"periplasmic\" ,",
+    "          replace \"disulfide\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"periplsmic\" ,",
+    "        match-text \"divison\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -4228,41 +4672,55 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"periplasmic\" ,",
+    "          replace \"division\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"petidase\" ,",
-    "        match-location contains ,",
+    "        match-text \"DNA\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"peptidase\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"pheremone\" ,",
+    "        match-text \"DNA for\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -4272,42 +4730,49 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"pheromone\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"phophate\" ,",
-    "        match-location contains ,",
+    "        match-text \"domain\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"phosphate\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"phopho\" ,",
-    "        match-location contains ,",
+    "        match-text \"domain 1\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -4316,108 +4781,182 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"phospho\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"phophoserine\" ,",
+    "        match-text \"domain domain\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"phosphoserine\" ,",
+    "          replace \"domain\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"phoshate\" ,",
-    "        match-location contains ,",
+    "        match-text \"domain family\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"phosphate\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"phospatase\" ,",
-    "        match-location contains ,",
+    "        match-text \"domain of unknown function\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"phosphatase\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"phosphateN\" ,",
-    "        match-location contains ,",
+    "        match-text \"domain of unknown function\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"domain of unknown function\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"domain of unknown function family protein\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"domain of unknown function protein\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"phosphate N\" ,",
+    "          replace \"protein of unknown function\" ,",
     "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "          weasel-to-putative TRUE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"phosphatidyltransferse\" ,",
-    "        match-location contains ,",
+    "        match-text \"domain of unknown function family protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -4426,20 +4965,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"phosphatidyltransferase\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"phosphatransferase\" ,",
-    "        match-location contains ,",
+    "        match-text \"domain of unknown function family protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -4448,42 +4990,56 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"phosphotransferase\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"phosphopantethiene\" ,",
-    "        match-location contains ,",
+    "        match-text \"domain of unknown function protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"phosphopantetheine\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"phosphotase\" ,",
-    "        match-location contains ,",
+    "        match-text \"domain protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -4492,42 +5048,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"phosphatase\" ,",
+    "          replace \"hypothetical protein\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"polimerase\" ,",
+    "        match-text \"domain protein domain protein\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"polymerase\" ,",
+    "          replace \"domain protein\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Portein\" ,",
-    "        match-location contains ,",
+    "        match-text \"domain-containing protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -4536,19 +5098,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"portein\" ,",
+    "        match-text \"domainl\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -4558,19 +5123,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
+    "          replace \"domain\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"posible\" ,",
+    "        match-text \"domian\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -4580,54 +5148,73 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"possible\" ,",
+    "          replace \"domain\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"possible\" ,",
-    "        match-location starts ,",
+    "        match-text \"doubtful\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"possible protein\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal TRUE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"doubtful CDS found within S. typhi pathogenicity island\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"poteasome\" ,",
+    "        match-text \"Drosophila\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -4637,20 +5224,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"proteasome\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"potential\" ,",
-    "        match-location starts ,",
+    "        match-text \"DUF\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -4659,145 +5249,130 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"potential protein\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    except",
+    "      string-constraint {",
+    "        match-text \"DUF\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type database ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"precurso\" ,",
-    "        match-location contains ,",
+    "        match-text \"DUF\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"precursor\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"precusor\" ,",
+    "        match-text \"dyhydrogenase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"precursor\" ,",
+    "          replace \"dihydrogenase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"predicted\" ,",
-    "        match-location starts ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"predicted protein\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "      string {",
-    "        match-text \"Predicted:\" ,",
-    "        match-location starts ,",
+    "        match-text \"dyhydrogenase\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
+    "          replace \"dehydrogenase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Predicted:\" ,",
-    "        match-location starts ,",
+    "        match-text \"E.coli\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"predictedprotein\" ,",
+    "        match-text \"ECOLI\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -4807,19 +5382,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"predicted protein\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"predictet\" ,",
+    "        match-text \"enentioselective\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -4829,41 +5407,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"predicted\" ,",
+    "          replace \"enantioselective\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"presursor\" ,",
+    "        match-text \"enterica\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"precursor\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"probabable\" ,",
+    "        match-text \"enzymye\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -4873,20 +5457,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"probable\" ,",
+    "          replace \"enzyme\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"probable\" ,",
-    "        match-location starts ,",
+    "        match-text \"ErfKYbiSYcfSYnhG\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -4895,55 +5482,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"probable protein\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
+    "          replace \"ErfK/YbiS/YcfS/YnhG\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"probable putative\" ,",
+    "        match-text \"Escherichia\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"proein\" ,",
-    "        match-location contains ,",
+    "        match-text \"EST\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -4952,76 +5532,108 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"proposed\" ,",
-    "        match-location starts ,",
+    "        match-text \"EST\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"proposed protein\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    except",
+    "      string-constraint {",
+    "        match-text \"EST\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type database ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"proptein\" ,",
+    "        match-text \"et al\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            word \"et al\" ,",
+    "            synonyms {",
+    "              \"unpublished\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } ,",
+    "          {",
+    "            word \"et al\" ,",
+    "            synonyms {",
+    "              \"citation\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } ,",
+    "          {",
+    "            word \"et al\" ,",
+    "            synonyms {",
+    "              \"published\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    except",
+    "      string-constraint {",
+    "        match-text \"resuscitation\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"protein\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type database ,",
+    "    description \"may contain publication reference\" ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"prortein\" ,",
+    "        match-text \"evidenced by\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -5031,19 +5643,15 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"protein\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protazoan\" ,",
+    "        match-text \"exporte\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -5053,42 +5661,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protozoan\" ,",
+    "          replace \"exported\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protei\" ,",
-    "        match-location contains ,",
+    "        match-text \"expressed\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protein protein\" ,",
-    "        match-location contains ,",
+    "        match-text \"expressed protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -5097,63 +5711,80 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"proteine\" ,",
+    "        match-text \"facotr\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
+    "          replace \"factor\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"proteinn\" ,",
-    "        match-location contains ,",
+    "        match-text \"factor\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"proten\" ,",
+    "        match-text \"faecal\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -5163,19 +5794,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
+    "          replace \"fecal\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protien\" ,",
+    "        match-text \"fagella\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -5185,41 +5819,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
+    "          replace \"flagella\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protrein\" ,",
+    "        match-text \"faimily\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
+    "          replace \"family\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protwin\" ,",
+    "        match-text \"faimly\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -5229,93 +5869,97 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
+    "          replace \"family\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"prptein\" ,",
+    "        match-text \"familie\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
+    "          replace \"family\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ptotein\" ,",
+    "        match-text \"familiy\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"protein\" ,",
+    "          replace \"family\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"PTS system\" ,",
+    "        match-text \"family\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"PTS system protein\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative TRUE } ,",
-    "      move-to-note FALSE } } ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"puataive\" ,",
+    "        match-text \"family family\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -5325,85 +5969,113 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
+    "          replace \"family\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"puatative\" ,",
-    "        match-location contains ,",
+    "        match-text \"family protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"puative\" ,",
+    "        match-text \"fibre\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
+    "          replace \"fiber\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putaitive\" ,",
-    "        match-location contains ,",
+    "        match-text \"finger\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putaitve\" ,",
+    "        match-text \"flageller\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -5413,63 +6085,65 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
+    "          replace \"flagellar\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putaive\" ,",
+    "        match-text \"FOG\" ,",
     "        match-location contains ,",
-    "        case-sensitive FALSE ,",
+    "        case-sensitive TRUE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type database ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putataive\" ,",
-    "        match-location contains ,",
+    "        match-text \"formly\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
+    "          replace \"formyl\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putatitve\" ,",
+    "        match-text \"Fragment\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -5479,33 +6153,31 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putative possible\" ,",
-    "        match-location starts ,",
+    "        match-text \"frame\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    feat-constraint {",
     "      string {",
-    "        match-text \"possible protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"frame shift\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -5514,20 +6186,16 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putative potential\" ,",
-    "        match-location starts ,",
+    "        match-text \"frame shift\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -5536,55 +6204,49 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"possible protein\" ,",
-    "        match-location equals ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"frameshift\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"putative potential\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"programmed frameshift\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putative predicted\" ,",
-    "        match-location contains ,",
+    "        match-text \"from\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -5593,99 +6255,91 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putative probable\" ,",
+    "        match-text \"funciton\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
+    "          replace \"function\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putative probable\" ,",
+    "        match-text \"function\" ,",
     "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"possible protein\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putative putative\" ,",
+    "        match-text \"fungi\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putative, putative\" ,",
-    "        match-location contains ,",
+    "        match-text \"g:t\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -5694,20 +6348,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putatuive\" ,",
-    "        match-location contains ,",
+    "        match-text \"galactose\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -5716,19 +6373,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putatuve\" ,",
+    "        match-text \"gambiae\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -5738,217 +6398,188 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putatve\" ,",
+    "        match-text \"gene\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type gene ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putatvie\" ,",
+    "        match-text \"genes\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type gene ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putayive\" ,",
+    "        match-text \"genome\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"puter\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"outer\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"putitative\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"genome instability\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"putitive\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"genome maintenance\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"puttive\" ,",
-    "        match-location contains ,",
+    "        match-text \"ggdef\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"pyradoxal\" ,",
+    "        match-text \"Giardia\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"pyridoxal\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"pyruvyltransferase\" ,",
+    "        match-text \"gIycerol\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"pyruvyl transferase\" ,",
+    "          replace \"glycerol\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"qlcohol\" ,",
+    "        match-text \"glcosyl\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -5958,19 +6589,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"alcohol\" ,",
+    "          replace \"glycosyl\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ranscriptional\" ,",
+    "        match-text \"Glimmer\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -5980,19 +6614,15 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"transcriptional\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"recognised\" ,",
+    "        match-text \"glucosainyl\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6002,107 +6632,138 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"recognized\" ,",
+    "          replace \"glucosaminyl\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"reductasee\" ,",
-    "        match-location contains ,",
+    "        match-text \"glutamate\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"reductase\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"regulatot\" ,",
-    "        match-location contains ,",
+    "        match-text \"Glutamic acid\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"regulator\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"reguratory\" ,",
-    "        match-location contains ,",
+    "        match-text \"Glutamine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"regulatory\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"reolvase\" ,",
+    "        match-text \"glutaminne\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"resolvase\" ,",
+    "          replace \"glutamine\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"repeatl\" ,",
+    "        match-text \"glycin\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6112,42 +6773,56 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"repeat\" ,",
+    "          replace \"glycine\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"reponse\" ,",
-    "        match-location contains ,",
+    "        match-text \"Glycine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"response\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"resistence\" ,",
-    "        match-location contains ,",
+    "        match-text \"glycolsyltransferase\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -6156,19 +6831,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"resistance\" ,",
+    "          replace \"glycosyltransferase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ribomal\" ,",
+    "        match-text \"glycosy\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6178,20 +6856,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"ribosomal\" ,",
+    "          replace \"glucosyl\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ribosimal\" ,",
-    "        match-location contains ,",
+    "        match-text \"GMP\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -6200,20 +6881,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"ribosomal\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ribosoml\" ,",
-    "        match-location contains ,",
+    "        match-text \"gp\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -6222,129 +6906,98 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"ribosomal\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"rsponse\" ,",
-    "        match-location contains ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"gph\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"response\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"serinr\" ,",
-    "        match-location contains ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"GPI\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"serine\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"shrot\" ,",
-    "        match-location contains ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"GPN\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"short\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"shrot-chain\" ,",
-    "        match-location contains ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"GPH\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"short-chain\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type putative-typo ,",
+    "    description \"may contain systematic gene product identifiers from phage\" ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"shuttlingfactor\" ,",
-    "        match-location contains ,",
+    "        match-text \"GTP\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"shuttling factor\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"signal peptide\" ,",
+    "        match-text \"guanine\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6362,19 +7015,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"signal peptide protein\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative TRUE } ,",
-    "      move-to-note FALSE } } ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"signalling\" ,",
+    "        match-text \"haem\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6384,19 +7040,59 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"archaemetzincin\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type british ,",
+    "    replace {",
+    "      replace-func",
+    "        haem-replace \"haem\" ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"halophilus\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"signaling\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"similiar\" ,",
+    "        match-text \"heam\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6406,63 +7102,69 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
-    "        simple-replace {",
-    "          replace \"similar\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        haem-replace \"haem\" ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"simmilar\" ,",
+    "        match-text \"heavychain\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"similar\" ,",
+    "          replace \"heavy chain\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"specfic\" ,",
+    "        match-text \"Helicobacter\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"specific\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"spscific\" ,",
+    "        match-text \"Helicoverpa\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6472,85 +7174,121 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"specific\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"stabilisation\" ,",
-    "        match-location contains ,",
+    "        match-text \"helium\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"stabilization\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"subnit\" ,",
-    "        match-location contains ,",
+    "        match-text \"helix\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"subunit\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"suger\" ,",
-    "        match-location contains ,",
+    "        match-text \"helix-turn-helix\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"sugar\" ,",
+    "          replace \"helix-turn-helix protein\" ,",
     "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "          weasel-to-putative TRUE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"sulfer\" ,",
+    "        match-text \"hemaggltinin\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6560,19 +7298,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"sulfur\" ,",
+    "          replace \"hemagglutinin\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"sulpho\" ,",
+    "        match-text \"hemelysin\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6582,19 +7323,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"sulfo\" ,",
+    "          replace \"hemolysin\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"sulphur\" ,",
+    "        match-text \"hemoglobine\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6604,20 +7348,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"sulfur\" ,",
+    "          replace \"hemoglobin\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"SWIM zinc finger\" ,",
-    "        match-location equals ,",
+    "        match-text \"hexapaptide\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -6626,41 +7373,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"SWIM zinc finger protein\" ,",
+    "          replace \"hexapeptide\" ,",
     "          whole-string FALSE ,",
-    "          weasel-to-putative TRUE } ,",
-    "      move-to-note FALSE } } ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"systhesis\" ,",
+    "        match-text \"hexpeptide\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"synthesis\" ,",
+    "          replace \"hexapeptide\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"sythase\" ,",
+    "        match-text \"highly conserved\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6670,19 +7423,15 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"synthase\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"tetracenpmycin\" ,",
+    "        match-text \"highly similar\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6692,43 +7441,42 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"tetracenomycin\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"thiamin/thiamin\" ,",
+    "        match-text \"histadine\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"thiamin/thiamine\" ,",
+    "          replace \"histidine\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"thiamineS\" ,",
+    "        match-text \"histide\" ,",
     "        match-location contains ,",
-    "        case-sensitive TRUE ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word TRUE ,",
@@ -6736,41 +7484,55 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"thiamine S\" ,",
+    "          replace \"histidine\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"thioderoxin\" ,",
-    "        match-location contains ,",
+    "        match-text \"Histidine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"thioredoxin\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"thiredoxin\" ,",
+    "        match-text \"homeserine\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6780,19 +7542,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"thioredoxin\" ,",
+    "          replace \"homoserine\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"threonin\" ,",
+    "        match-text \"homlog\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6802,19 +7567,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"threonine\" ,",
+    "          replace \"homolog\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"trancription\" ,",
+    "        match-text \"homo\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6824,19 +7592,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transcription\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"trancsriptional\" ,",
+    "        match-text \"homo sapiens\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6846,63 +7617,83 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transcription\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"tranferase\" ,",
+    "        match-text \"homocystein\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transferase\" ,",
+    "          replace \"homocysteine\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"tranporter\" ,",
+    "        match-text \"Homolog\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"transporter\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type evolutionary-relationship ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transcirbed\" ,",
+    "        match-text \"Homologue\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type evolutionary-relationship ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"horikoshii\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6912,21 +7703,24 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transcribed\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transcrIpt\" ,",
+    "        match-text \"hpothetical\" ,",
     "        match-location contains ,",
-    "        case-sensitive TRUE ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
@@ -6934,19 +7728,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transcript\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transcriptionnal \" ,",
+    "        match-text \"human\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -6956,20 +7753,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transcriptional\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transcriptonal\" ,",
-    "        match-location contains ,",
+    "        match-text \"hy0\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -6978,19 +7778,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transcriptional\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transcritional\" ,",
+    "        match-text \"hydolase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7000,64 +7803,81 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transcriptional\" ,",
+    "          replace \"hydrolase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transebrane\" ,",
-    "        match-location contains ,",
+    "        match-text \"hydrogen\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transmembrane\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transemembrane\" ,",
+    "        match-text \"hydrolas\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transmembrane\" ,",
+    "          replace \"hydrolase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Transemembrane\" ,",
-    "        match-location contains ,",
+    "        match-text \"hydrolases of the alpha/beta superfamily\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -7066,19 +7886,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transmembrane\" ,",
+    "          replace \"hydrolase of the alpha/beta superfamily\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transerfase\" ,",
+    "        match-text \"hyopothetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7088,41 +7911,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transferase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transferasee\" ,",
+    "        match-text \"hyopthetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transferase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transglycolase\" ,",
+    "        match-text \"hyothetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7132,20 +7961,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transglycosylase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Transmebrane\" ,",
-    "        match-location contains ,",
+    "        match-text \"hyp domain protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -7154,19 +7986,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transmembrane\" ,",
+    "          replace \"hypothetical protein\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transmebrane\" ,",
+    "        match-text \"hyperthetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7176,41 +8011,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transmembrane\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transmemembrane\" ,",
+    "        match-text \"hyphotetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transmembrane\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transorter\" ,",
+    "        match-text \"hyphotheical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7220,19 +8061,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transporter\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transpoase\" ,",
+    "        match-text \"hyphothetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7242,19 +8086,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transposase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transport-associated\" ,",
+    "        match-text \"hypo\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7272,19 +8119,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transport-associated protein\" ,",
+    "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transportor\" ,",
+    "        match-text \"hypohetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7294,42 +8144,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transporter\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transposase and inactivated derivative\" ,",
-    "        match-location equals ,",
+    "        match-text \"hypot\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transposase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transposase and inactivated derivatives\" ,",
-    "        match-location equals ,",
+    "        match-text \"hypotehtical\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -7338,20 +8194,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transposase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transposase and inactive derivative\" ,",
-    "        match-location equals ,",
+    "        match-text \"hypotethical\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -7360,20 +8219,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transposase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transposase and inactive derivatives\" ,",
-    "        match-location equals ,",
+    "        match-text \"hypotetical\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -7382,72 +8244,73 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transposase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transposase of\" ,",
-    "        match-location equals ,",
+    "        match-text \"hypoth\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transposase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
-    "          weasel-to-putative TRUE } ,",
-    "      move-to-note FALSE } } ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transposases and inactivated derivative\" ,",
-    "        match-location equals ,",
+    "        match-text \"hypothe\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transposase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transposases and inactivated derivatives\" ,",
-    "        match-location equals ,",
+    "        match-text \"hypotheical\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -7456,20 +8319,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transposase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transposases and inactive derivative\" ,",
-    "        match-location equals ,",
+    "        match-text \"hypotheitcal\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -7478,20 +8344,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transposase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transposases and inactive derivatives\" ,",
-    "        match-location equals ,",
+    "        match-text \"hypotherical\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -7500,19 +8369,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transposase\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transproter\" ,",
+    "        match-text \"hypothertical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7522,41 +8394,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transporter\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transulfuration\" ,",
+    "        match-text \"hypothet\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transsulfuration\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"trnasporter\" ,",
+    "        match-text \"hypothetcial\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7566,41 +8444,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"transporter\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"trunucated\" ,",
+    "        match-text \"hypothethical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"truncated\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"typr\" ,",
+    "        match-text \"hypotheti\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7610,19 +8494,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"type\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"uncharacterizaed\" ,",
+    "        match-text \"hypothetial\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7632,20 +8519,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"uncharacterized\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"uncharacterized\" ,",
-    "        match-location starts ,",
+    "        match-text \"hypothetic\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -7654,12 +8544,97 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"uncharacterized protein\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"hypothetica\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"hypothetical\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"hypothetical\" ,",
+    "        match-location starts ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"hypothetical protein\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
@@ -7667,9 +8642,11 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "      string {",
-    "        match-text \"uncharacterized protein conserved in bacteria\" ,",
+    "        match-text \"hypothetical domain protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7679,9 +8656,11 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "      string {",
-    "        match-text \"uncharacterized conserved protein\" ,",
+    "        match-text \"hypothetical ORF\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7691,9 +8670,11 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "      string {",
-    "        match-text \"uncharacterized\" ,",
+    "        match-text \"hypothetical\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7703,9 +8684,11 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "      string {",
-    "        match-text \"uncharacterized domain 1\" ,",
+    "        match-text \"Hypothetical conserved protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7715,9 +8698,11 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "      string {",
-    "        match-text \"uncharacterized protein\" ,",
+    "        match-text \"hypothetical protein\" ,",
     "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7727,7 +8712,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "      string {",
     "        match-text \"UPF\" ,",
     "        match-location contains ,",
@@ -7749,7 +8736,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
@@ -7757,12 +8746,13 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"putative\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"undecapaprenyl\" ,",
-    "        match-location contains ,",
+    "        match-text \"hypothetical protein\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -7771,76 +8761,98 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"undecaprenyl\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    except",
     "      string-constraint {",
-    "        match-text \"unique\" ,",
-    "        match-location starts ,",
+    "        match-text \"hypothetical protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"unique protein\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type putative-typo ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Hypothetical protein gene\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
+    "        ignore-space TRUE ,",
+    "        ignore-punct TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            word \"gene\" ,",
+    "            synonyms {",
+    "              \"sequence\" ,",
+    "              \"partial sequence\" ,",
+    "              \"complete sequence\" ,",
+    "              \"partial\" ,",
+    "              \"complete\" ,",
+    "              \"gene sequence\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word FALSE } ,",
+    "          {",
+    "            word \"hypothetical\" ,",
+    "            synonyms {",
+    "              \"putative\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word FALSE } } ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"unkown\" ,",
+    "        match-text \"hypotheticala\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"unknown\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"vigtamin\" ,",
+    "        match-text \"hypotheticalprotein\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7850,63 +8862,72 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"vitamin\" ,",
+    "          replace \"hypothetical protein\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"YeeEYedE\" ,",
+    "        match-text \"hypotheticial\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"YeeE/YedE\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"YjgPYjgQ\" ,",
+    "        match-text \"hypotheticical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"YjgP/YjgQ\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ypothetical\" ,",
+    "        match-text \"hypotheticl\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7916,7 +8937,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
@@ -7924,11 +8947,12 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ytochrome\" ,",
+    "        match-text \"hypotheticla\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7938,19 +8962,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"cytochrome\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"yypothetical\" ,",
+    "        match-text \"hypothteical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -7960,7 +8987,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
@@ -7968,12 +8997,13 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"zinc finger\" ,",
-    "        match-location equals ,",
+    "        match-text \"hypothtical\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -7982,27 +9012,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"zinc finger protein\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
-    "          weasel-to-putative TRUE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      contains-plural NULL ,",
-    "    rule-type putative-typo } ,",
-    "  {",
-    "    find",
-    "      all-caps NULL ,",
-    "    rule-type putative-typo } ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"authentic point mutation\" ,",
+    "        match-text \"hypoyhtetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8012,12 +9037,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"deletion\" ,",
+    "        match-text \"hyppothetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8027,12 +9062,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"doubtful\" ,",
+    "        match-text \"hyprothetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8042,12 +9087,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Fragment\" ,",
+    "        match-text \"hypthetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8057,12 +9112,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"frame shift\" ,",
+    "        match-text \"hyptohetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8072,12 +9137,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"frameshift\" ,",
+    "        match-text \"hyptothetcial\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8087,25 +9162,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"programmed frameshift\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"hyptothetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"incomplete ORF\" ,",
+    "        match-text \"hyputhetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8115,26 +9212,41 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    except",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
     "      string-constraint {",
-    "        match-text \"incomplete ORF domain protein\" ,",
-    "        match-location equals ,",
-    "        case-sensitive TRUE ,",
+    "        match-text \"identity\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"interrupt\" ,",
-    "        match-location contains ,",
+    "        match-text \"immunoreactive\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -8143,12 +9255,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"immunoreactive protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Low Quality Protein\" ,",
+    "        match-text \"inactivated derivative\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8158,40 +9280,58 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"open reading frame\" ,",
+    "        match-text \"Includes:\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"open reading frame\" ,",
-    "        match-location equals ,",
-    "        case-sensitive TRUE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"incolved\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"involved\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"orphan protein\" ,",
+    "        match-text \"incomplete ORF\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8201,26 +9341,31 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"orphan protein\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    except",
+    "      string-constraint {",
+    "        match-text \"incomplete ORF domain protein\" ,",
     "        match-location equals ,",
-    "        case-sensitive FALSE ,",
+    "        case-sensitive TRUE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal TRUE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"partial\" ,",
-    "        match-location contains ,",
+    "        match-text \"incomplete ORF domain protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -8229,42 +9374,72 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"pseudo\" ,",
+    "        match-text \"indepedent\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"independent\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"pseudogene\" ,",
+    "        match-text \"inductible\" ,",
     "        match-location contains ,",
-    "        case-sensitive TRUE ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"inducible\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"remnant\" ,",
+    "        match-text \"initation\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8274,91 +9449,105 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"initiation\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"start codon\" ,",
-    "        match-location contains ,",
+    "        match-text \"inorganic phosphate\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"truncat\" ,",
-    "        match-location contains ,",
+    "        match-text \"insertion sequence\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"unknown\" ,",
+    "        match-text \"insitol\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      field {",
-    "        field",
-    "          feature-field {",
-    "            type cds ,",
-    "            field",
-    "              legal-qual product } ,",
-    "        string-constraint {",
-    "          match-text \"protein of unknown function\" ,",
-    "          match-location contains ,",
-    "          case-sensitive FALSE ,",
-    "          ignore-space FALSE ,",
-    "          ignore-punct FALSE ,",
-    "          whole-word FALSE ,",
-    "          not-present TRUE ,",
-    "          is-all-caps FALSE ,",
-    "          is-all-lower FALSE ,",
-    "          is-all-punct FALSE ,",
-    "          ignore-weasel FALSE } } ,",
-    "      field {",
-    "        field",
-    "          feature-field {",
-    "            type cds ,",
-    "            field",
-    "              legal-qual product } ,",
-    "        string-constraint {",
-    "          match-text \"domain of unknown function\" ,",
-    "          match-location contains ,",
-    "          case-sensitive FALSE ,",
-    "          ignore-space FALSE ,",
-    "          ignore-punct FALSE ,",
-    "          whole-word FALSE ,",
-    "          not-present TRUE ,",
-    "          is-all-caps FALSE ,",
-    "          is-all-lower FALSE ,",
-    "          is-all-punct FALSE ,",
-    "          ignore-weasel FALSE } } ,",
-    "      string {",
-    "        match-text \"unknown\" ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"inositol\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"intein C-terminal splicing region\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8368,9 +9557,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "      string {",
-    "        match-text \"unknown protein\" ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"intein N-terminal splicing region\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8380,31 +9582,49 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } } ,",
-    "    rule-type might-be-nonfunctional } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
-    "      three-numbers NULL ,",
-    "    except",
     "      string-constraint {",
-    "        match-text \"methyltransferas\" ,",
-    "        match-location contains ,",
+    "        match-text \"interacts with\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type database } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"&apos\" ,",
-    "        match-location contains ,",
-    "        case-sensitive TRUE ,",
+    "        match-text \"internal repeat sequences detected\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
@@ -8412,12 +9632,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type database } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"(TC \" ,",
+    "        match-text \"interrupt\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8427,40 +9657,40 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type database } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"COG\" ,",
+    "        match-text \"Intiation\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    except",
-    "      string-constraint {",
-    "        match-text \"COG\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type database } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"initiation\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"database\" ,",
+    "        match-text \"invertion\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8470,26 +9700,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"no significant database hits\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } } ,",
-    "    rule-type database } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"inversion\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"DUF\" ,",
-    "        match-location contains ,",
+    "        match-text \"involved\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -8498,128 +9725,150 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    except",
-    "      string-constraint {",
-    "        match-text \"DUF\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type database } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"EST\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    except",
-    "      string-constraint {",
-    "        match-text \"EST\" ,",
+    "        match-text \"iron\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type database } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
-    "      string-constraint {",
-    "        match-text \"FOG\" ,",
-    "        match-location contains ,",
-    "        case-sensitive TRUE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type database } ,",
+    "      prefix-and-numbers \"IS\" ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"undefined product\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"undefined product\" ,",
+    "        match-text \"IS ORF\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } } ,",
-    "    rule-type database } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"IS protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative TRUE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"UPF\" ,",
+    "        match-text \"isation\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    except",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"ization\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
     "      string-constraint {",
-    "        match-text \"UPF\" ,",
+    "        match-text \"Isoleucine\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type database } ,",
-    "  {",
-    "    find",
-    "      underscore NULL ,",
-    "    rule-type database } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \" Anopheles\" ,",
+    "        match-text \"isomaerase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8629,19 +9878,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"isomerase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Agrobacterium\" ,",
+    "        match-text \"isomerse\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8651,19 +9903,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"isomerase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Arabidopsis\" ,",
+    "        match-text \"Jejuni\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8673,7 +9928,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
@@ -8681,11 +9938,12 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Aspergillus\" ,",
+    "        match-text \"K potassium\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8695,19 +9953,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"potassium\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"aureus\" ,",
+    "        match-text \"K+ potassium\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8717,19 +9978,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"potassium\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"B.subtilis\" ,",
+    "        match-text \"lacitehtopyh\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8739,19 +10003,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Bacillus\" ,",
+    "        match-text \"Leishmania\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8761,7 +10028,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
@@ -8769,34 +10038,46 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Bacterioides\" ,",
-    "        match-location contains ,",
+    "        match-text \"Leucine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Bacteroides\" ,",
-    "        match-location contains ,",
+    "        match-text \"like\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -8805,41 +10086,40 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Bombyx\" ,",
+    "        match-text \"likeity\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"bos taurus\" ,",
+    "        match-text \"likely\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8849,20 +10129,16 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Campylobacter\" ,",
-    "        match-location contains ,",
+    "        match-text \"likely\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -8871,51 +10147,59 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Candida\" ,",
+    "        match-text \"liporotein\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"lipoprotein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"cerevisiae\" ,",
-    "        match-location contains ,",
+    "        match-text \"listeria/Bacterioides\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
@@ -8923,33 +10207,37 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Chlamydial\" ,",
+    "        match-text \"localisation\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"localization\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Chlamydomonas\" ,",
+    "        match-text \"localised\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -8959,55 +10247,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"localized\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"coli\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"adenomatous polyposis coli \" ,",
-    "        match-location contains ,",
+    "        match-text \"localization of periplasmic protein complexes\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Drosophila\" ,",
-    "        match-location contains ,",
+    "        match-text \"located in\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -9016,107 +10297,112 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"E.coli\" ,",
+    "        match-text \"Low Quality Protein\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"ECOLI\" ,",
-    "        match-location contains ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"LOW QUALITY PROTEIN:\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal TRUE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"enterica\" ,",
-    "        match-location contains ,",
+    "        match-text \"Low Quality Protein: \" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Escherichia\" ,",
-    "        match-location contains ,",
+    "        match-text \"Lysine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"gambiae\" ,",
+    "        match-text \"majour\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9126,63 +10412,80 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"major\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"halophilus\" ,",
-    "        match-location contains ,",
+    "        match-text \"malate\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Helicobacter\" ,",
-    "        match-location contains ,",
+    "        match-text \"Maltose\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Helicoverpa\" ,",
+    "        match-text \"mambrane\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9192,19 +10495,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"membrane\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"homo\" ,",
+    "        match-text \"Marinococcus\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9214,7 +10520,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
@@ -9222,11 +10530,12 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"homo sapiens\" ,",
+    "        match-text \"meausure\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9236,42 +10545,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"measure\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"human\" ,",
+    "        match-text \"medated\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"mediated\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Jejuni\" ,",
-    "        match-location contains ,",
+    "        match-text \"mediates\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -9280,41 +10595,55 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Leishmania\" ,",
-    "        match-location contains ,",
+    "        match-text \"membrane\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"listeria/Bacterioides\" ,",
+    "        match-text \"membrane protein of\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9324,107 +10653,122 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"membrane protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Marinococcus\" ,",
+    "        match-text \"membraneprotein\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"membrane protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mouse\" ,",
+    "        match-text \"membranetransport\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"membrane transport\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Mus musculus\" ,",
+    "        match-text \"membranne\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"membrane\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Mycobacterium\" ,",
+    "        match-text \"membtrane\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"membrane\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mycoplasma\" ,",
+    "        match-text \"memebrane\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9434,86 +10778,106 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"membrane\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Neurospora\" ,",
-    "        match-location contains ,",
+    "        match-text \"Methionine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"niger\" ,",
+    "        match-text \"methlytransferase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"methyltransferase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Pestis\" ,",
+    "        match-text \"metylase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"methylase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Plasmodium\" ,",
-    "        match-location contains ,",
+    "        match-text \"miscellaneous\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -9522,63 +10886,55 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"pombe\" ,",
+    "        match-text \"miscellaneous\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
-    "  {",
-    "    find",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    except",
     "      string-constraint {",
-    "        match-text \"pseudomonas\" ,",
-    "        match-location contains ,",
+    "        match-text \"miscellaneous\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"pylori\" ,",
+    "        match-text \"mitchondrial\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9588,63 +10944,72 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"mitochondrial\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"rat\" ,",
+    "        match-text \"mobilisation\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"mobilization\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Rhodobacter\" ,",
+    "        match-text \"molibdenum\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"molybdenum\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"rickettsia\" ,",
+    "        match-text \"molybopterin\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9654,41 +11019,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"molybdopterin\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Salmonella\" ,",
+    "        match-text \"molydopterin\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"molybdopterin\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"sapiens\" ,",
+    "        match-text \"monooxigenase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9698,42 +11069,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"monooxygenase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"serovar\" ,",
+    "        match-text \"monoxyde\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"monoxide\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"siphovirus\" ,",
-    "        match-location equals ,",
+    "        match-text \"monoxygenase\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -9742,29 +11119,34 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"monooxygenase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"sphaeroides\" ,",
+    "        match-text \"mouse\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
@@ -9772,33 +11154,45 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Spodoptera\" ,",
-    "        match-location contains ,",
+    "        match-text \"mRNA\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"sreptomyces\" ,",
+    "        match-text \"mulitdrug\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9808,85 +11202,104 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"multidrug\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Staphlococcal\" ,",
+    "        match-text \"mulitfunction\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"multifunction\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Staphlococcus\" ,",
+    "        match-text \"MULTISPECIES\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"MULTISPECIES:\" ,",
+    "        match-location starts ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"staphylococcal\" ,",
-    "        match-location contains ,",
+    "        match-text \"MULTISPECIES: \" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Staphylococcus\" ,",
+    "        match-text \"Mus musculus\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9896,7 +11309,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
@@ -9904,11 +11319,12 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"streptococcal\" ,",
+    "        match-text \"mutatrotase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9918,41 +11334,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"mutarotase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Streptococcus\" ,",
+    "        match-text \"mutlifunction\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"multifunction\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"streptomyces\" ,",
+    "        match-text \"Mycobacterium\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -9962,7 +11384,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
@@ -9970,21 +11394,24 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"subsp\" ,",
+    "        match-text \"mycoplasma\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
@@ -9992,33 +11419,37 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Subtilis\" ,",
+    "        match-text \"mypothetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"thaliana\" ,",
+    "        match-text \"mythylglyoxyl \" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -10028,42 +11459,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"methylglyoxyl\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Tuberculosis\" ,",
-    "        match-location contains ,",
+    "        match-text \"n-terminal domain protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"tumefaciens\" ,",
-    "        match-location contains ,",
+    "        match-text \"N-terminus\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10072,157 +11509,207 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Typhimurium\" ,",
-    "        match-location contains ,",
+    "        match-text \"Na\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"xenopus\" ,",
-    "        match-location contains ,",
+    "        match-text \"Na+\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"yeast\" ,",
-    "        match-location contains ,",
+    "        match-text \"NAD\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Yersinia\" ,",
+    "        match-text \"narrowly conserved\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type remove-organism-name ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
-    "  {",
-    "    find",
-    "      unbalanced-paren NULL ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"#\" ,",
+    "        match-text \"ncharacterized\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"uncharacterized\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"%\" ,",
-    "        match-location contains ,",
+    "        match-text \"ncRNA\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"()\" ,",
+    "        match-text \"ndoribonuclease\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"endoribonuclease\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \",\" ,",
-    "        match-location ends ,",
+    "        match-text \"Neurospora\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10231,13 +11718,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \",\" ,",
-    "        match-location starts ,",
+    "        match-text \"Ni\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10246,13 +11743,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"-\" ,",
-    "        match-location ends ,",
+    "        match-text \"nickle\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10261,43 +11768,81 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"nickel\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"-\" ,",
-    "        match-location starts ,",
+    "        match-text \"niger\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \".\" ,",
-    "        match-location ends ,",
+    "        match-text \"nitrogen\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \".\" ,",
-    "        match-location starts ,",
+    "        match-text \"Nmr solution\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10306,12 +11851,15 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \". \" ,",
+    "        match-text \"No definition line found\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -10321,29 +11869,50 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \".,\" ,",
-    "        match-location contains ,",
+    "        match-text \"No definition line found\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"./\" ,",
-    "        match-location contains ,",
-    "        case-sensitive TRUE ,",
+    "        match-text \"no function assigned\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
@@ -10351,13 +11920,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"/\" ,",
-    "        match-location ends ,",
+    "        match-text \"no likeity\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10366,13 +11945,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \":\" ,",
-    "        match-location ends ,",
+    "        match-text \"no significant database hits\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10381,13 +11970,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"=\" ,",
-    "        match-location contains ,",
+    "        match-text \"no significant database matches\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10396,13 +11995,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"?\" ,",
-    "        match-location contains ,",
+    "        match-text \"no significant homology\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10411,14 +12020,24 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"@\" ,",
+    "        match-text \"no significant homology\" ,",
     "        match-location contains ,",
-    "        case-sensitive TRUE ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
@@ -10426,28 +12045,31 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
-    "  {",
-    "    find",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    except",
     "      string-constraint {",
-    "        match-text \"complete\" ,",
-    "        match-location contains ,",
+    "        match-text \"no significant homology\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"contig\" ,",
-    "        match-location contains ,",
+    "        match-text \"novel\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10456,57 +12078,70 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"Critica\" ,",
-    "        match-location contains ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"novel protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Crystal Structure\" ,",
+    "        match-text \"novel\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
-    "  {",
-    "    find",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    except",
     "      string-constraint {",
-    "        match-text \"DNA for\" ,",
-    "        match-location contains ,",
+    "        match-text \"novel protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"genome\" ,",
+    "        match-text \"ntegral \" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -10516,37 +12151,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"genome instability\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "      string {",
-    "        match-text \"genome maintenance\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"integral \" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Glimmer\" ,",
+    "        match-text \"nucear\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -10556,27 +12176,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"Nmr solution\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"nuclear\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"No definition line found\" ,",
+    "        match-text \"nucelar\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -10586,12 +12201,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"nuclear\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"raw score\" ,",
+    "        match-text \"nucleotydyl\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -10601,40 +12226,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"raw score\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } } ,",
-    "    rule-type inappropriate-symbol } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"RNA for\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"nucleotidyl\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"shotgun\" ,",
+    "        match-text \"nucletide\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -10644,27 +12251,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"nucleotide\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"solution Nmr\" ,",
+    "        match-text \"nulcear\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"nuclear\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"solution structure\" ,",
+    "        match-text \"nulceotide\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -10674,73 +12301,139 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"nucleotide\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"structure of\" ,",
-    "        match-location contains ,",
+    "        match-text \"null\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"xray structure\" ,",
-    "        match-location contains ,",
+    "        match-text \"o252\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"\\\" ,",
-    "        match-location ends ,",
+    "        match-text \"o252 protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"\\\\-PA\" ,",
+    "        match-text \"obalt\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"cobalt\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"_\" ,",
-    "        match-location ends ,",
+    "        match-text \"observed by proteomics\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10749,28 +12442,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"|\" ,",
+    "        match-text \"odule\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"module\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"analog\" ,",
-    "        match-location contains ,",
+    "        match-text \"of\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10779,57 +12492,73 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type evolutionary-relationship } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Homolog\" ,",
-    "        match-location contains ,",
+    "        match-text \"open reading frame\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type evolutionary-relationship } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ortholog\" ,",
+    "        match-text \"open reading frame\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type evolutionary-relationship } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"paralog\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"open reading frame\" ,",
+    "        match-location equals ,",
+    "        case-sensitive TRUE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type evolutionary-relationship } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal TRUE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"adenine\" ,",
+    "        match-text \"ORF\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -10847,7 +12576,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -10855,11 +12586,12 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ADP\" ,",
+    "        match-text \"orf, hyp\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -10869,19 +12601,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Alanine\" ,",
+    "        match-text \"orf, hypothetical\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -10899,7 +12634,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -10907,12 +12644,13 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"alpha\" ,",
-    "        match-location equals ,",
+    "        match-text \"organise\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -10921,191 +12659,166 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"organize\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"alternate protein name\" ,",
+    "        match-text \"orphan protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"amino acid\" ,",
-    "        match-location equals ,",
+    "        match-text \"orphan protein\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"orphan protein\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"anion\" ,",
-    "        match-location equals ,",
+    "        match-text \"ortholog\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type evolutionary-relationship ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Arginine\" ,",
-    "        match-location equals ,",
+    "        match-text \"orthologue\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type evolutionary-relationship ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Asparagine\" ,",
-    "        match-location equals ,",
+    "        match-text \"Outative\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Aspartic acid\" ,",
-    "        match-location equals ,",
+    "        match-text \"outers\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"outer\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"aspartyl\" ,",
+    "        match-text \"Oxalate\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -11115,7 +12828,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -11123,124 +12838,113 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ATP\" ,",
-    "        match-location equals ,",
+    "        match-text \"oxidoreducatse\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"oxidoreductase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"bacteriophage\" ,",
+    "        match-text \"oxidoreductase ()\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"oxidoreductase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"barrel\" ,",
-    "        match-location equals ,",
+    "        match-text \"oxidoreductasee\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"oxidoreductase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"believed\" ,",
-    "        match-location starts ,",
+    "        match-text \"oxidoreductasse\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"oxidoreductase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"bifunctional\" ,",
-    "        match-location equals ,",
+    "        match-text \"oxidoredutase\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11249,42 +12953,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"oxidoreductase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"binds\" ,",
-    "        match-location starts ,",
+    "        match-text \"oxidoreduxtase\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"oxidoreductase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"bis\" ,",
-    "        match-location equals ,",
+    "        match-text \"oxigenase\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11293,20 +13003,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"oxygenase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"C-terminus\" ,",
-    "        match-location equals ,",
+    "        match-text \"oxydase\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11315,19 +13028,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"oxidase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"carbon\" ,",
+    "        match-text \"oxygen\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -11345,7 +13061,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -11353,95 +13071,93 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"CBS domain pair\" ,",
+    "        match-text \"p-loop\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "          replace \"p-loop protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative TRUE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"citrate\" ,",
-    "        match-location equals ,",
+    "        match-text \"paralog\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type evolutionary-relationship ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"clustered with\" ,",
-    "        match-location starts ,",
+    "        match-text \"paralogue\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type evolutionary-relationship ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"COG\" ,",
-    "        match-location equals ,",
+    "        match-text \"part\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -11449,41 +13165,30 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conser\" ,",
-    "        match-location equals ,",
+    "        match-text \"partial\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal TRUE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserve\" ,",
+    "        match-text \"PASTA\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -11501,19 +13206,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "          replace \"PASTA protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative TRUE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserved\" ,",
+    "        match-text \"peptide\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -11531,7 +13239,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -11539,12 +13249,13 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserved domain protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"peptidodoglycan\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11553,37 +13264,34 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"peptidoglycan\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserved hypothetical\" ,",
+    "        match-text \"peptidyl-prolyl cis-trans\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -11591,12 +13299,13 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserved hypothetical domain protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"periplamic\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11605,20 +13314,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"periplasmic\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserved hypothetical family protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"periplasmc\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11627,72 +13339,73 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"periplasmic\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserved hypothetical protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"periplsmic\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"periplasmic\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserved predicted domain protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"Pestis\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserved predicted protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"petidase\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11701,29 +13414,42 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"peptidase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserved protein\" ,",
+    "        match-text \"phage\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -11731,21 +13457,32 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserved protein of unknown function\" ,",
+    "        match-text \"Phenylalanine\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -11753,34 +13490,38 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"conserved putative protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"pheremone\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"pheromone\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Conserved subname: full\" ,",
-    "        match-location equals ,",
+    "        match-text \"phophate\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11789,20 +13530,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"phosphate\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Conserved with\" ,",
-    "        match-location starts ,",
+    "        match-text \"phopho\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11811,20 +13555,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"phospho\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"containing\" ,",
-    "        match-location starts ,",
+    "        match-text \"phophoserine\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11833,20 +13580,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"phosphoserine\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"contains\" ,",
-    "        match-location starts ,",
+    "        match-text \"phoshate\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11855,102 +13605,98 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"phosphate\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"CTP\" ,",
-    "        match-location equals ,",
+    "        match-text \"phospatase\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"phosphatase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Cysteine\" ,",
-    "        match-location equals ,",
+    "        match-text \"phosphateN\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"phosphate N\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"cytosine\" ,",
-    "        match-location equals ,",
+    "        match-text \"phosphatidyltransferse\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"phosphatidyltransferase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"di\" ,",
-    "        match-location equals ,",
+    "        match-text \"phosphatransferase\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11959,20 +13705,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"phosphotransferase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"dipeptide\" ,",
-    "        match-location equals ,",
+    "        match-text \"phosphopantethiene\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -11981,49 +13730,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"phosphopantetheine\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"DNA\" ,",
-    "        match-location equals ,",
+    "        match-text \"phosphotase\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"phosphatase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domain\" ,",
+    "        match-text \"plasmid\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -12041,7 +13788,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -12049,11 +13798,12 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domain 1\" ,",
+    "        match-text \"plasmid-like protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -12063,7 +13813,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -12071,72 +13823,63 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domain family\" ,",
-    "        match-location equals ,",
+    "        match-text \"Plasmodium\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domain of unknown function\" ,",
-    "        match-location equals ,",
+    "        match-text \"polimerase\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"polymerase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domain of unknown function family protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"polymeris\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -12145,72 +13888,98 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"polymeriz\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domain of unknown function family protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"pombe\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            word \"pombe\" ,",
+    "            synonyms {",
+    "              \"genitalium\" ,",
+    "              \"leprae\" ,",
+    "              \"crassa\" ,",
+    "              \"ciliare\" ,",
+    "              \"falciparum\" ,",
+    "              \"fumigata\" ,",
+    "              \"vinifera\" ,",
+    "              \"lipolytica\" ,",
+    "              \"ambisexualis\" ,",
+    "              \"brasilense\" ,",
+    "              \"carbonum\" ,",
+    "              \"elegans\" ,",
+    "              \"melanogaster\" ,",
+    "              \"capricolum\" ,",
+    "              \"pneumoniae\" ,",
+    "              \"pseudotuberculosis\" ,",
+    "              \"histolytica\" ,",
+    "              \"influenzae\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word FALSE } } ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    description \"contains organism name\" ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domain of unknown function protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"portein\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domain protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"Portein\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -12219,20 +13988,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
+    "          replace \"protein\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"domain-containing protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"posible\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -12241,50 +14013,63 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"possible\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"doubtful CDS found within S. typhi pathogenicity island\" ,",
+    "        match-text \"possible\" ,",
+    "        match-location starts ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"possible protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"DUF\" ,",
-    "        match-location equals ,",
+    "        match-text \"possibly\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -12293,85 +14078,130 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"poteasome\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"proteasome\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"EST\" ,",
-    "        match-location equals ,",
+    "        match-text \"potein\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"expressed\" ,",
+    "        match-text \"potential\" ,",
+    "        match-location starts ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"potential protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"expressed protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"precurso\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"precursor\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"factor\" ,",
+    "        match-text \"precursor\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -12389,7 +14219,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -12397,33 +14229,37 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"family\" ,",
-    "        match-location equals ,",
+    "        match-text \"precusor\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"precursor\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"family protein\" ,",
+    "        match-text \"predicted\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -12441,7 +14277,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -12449,184 +14287,142 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"finger\" ,",
-    "        match-location equals ,",
+    "        match-text \"predicted\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"from\" ,",
-    "        match-location starts ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"predicted protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"ggdef\" ,",
-    "        match-location equals ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"Predicted:\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Glutamic acid\" ,",
-    "        match-location equals ,",
+    "        match-text \"Predicted:\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Glutamine\" ,",
-    "        match-location equals ,",
+    "        match-text \"predictedprotein\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"predicted protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Glycine\" ,",
-    "        match-location equals ,",
+    "        match-text \"predictet\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"predicted\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"GMP\" ,",
-    "        match-location equals ,",
+    "        match-text \"presursor\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -12635,20 +14431,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"precursor\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"GTP\" ,",
-    "        match-location equals ,",
+    "        match-text \"probabable\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -12657,19 +14456,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"probable\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"guanine\" ,",
+    "        match-text \"probable\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -12687,7 +14489,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -12695,102 +14499,78 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"helium\" ,",
-    "        match-location equals ,",
+    "        match-text \"probable\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"helix\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"probable protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Histidine\" ,",
+    "        match-text \"probable protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hy0\" ,",
-    "        match-location equals ,",
+    "        match-text \"probable putative\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -12799,50 +14579,41 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hydrogen\" ,",
-    "        match-location equals ,",
+    "        match-text \"probably\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hyp domain protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"proein\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -12851,19 +14622,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
+    "          replace \"protein\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypo\" ,",
+    "        match-text \"Proline\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -12881,7 +14655,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -12889,75 +14665,52 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypothetical\" ,",
-    "        match-location equals ,",
+    "        match-text \"proposed\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"Hypothetical protein gene\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"proposed protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
-    "        ignore-space TRUE ,",
-    "        ignore-punct TRUE ,",
-    "        ignore-words {",
-    "          {",
-    "            word \"gene\" ,",
-    "            synonyms {",
-    "              \"sequence\" ,",
-    "              \"partial sequence\" ,",
-    "              \"complete sequence\" ,",
-    "              \"partial\" ,",
-    "              \"complete\" ,",
-    "              \"gene sequence\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word FALSE } } ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"incomplete ORF domain protein\" ,",
+    "        match-text \"proposed protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -12967,7 +14720,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -12975,42 +14730,38 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"insertion sequence\" ,",
-    "        match-location equals ,",
+    "        match-text \"proptein\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"intein C-terminal splicing region\" ,",
-    "        match-location equals ,",
+    "        match-text \"prortein\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -13019,42 +14770,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"intein N-terminal splicing region\" ,",
-    "        match-location equals ,",
+    "        match-text \"protazoan\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protozoan\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"interacts with\" ,",
-    "        match-location starts ,",
+    "        match-text \"protei\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -13063,100 +14820,106 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"involved\" ,",
-    "        match-location starts ,",
+    "        match-text \"protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"iron\" ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"hypothetical protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"uncharacterized protein\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
-    "      prefix-and-numbers \"IS\" ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      string-constraint {",
+    "        match-text \"protein associated to\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Isoleucine\" ,",
+    "        match-text \"protein conserved in bacteria\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -13164,11 +14927,12 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Leucine\" ,",
+    "        match-text \"protein containing\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -13186,7 +14950,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -13194,21 +14960,24 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"like\" ,",
-    "        match-location starts ,",
+    "        match-text \"protein of\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -13216,21 +14985,32 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"located in\" ,",
-    "        match-location starts ,",
+    "        match-text \"protein of unknown function\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -13238,21 +15018,23 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Lysine\" ,",
+    "        match-text \"protein of unknown function, duf\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        ignore-words {",
     "          {",
+    "            word \"protein of unknown function, duf\" ,",
     "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
+    "              \"protein of unknown function duf\" ,",
+    "              \"domain of unknown function duf\" ,",
+    "              \"domain of unknown function, duf\" } ,",
     "            case-sensitive FALSE ,",
     "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
@@ -13260,7 +15042,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -13268,81 +15052,74 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"malate\" ,",
+    "        match-text \"protein product\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mediates\" ,",
-    "        match-location starts ,",
+    "        match-text \"protein protein\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"membrane\" ,",
+    "        match-text \"Protein putative protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -13350,29 +15127,24 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Methionine\" ,",
+    "        match-text \"protein, conserved\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -13380,11 +15152,12 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mRNA\" ,",
+    "        match-text \"protein-containing\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -13402,7 +15175,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -13410,176 +15185,163 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"N-terminus\" ,",
-    "        match-location equals ,",
+    "        match-text \"proteine\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Na\" ,",
-    "        match-location equals ,",
+    "        match-text \"proteinn\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"NAD\" ,",
-    "        match-location equals ,",
+    "        match-text \"proten\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ncRNA\" ,",
-    "        match-location equals ,",
+    "        match-text \"protien\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"nitrogen\" ,",
-    "        match-location equals ,",
+    "        match-text \"protrein\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"No definition line found\" ,",
-    "        match-location equals ,",
+    "        match-text \"protwin\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"no function assigned\" ,",
-    "        match-location equals ,",
+    "        match-text \"prptein\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -13588,19 +15350,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"protein\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"no significant database hits\" ,",
+    "        match-text \"pseudo\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -13610,7 +15375,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -13618,59 +15385,42 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"o252\" ,",
-    "        match-location equals ,",
+    "        match-text \"pseudo\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal TRUE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"o252 protein\" ,",
+    "        match-text \"pseudogene\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -13678,64 +15428,56 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"open reading frame\" ,",
-    "        match-location equals ,",
+    "        match-text \"pseudogene\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal TRUE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ORF\" ,",
-    "        match-location equals ,",
+    "        match-text \"pseudomonas\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"orf, hyp\" ,",
-    "        match-location equals ,",
+    "        match-text \"ptotein\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -13744,19 +15486,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
+    "          replace \"protein\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"orf, hypothetical\" ,",
+    "        match-text \"PTS system\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -13774,20 +15519,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "          replace \"PTS system protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative TRUE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"orphan protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"puataive\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -13796,71 +15544,72 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
+    "          replace \"putative\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"oxygen\" ,",
-    "        match-location equals ,",
+    "        match-text \"puatative\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"part\" ,",
-    "        match-location starts ,",
+    "        match-text \"puative\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"peptide\" ,",
+    "        match-text \"purine\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -13878,7 +15627,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -13886,102 +15637,88 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"phage\" ,",
-    "        match-location equals ,",
+    "        match-text \"putaitive\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Phenylalanine\" ,",
-    "        match-location equals ,",
+    "        match-text \"putaitve\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"plasmid\" ,",
-    "        match-location equals ,",
+    "        match-text \"putaive\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"plasmid-like protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"putataive\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -13990,79 +15727,72 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"precursor\" ,",
-    "        match-location equals ,",
+    "        match-text \"putatitve\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"predicted\" ,",
-    "        match-location equals ,",
+    "        match-text \"putativ\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"probable\" ,",
+    "        match-text \"putative\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -14080,7 +15810,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -14088,12 +15820,13 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"probable protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"putative possible\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -14102,50 +15835,38 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"Proline\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"possible protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"proposed protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"putative potential\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -14154,20 +15875,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"putative potential\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -14176,22 +15900,12 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    feat-constraint {",
     "      string {",
-    "        match-text \"hypothetical protein\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "      string {",
-    "        match-text \"uncharacterized protein\" ,",
+    "        match-text \"possible protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -14201,20 +15915,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
+    "          replace \"putative\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protein conserved in bacteria\" ,",
-    "        match-location equals ,",
+    "        match-text \"putative predicted\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -14223,80 +15940,63 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protein containing\" ,",
-    "        match-location equals ,",
+    "        match-text \"putative probable\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"protein of unknown function\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"possible protein\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protein, conserved\" ,",
-    "        match-location equals ,",
+    "        match-text \"putative probable\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -14305,67 +16005,59 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protein-containing\" ,",
-    "        match-location equals ,",
+    "        match-text \"putative putative\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"pseudo\" ,",
+    "        match-text \"putative uncharacterized\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -14373,72 +16065,63 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"purine\" ,",
-    "        match-location equals ,",
+    "        match-text \"putative, putative\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putative\" ,",
-    "        match-location equals ,",
+    "        match-text \"putativie\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putative uncharacterized\" ,",
-    "        match-location equals ,",
+    "        match-text \"putatuive\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -14447,20 +16130,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"raw score\" ,",
-    "        match-location equals ,",
+    "        match-text \"putatuve\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -14469,266 +16155,248 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"region\" ,",
-    "        match-location starts ,",
+    "        match-text \"putatve\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Related\" ,",
-    "        match-location starts ,",
+    "        match-text \"putatvie\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"repeat\" ,",
-    "        match-location equals ,",
+    "        match-text \"putayive\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"RNA\" ,",
-    "        match-location equals ,",
+    "        match-text \"puter\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"outer\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"rRNA\" ,",
-    "        match-location equals ,",
+    "        match-text \"putitative\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"secreted\" ,",
-    "        match-location equals ,",
+    "        match-text \"putitive\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Serine\" ,",
-    "        match-location equals ,",
+    "        match-text \"puttive\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"signal\" ,",
-    "        match-location equals ,",
+    "        match-text \"pylori\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"similar\" ,",
-    "        match-location starts ,",
+    "        match-text \"pyradoxal\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"pyridoxal\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"sodium\" ,",
-    "        match-location equals ,",
+    "        match-text \"Pyrococcus\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -14737,209 +16405,167 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
-    "          whole-string FALSE ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"subunit\" ,",
-    "        match-location equals ,",
+    "        match-text \"pyruvyltransferase\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"pyruvyl transferase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Threonine\" ,",
-    "        match-location equals ,",
+    "        match-text \"qlcohol\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"alcohol\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"thymine\" ,",
-    "        match-location equals ,",
+    "        match-text \"ranscriptional\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"transcriptional\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"TPA_inf\" ,",
-    "        match-location starts ,",
+    "        match-text \"rat\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"transposon\" ,",
-    "        match-location equals ,",
+    "        match-text \"raw score\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"tRNA\" ,",
-    "        match-location equals ,",
-    "        case-sensitive FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"raw score\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Tryptophan\" ,",
+    "        match-text \"raw score\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -14947,12 +16573,13 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ttg start\" ,",
-    "        match-location equals ,",
+    "        match-text \"recognised\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -14961,59 +16588,59 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
+    "          replace \"recognized\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Tyrosine\" ,",
-    "        match-location equals ,",
+    "        match-text \"reductasee\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"reductase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"uncharacterized\" ,",
-    "        match-location equals ,",
+    "        match-text \"region\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -15021,34 +16648,31 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"unclassified\" ,",
-    "        match-location equals ,",
+    "        match-text \"regulates\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"undefined product\" ,",
-    "        match-location equals ,",
+    "        match-text \"regulatot\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15057,20 +16681,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"regulator\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"unkn\" ,",
-    "        match-location equals ,",
+    "        match-text \"reguratory\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15079,29 +16706,34 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
+    "          replace \"regulatory\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"unknown\" ,",
-    "        match-location equals ,",
+    "        match-text \"Related\" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -15109,12 +16741,13 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"unknown function\" ,",
-    "        match-location equals ,",
+    "        match-text \"remnant\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15123,29 +16756,60 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal TRUE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"reolvase\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"resolvase\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"unknown protein\" ,",
+    "        match-text \"repeat\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -15153,12 +16817,13 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"unnamed\" ,",
-    "        match-location equals ,",
+    "        match-text \"repeatl\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15167,20 +16832,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
+    "          replace \"repeat\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"unnamed protein product\" ,",
-    "        match-location equals ,",
+    "        match-text \"replicaiton\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15189,20 +16857,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
+    "          replace \"replication\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"unusual protein\" ,",
-    "        match-location equals ,",
+    "        match-text \"reponse\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15211,20 +16882,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"response\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"UPF\" ,",
-    "        match-location equals ,",
+    "        match-text \"resistence\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15233,102 +16907,98 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"resistance\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"uracil\" ,",
-    "        match-location equals ,",
+    "        match-text \"Rhodobacter\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"UTP\" ,",
-    "        match-location equals ,",
+    "        match-text \"ribomal\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"ribosomal\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Valine\" ,",
-    "        match-location equals ,",
+    "        match-text \"ribonuleotide\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"ribonucleotide\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"xanthine\" ,",
-    "        match-location equals ,",
+    "        match-text \"ribosimal\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15337,37 +17007,34 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"ribosomal\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"zinc\" ,",
+    "        match-text \"ribosomal RNA\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        ignore-words {",
-    "          {",
-    "            synonyms {",
-    "              \"probable\" ,",
-    "              \"putative\" ,",
-    "              \"hypothetical\" } ,",
-    "            case-sensitive FALSE ,",
-    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -15375,11 +17042,12 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"aluminium\" ,",
+    "        match-text \"ribosoml\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -15389,41 +17057,47 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"aluminum\" ,",
+    "          replace \"ribosomal\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"dimerisation\" ,",
+    "        match-text \"ribossomal\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"dimerization\" ,",
+    "          replace \"ribosomal\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"dimerising\" ,",
+    "        match-text \"rickettsia\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -15433,117 +17107,181 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"dimerizing\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"fibre\" ,",
+    "        match-text \"riobosyltransferase\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"fiber\" ,",
+    "          replace \"ribosyltransferase\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"haem\" ,",
-    "        match-location contains ,",
+    "        match-text \"RNA\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"archaemetzincin\" ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"RNA for\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"rRNA\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
-    "        haem-replace \"haem\" ,",
-    "      move-to-note FALSE } } ,",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"localisation\" ,",
+    "        match-text \"rsponse\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"localization\" ,",
+    "          replace \"response\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"majour\" ,",
+    "        match-text \"Salmonella\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"major\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"mobilisation\" ,",
+    "        match-text \"sapiens\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -15553,63 +17291,88 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"mobilization\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"polymeris\" ,",
-    "        match-location contains ,",
+    "        match-text \"secreted\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"polymeriz\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"sulphate\" ,",
-    "        match-location contains ,",
+    "        match-text \"Serine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"sulfate\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"sulphide\" ,",
+    "        match-text \"serinr\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -15619,115 +17382,231 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"sulfide\" ,",
+    "          replace \"serine\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"tumour\" ,",
+    "        match-text \"serovar\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"tumor\" ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"shotgun\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"shrot\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"short\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"utilisation\" ,",
+    "        match-text \"shrot-chain\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"utilization\" ,",
+    "          replace \"short-chain\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"utilising\" ,",
+    "        match-text \"shutting\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"utilizing\" ,",
+    "          replace \"shuttling\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \";\" ,",
+    "        match-text \"shuttlingfactor\" ,",
     "        match-location contains ,",
-    "        case-sensitive TRUE ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"shuttling factor\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"signal\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"a \" ,",
-    "        match-location starts ,",
-    "        case-sensitive TRUE ,",
+    "        match-text \"signal peptide\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"signal peptide protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative TRUE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"alternate protein name\" ,",
+    "        match-text \"signalling\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -15737,26 +17616,3191 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"signaling\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"similar\" ,",
+    "        match-location starts ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"similiar\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"similar\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"simmilar\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"similar\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"siphovirus\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"sodium\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"solution Nmr\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"solution structure\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"specfic\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"specific\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"specific\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"sphaeroides\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Spodoptera\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"spscific\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"specific\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"sreptomyces\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"stabilisation\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"stabilization\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Staphlococcal\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Staphlococcus\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"staphylococcal\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Staphylococcus\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"start codon\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal TRUE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"streptococcal\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Streptococcus\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"streptomyces\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"strongly conserved\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"strongly similar\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"structual\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"structural\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"structure of\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"subitilus\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"subnit\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"subunit\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"subsp\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Subtilis\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"subunit\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"sugar\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"suger\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"sugar\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"sulfer\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"sulfur\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"sulphate\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"sulfate\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"sulphide\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"sulfide\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"sulpho\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"sulfo\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"sulphur\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"sulfur\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"SWIM zinc finger\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"SWIM zinc finger protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative TRUE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"systhesis\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"synthesis\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"sythase\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"synthase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"tetracenpmycin\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"tetracenomycin\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"thaliana\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"thiamin/thiamin\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"thiamin/thiamine\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"thiamineS\" ,",
+    "        match-location contains ,",
+    "        case-sensitive TRUE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"thiamine S\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"thioderoxin\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"thioredoxin\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"thiredoxin\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"thioredoxin\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"threonin\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"threonine\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Threonine\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"thymine\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"TPA:\" ,",
+    "        match-location starts ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type database ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"TPA_inf\" ,",
+    "        match-location starts ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"trancription\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transcription\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"trancsriptional\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transcription\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"tranferase\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transferase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"tranporter\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transporter\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transcirbed\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transcribed\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transcirption\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transcription\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transcripitonal\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transcriptional\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transcrIpt\" ,",
+    "        match-location contains ,",
+    "        case-sensitive TRUE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transcript\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transcriptionnal \" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transcriptional\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transcriptonal\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transcriptional\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transcritional\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transcriptional\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transebrane\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transmembrane\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transemembrane\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transmembrane\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Transemembrane\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transmembrane\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transerfase\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transferase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transferasee\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transferase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transglycolase\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transglycosylase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Transmebrane\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transmembrane\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transmebrane\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transmembrane\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transmemembrane\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transmembrane\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transorter\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transporter\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transpoase\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transposase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transport-associated\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transport-associated protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transportor\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transporter\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transposase and inactivated derivative\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transposase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transposase and inactivated derivatives\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transposase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transposase and inactive derivative\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transposase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transposase and inactive derivatives\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transposase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transposase of\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transposase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative TRUE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transposase transposase\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transposase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transposases and inactivated derivative\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transposase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transposases and inactivated derivatives\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transposase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transposases and inactive derivative\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transposase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transposases and inactive derivatives\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transposase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transposon\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transproter\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transporter\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"transulfuration\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transsulfuration\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"trasnferase\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transferase\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"trasporter\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transporter\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"tRNA\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"trnasporter\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"transporter\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"truncat\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"trunucated\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"truncated\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Tryptophan\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"ttg start\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"ttg start\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"ttg start codon\" ,",
+    "        match-location equals ,",
+    "        case-sensitive TRUE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Tuberculosis\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"tumefaciens\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"tumour\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"tumor\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Type II\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Typhimurium\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"typr\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"type\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"Tyrosine\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"uknown\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"uncharacterizaed\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"uncharacterized\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"uncharacterized\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"uncharacterized\" ,",
+    "        match-location starts ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"uncharacterized protein\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"uncharacterized protein conserved in bacteria\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"uncharacterized conserved protein\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"uncharacterized\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"uncharacterized domain 1\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"uncharacterized protein\" ,",
+    "        match-location starts ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "      string {",
+    "        match-text \"UPF\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            word \"UPF\" ,",
+    "            synonyms {",
+    "              \"UCP\" ,",
+    "              \"DUF\" ,",
+    "              \"PUF\" ,",
+    "              \"CHP\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word FALSE } } ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"unclassified\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"undecapaprenyl\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"undecaprenyl\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"undefined product\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"undefined product\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"undefined product\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type database ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"unique\" ,",
+    "        match-location starts ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"unique protein\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present TRUE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type typo ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"putative\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"unkn\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"unknow protein\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"unknown\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"unknown\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      field {",
+    "        field",
+    "          feature-field {",
+    "            type cds ,",
+    "            field",
+    "              legal-qual product } ,",
+    "        string-constraint {",
+    "          match-text \"protein of unknown function\" ,",
+    "          match-location contains ,",
+    "          case-sensitive FALSE ,",
+    "          ignore-space FALSE ,",
+    "          ignore-punct FALSE ,",
+    "          whole-word FALSE ,",
+    "          not-present TRUE ,",
+    "          is-all-caps FALSE ,",
+    "          is-all-lower FALSE ,",
+    "          is-all-punct FALSE ,",
+    "          ignore-weasel FALSE ,",
+    "          is-first-cap FALSE ,",
+    "          is-first-each-cap FALSE } } ,",
+    "      field {",
+    "        field",
+    "          feature-field {",
+    "            type cds ,",
+    "            field",
+    "              legal-qual product } ,",
+    "        string-constraint {",
+    "          match-text \"domain of unknown function\" ,",
+    "          match-location contains ,",
+    "          case-sensitive FALSE ,",
+    "          ignore-space FALSE ,",
+    "          ignore-punct FALSE ,",
+    "          whole-word FALSE ,",
+    "          not-present TRUE ,",
+    "          is-all-caps FALSE ,",
+    "          is-all-lower FALSE ,",
+    "          is-all-punct FALSE ,",
+    "          ignore-weasel FALSE ,",
+    "          is-first-cap FALSE ,",
+    "          is-first-each-cap FALSE } } ,",
+    "      string {",
+    "        match-text \"unknown\" ,",
+    "        match-location equals ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct FALSE ,",
+    "        whole-word FALSE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "      string {",
-    "        match-text \"alternative protein name\" ,",
+    "        match-text \"unknown protein\" ,",
     "        match-location equals ,",
-    "        case-sensitive TRUE ,",
+    "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present TRUE ,",
+    "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } } ,",
-    "    rule-type description } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type might-be-nonfunctional ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"and related enzyme\" ,",
-    "        match-location ends ,",
+    "        match-text \"unknown domain\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15765,19 +20809,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"and related enzymes\" ,",
-    "        match-location ends ,",
+    "        match-text \"unknown function\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15786,19 +20834,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"and related protein\" ,",
-    "        match-location ends ,",
+    "        match-text \"unknown protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15807,19 +20859,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"and related proteins\" ,",
-    "        match-location ends ,",
+    "        match-text \"unkown\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15828,19 +20884,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
+    "          replace \"unknown\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"CDS\" ,",
-    "        match-location contains ,",
+    "        match-text \"unnamed\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15849,13 +20909,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"function\" ,",
-    "        match-location starts ,",
+    "        match-text \"unnamed\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15864,28 +20934,31 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"highly conserved\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    feat-constraint {",
+    "      string {",
+    "        match-text \"unnamed\" ,",
+    "        match-location equals ,",
+    "        case-sensitive TRUE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
     "        whole-word FALSE ,",
-    "        not-present FALSE ,",
+    "        not-present TRUE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"identity\" ,",
-    "        match-location contains ,",
+    "        match-text \"unnamed protein product\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15894,13 +20967,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"inactivated derivative\" ,",
-    "        match-location contains ,",
+    "        match-text \"unspecified product\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15909,28 +20992,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"Includes:\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"narrowly conserved\" ,",
-    "        match-location contains ,",
+    "        match-text \"unusual protein\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15939,25 +21017,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"novel\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    except",
-    "      string-constraint {",
-    "        match-text \"novel protein\" ,",
+    "        match-text \"UPF\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -15967,12 +21042,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type description } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protein associated to\" ,",
+    "        match-text \"UPF\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -15982,13 +21067,13 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description } ,",
-    "  {",
-    "    find",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    except",
     "      string-constraint {",
-    "        match-text \"ttg start\" ,",
-    "        match-location contains ,",
+    "        match-text \"UPF\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -15997,68 +21082,48 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"ttg start codon\" ,",
-    "        match-location equals ,",
-    "        case-sensitive TRUE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } } ,",
-    "    rule-type description } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type database ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"unnamed\" ,",
-    "        match-location contains ,",
-    "        case-sensitive FALSE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
-    "        not-present FALSE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    feat-constraint {",
-    "      string {",
-    "        match-text \"unnamed\" ,",
+    "        match-text \"uracil\" ,",
     "        match-location equals ,",
-    "        case-sensitive TRUE ,",
-    "        ignore-space FALSE ,",
-    "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
-    "        not-present TRUE ,",
-    "        is-all-caps FALSE ,",
-    "        is-all-lower FALSE ,",
-    "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } } ,",
-    "    rule-type description } ,",
-    "  {",
-    "    find",
-    "      string-constraint {",
-    "        match-text \"weakly conserved\" ,",
-    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"widely conserved\" ,",
+    "        match-text \"utilisation\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -16068,130 +21133,166 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type description } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"utilization\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"gene\" ,",
+    "        match-text \"utilising\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type gene } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type british ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"utilizing\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"genes\" ,",
-    "        match-location contains ,",
+    "        match-text \"UTP\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
-    "    rule-type gene } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
+    "    replace {",
+    "      replace-func",
+    "        simple-replace {",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
+    "          weasel-to-putative FALSE } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"claster\" ,",
-    "        match-location contains ,",
+    "        match-text \"Valine\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"cluster\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putativie\" ,",
+    "        match-text \"vigtamin\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
+    "          replace \"vitamin\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"putativ\" ,",
+    "        match-text \"weakly conserved\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"putative\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ysine\" ,",
+    "        match-text \"widely conserved\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word TRUE ,",
+    "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"lysine\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type description ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"unknow protein\" ,",
+    "        match-text \"xanthine\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -16201,19 +21302,22 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
-    "          whole-string FALSE ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"lacitehtopyh\" ,",
+    "        match-text \"xenopus\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -16223,20 +21327,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
-    "          whole-string FALSE ,",
+    "          replace \"hypothetical protein\" ,",
+    "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"protein of\" ,",
-    "        match-location equals ,",
+    "        match-text \"xray structure\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -16245,174 +21352,191 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"g:t\" ,",
-    "        match-location equals ,",
+    "        match-text \"yeast\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Archaeal\" ,",
-    "        match-location equals ,",
+    "        match-text \"YeeEYedE\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"YeeE/YedE\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"ABC-type polysaccharide\" ,",
-    "        match-location equals ,",
+    "        match-text \"Yersinia\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type remove-organism-name ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Calcium\" ,",
-    "        match-location equals ,",
+    "        match-text \"YjgPYjgQ\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"YjgP/YjgQ\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Na+\" ,",
-    "        match-location equals ,",
+    "        match-text \"ypothetical\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Ni\" ,",
-    "        match-location equals ,",
+    "        match-text \"ysine\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"lysine\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Oxalate\" ,",
-    "        match-location equals ,",
+    "        match-text \"ytochrome\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"cytochrome\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Maltose\" ,",
-    "        match-location equals ,",
+    "        match-text \"yypothetical\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -16421,29 +21545,42 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"hypothetical\" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Protein putative protein\" ,",
+    "        match-text \"zinc\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
+    "        ignore-words {",
+    "          {",
+    "            synonyms {",
+    "              \"probable\" ,",
+    "              \"putative\" ,",
+    "              \"hypothetical\" } ,",
+    "            case-sensitive FALSE ,",
+    "            whole-word TRUE } } ,",
     "        whole-word FALSE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -16451,11 +21588,12 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note TRUE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Type II\" ,",
+    "        match-text \"zinc finger\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -16465,20 +21603,23 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "          replace \"zinc finger protein\" ,",
+    "          whole-string FALSE ,",
+    "          weasel-to-putative TRUE } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"membrane protein of\" ,",
-    "        match-location equals ,",
+    "        match-text \"\\\" ,",
+    "        match-location ends ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -16487,20 +21628,16 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type typo ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"membrane protein\" ,",
-    "          whole-string FALSE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \":\" ,",
-    "        match-location starts ,",
+    "        match-text \"\\\\-PA\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -16509,13 +21646,16 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type inappropriate-symbol } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"sugar\" ,",
-    "        match-location equals ,",
+    "        match-text \"_\" ,",
+    "        match-location ends ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -16524,20 +21664,21 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
+    "  {",
+    "    find",
+    "      underscore NULL ,",
+    "    rule-type database ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"galactose\" ,",
-    "        match-location equals ,",
+    "        match-text \"|\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -16546,51 +21687,52 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
-    "    replace {",
-    "      replace-func",
-    "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
-    "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type inappropriate-symbol ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hyppothetical\" ,",
+    "        match-text \"familly\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical\" ,",
+    "          replace \"family\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"hypotheticial\" ,",
+    "        match-text \"hypotheitical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
@@ -16598,56 +21740,63 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"organise\" ,",
+    "        match-text \"hypopthetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"organize\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"isation\" ,",
+    "        match-text \"hypothetetical\" ,",
     "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
-    "        whole-word FALSE ,",
+    "        whole-word TRUE ,",
     "        not-present FALSE ,",
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type british ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"ization\" ,",
+    "          replace \"hypothetical\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"Giardia\" ,",
-    "        match-location contains ,",
+    "        match-text \"no product string in file\" ,",
+    "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -16656,12 +21805,15 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type remove-organism-name } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type none ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"specific\" ,",
+    "        match-text \"distantly\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -16671,7 +21823,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -16679,11 +21833,12 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"peptidyl-prolyl cis-trans\" ,",
+    "        match-text \"protein distantly\" ,",
     "        match-location equals ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
@@ -16693,7 +21848,9 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type hypothetical ,",
     "    replace {",
     "      replace-func",
@@ -16701,12 +21858,13 @@ static const char* const s_Defaultproductrules[] = {
     "          replace \"hypothetical protein\" ,",
     "          whole-string TRUE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"inorganic phosphate\" ,",
-    "        match-location equals ,",
+    "        match-text \"ifunctional \" ,",
+    "        match-location starts ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -16715,20 +21873,41 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel TRUE } ,",
-    "    rule-type hypothetical ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"hypothetical protein\" ,",
-    "          whole-string TRUE ,",
+    "          replace \"bifunctional \" ,",
+    "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note TRUE } } ,",
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } ,",
     "  {",
     "    find",
     "      string-constraint {",
-    "        match-text \"likely\" ,",
-    "        match-location starts ,",
+    "        match-text \"refseq\" ,",
+    "        match-location contains ,",
+    "        case-sensitive FALSE ,",
+    "        ignore-space FALSE ,",
+    "        ignore-punct TRUE ,",
+    "        whole-word TRUE ,",
+    "        not-present FALSE ,",
+    "        is-all-caps FALSE ,",
+    "        is-all-lower FALSE ,",
+    "        is-all-punct FALSE ,",
+    "        ignore-weasel TRUE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
+    "    rule-type none ,",
+    "    fatal TRUE } ,",
+    "  {",
+    "    find",
+    "      string-constraint {",
+    "        match-text \"casette\" ,",
+    "        match-location contains ,",
     "        case-sensitive FALSE ,",
     "        ignore-space FALSE ,",
     "        ignore-punct FALSE ,",
@@ -16737,13 +21916,16 @@ static const char* const s_Defaultproductrules[] = {
     "        is-all-caps FALSE ,",
     "        is-all-lower FALSE ,",
     "        is-all-punct FALSE ,",
-    "        ignore-weasel FALSE } ,",
+    "        ignore-weasel FALSE ,",
+    "        is-first-cap FALSE ,",
+    "        is-first-each-cap FALSE } ,",
     "    rule-type typo ,",
     "    replace {",
     "      replace-func",
     "        simple-replace {",
-    "          replace \"putative\" ,",
+    "          replace \"cassette\" ,",
     "          whole-string FALSE ,",
     "          weasel-to-putative FALSE } ,",
-    "      move-to-note FALSE } } }"
+    "      move-to-note FALSE } ,",
+    "    fatal FALSE } }"
 };
diff --git a/c++/src/objects/macro/product_rules.prt b/c++/src/objects/macro/product_rules.prt
index 277d46f..06f1abf 100644
--- a/c++/src/objects/macro/product_rules.prt
+++ b/c++/src/objects/macro/product_rules.prt
@@ -1,74 +1,147 @@
 Suspect-rule-set ::= {
   {
     find
+      contains-plural NULL ,
+    rule-type putative-typo ,
+    fatal FALSE } ,
+  {
+    find
+      three-numbers NULL ,
+    except
       string-constraint {
-        match-text " citochrome" ,
+        match-text "methyltransferas" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            word "methyltransferas" ,
+            synonyms {
+              "F420" ,
+              "FK506" } ,
+            case-sensitive FALSE ,
+            whole-word FALSE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "cytochrome" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "16S rRNA pseudouridine(516) synthase" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text " 23S rRNA pseudouridine(955/2504/2580) synthase" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "23S rRNA pseudouridine(1911/1915/1917) synthase" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type database ,
+    description "contains three or more numbers together that may be
+ identifiers more appropriate in note" ,
+    fatal FALSE } ,
   {
     find
-      string-constraint {
-        match-text " cytochome" ,
+      all-caps NULL ,
+    rule-type putative-typo ,
+    fatal FALSE } ,
+  {
+    find
+      unbalanced-paren NULL ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
+  {
+    find
+      too-long 100 ,
+    feat-constraint {
+      string {
+        match-text "multifunctional" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "cytochrome" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
-  {
-    find
-      string-constraint {
-        match-text " cytochorme" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "bifunctional" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "cytochrome" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "acetylglucosamine" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type description ,
+    description "Is longer than 100 characters. Remove descriptive phrases or
+ synonyms from product names. Keep valid long product names, eg long enzyme
+ names" ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "accessroy" ,
+        match-text " Anopheles" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -78,19 +151,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "accessory" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "aceytltranferase" ,
+        match-text " citochrome" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -100,19 +176,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "acetyltransferase" ,
+          replace "cytochrome" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "adenylattransferase" ,
+        match-text " cytochome" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -122,19 +201,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "adenylate transferase" ,
+          replace "cytochrome" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "adenylytransferase" ,
+        match-text " cytochorme" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -144,107 +226,94 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "adenylyltransferase" ,
+          replace "cytochrome" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "alchohol" ,
+        match-text "#" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "alcohol" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "aminomutaseaminotransferase" ,
+        match-text "%" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "aminomutase aminotransferase" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "aminotransferasee" ,
+        match-text "&apos" ,
         match-location contains ,
-        case-sensitive FALSE ,
+        case-sensitive TRUE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "aminotransferase" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type database ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "aminotransferease" ,
-        match-location contains ,
+        match-text "'" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "aminotransferase" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "aparaginase" ,
+        match-text "()" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -254,64 +323,52 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "asparaginase" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "archael" ,
+        match-text "(TC " ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "archaeal" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type database ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "arginin " ,
-        match-location contains ,
+        match-text "," ,
+        match-location ends ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "arginine " ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "argininte" ,
-        match-location contains ,
+        match-text "," ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -320,20 +377,16 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "arginine" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "asparate" ,
-        match-location contains ,
+        match-text "-" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -342,64 +395,52 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "aspartate" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "assemby" ,
-        match-location contains ,
+        match-text "-" ,
+        match-location ends ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "assembly" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "assessory" ,
-        match-location contains ,
+        match-text "." ,
+        match-location ends ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "accessory" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "bifunctionnal" ,
-        match-location contains ,
+        match-text "." ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -408,19 +449,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "bifunctional" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "bigenesis" ,
+        match-text ". " ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -430,43 +467,35 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "biogenesis" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "bioin" ,
+        match-text ".," ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "biotin" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "biosyntesis" ,
+        match-text "./" ,
         match-location contains ,
-        case-sensitive FALSE ,
+        case-sensitive TRUE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
@@ -474,20 +503,16 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "biosynthesis" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "biosythesis" ,
-        match-location contains ,
+        match-text "/" ,
+        match-location ends ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -496,64 +521,90 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "biosynthesis" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "bnding" ,
-        match-location contains ,
+        match-text "16S ribosomal RNA" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            word "16S" ,
+            synonyms {
+              "18S" ,
+              "28S" ,
+              "5S" ,
+              "5.8S" ,
+              "23S" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "binding" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    description "equals ribosomal RNA" ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "calchone" ,
-        match-location contains ,
+        match-text "16S rRNA" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            word "16S" ,
+            synonyms {
+              "18S" ,
+              "28S" ,
+              "5S" ,
+              "5.8S" ,
+              "23S" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "chalcone" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    description "equals rRNA" ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "candidate" ,
-        match-location starts ,
+        match-text ":" ,
+        match-location ends ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -562,34 +613,35 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "candidate protein" ,
-        match-location equals ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text ":" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "carboxilic" ,
+        match-text ";" ,
         match-location contains ,
-        case-sensitive FALSE ,
+        case-sensitive TRUE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
@@ -597,19 +649,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "carboxylic" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "cell divisionFtsK/SpoIIIE" ,
+        match-text "=" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -619,19 +667,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "cell division FtsK/SpoIIIE" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "characteris" ,
+        match-text "?" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -641,21 +685,17 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "characteriz" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "charateriz" ,
+        match-text "@" ,
         match-location contains ,
-        case-sensitive FALSE ,
+        case-sensitive TRUE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
@@ -663,85 +703,83 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "characteriz" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "CHC2 zinc finger" ,
-        match-location equals ,
-        case-sensitive FALSE ,
+        match-text "a " ,
+        match-location starts ,
+        case-sensitive TRUE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "CHC2 zinc finger protein" ,
-          whole-string FALSE ,
-          weasel-to-putative TRUE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "chelatin" ,
-        match-location contains ,
+        match-text "ABC-type polysaccharide" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "chelating" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "chroamtid" ,
+        match-text "accessroy" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "chromatid" ,
+          replace "accessory" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "coantaining" ,
+        match-text "aceytltranferase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -751,41 +789,55 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "containing" ,
+          replace "acetyltransferase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "coenzye" ,
-        match-location contains ,
+        match-text "adenine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "coenzyme" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "compnent" ,
+        match-text "adenylattransferase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -795,19 +847,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "component" ,
+          replace "adenylate transferase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "componenet" ,
+        match-text "adenylytransferase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -817,20 +872,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "component" ,
+          replace "adenylyltransferase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "componnent" ,
-        match-location contains ,
+        match-text "ADP" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -839,108 +897,131 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "component" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserv" ,
+        match-text "Agrobacterium" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "conserved" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Conservd" ,
-        match-location contains ,
+        match-text "Alanine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "conserved" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "consevered" ,
+        match-text "alchohol" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "conserved" ,
+          replace "alcohol" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "contain" ,
-        match-location contains ,
+        match-text "alpha" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "containing" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "containg" ,
-        match-location contains ,
+        match-text "alpha-1" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -949,41 +1030,40 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "containing" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "containinging" ,
+        match-text "alternate gene name" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "containing" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "converved" ,
+        match-text "alternate name" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -993,41 +1073,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "conserved" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "coserved" ,
-        match-location contains ,
+        match-text "alternate protein name" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "conserved" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "cotaining" ,
+        match-text "alternate protein name" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1037,19 +1124,30 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "containing" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "alternative protein name" ,
+        match-location equals ,
+        case-sensitive TRUE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "degration" ,
+        match-text "aluminium" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1059,41 +1157,55 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
     replace {
       replace-func
         simple-replace {
-          replace "degradation" ,
+          replace "aluminum" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "dependant" ,
-        match-location contains ,
+        match-text "amino acid" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "dependent" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "deulfurase" ,
+        match-text "aminomutaseaminotransferase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1103,19 +1215,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "desulfurase" ,
+          replace "aminomutase aminotransferase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "deydrogenase" ,
+        match-text "aminotransferasee" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1125,19 +1240,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "dehydrogenase" ,
+          replace "aminotransferase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "diacyglycerol" ,
+        match-text "aminotransferease" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1147,64 +1265,66 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "diacylglycerol" ,
+          replace "aminotransferase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "dioxyenase" ,
+        match-text "aminotransferease" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "dioxygenase" ,
+          replace "aminotransferase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "disulphide" ,
+        match-text "analog" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "disulfide" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type evolutionary-relationship ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "divison" ,
-        match-location contains ,
+        match-text "and related enzyme" ,
+        match-location ends ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -1213,42 +1333,46 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
     replace {
       replace-func
         simple-replace {
-          replace "division" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domain domain" ,
-        match-location contains ,
+        match-text "and related enzymes" ,
+        match-location ends ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
     replace {
       replace-func
         simple-replace {
-          replace "domain" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domain of unknown function" ,
-        match-location starts ,
+        match-text "and related protein" ,
+        match-location ends ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -1257,78 +1381,45 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    feat-constraint {
-      string {
-        match-text "domain of unknown function" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-      string {
-        match-text "domain of unknown function family protein" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-      string {
-        match-text "domain of unknown function protein" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel TRUE } } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
     replace {
       replace-func
         simple-replace {
-          replace "protein of unknown function" ,
           whole-string FALSE ,
-          weasel-to-putative TRUE } ,
-      move-to-note FALSE } } ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domain protein domain protein" ,
-        match-location contains ,
+        match-text "and related proteins" ,
+        match-location ends ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
     replace {
       replace-func
         simple-replace {
-          replace "domain protein" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domainl" ,
+        match-text "animal" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1338,20 +1429,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "domain" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domian" ,
-        match-location contains ,
+        match-text "anion" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -1360,19 +1454,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "domain" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "dyhydrogenase" ,
+        match-text "aparaginase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1382,42 +1479,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "dehydrogenase" ,
+          replace "asparaginase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "dyhydrogenase" ,
+        match-text "Arabidopsis" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "dihydrogenase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "enentioselective" ,
-        match-location contains ,
+        match-text "Archaeal" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -1426,41 +1529,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "enantioselective" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "enzymye" ,
+        match-text "archael" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "enzyme" ,
+          replace "archaeal" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ErfKYbiSYcfSYnhG" ,
+        match-text "arginin " ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1470,41 +1579,55 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "ErfK/YbiS/YcfS/YnhG" ,
+          replace "arginine " ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "exporte" ,
-        match-location contains ,
+        match-text "Arginine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "exported" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "facotr" ,
+        match-text "argininte" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1514,86 +1637,114 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "factor" ,
+          replace "arginine" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "fagella" ,
-        match-location contains ,
+        match-text "Asparagine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "flagella" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "familie" ,
+        match-text "asparate" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "family" ,
+          replace "aspartate" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "family family" ,
-        match-location contains ,
+        match-text "Aspartic acid" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "family" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "flageller" ,
-        match-location contains ,
+        match-text "aspartyl" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -1602,107 +1753,130 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "flagellar" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "gIycerol" ,
+        match-text "Aspergillus" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "glycerol" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "glcosyl" ,
+        match-text "assemby" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "glycosyl" ,
+          replace "assembly" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "glucosainyl" ,
+        match-text "assessory" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "glucosaminyl" ,
+          replace "accessory" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "glutaminne" ,
-        match-location contains ,
+        match-text "ATP" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "glutamine" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "glycin" ,
+        match-text "ATPas" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1712,19 +1886,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "glycine" ,
+          replace "ATPase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "glycosy" ,
+        match-text "aureus" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1734,19 +1911,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "glucosyl" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "heam" ,
+        match-text "authentic point mutation" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1756,16 +1936,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        haem-replace "haem" ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
+    fatal TRUE } ,
   {
     find
       string-constraint {
-        match-text "heavychain" ,
+        match-text "B.subtilis" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1775,49 +1954,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "heavy chain" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "helix-turn-helix" ,
-        match-location equals ,
+        match-text "Bacilllus" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "helix-turn-helix protein" ,
-          whole-string FALSE ,
-          weasel-to-putative TRUE } ,
-      move-to-note FALSE } } ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hemaggltinin" ,
+        match-text "Bacillus" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1827,19 +2004,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "hemagglutinin" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hemelysin" ,
+        match-text "Bacterioides" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -1849,130 +2029,164 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "hemolysin" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hemoglobine" ,
-        match-location contains ,
+        match-text "bacteriophage" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hemoglobin" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hexapaptide" ,
+        match-text "Bacteroides" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "hexapeptide" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hexpeptide" ,
-        match-location contains ,
+        match-text "barrel" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hexapeptide" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "histadine" ,
-        match-location contains ,
+        match-text "believed" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "histidine" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "histide" ,
+        match-text "bifuctional" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "histidine" ,
+          replace "bifunctional" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "homeserine" ,
-        match-location contains ,
+        match-text "bifunctional" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -1981,107 +2195,122 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "homoserine" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "homlog" ,
+        match-text "bifunctionnal" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "homolog" ,
+          replace "bifunctional" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "homocystein" ,
+        match-text "bigenesis" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "homocysteine" ,
+          replace "biogenesis" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hpothetical" ,
-        match-location contains ,
+        match-text "binds" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hydrolases of the alpha/beta superfamily" ,
-        match-location equals ,
+        match-text "bioin" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hydrolase of the alpha/beta superfamily" ,
+          replace "biotin" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hyopothetical" ,
+        match-text "biosyntesis" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -2091,19 +2320,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
+          replace "biosynthesis" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hyopthetical" ,
+        match-text "biosythesis" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -2113,20 +2345,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
+          replace "biosynthesis" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hyothetical" ,
-        match-location contains ,
+        match-text "bis" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -2135,19 +2370,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hyperthetical" ,
+        match-text "bnding" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -2157,41 +2395,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
+          replace "binding" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hyphotetical" ,
+        match-text "Bombyx" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hyphotheical" ,
+        match-text "bos taurus" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -2201,20 +2445,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypohetical" ,
-        match-location contains ,
+        match-text "c-terminal domain protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -2223,64 +2470,73 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypot" ,
-        match-location contains ,
+        match-text "C-terminus" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypotehtical" ,
+        match-text "calchone" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
+          replace "chalcone" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypotethical" ,
-        match-location contains ,
+        match-text "Calcium" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -2289,41 +2545,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypotetical" ,
+        match-text "Campylobacter" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypoth" ,
+        match-text "Candida" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -2333,63 +2595,95 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypothe" ,
-        match-location contains ,
+        match-text "candidate" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "candidate protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
+          replace "putative" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypotheical" ,
-        match-location contains ,
+        match-text "carbon" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypotheitcal" ,
+        match-text "carboxilic" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -2399,85 +2693,90 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
+          replace "carboxylic" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypotherical" ,
+        match-text "catalize" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
+          replace "catalyze" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypothet" ,
-        match-location contains ,
+        match-text "CBS domain pair" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypothetcial" ,
+        match-text "CDS" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypothethical" ,
+        match-text "cell divisionFtsK/SpoIIIE" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -2487,19 +2786,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
+          replace "cell division FtsK/SpoIIIE" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypotheti" ,
+        match-text "cerevisiae" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -2509,269 +2811,248 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypothetic" ,
-        match-location contains ,
+        match-text "Changed start to match that seen in other orgs" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypothetica" ,
-        match-location contains ,
+        match-text "Changed start to match that seen in other orgs" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypothetical" ,
-        match-location starts ,
+        match-text "characteris" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "hypothetical protein" ,
-        match-location equals ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "characteriz" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "charateriz" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-      string {
-        match-text "hypothetical domain protein" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "characteriz" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "CHC2 zinc finger" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-      string {
-        match-text "hypothetical ORF" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-      string {
-        match-text "hypothetical" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-      string {
-        match-text "Hypothetical conserved protein" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-      string {
-        match-text "hypothetical protein" ,
-        match-location starts ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word TRUE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-      string {
-        match-text "UPF" ,
-        match-location contains ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        ignore-words {
-          {
-            word "UPF" ,
-            synonyms {
-              "UCP" ,
-              "DUF" ,
-              "PUF" ,
-              "CHP" } ,
-            case-sensitive FALSE ,
-            whole-word FALSE } } ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "CHC2 zinc finger protein" ,
           whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+          weasel-to-putative TRUE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypotheticalprotein" ,
+        match-text "chelatin" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
+          replace "chelating" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypothteical" ,
+        match-text "Chlamydial" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypothtical" ,
+        match-text "Chlamydomonas" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypthetical" ,
+        match-text "chlorAMPhenicol" ,
         match-location contains ,
-        case-sensitive FALSE ,
+        case-sensitive TRUE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
+          replace "chloramphenicol " ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hyptothetical" ,
-        match-location contains ,
+        match-text "chloroplastic" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -2780,86 +3061,106 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hyputhetical" ,
+        match-text "chroamtid" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
+          replace "chromatid" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "incolved" ,
-        match-location contains ,
+        match-text "citrate" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "involved" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "inductible" ,
+        match-text "claster" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "inducible" ,
+          replace "cluster" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "initation" ,
-        match-location contains ,
+        match-text "clustered with" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -2868,41 +3169,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "initiation" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "insitol" ,
+        match-text "coantaining" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "inositol" ,
+          replace "containing" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Intiation" ,
+        match-text "coenzye" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -2912,41 +3219,37 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "initiation" ,
+          replace "coenzyme" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "invertion" ,
+        match-text "COG" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "inversion" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
-  {
-    find
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    except
       string-constraint {
-        match-text "IS ORF" ,
+        match-text "COG" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -2956,20 +3259,16 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "IS protein" ,
-          whole-string FALSE ,
-          weasel-to-putative TRUE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type database ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "isomaerase" ,
-        match-location contains ,
+        match-text "COG" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -2978,19 +3277,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "isomerase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "isomerse" ,
+        match-text "COGnitor" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -3000,19 +3302,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "isomerase" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "K potassium" ,
+        match-text "coli" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -3022,107 +3320,105 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "potassium" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
-  {
-    find
-      string-constraint {
-        match-text "K+ potassium" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "adenomatous polyposis coli " ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
-        not-present FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "potassium" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mambrane" ,
+        match-text "colour" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
     replace {
       replace-func
         simple-replace {
-          replace "membrane" ,
+          replace "color" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "meausure" ,
+        match-text "complete" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "measure" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "medated" ,
+        match-text "compnent" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "mediated" ,
+          replace "component" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "membraneprotein" ,
+        match-text "componenet" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -3132,19 +3428,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "membrane protein" ,
+          replace "component" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "membranetransport" ,
+        match-text "componnent" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -3154,63 +3453,80 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "membrane transport" ,
+          replace "component" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "membranne" ,
-        match-location contains ,
+        match-text "conser" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "membrane" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "membtrane" ,
+        match-text "conserv" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "membrane" ,
+          replace "conserved" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "memebrane" ,
+        match-text "Conservd" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -3220,108 +3536,147 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "membrane" ,
+          replace "conserved" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "methlytransferase" ,
-        match-location contains ,
+        match-text "conserve" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "methyltransferase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "metylase" ,
-        match-location contains ,
+        match-text "conserved" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "methylase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mitchondrial" ,
-        match-location contains ,
+        match-text "conserved domain protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "mitochondrial" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "molibdenum" ,
-        match-location contains ,
+        match-text "conserved hypothetical" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "molybdenum" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "molybopterin" ,
-        match-location contains ,
+        match-text "conserved hypothetical domain protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -3330,20 +3685,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "molybdopterin" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "molydopterin" ,
-        match-location contains ,
+        match-text "conserved hypothetical family protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -3352,42 +3710,56 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "molybdopterin" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "monooxigenase" ,
-        match-location contains ,
+        match-text "conserved hypothetical protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "monooxygenase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "monoxyde" ,
-        match-location contains ,
+        match-text "conserved predicted domain protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -3396,20 +3768,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "monoxide" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "monoxygenase" ,
-        match-location contains ,
+        match-text "conserved predicted protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -3418,20 +3793,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "monooxygenase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mulitdrug" ,
-        match-location contains ,
+        match-text "conserved protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -3440,20 +3818,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "multidrug" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mulitfunction" ,
-        match-location contains ,
+        match-text "conserved protein of unknown function" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -3462,42 +3843,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "multifunction" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mutatrotase" ,
-        match-location contains ,
+        match-text "conserved putative protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "mutarotase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mutlifunction" ,
-        match-location contains ,
+        match-text "Conserved subname: full" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -3506,20 +3893,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "multifunction" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mypothetical" ,
-        match-location contains ,
+        match-text "Conserved with" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -3528,41 +3918,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mythylglyoxyl " ,
+        match-text "consevered" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "methylglyoxyl" ,
+          replace "conserved" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ncharacterized" ,
+        match-text "contain" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -3572,42 +3968,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "uncharacterized" ,
+          replace "containing" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ndoribonuclease" ,
+        match-text "containg" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "endoribonuclease" ,
+          replace "containing" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "nickle" ,
-        match-location contains ,
+        match-text "containing" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -3616,20 +4018,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "nickel" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "novel" ,
-        match-location starts ,
+        match-text "containinging" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -3638,54 +4043,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "novel protein" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "containing" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ntegral " ,
-        match-location contains ,
+        match-text "contains" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "integral " ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "nucear" ,
+        match-text "contig" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -3695,19 +4093,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "nuclear" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "nucelar" ,
+        match-text "converved" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -3717,19 +4111,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "nuclear" ,
+          replace "conserved" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "nucleotydyl" ,
+        match-text "coserved" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -3739,173 +4136,207 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "nucleotidyl" ,
+          replace "conserved" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "nucletide" ,
+        match-text "cotaining" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "nucleotide" ,
+          replace "containing" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "nulcear" ,
+        match-text "Critica" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "nuclear" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "nulceotide" ,
+        match-text "Crystal Structure" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "nucleotide" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "obalt" ,
-        match-location contains ,
+        match-text "CTP" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "cobalt" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "odule" ,
-        match-location contains ,
+        match-text "Cysteine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "module" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Outative" ,
-        match-location contains ,
+        match-text "cytosine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "outers" ,
+        match-text "database" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "outer" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "no significant database hits" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type database ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "oxidoreducatse" ,
+        match-text "degration" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -3915,41 +4346,40 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "oxidoreductase" ,
+          replace "degradation" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "oxidoreductasee" ,
+        match-text "deletion" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "oxidoreductase" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "oxidoreductasse" ,
+        match-text "dependant" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -3959,64 +4389,73 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "oxidoreductase" ,
+          replace "dependent" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "oxidoredutase" ,
+        match-text "deulfurase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "oxidoreductase" ,
+          replace "desulfurase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "oxidoreduxtase" ,
+        match-text "deydrogenase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "oxidoreductase" ,
+          replace "dehydrogenase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "oxigenase" ,
-        match-location contains ,
+        match-text "di" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -4025,101 +4464,97 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "oxygenase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "oxydase" ,
+        match-text "diacyglycerol" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "oxidase" ,
+          replace "diacylglycerol" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "p-loop" ,
-        match-location equals ,
+        match-text "dimerisation" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
     replace {
       replace-func
         simple-replace {
-          replace "p-loop protein" ,
+          replace "dimerization" ,
           whole-string FALSE ,
-          weasel-to-putative TRUE } ,
-      move-to-note FALSE } } ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "PASTA" ,
-        match-location equals ,
+        match-text "dimerising" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
     replace {
       replace-func
         simple-replace {
-          replace "PASTA protein" ,
+          replace "dimerizing" ,
           whole-string FALSE ,
-          weasel-to-putative TRUE } ,
-      move-to-note FALSE } } ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "peptidodoglycan" ,
+        match-text "dioxyenase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -4129,20 +4564,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "peptidoglycan" ,
+          replace "dioxygenase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "periplamic" ,
-        match-location contains ,
+        match-text "dipeptide" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -4151,19 +4589,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "periplasmic" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "periplasmc" ,
+        match-text "disulphide" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -4173,19 +4614,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "periplasmic" ,
+          replace "disulfide" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "periplsmic" ,
+        match-text "divison" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -4195,41 +4639,55 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "periplasmic" ,
+          replace "division" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "petidase" ,
-        match-location contains ,
+        match-text "DNA" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "peptidase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "pheremone" ,
+        match-text "DNA for" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -4239,42 +4697,49 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "pheromone" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "phophate" ,
-        match-location contains ,
+        match-text "domain" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "phosphate" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "phopho" ,
-        match-location contains ,
+        match-text "domain 1" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -4283,108 +4748,182 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "phospho" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "phophoserine" ,
+        match-text "domain domain" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "phosphoserine" ,
+          replace "domain" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "phoshate" ,
-        match-location contains ,
+        match-text "domain family" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "phosphate" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "phospatase" ,
-        match-location contains ,
+        match-text "domain of unknown function" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "phosphatase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "phosphateN" ,
-        match-location contains ,
+        match-text "domain of unknown function" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "domain of unknown function" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "domain of unknown function family protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "domain of unknown function protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "phosphate N" ,
+          replace "protein of unknown function" ,
           whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+          weasel-to-putative TRUE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "phosphatidyltransferse" ,
-        match-location contains ,
+        match-text "domain of unknown function family protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -4393,20 +4932,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "phosphatidyltransferase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "phosphatransferase" ,
-        match-location contains ,
+        match-text "domain of unknown function family protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -4415,42 +4957,56 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "phosphotransferase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "phosphopantethiene" ,
-        match-location contains ,
+        match-text "domain of unknown function protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "phosphopantetheine" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "phosphotase" ,
-        match-location contains ,
+        match-text "domain protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -4459,42 +5015,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "phosphatase" ,
+          replace "hypothetical protein" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "polimerase" ,
+        match-text "domain protein domain protein" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "polymerase" ,
+          replace "domain protein" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Portein" ,
-        match-location contains ,
+        match-text "domain-containing protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -4503,19 +5065,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "portein" ,
+        match-text "domainl" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -4525,19 +5090,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
+          replace "domain" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "posible" ,
+        match-text "domian" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -4547,54 +5115,73 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "possible" ,
+          replace "domain" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "possible" ,
-        match-location starts ,
+        match-text "doubtful" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "possible protein" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
+    fatal TRUE } ,
+  {
+    find
+      string-constraint {
+        match-text "doubtful CDS found within S. typhi pathogenicity island" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "poteasome" ,
+        match-text "Drosophila" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -4604,20 +5191,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "proteasome" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "potential" ,
-        match-location starts ,
+        match-text "DUF" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -4626,145 +5216,130 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "potential protein" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    except
+      string-constraint {
+        match-text "DUF" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type database ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "precurso" ,
-        match-location contains ,
+        match-text "DUF" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "precursor" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "precusor" ,
+        match-text "dyhydrogenase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "precursor" ,
+          replace "dihydrogenase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "predicted" ,
-        match-location starts ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word TRUE ,
-        not-present FALSE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "predicted protein" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-      string {
-        match-text "Predicted:" ,
-        match-location starts ,
+        match-text "dyhydrogenase" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "dehydrogenase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Predicted:" ,
-        match-location starts ,
+        match-text "E.coli" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "predictedprotein" ,
+        match-text "ECOLI" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -4774,19 +5349,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "predicted protein" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "predictet" ,
+        match-text "enentioselective" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -4796,41 +5374,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "predicted" ,
+          replace "enantioselective" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "presursor" ,
+        match-text "enterica" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "precursor" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "probabable" ,
+        match-text "enzymye" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -4840,20 +5424,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "probable" ,
+          replace "enzyme" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "probable" ,
-        match-location starts ,
+        match-text "ErfKYbiSYcfSYnhG" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -4862,55 +5449,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "probable protein" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "ErfK/YbiS/YcfS/YnhG" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "probable putative" ,
+        match-text "Escherichia" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "proein" ,
-        match-location contains ,
+        match-text "EST" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -4919,76 +5499,108 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "proposed" ,
-        match-location starts ,
+        match-text "EST" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "proposed protein" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    except
+      string-constraint {
+        match-text "EST" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type database ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "proptein" ,
+        match-text "et al" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct TRUE ,
+        ignore-words {
+          {
+            word "et al" ,
+            synonyms {
+              "unpublished" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } ,
+          {
+            word "et al" ,
+            synonyms {
+              "citation" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } ,
+          {
+            word "et al" ,
+            synonyms {
+              "published" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    except
+      string-constraint {
+        match-text "resuscitation" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "protein" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type database ,
+    description "may contain publication reference" ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "prortein" ,
+        match-text "evidenced by" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -4998,19 +5610,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "protein" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protazoan" ,
+        match-text "exporte" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -5020,42 +5628,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "protozoan" ,
+          replace "exported" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protei" ,
-        match-location contains ,
+        match-text "expressed" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protein protein" ,
-        match-location contains ,
+        match-text "expressed protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -5064,63 +5678,80 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "proteine" ,
+        match-text "facotr" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
+          replace "factor" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "proteinn" ,
-        match-location contains ,
+        match-text "factor" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "proten" ,
+        match-text "faecal" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -5130,19 +5761,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
+          replace "fecal" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protien" ,
+        match-text "fagella" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -5152,41 +5786,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
+          replace "flagella" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protrein" ,
+        match-text "faimily" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
+          replace "family" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protwin" ,
+        match-text "faimly" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -5196,93 +5836,97 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
+          replace "family" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "prptein" ,
+        match-text "familie" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
+          replace "family" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ptotein" ,
+        match-text "familiy" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "protein" ,
+          replace "family" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "PTS system" ,
+        match-text "family" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "PTS system protein" ,
-          whole-string FALSE ,
-          weasel-to-putative TRUE } ,
-      move-to-note FALSE } } ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "puataive" ,
+        match-text "family family" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -5292,85 +5936,113 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "family" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "puatative" ,
-        match-location contains ,
+        match-text "family protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "puative" ,
+        match-text "fibre" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "fiber" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putaitive" ,
-        match-location contains ,
+        match-text "finger" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putaitve" ,
+        match-text "flageller" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -5380,63 +6052,65 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "flagellar" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putaive" ,
+        match-text "FOG" ,
         match-location contains ,
-        case-sensitive FALSE ,
+        case-sensitive TRUE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type database ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putataive" ,
-        match-location contains ,
+        match-text "formly" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "formyl" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putatitve" ,
+        match-text "Fragment" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -5446,33 +6120,31 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putative possible" ,
-        match-location starts ,
+        match-text "frame" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     feat-constraint {
       string {
-        match-text "possible protein" ,
-        match-location equals ,
+        match-text "frame shift" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -5481,20 +6153,16 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type might-be-nonfunctional ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putative potential" ,
-        match-location starts ,
+        match-text "frame shift" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -5503,55 +6171,49 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "possible protein" ,
-        match-location equals ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "frameshift" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
-  {
-    find
-      string-constraint {
-        match-text "putative potential" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "programmed frameshift" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type might-be-nonfunctional ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putative predicted" ,
-        match-location contains ,
+        match-text "from" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -5560,77 +6222,91 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putative probable" ,
+        match-text "funciton" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "function" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putative probable" ,
+        match-text "function" ,
         match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "possible protein" ,
-        match-location equals ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "fungi" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
+        whole-word TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putative putative" ,
-        match-location contains ,
+        match-text "g:t" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -5639,20 +6315,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putative, putative" ,
-        match-location contains ,
+        match-text "galactose" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -5661,19 +6340,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putatuive" ,
+        match-text "gambiae" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -5683,151 +6365,163 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putatuve" ,
+        match-text "gene" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type gene ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putatve" ,
+        match-text "genes" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type gene ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putatvie" ,
+        match-text "genome" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
-  {
-    find
-      string-constraint {
-        match-text "putayive" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "genome instability" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "genome maintenance" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "puter" ,
-        match-location contains ,
+        match-text "ggdef" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "outer" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putitative" ,
+        match-text "Giardia" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putitive" ,
+        match-text "gIycerol" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -5837,19 +6531,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "glycerol" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "puttive" ,
+        match-text "glcosyl" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -5859,19 +6556,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "glycosyl" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "pyradoxal" ,
+        match-text "Glimmer" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -5881,42 +6581,41 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "pyridoxal" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "pyruvyltransferase" ,
+        match-text "glucosainyl" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "pyruvyl transferase" ,
+          replace "glucosaminyl" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "qlcohol" ,
-        match-location contains ,
+        match-text "glutamate" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -5925,151 +6624,196 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "alcohol" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ranscriptional" ,
-        match-location contains ,
+        match-text "Glutamic acid" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "transcriptional" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "recognised" ,
-        match-location contains ,
+        match-text "Glutamine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "recognized" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "reductasee" ,
+        match-text "glutaminne" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "reductase" ,
+          replace "glutamine" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "regulatot" ,
+        match-text "glycin" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "regulator" ,
+          replace "glycine" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "reguratory" ,
-        match-location contains ,
+        match-text "Glycine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "regulatory" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "reolvase" ,
-        match-location contains ,
+        match-text "glycolsyltransferase" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "resolvase" ,
+          replace "glycosyltransferase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "repeatl" ,
+        match-text "glycosy" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6079,20 +6823,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "repeat" ,
+          replace "glucosyl" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "reponse" ,
-        match-location contains ,
+        match-text "GMP" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -6101,20 +6848,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "response" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "resistence" ,
-        match-location contains ,
+        match-text "gp" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -6123,42 +6873,74 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "resistance" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
-  {
-    find
-      string-constraint {
-        match-text "ribomal" ,
-        match-location contains ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "gph" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
-        not-present FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "ribosomal" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "GPI" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "GPN" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "GPH" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type putative-typo ,
+    description "may contain systematic gene product identifiers from phage" ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ribosimal" ,
-        match-location contains ,
+        match-text "GTP" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -6167,85 +6949,92 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "ribosomal" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ribosoml" ,
-        match-location contains ,
+        match-text "guanine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "ribosomal" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "rsponse" ,
+        match-text "haem" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "response" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
-  {
-    find
-      string-constraint {
-        match-text "serinr" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "archaemetzincin" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type british ,
     replace {
       replace-func
-        simple-replace {
-          replace "serine" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        haem-replace "haem" ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "shrot" ,
+        match-text "halophilus" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6255,41 +7044,44 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "short" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "shrot-chain" ,
+        match-text "heam" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
-        simple-replace {
-          replace "short-chain" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        haem-replace "haem" ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "shuttlingfactor" ,
+        match-text "heavychain" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6299,49 +7091,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "shuttling factor" ,
+          replace "heavy chain" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "signal peptide" ,
-        match-location equals ,
+        match-text "Helicobacter" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "signal peptide protein" ,
-          whole-string FALSE ,
-          weasel-to-putative TRUE } ,
-      move-to-note FALSE } } ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "signalling" ,
+        match-text "Helicoverpa" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6351,107 +7141,146 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "signaling" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "similiar" ,
-        match-location contains ,
+        match-text "helium" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "similar" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "simmilar" ,
-        match-location contains ,
+        match-text "helix" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "similar" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "specfic" ,
-        match-location contains ,
+        match-text "helix-turn-helix" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "specific" ,
+          replace "helix-turn-helix protein" ,
           whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+          weasel-to-putative TRUE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "spscific" ,
+        match-text "hemaggltinin" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "specific" ,
+          replace "hemagglutinin" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "stabilisation" ,
+        match-text "hemelysin" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6461,19 +7290,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "stabilization" ,
+          replace "hemolysin" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "subnit" ,
+        match-text "hemoglobine" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6483,19 +7315,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "subunit" ,
+          replace "hemoglobin" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "suger" ,
+        match-text "hexapaptide" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6505,19 +7340,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "sugar" ,
+          replace "hexapeptide" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "sulfer" ,
+        match-text "hexpeptide" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6527,19 +7365,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "sulfur" ,
+          replace "hexapeptide" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "sulpho" ,
+        match-text "highly conserved" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6549,19 +7390,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "sulfo" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "sulphur" ,
+        match-text "highly similar" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6571,20 +7408,16 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "sulfur" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "SWIM zinc finger" ,
-        match-location equals ,
+        match-text "histadine" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -6593,63 +7426,80 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "SWIM zinc finger protein" ,
+          replace "histidine" ,
           whole-string FALSE ,
-          weasel-to-putative TRUE } ,
-      move-to-note FALSE } } ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "systhesis" ,
+        match-text "histide" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "synthesis" ,
+          replace "histidine" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "sythase" ,
-        match-location contains ,
+        match-text "Histidine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "synthase" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "tetracenpmycin" ,
+        match-text "homeserine" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6659,19 +7509,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "tetracenomycin" ,
+          replace "homoserine" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "thiamin/thiamin" ,
+        match-text "homlog" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6681,21 +7534,24 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "thiamin/thiamine" ,
+          replace "homolog" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "thiamineS" ,
+        match-text "homo" ,
         match-location contains ,
-        case-sensitive TRUE ,
+        case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word TRUE ,
@@ -6703,19 +7559,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "thiamine S" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "thioderoxin" ,
+        match-text "homo sapiens" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6725,41 +7584,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "thioredoxin" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "thiredoxin" ,
+        match-text "homocystein" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "thioredoxin" ,
+          replace "homocysteine" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "threonin" ,
+        match-text "Homolog" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6769,19 +7634,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "threonine" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type evolutionary-relationship ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "trancription" ,
+        match-text "Homologue" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6791,19 +7652,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "transcription" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type evolutionary-relationship ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "trancsriptional" ,
+        match-text "horikoshii" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6813,19 +7670,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "transcription" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "tranferase" ,
+        match-text "hpothetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6835,19 +7695,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transferase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "tranporter" ,
+        match-text "human" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6857,20 +7720,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "transporter" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transcirbed" ,
-        match-location contains ,
+        match-text "hy0" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -6879,21 +7745,24 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "transcribed" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transcrIpt" ,
+        match-text "hydolase" ,
         match-location contains ,
-        case-sensitive TRUE ,
+        case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
@@ -6901,64 +7770,81 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transcript" ,
+          replace "hydrolase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transcriptionnal " ,
-        match-location contains ,
+        match-text "hydrogen" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "transcriptional" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transcriptonal" ,
+        match-text "hydrolas" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transcriptional" ,
+          replace "hydrolase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transcritional" ,
-        match-location contains ,
+        match-text "hydrolases of the alpha/beta superfamily" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -6967,19 +7853,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transcriptional" ,
+          replace "hydrolase of the alpha/beta superfamily" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transebrane" ,
+        match-text "hyopothetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -6989,19 +7878,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transmembrane" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transemembrane" ,
+        match-text "hyopthetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7011,19 +7903,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transmembrane" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Transemembrane" ,
+        match-text "hyothetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7033,20 +7928,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transmembrane" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transerfase" ,
-        match-location contains ,
+        match-text "hyp domain protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -7055,41 +7953,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "transferase" ,
+          replace "hypothetical protein" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transferasee" ,
+        match-text "hyperthetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transferase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transglycolase" ,
+        match-text "hyphotetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7099,19 +8003,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transglycosylase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Transmebrane" ,
+        match-text "hyphotheical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7121,19 +8028,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transmembrane" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transmebrane" ,
+        match-text "hyphothetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7143,41 +8053,55 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transmembrane" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transmemembrane" ,
-        match-location contains ,
+        match-text "hypo" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "transmembrane" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transorter" ,
+        match-text "hypohetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7187,71 +8111,72 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transporter" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transpoase" ,
+        match-text "hypot" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transposase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transport-associated" ,
-        match-location equals ,
+        match-text "hypotehtical" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transport-associated protein" ,
-          whole-string TRUE ,
+          replace "hypothetical" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transportor" ,
+        match-text "hypotethical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7261,20 +8186,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transporter" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transposase and inactivated derivative" ,
-        match-location equals ,
+        match-text "hypotetical" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -7283,64 +8211,73 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transposase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transposase and inactivated derivatives" ,
-        match-location equals ,
+        match-text "hypoth" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transposase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transposase and inactive derivative" ,
-        match-location equals ,
+        match-text "hypothe" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transposase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transposase and inactive derivatives" ,
-        match-location equals ,
+        match-text "hypotheical" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -7349,50 +8286,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transposase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transposase of" ,
-        match-location equals ,
+        match-text "hypotheitcal" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transposase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
-          weasel-to-putative TRUE } ,
-      move-to-note FALSE } } ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transposases and inactivated derivative" ,
-        match-location equals ,
+        match-text "hypotherical" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -7401,20 +8336,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transposase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transposases and inactivated derivatives" ,
-        match-location equals ,
+        match-text "hypothertical" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -7423,42 +8361,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transposase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transposases and inactive derivative" ,
-        match-location equals ,
+        match-text "hypothet" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transposase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transposases and inactive derivatives" ,
-        match-location equals ,
+        match-text "hypothetcial" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -7467,19 +8411,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transposase" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transproter" ,
+        match-text "hypothethical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7489,41 +8436,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transporter" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transulfuration" ,
+        match-text "hypotheti" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transsulfuration" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "trnasporter" ,
+        match-text "hypothetial" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7533,19 +8486,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "transporter" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "trunucated" ,
+        match-text "hypothetic" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7555,19 +8511,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "truncated" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "typr" ,
+        match-text "hypothetica" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7577,41 +8536,55 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "type" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "uncharacterizaed" ,
-        match-location contains ,
+        match-text "hypothetical" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "uncharacterized" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "uncharacterized" ,
+        match-text "hypothetical" ,
         match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7621,10 +8594,12 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     feat-constraint {
       string {
-        match-text "uncharacterized protein" ,
+        match-text "hypothetical protein" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7634,9 +8609,11 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
       string {
-        match-text "uncharacterized protein conserved in bacteria" ,
+        match-text "hypothetical domain protein" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7646,9 +8623,11 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
       string {
-        match-text "uncharacterized conserved protein" ,
+        match-text "hypothetical ORF" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7658,9 +8637,11 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
       string {
-        match-text "uncharacterized" ,
+        match-text "hypothetical" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7670,9 +8651,11 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
       string {
-        match-text "uncharacterized domain 1" ,
+        match-text "Hypothetical conserved protein" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7682,9 +8665,11 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
       string {
-        match-text "uncharacterized protein" ,
+        match-text "hypothetical protein" ,
         match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7694,7 +8679,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
       string {
         match-text "UPF" ,
         match-location contains ,
@@ -7716,7 +8703,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
     rule-type typo ,
     replace {
       replace-func
@@ -7724,12 +8713,13 @@ Suspect-rule-set ::= {
           replace "putative" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "undecapaprenyl" ,
-        match-location contains ,
+        match-text "hypothetical protein" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -7738,20 +8728,74 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    except
+      string-constraint {
+        match-text "hypothetical protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type putative-typo ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Hypothetical protein gene" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space TRUE ,
+        ignore-punct TRUE ,
+        ignore-words {
+          {
+            word "gene" ,
+            synonyms {
+              "sequence" ,
+              "partial sequence" ,
+              "complete sequence" ,
+              "partial" ,
+              "complete" ,
+              "gene sequence" } ,
+            case-sensitive FALSE ,
+            whole-word FALSE } ,
+          {
+            word "hypothetical" ,
+            synonyms {
+              "putative" } ,
+            case-sensitive FALSE ,
+            whole-word FALSE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "undecaprenyl" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unique" ,
-        match-location starts ,
+        match-text "hypotheticala" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -7760,32 +8804,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "unique protein" ,
-        match-location equals ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "hypotheticalprotein" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
+        whole-word TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "hypothetical protein" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unkown" ,
+        match-text "hypotheticial" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7795,41 +8854,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "unknown" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "vigtamin" ,
+        match-text "hypotheticical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "vitamin" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "YeeEYedE" ,
+        match-text "hypotheticl" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7839,19 +8904,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "YeeE/YedE" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "YjgPYjgQ" ,
+        match-text "hypotheticla" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7861,29 +8929,34 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "YjgP/YjgQ" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ypothetical" ,
+        match-text "hypothteical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
@@ -7891,33 +8964,37 @@ Suspect-rule-set ::= {
           replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ytochrome" ,
+        match-text "hypothtical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "cytochrome" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "yypothetical" ,
+        match-text "hypoyhtetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7927,7 +9004,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
@@ -7935,12 +9014,13 @@ Suspect-rule-set ::= {
           replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "zinc finger" ,
-        match-location equals ,
+        match-text "hyppothetical" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -7949,27 +9029,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "zinc finger protein" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
-          weasel-to-putative TRUE } ,
-      move-to-note FALSE } } ,
-  {
-    find
-      contains-plural NULL ,
-    rule-type putative-typo } ,
-  {
-    find
-      all-caps NULL ,
-    rule-type putative-typo } ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "authentic point mutation" ,
+        match-text "hyprothetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7979,12 +9054,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "deletion" ,
+        match-text "hypthetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -7994,12 +9079,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "doubtful" ,
+        match-text "hyptohetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8009,12 +9104,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Fragment" ,
+        match-text "hyptothetcial" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8024,12 +9129,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "frame shift" ,
+        match-text "hyptothetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8039,12 +9154,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "frameshift" ,
+        match-text "hyputhetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8054,26 +9179,41 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "programmed frameshift" ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "identity" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
+        whole-word TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "incomplete ORF" ,
-        match-location contains ,
+        match-text "immunoreactive" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -8082,12 +9222,24 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    except
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "immunoreactive protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
       string-constraint {
-        match-text "incomplete ORF domain protein" ,
-        match-location equals ,
-        case-sensitive TRUE ,
+        match-text "inactivated derivative" ,
+        match-location contains ,
+        case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
@@ -8095,27 +9247,33 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "interrupt" ,
+        match-text "Includes:" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Low Quality Protein" ,
+        match-text "incolved" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8125,12 +9283,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "involved" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "open reading frame" ,
+        match-text "incomplete ORF" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8140,27 +9308,31 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "open reading frame" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    except
+      string-constraint {
+        match-text "incomplete ORF domain protein" ,
         match-location equals ,
         case-sensitive TRUE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } } ,
-    rule-type might-be-nonfunctional,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
     fatal TRUE } ,
   {
     find
       string-constraint {
-        match-text "orphan protein" ,
-        match-location contains ,
+        match-text "incomplete ORF domain protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -8169,25 +9341,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "orphan protein" ,
-        match-location equals ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "indepedent" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "independent" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "partial" ,
+        match-text "inductible" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8197,30 +9391,2693 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional,
-    fatal TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "inducible" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "initation" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "initiation" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "inorganic phosphate" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "insertion sequence" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "insitol" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "inositol" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "intein C-terminal splicing region" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "intein N-terminal splicing region" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "interacts with" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "internal repeat sequences detected" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "interrupt" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Intiation" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "initiation" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "invertion" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "inversion" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "involved" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "iron" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      prefix-and-numbers "IS" ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "IS ORF" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "IS protein" ,
+          whole-string FALSE ,
+          weasel-to-putative TRUE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "isation" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "ization" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Isoleucine" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "isomaerase" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "isomerase" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "isomerse" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "isomerase" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Jejuni" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "K potassium" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "potassium" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "K+ potassium" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "potassium" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "lacitehtopyh" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Leishmania" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Leucine" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "like" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "likeity" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "likely" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "likely" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "putative" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "liporotein" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "lipoprotein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "listeria/Bacterioides" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "localisation" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "localization" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "localised" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "localized" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "localization of periplasmic protein complexes" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "located in" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Low Quality Protein" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "LOW QUALITY PROTEIN:" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type might-be-nonfunctional ,
+    fatal TRUE } ,
+  {
+    find
+      string-constraint {
+        match-text "Low Quality Protein: " ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Lysine" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "majour" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "major" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "malate" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Maltose" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mambrane" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "membrane" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Marinococcus" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "meausure" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "measure" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "medated" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "mediated" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mediates" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "membrane" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "membrane protein of" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "membrane protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "membraneprotein" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "membrane protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "membranetransport" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "membrane transport" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "membranne" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "membrane" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "membtrane" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "membrane" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "memebrane" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "membrane" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Methionine" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "methlytransferase" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "methyltransferase" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "metylase" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "methylase" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "miscellaneous" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "miscellaneous" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    except
+      string-constraint {
+        match-text "miscellaneous" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mitchondrial" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "mitochondrial" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mobilisation" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "mobilization" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "molibdenum" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "molybdenum" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "molybopterin" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "molybdopterin" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "molydopterin" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "molybdopterin" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "monooxigenase" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "monooxygenase" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "monoxyde" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "monoxide" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "monoxygenase" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "monooxygenase" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mouse" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mRNA" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mulitdrug" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "multidrug" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mulitfunction" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "multifunction" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "MULTISPECIES" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "MULTISPECIES:" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type description ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "MULTISPECIES: " ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Mus musculus" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mutatrotase" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "mutarotase" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mutlifunction" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "multifunction" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Mycobacterium" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mycoplasma" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mypothetical" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "mythylglyoxyl " ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "methylglyoxyl" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "n-terminal domain protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "N-terminus" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Na" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Na+" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "NAD" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "narrowly conserved" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "ncharacterized" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "uncharacterized" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "ncRNA" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "ndoribonuclease" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "endoribonuclease" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Neurospora" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Ni" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "nickle" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "nickel" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "niger" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "nitrogen" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "Nmr solution" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "No definition line found" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "No definition line found" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "no function assigned" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "no likeity" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "no significant database hits" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "no significant database matches" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "no significant homology" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "pseudo" ,
+        match-text "no significant homology" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    except
+      string-constraint {
+        match-text "no significant homology" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "novel" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
         whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "novel protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "putative" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "pseudogene" ,
+        match-text "novel" ,
         match-location contains ,
-        case-sensitive TRUE ,
+        case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word TRUE ,
@@ -8228,12 +12085,105 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    except
+      string-constraint {
+        match-text "novel protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "remnant" ,
+        match-text "ntegral " ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "integral " ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "nucear" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "nuclear" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "nucelar" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "nuclear" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "nucleotydyl" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8243,12 +12193,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "nucleotidyl" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "start codon" ,
+        match-text "nucletide" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8258,13 +12218,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional,
-    fatal TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "nucleotide" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "truncat" ,
+        match-text "nulcear" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8274,107 +12243,165 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "nuclear" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unknown" ,
+        match-text "nulceotide" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "nucleotide" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "null" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      field {
-        field
-          feature-field {
-            type cds ,
-            field
-              legal-qual product } ,
-        string-constraint {
-          match-text "protein of unknown function" ,
-          match-location contains ,
-          case-sensitive FALSE ,
-          ignore-space FALSE ,
-          ignore-punct FALSE ,
-          whole-word FALSE ,
-          not-present TRUE ,
-          is-all-caps FALSE ,
-          is-all-lower FALSE ,
-          is-all-punct FALSE ,
-          ignore-weasel FALSE } } ,
-      field {
-        field
-          feature-field {
-            type cds ,
-            field
-              legal-qual product } ,
-        string-constraint {
-          match-text "domain of unknown function" ,
-          match-location contains ,
-          case-sensitive FALSE ,
-          ignore-space FALSE ,
-          ignore-punct FALSE ,
-          whole-word FALSE ,
-          not-present TRUE ,
-          is-all-caps FALSE ,
-          is-all-lower FALSE ,
-          is-all-punct FALSE ,
-          ignore-weasel FALSE } } ,
-      string {
-        match-text "unknown" ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "o252" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-      string {
-        match-text "unknown protein" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "o252 protein" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } } ,
-    rule-type might-be-nonfunctional } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
-      three-numbers NULL ,
-    except
       string-constraint {
-        match-text "methyltransferas" ,
+        match-text "obalt" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type database } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "cobalt" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "&apos" ,
-        match-location contains ,
-        case-sensitive TRUE ,
+        match-text "observed by proteomics" ,
+        match-location equals ,
+        case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
@@ -8382,28 +12409,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type database } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "(TC " ,
+        match-text "odule" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type database } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "module" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "COG" ,
-        match-location contains ,
+        match-text "of" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -8412,10 +12459,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    except
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
+  {
+    find
       string-constraint {
-        match-text "COG" ,
+        match-text "open reading frame" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8425,12 +12477,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type database } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "database" ,
+        match-text "open reading frame" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8440,12 +12502,14 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     feat-constraint {
       string {
-        match-text "no significant database hits" ,
+        match-text "open reading frame" ,
         match-location equals ,
-        case-sensitive FALSE ,
+        case-sensitive TRUE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
@@ -8453,53 +12517,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } } ,
-    rule-type database } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type might-be-nonfunctional ,
+    fatal TRUE } ,
   {
     find
       string-constraint {
-        match-text "DUF" ,
-        match-location contains ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word TRUE ,
-        not-present FALSE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    except
-      string-constraint {
-        match-text "DUF" ,
+        match-text "ORF" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type database } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "EST" ,
-        match-location contains ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word TRUE ,
-        not-present FALSE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    except
-      string-constraint {
-        match-text "EST" ,
+        match-text "orf, hyp" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8509,27 +12568,55 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type database } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "FOG" ,
-        match-location contains ,
-        case-sensitive TRUE ,
+        match-text "orf, hypothetical" ,
+        match-location equals ,
+        case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type database } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "undefined product" ,
+        match-text "organise" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8539,101 +12626,116 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    feat-constraint {
-      string {
-        match-text "undefined product" ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "organize" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "orphan protein" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } } ,
-    rule-type database } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "UPF" ,
+        match-text "orphan protein" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    except
-      string-constraint {
-        match-text "UPF" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "orphan protein" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type database } ,
-  {
-    find
-      underscore NULL ,
-    rule-type database } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type might-be-nonfunctional ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text " Anopheles" ,
+        match-text "ortholog" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type evolutionary-relationship ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Agrobacterium" ,
+        match-text "orthologue" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type evolutionary-relationship ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Arabidopsis" ,
+        match-text "Outative" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8643,19 +12745,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Aspergillus" ,
+        match-text "outers" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8665,151 +12770,172 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "outer" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "aureus" ,
-        match-location contains ,
+        match-text "Oxalate" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "B.subtilis" ,
+        match-text "oxidoreducatse" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "oxidoreductase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Bacillus" ,
-        match-location contains ,
+        match-text "oxidoreductase ()" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "oxidoreductase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Bacterioides" ,
+        match-text "oxidoreductasee" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "oxidoreductase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Bacteroides" ,
+        match-text "oxidoreductasse" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "oxidoreductase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Bombyx" ,
+        match-text "oxidoredutase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "oxidoreductase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "bos taurus" ,
+        match-text "oxidoreduxtase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8819,107 +12945,138 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "oxidoreductase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Campylobacter" ,
+        match-text "oxigenase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "oxygenase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Candida" ,
+        match-text "oxydase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "oxidase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "cerevisiae" ,
-        match-location contains ,
+        match-text "oxygen" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Chlamydial" ,
-        match-location contains ,
+        match-text "p-loop" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+          replace "p-loop protein" ,
+          whole-string FALSE ,
+          weasel-to-putative TRUE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Chlamydomonas" ,
+        match-text "paralog" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8929,19 +13086,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type evolutionary-relationship ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "coli" ,
+        match-text "paralogue" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -8951,142 +13104,174 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "adenomatous polyposis coli " ,
-        match-location contains ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type evolutionary-relationship ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "part" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
+        whole-word TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Drosophila" ,
+        match-text "partial" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
+    fatal TRUE } ,
   {
     find
       string-constraint {
-        match-text "E.coli" ,
-        match-location contains ,
+        match-text "PASTA" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+          replace "PASTA protein" ,
+          whole-string FALSE ,
+          weasel-to-putative TRUE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ECOLI" ,
-        match-location contains ,
+        match-text "peptide" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "enterica" ,
+        match-text "peptidodoglycan" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "peptidoglycan" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Escherichia" ,
-        match-location contains ,
+        match-text "peptidyl-prolyl cis-trans" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "gambiae" ,
+        match-text "periplamic" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -9096,73 +13281,84 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "periplasmic" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "halophilus" ,
+        match-text "periplasmc" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "periplasmic" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Helicobacter" ,
+        match-text "periplsmic" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "periplasmic" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Helicoverpa" ,
+        match-text "Pestis" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type remove-organism-name ,
     replace {
       replace-func
@@ -9170,77 +13366,103 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "homo" ,
+        match-text "petidase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "peptidase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "homo sapiens" ,
-        match-location contains ,
+        match-text "phage" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "human" ,
-        match-location contains ,
+        match-text "Phenylalanine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Jejuni" ,
+        match-text "pheremone" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -9250,42 +13472,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "pheromone" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Leishmania" ,
+        match-text "phophate" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "phosphate" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "listeria/Bacterioides" ,
-        match-location equals ,
+        match-text "phopho" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -9294,63 +13522,72 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "phospho" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Marinococcus" ,
+        match-text "phophoserine" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "phosphoserine" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mouse" ,
+        match-text "phoshate" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "phosphate" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Mus musculus" ,
+        match-text "phospatase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -9360,19 +13597,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "phosphatase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Mycobacterium" ,
+        match-text "phosphateN" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -9382,19 +13622,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "phosphate N" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mycoplasma" ,
+        match-text "phosphatidyltransferse" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -9404,19 +13647,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "phosphatidyltransferase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Neurospora" ,
+        match-text "phosphatransferase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -9426,117 +13672,142 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "phosphotransferase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "niger" ,
+        match-text "phosphopantethiene" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "phosphopantetheine" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Pestis" ,
+        match-text "phosphotase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "phosphatase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Plasmodium" ,
-        match-location contains ,
+        match-text "plasmid" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "pombe" ,
-        match-location contains ,
+        match-text "plasmid-like protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "pseudomonas" ,
+        match-text "Plasmodium" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type remove-organism-name ,
     replace {
       replace-func
@@ -9544,65 +13815,98 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "pylori" ,
+        match-text "polimerase" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "polymerase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "rat" ,
+        match-text "polymeris" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "polymeriz" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Rhodobacter" ,
+        match-text "pombe" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            word "pombe" ,
+            synonyms {
+              "genitalium" ,
+              "leprae" ,
+              "crassa" ,
+              "ciliare" ,
+              "falciparum" ,
+              "fumigata" ,
+              "vinifera" ,
+              "lipolytica" ,
+              "ambisexualis" ,
+              "brasilense" ,
+              "carbonum" ,
+              "elegans" ,
+              "melanogaster" ,
+              "capricolum" ,
+              "pneumoniae" ,
+              "pseudotuberculosis" ,
+              "histolytica" ,
+              "influenzae" } ,
+            case-sensitive FALSE ,
+            whole-word FALSE } } ,
         whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type remove-organism-name ,
     replace {
       replace-func
@@ -9610,55 +13914,63 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    description "contains organism name" ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "rickettsia" ,
+        match-text "portein" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "protein" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Salmonella" ,
+        match-text "Portein" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "protein" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "sapiens" ,
+        match-text "posible" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -9668,20 +13980,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "possible" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "serovar" ,
-        match-location contains ,
+        match-text "possible" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -9690,20 +14005,38 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "possible protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "siphovirus" ,
-        match-location equals ,
+        match-text "possibly" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -9712,85 +14045,105 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type remove-organism-name ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "sphaeroides" ,
+        match-text "poteasome" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "proteasome" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Spodoptera" ,
+        match-text "potein" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "protein" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "sreptomyces" ,
-        match-location contains ,
+        match-text "potential" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "potential protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Staphlococcal" ,
+        match-text "precurso" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -9800,41 +14153,55 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "precursor" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Staphlococcus" ,
-        match-location contains ,
+        match-text "precursor" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "staphylococcal" ,
+        match-text "precusor" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -9844,42 +14211,56 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "precursor" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Staphylococcus" ,
-        match-location contains ,
+        match-text "predicted" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "streptococcal" ,
-        match-location contains ,
+        match-text "predicted" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -9888,281 +14269,376 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "predicted protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "Predicted:" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Streptococcus" ,
-        match-location contains ,
+        match-text "Predicted:" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "streptomyces" ,
+        match-text "predictedprotein" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "predicted protein" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "subsp" ,
+        match-text "predictet" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "predicted" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Subtilis" ,
+        match-text "presursor" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "precursor" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "thaliana" ,
+        match-text "probabable" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "probable" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Tuberculosis" ,
-        match-location contains ,
+        match-text "probable" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "tumefaciens" ,
-        match-location contains ,
+        match-text "probable" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "probable protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Typhimurium" ,
-        match-location contains ,
+        match-text "probable protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
-          whole-string TRUE ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "xenopus" ,
+        match-text "probable putative" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "yeast" ,
+        match-text "probably" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Yersinia" ,
+        match-text "proein" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type remove-organism-name ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "protein" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
-  {
-    find
-      unbalanced-paren NULL ,
-    rule-type inappropriate-symbol } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "#" ,
-        match-location contains ,
+        match-text "Proline" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "%" ,
-        match-location contains ,
+        match-text "proposed" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -10171,28 +14647,38 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
-  {
-    find
-      string-constraint {
-        match-text "()" ,
-        match-location contains ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "proposed protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "putative" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "," ,
-        match-location ends ,
+        match-text "proposed protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -10201,28 +14687,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "," ,
-        match-location starts ,
+        match-text "proptein" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "-" ,
-        match-location ends ,
+        match-text "prortein" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -10231,43 +14737,73 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "-" ,
-        match-location starts ,
+        match-text "protazoan" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protozoan" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "." ,
-        match-location ends ,
+        match-text "protei" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "." ,
-        match-location starts ,
+        match-text "protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -10276,58 +14812,70 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
-  {
-    find
-      string-constraint {
-        match-text ". " ,
-        match-location contains ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "hypothetical protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
-  {
-    find
-      string-constraint {
-        match-text ".," ,
-        match-location contains ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "uncharacterized protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "./" ,
+        match-text "protein associated to" ,
         match-location contains ,
-        case-sensitive TRUE ,
+        case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "/" ,
-        match-location ends ,
+        match-text "protein conserved in bacteria" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -10336,28 +14884,56 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text ":" ,
-        match-location ends ,
+        match-text "protein containing" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "=" ,
-        match-location contains ,
+        match-text "protein of" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -10366,88 +14942,165 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "?" ,
-        match-location contains ,
+        match-text "protein of unknown function" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "@" ,
-        match-location contains ,
-        case-sensitive TRUE ,
+        match-text "protein of unknown function, duf" ,
+        match-location equals ,
+        case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            word "protein of unknown function, duf" ,
+            synonyms {
+              "protein of unknown function duf" ,
+              "domain of unknown function duf" ,
+              "domain of unknown function, duf" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "complete" ,
-        match-location contains ,
+        match-text "protein product" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "contig" ,
+        match-text "protein protein" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Critica" ,
-        match-location contains ,
+        match-text "Protein putative protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Crystal Structure" ,
-        match-location contains ,
+        match-text "protein, conserved" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -10456,27 +15109,55 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "DNA for" ,
-        match-location contains ,
+        match-text "protein-containing" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "genome" ,
+        match-text "proteine" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -10486,52 +15167,97 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "genome instability" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "proteinn" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
+        whole-word TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-      string {
-        match-text "genome maintenance" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "proten" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
+        whole-word TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Glimmer" ,
+        match-text "protien" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Nmr solution" ,
+        match-text "protrein" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -10541,27 +15267,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "No definition line found" ,
+        match-text "protwin" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "raw score" ,
+        match-text "prptein" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -10571,25 +15317,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "raw score" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "pseudo" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "RNA for" ,
+        match-text "pseudo" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -10599,27 +15367,40 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
+    fatal TRUE } ,
   {
     find
       string-constraint {
-        match-text "shotgun" ,
-        match-location contains ,
+        match-text "pseudogene" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "solution Nmr" ,
+        match-text "pseudogene" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -10629,12 +15410,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
+    fatal TRUE } ,
   {
     find
       string-constraint {
-        match-text "solution structure" ,
+        match-text "pseudomonas" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -10644,43 +15428,81 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "structure of" ,
+        match-text "ptotein" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "xray structure" ,
-        match-location contains ,
+        match-text "PTS system" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "PTS system protein" ,
+          whole-string FALSE ,
+          weasel-to-putative TRUE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "\" ,
-        match-location ends ,
+        match-text "puataive" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -10689,12 +15511,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "putative" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "\\-PA" ,
+        match-text "puatative" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -10704,13 +15536,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "putative" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "_" ,
-        match-location ends ,
+        match-text "puative" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -10719,139 +15561,205 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "putative" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "|" ,
-        match-location contains ,
+        match-text "purine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "analog" ,
+        match-text "putaitive" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type evolutionary-relationship } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "putative" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Homolog" ,
+        match-text "putaitve" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type evolutionary-relationship } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "putative" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ortholog" ,
+        match-text "putaive" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type evolutionary-relationship } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "putative" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "paralog" ,
+        match-text "putataive" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type evolutionary-relationship } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "putative" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "adenine" ,
-        match-location equals ,
+        match-text "putatitve" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ADP" ,
-        match-location equals ,
+        match-text "putativ" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Alanine" ,
+        match-text "putative" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -10869,7 +15777,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -10877,12 +15787,13 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "alpha" ,
-        match-location equals ,
+        match-text "putative possible" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -10891,80 +15802,63 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
-  {
-    find
-      string-constraint {
-        match-text "alternate protein name" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "possible protein" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "amino acid" ,
-        match-location equals ,
+        match-text "putative potential" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "anion" ,
-        match-location equals ,
+        match-text "putative potential" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -10973,110 +15867,103 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
-  {
-    find
-      string-constraint {
-        match-text "Arginine" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "possible protein" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Asparagine" ,
-        match-location equals ,
+        match-text "putative predicted" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Aspartic acid" ,
-        match-location equals ,
+        match-text "putative probable" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "possible protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "aspartyl" ,
-        match-location equals ,
+        match-text "putative probable" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -11085,67 +15972,59 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ATP" ,
-        match-location equals ,
+        match-text "putative putative" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "bacteriophage" ,
+        match-text "putative uncharacterized" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -11153,64 +16032,63 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "barrel" ,
-        match-location equals ,
+        match-text "putative, putative" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "believed" ,
-        match-location starts ,
+        match-text "putativie" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "bifunctional" ,
-        match-location equals ,
+        match-text "putatuive" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -11219,42 +16097,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "binds" ,
-        match-location starts ,
+        match-text "putatuve" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "bis" ,
-        match-location equals ,
+        match-text "putatve" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -11263,20 +16147,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
-      string-constraint {
-        match-text "C-terminus" ,
-        match-location equals ,
+      string-constraint {
+        match-text "putatvie" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -11285,102 +16172,98 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "carbon" ,
-        match-location equals ,
+        match-text "putayive" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "CBS domain pair" ,
-        match-location equals ,
+        match-text "puter" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "outer" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "citrate" ,
-        match-location equals ,
+        match-text "putitative" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "clustered with" ,
-        match-location starts ,
+        match-text "putitive" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -11389,20 +16272,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "COG" ,
-        match-location equals ,
+        match-text "puttive" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -11411,235 +16297,230 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "putative" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conser" ,
-        match-location equals ,
+        match-text "pylori" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserve" ,
-        match-location equals ,
+        match-text "pyradoxal" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "pyridoxal" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserved" ,
-        match-location equals ,
+        match-text "Pyrococcus" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserved domain protein" ,
-        match-location equals ,
+        match-text "pyruvyltransferase" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "pyruvyl transferase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserved hypothetical" ,
-        match-location equals ,
+        match-text "qlcohol" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "alcohol" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserved hypothetical domain protein" ,
-        match-location equals ,
+        match-text "ranscriptional" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transcriptional" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserved hypothetical family protein" ,
-        match-location equals ,
+        match-text "rat" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserved hypothetical protein" ,
-        match-location equals ,
+        match-text "raw score" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "raw score" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserved predicted domain protein" ,
+        match-text "raw score" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -11649,7 +16530,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -11657,12 +16540,13 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserved predicted protein" ,
-        match-location equals ,
+        match-text "recognised" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -11671,51 +16555,59 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "recognized" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserved protein" ,
-        match-location equals ,
+        match-text "reductasee" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "reductase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserved protein of unknown function" ,
-        match-location equals ,
+        match-text "region" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -11723,34 +16615,31 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "conserved putative protein" ,
-        match-location equals ,
+        match-text "regulates" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Conserved subname: full" ,
-        match-location equals ,
+        match-text "regulatot" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -11759,20 +16648,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "regulator" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Conserved with" ,
-        match-location starts ,
+        match-text "reguratory" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -11781,29 +16673,34 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "regulatory" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "containing" ,
+        match-text "Related" ,
         match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -11811,12 +16708,13 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "contains" ,
-        match-location starts ,
+        match-text "remnant" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -11825,41 +16723,40 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
+    fatal TRUE } ,
   {
     find
       string-constraint {
-        match-text "CTP" ,
-        match-location equals ,
+        match-text "reolvase" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "resolvase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Cysteine" ,
+        match-text "repeat" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -11877,7 +16774,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -11885,64 +16784,63 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "cytosine" ,
-        match-location equals ,
+        match-text "repeatl" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "repeat" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "di" ,
-        match-location equals ,
+        match-text "replicaiton" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "replication" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "dipeptide" ,
-        match-location equals ,
+        match-text "reponse" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -11951,161 +16849,147 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "response" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "DNA" ,
-        match-location equals ,
+        match-text "resistence" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "resistance" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domain" ,
-        match-location equals ,
+        match-text "Rhodobacter" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domain 1" ,
-        match-location equals ,
+        match-text "ribomal" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "ribosomal" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domain family" ,
-        match-location equals ,
+        match-text "ribonuleotide" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "ribonucleotide" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domain of unknown function" ,
-        match-location equals ,
+        match-text "ribosimal" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "ribosomal" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domain of unknown function family protein" ,
+        match-text "ribosomal RNA" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -12115,7 +16999,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -12123,12 +17009,13 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domain of unknown function family protein" ,
-        match-location equals ,
+        match-text "ribosoml" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -12137,50 +17024,73 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "ribosomal" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domain of unknown function protein" ,
-        match-location equals ,
+        match-text "ribossomal" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "ribosomal" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "rickettsia" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domain protein" ,
-        match-location equals ,
+        match-text "riobosyltransferase" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -12189,29 +17099,42 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
+          replace "ribosyltransferase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "domain-containing protein" ,
+        match-text "RNA" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -12219,11 +17142,30 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "doubtful CDS found within S. typhi pathogenicity island" ,
+        match-text "RNA for" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "rRNA" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -12241,7 +17183,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -12249,56 +17193,63 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "DUF" ,
-        match-location equals ,
+        match-text "rsponse" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "response" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "EST" ,
-        match-location equals ,
+        match-text "Salmonella" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "expressed" ,
-        match-location equals ,
+        match-text "sapiens" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -12307,29 +17258,42 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "expressed protein" ,
+        match-text "secreted" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -12337,11 +17301,12 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "factor" ,
+        match-text "Serine" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -12359,7 +17324,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -12367,12 +17334,13 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "family" ,
-        match-location equals ,
+        match-text "serinr" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -12381,161 +17349,165 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "serine" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "family protein" ,
-        match-location equals ,
+        match-text "serovar" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "finger" ,
-        match-location equals ,
+        match-text "shotgun" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "shrot" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "short" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "from" ,
-        match-location starts ,
+        match-text "shrot-chain" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "short-chain" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ggdef" ,
-        match-location equals ,
+        match-text "shutting" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "shuttling" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Glutamic acid" ,
-        match-location equals ,
+        match-text "shuttlingfactor" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "shuttling factor" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Glutamine" ,
+        match-text "signal" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -12553,7 +17525,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -12561,11 +17535,12 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Glycine" ,
+        match-text "signal peptide" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -12583,20 +17558,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+          replace "signal peptide protein" ,
+          whole-string FALSE ,
+          weasel-to-putative TRUE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "GMP" ,
-        match-location equals ,
+        match-text "signalling" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -12605,20 +17583,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "signaling" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "GTP" ,
-        match-location equals ,
+        match-text "similar" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -12627,7 +17608,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -12635,184 +17618,149 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "guanine" ,
-        match-location equals ,
+        match-text "similiar" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "similar" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "helium" ,
-        match-location equals ,
+        match-text "simmilar" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "similar" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "helix" ,
+        match-text "siphovirus" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Histidine" ,
+        match-text "sodium" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
-          whole-string TRUE ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hy0" ,
-        match-location equals ,
+        match-text "solution Nmr" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hydrogen" ,
-        match-location equals ,
+        match-text "solution structure" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hyp domain protein" ,
-        match-location equals ,
+        match-text "specfic" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -12821,37 +17769,34 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
+          replace "specific" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypo" ,
+        match-text "specific" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -12859,76 +17804,63 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypothetical" ,
-        match-location equals ,
+        match-text "sphaeroides" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Hypothetical protein gene" ,
-        match-location equals ,
+        match-text "Spodoptera" ,
+        match-location contains ,
         case-sensitive FALSE ,
-        ignore-space TRUE ,
-        ignore-punct TRUE ,
-        ignore-words {
-          {
-            word "gene" ,
-            synonyms {
-              "sequence" ,
-              "partial sequence" ,
-              "complete sequence" ,
-              "partial" ,
-              "complete" ,
-              "gene sequence" } ,
-            case-sensitive FALSE ,
-            whole-word FALSE } } ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "incomplete ORF domain protein" ,
-        match-location equals ,
+        match-text "spscific" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -12937,50 +17869,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "specific" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "insertion sequence" ,
-        match-location equals ,
+        match-text "sreptomyces" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "intein C-terminal splicing region" ,
-        match-location equals ,
+        match-text "stabilisation" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -12989,42 +17919,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "stabilization" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "intein N-terminal splicing region" ,
-        match-location equals ,
+        match-text "Staphlococcal" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "interacts with" ,
-        match-location starts ,
+        match-text "Staphlococcus" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -13033,20 +17969,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "involved" ,
-        match-location starts ,
+        match-text "staphylococcal" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -13055,121 +17994,116 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "iron" ,
-        match-location equals ,
+        match-text "Staphylococcus" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
-      prefix-and-numbers "IS" ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      string-constraint {
+        match-text "start codon" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
+    fatal TRUE } ,
   {
     find
       string-constraint {
-        match-text "Isoleucine" ,
-        match-location equals ,
+        match-text "streptococcal" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Leucine" ,
-        match-location equals ,
+        match-text "Streptococcus" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "like" ,
-        match-location starts ,
+        match-text "streptomyces" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -13178,183 +18112,201 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "located in" ,
-        match-location starts ,
+        match-text "strongly conserved" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Lysine" ,
-        match-location equals ,
+        match-text "strongly similar" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "structual" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "structural" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "malate" ,
-        match-location equals ,
+        match-text "structure of" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
+  {
+    find
+      string-constraint {
+        match-text "subitilus" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mediates" ,
-        match-location starts ,
+        match-text "subnit" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "subunit" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "membrane" ,
-        match-location equals ,
+        match-text "subsp" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Methionine" ,
-        match-location equals ,
+        match-text "Subtilis" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mRNA" ,
+        match-text "subunit" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -13372,7 +18324,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -13380,11 +18334,12 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "N-terminus" ,
+        match-text "sugar" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -13394,7 +18349,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -13402,12 +18359,13 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Na" ,
-        match-location equals ,
+        match-text "suger" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -13416,140 +18374,123 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "sugar" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "NAD" ,
-        match-location equals ,
+        match-text "sulfer" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "sulfur" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ncRNA" ,
-        match-location equals ,
+        match-text "sulphate" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "sulfate" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "nitrogen" ,
-        match-location equals ,
+        match-text "sulphide" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "sulfide" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "No definition line found" ,
-        match-location equals ,
+        match-text "sulpho" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "sulfo" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "no function assigned" ,
-        match-location equals ,
+        match-text "sulphur" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -13558,19 +18499,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "sulfur" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "no significant database hits" ,
+        match-text "SWIM zinc finger" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -13580,80 +18524,73 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+          replace "SWIM zinc finger protein" ,
+          whole-string FALSE ,
+          weasel-to-putative TRUE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "o252" ,
-        match-location equals ,
+        match-text "systhesis" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "synthesis" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "o252 protein" ,
-        match-location equals ,
+        match-text "sythase" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "synthase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "open reading frame" ,
-        match-location equals ,
+        match-text "tetracenpmycin" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -13662,102 +18599,98 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
+          replace "tetracenomycin" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ORF" ,
-        match-location equals ,
+        match-text "thaliana" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "orf, hyp" ,
-        match-location equals ,
+        match-text "thiamin/thiamin" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
+          replace "thiamin/thiamine" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "orf, hypothetical" ,
-        match-location equals ,
-        case-sensitive FALSE ,
+        match-text "thiamineS" ,
+        match-location contains ,
+        case-sensitive TRUE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "thiamine S" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "orphan protein" ,
-        match-location equals ,
+        match-text "thioderoxin" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -13766,50 +18699,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
+          replace "thioredoxin" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "oxygen" ,
-        match-location equals ,
+        match-text "thiredoxin" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "thioredoxin" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "part" ,
-        match-location starts ,
+        match-text "threonin" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -13818,19 +18749,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "threonine" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "peptide" ,
+        match-text "Threonine" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -13848,7 +18782,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -13856,11 +18792,12 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "phage" ,
+        match-text "thymine" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -13878,7 +18815,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -13886,59 +18825,42 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Phenylalanine" ,
-        match-location equals ,
+        match-text "TPA:" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type database ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "plasmid" ,
-        match-location equals ,
+        match-text "TPA_inf" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -13946,124 +18868,113 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "plasmid-like protein" ,
-        match-location equals ,
+        match-text "trancription" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transcription" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "precursor" ,
-        match-location equals ,
+        match-text "trancsriptional" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transcription" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "predicted" ,
-        match-location equals ,
+        match-text "tranferase" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transferase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "probable" ,
-        match-location equals ,
+        match-text "tranporter" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transporter" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "probable protein" ,
-        match-location equals ,
+        match-text "transcirbed" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -14072,73 +18983,74 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
+          replace "transcribed" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Proline" ,
-        match-location equals ,
+        match-text "transcirption" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transcription" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "proposed protein" ,
-        match-location equals ,
+        match-text "transcripitonal" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transcriptional" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protein" ,
-        match-location equals ,
-        case-sensitive FALSE ,
+        match-text "transcrIpt" ,
+        match-location contains ,
+        case-sensitive TRUE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
@@ -14146,45 +19058,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    feat-constraint {
-      string {
-        match-text "hypothetical protein" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-      string {
-        match-text "uncharacterized protein" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
+          replace "transcript" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protein conserved in bacteria" ,
-        match-location equals ,
+        match-text "transcriptionnal " ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -14193,80 +19083,73 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transcriptional" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protein containing" ,
-        match-location equals ,
+        match-text "transcriptonal" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transcriptional" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protein of unknown function" ,
-        match-location equals ,
+        match-text "transcritional" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transcriptional" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protein, conserved" ,
-        match-location equals ,
+        match-text "transebrane" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -14275,140 +19158,123 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transmembrane" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protein-containing" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
+        match-text "transemembrane" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transmembrane" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "pseudo" ,
-        match-location equals ,
+        match-text "Transemembrane" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transmembrane" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "purine" ,
-        match-location equals ,
+        match-text "transerfase" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transferase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putative" ,
-        match-location equals ,
+        match-text "transferasee" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transferase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putative uncharacterized" ,
-        match-location equals ,
+        match-text "transglycolase" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -14417,20 +19283,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transglycosylase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "raw score" ,
-        match-location equals ,
+        match-text "Transmebrane" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -14439,42 +19308,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transmembrane" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "region" ,
-        match-location starts ,
+        match-text "transmebrane" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transmembrane" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Related" ,
-        match-location starts ,
+        match-text "transmemembrane" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -14483,79 +19358,72 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transmembrane" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "repeat" ,
-        match-location equals ,
+        match-text "transorter" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transporter" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "RNA" ,
-        match-location equals ,
+        match-text "transpoase" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transposase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "rRNA" ,
+        match-text "transport-associated" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -14573,110 +19441,98 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
+          replace "transport-associated protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "secreted" ,
-        match-location equals ,
+        match-text "transportor" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transporter" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Serine" ,
+        match-text "transposase and inactivated derivative" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transposase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "signal" ,
+        match-text "transposase and inactivated derivatives" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transposase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "similar" ,
-        match-location starts ,
+        match-text "transposase and inactive derivative" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -14685,19 +19541,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transposase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "sodium" ,
+        match-text "transposase and inactive derivatives" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -14707,19 +19566,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
+          replace "transposase" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "subunit" ,
+        match-text "transposase of" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -14737,80 +19599,73 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+          replace "transposase" ,
+          whole-string FALSE ,
+          weasel-to-putative TRUE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Threonine" ,
-        match-location equals ,
+        match-text "transposase transposase" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transposase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "thymine" ,
-        match-location equals ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
+        match-text "transposases and inactivated derivative" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transposase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "TPA_inf" ,
-        match-location starts ,
+        match-text "transposases and inactivated derivatives" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -14819,79 +19674,72 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transposase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "transposon" ,
+        match-text "transposases and inactive derivative" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transposase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "tRNA" ,
+        match-text "transposases and inactive derivatives" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transposase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Tryptophan" ,
+        match-text "transposon" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -14909,7 +19757,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -14917,12 +19767,13 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ttg start" ,
-        match-location equals ,
+        match-text "transproter" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -14931,50 +19782,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
+          replace "transporter" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Tyrosine" ,
-        match-location equals ,
+        match-text "transulfuration" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transsulfuration" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "uncharacterized" ,
-        match-location equals ,
+        match-text "trasnferase" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -14983,51 +19832,67 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transferase" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unclassified" ,
-        match-location equals ,
+        match-text "trasporter" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "transporter" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "undefined product" ,
+        match-text "tRNA" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -15035,12 +19900,13 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unkn" ,
-        match-location equals ,
+        match-text "trnasporter" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15049,20 +19915,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
+          replace "transporter" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unknown" ,
-        match-location equals ,
+        match-text "truncat" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15071,51 +19940,60 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type might-be-nonfunctional ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unknown function" ,
-        match-location equals ,
+        match-text "trunucated" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "truncated" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unknown protein" ,
+        match-text "Tryptophan" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -15123,21 +20001,24 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unnamed" ,
+        match-text "ttg start" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -15145,56 +20026,71 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unnamed protein product" ,
-        match-location equals ,
+        match-text "ttg start" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "ttg start codon" ,
+        match-location equals ,
+        case-sensitive TRUE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unusual protein" ,
-        match-location equals ,
+        match-text "Tuberculosis" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "UPF" ,
-        match-location equals ,
+        match-text "tumefaciens" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15203,49 +20099,47 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "uracil" ,
-        match-location equals ,
+        match-text "tumour" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "tumor" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "UTP" ,
+        match-text "Type II" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -15255,7 +20149,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -15263,63 +20159,62 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Valine" ,
-        match-location equals ,
+        match-text "Typhimurium" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        ignore-words {
-          {
-            synonyms {
-              "probable" ,
-              "putative" ,
-              "hypothetical" } ,
-            case-sensitive FALSE ,
-            whole-word TRUE } } ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "xanthine" ,
-        match-location equals ,
+        match-text "typr" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "type" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "zinc" ,
+        match-text "Tyrosine" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -15337,7 +20232,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -15345,12 +20242,13 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "aluminium" ,
-        match-location contains ,
+        match-text "uknown" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15359,19 +20257,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type british ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "aluminum" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "dimerisation" ,
+        match-text "uncharacterizaed" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -15381,20 +20282,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type british ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "dimerization" ,
+          replace "uncharacterized" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "dimerising" ,
-        match-location contains ,
+        match-text "uncharacterized" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15403,20 +20307,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type british ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "dimerizing" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "fibre" ,
-        match-location contains ,
+        match-text "uncharacterized" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15425,33 +20332,27 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type british ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "fiber" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
-  {
-    find
-      string-constraint {
-        match-text "haem" ,
-        match-location contains ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "uncharacterized protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
       string {
-        match-text "archaemetzincin" ,
-        match-location contains ,
+        match-text "uncharacterized protein conserved in bacteria" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15460,61 +20361,103 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } } ,
-    rule-type british ,
-    replace {
-      replace-func
-        haem-replace "haem" ,
-      move-to-note FALSE } } ,
-  {
-    find
-      string-constraint {
-        match-text "localisation" ,
-        match-location contains ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "uncharacterized conserved protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type british ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "localization" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
-  {
-    find
-      string-constraint {
-        match-text "majour" ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "uncharacterized" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "uncharacterized domain 1" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "uncharacterized protein" ,
+        match-location starts ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word TRUE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+      string {
+        match-text "UPF" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            word "UPF" ,
+            synonyms {
+              "UCP" ,
+              "DUF" ,
+              "PUF" ,
+              "CHP" } ,
+            case-sensitive FALSE ,
+            whole-word FALSE } } ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type british ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "major" ,
+          replace "putative" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "mobilisation" ,
-        match-location contains ,
+        match-text "unclassified" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15523,19 +20466,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type british ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "mobilization" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "polymeris" ,
+        match-text "undecapaprenyl" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -15545,20 +20491,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type british ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "polymeriz" ,
+          replace "undecaprenyl" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "sulphate" ,
-        match-location contains ,
+        match-text "undefined product" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15567,19 +20516,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type british ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "sulfate" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "sulphide" ,
+        match-text "undefined product" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -15589,42 +20541,71 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type british ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "sulfide" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "undefined product" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type database ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "tumour" ,
-        match-location contains ,
+        match-text "unique" ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type british ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "unique protein" ,
+        match-location equals ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct FALSE ,
+        whole-word FALSE ,
+        not-present TRUE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "tumor" ,
+          replace "putative" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "utilisation" ,
-        match-location contains ,
+        match-text "unkn" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15633,20 +20614,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type british ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "utilization" ,
+          replace "hypothetical protein" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "utilising" ,
-        match-location contains ,
+        match-text "unknow protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15655,21 +20639,24 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type british ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "utilizing" ,
+          replace "hypothetical protein" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text ";" ,
-        match-location contains ,
-        case-sensitive TRUE ,
+        match-text "unknown" ,
+        match-location equals ,
+        case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
@@ -15677,28 +20664,78 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "a " ,
-        match-location starts ,
-        case-sensitive TRUE ,
+        match-text "unknown" ,
+        match-location contains ,
+        case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description } ,
-  {
-    find
-      string-constraint {
-        match-text "alternate protein name" ,
-        match-location contains ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      field {
+        field
+          feature-field {
+            type cds ,
+            field
+              legal-qual product } ,
+        string-constraint {
+          match-text "protein of unknown function" ,
+          match-location contains ,
+          case-sensitive FALSE ,
+          ignore-space FALSE ,
+          ignore-punct FALSE ,
+          whole-word FALSE ,
+          not-present TRUE ,
+          is-all-caps FALSE ,
+          is-all-lower FALSE ,
+          is-all-punct FALSE ,
+          ignore-weasel FALSE ,
+          is-first-cap FALSE ,
+          is-first-each-cap FALSE } } ,
+      field {
+        field
+          feature-field {
+            type cds ,
+            field
+              legal-qual product } ,
+        string-constraint {
+          match-text "domain of unknown function" ,
+          match-location contains ,
+          case-sensitive FALSE ,
+          ignore-space FALSE ,
+          ignore-punct FALSE ,
+          whole-word FALSE ,
+          not-present TRUE ,
+          is-all-caps FALSE ,
+          is-all-lower FALSE ,
+          is-all-punct FALSE ,
+          ignore-weasel FALSE ,
+          is-first-cap FALSE ,
+          is-first-each-cap FALSE } } ,
+      string {
+        match-text "unknown" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15707,26 +20744,30 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
       string {
-        match-text "alternative protein name" ,
+        match-text "unknown protein" ,
         match-location equals ,
-        case-sensitive TRUE ,
+        case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present TRUE ,
+        not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } } ,
-    rule-type description } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type might-be-nonfunctional ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "and related enzyme" ,
-        match-location ends ,
+        match-text "unknown domain" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15735,19 +20776,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "and related enzymes" ,
-        match-location ends ,
+        match-text "unknown function" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15756,19 +20801,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "and related protein" ,
-        match-location ends ,
+        match-text "unknown protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15777,19 +20826,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "and related proteins" ,
-        match-location ends ,
+        match-text "unkown" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15798,19 +20851,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
+          replace "unknown" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "CDS" ,
-        match-location contains ,
+        match-text "unnamed" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15819,13 +20876,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "function" ,
-        match-location starts ,
+        match-text "unnamed" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15834,28 +20901,31 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description } ,
-  {
-    find
-      string-constraint {
-        match-text "highly conserved" ,
-        match-location contains ,
-        case-sensitive FALSE ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    feat-constraint {
+      string {
+        match-text "unnamed" ,
+        match-location equals ,
+        case-sensitive TRUE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
         whole-word FALSE ,
-        not-present FALSE ,
+        not-present TRUE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "identity" ,
-        match-location contains ,
+        match-text "unnamed protein product" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15864,13 +20934,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "inactivated derivative" ,
-        match-location contains ,
+        match-text "unspecified product" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15879,28 +20959,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description } ,
-  {
-    find
-      string-constraint {
-        match-text "Includes:" ,
-        match-location contains ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word TRUE ,
-        not-present FALSE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "narrowly conserved" ,
-        match-location contains ,
+        match-text "unusual protein" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15909,25 +20984,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "novel" ,
-        match-location contains ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word TRUE ,
-        not-present FALSE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    except
-      string-constraint {
-        match-text "novel protein" ,
+        match-text "UPF" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -15937,12 +21009,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type description } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protein associated to" ,
+        match-text "UPF" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -15952,13 +21034,13 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description } ,
-  {
-    find
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    except
       string-constraint {
-        match-text "ttg start" ,
-        match-location contains ,
+        match-text "UPF" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -15967,68 +21049,48 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "ttg start codon" ,
-        match-location equals ,
-        case-sensitive TRUE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel TRUE } } ,
-    rule-type description } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type database ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unnamed" ,
-        match-location contains ,
-        case-sensitive FALSE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word TRUE ,
-        not-present FALSE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    feat-constraint {
-      string {
-        match-text "unnamed" ,
+        match-text "uracil" ,
         match-location equals ,
-        case-sensitive TRUE ,
-        ignore-space FALSE ,
-        ignore-punct FALSE ,
-        whole-word FALSE ,
-        not-present TRUE ,
-        is-all-caps FALSE ,
-        is-all-lower FALSE ,
-        is-all-punct FALSE ,
-        ignore-weasel TRUE } } ,
-    rule-type description } ,
-  {
-    find
-      string-constraint {
-        match-text "weakly conserved" ,
-        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "widely conserved" ,
+        match-text "utilisation" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -16038,130 +21100,166 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type description } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "utilization" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "gene" ,
+        match-text "utilising" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type gene } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type british ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "utilizing" ,
+          whole-string FALSE ,
+          weasel-to-putative FALSE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "genes" ,
-        match-location contains ,
+        match-text "UTP" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
-    rule-type gene } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
+    replace {
+      replace-func
+        simple-replace {
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
+          weasel-to-putative FALSE } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "claster" ,
-        match-location contains ,
+        match-text "Valine" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
-          replace "cluster" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putativie" ,
+        match-text "vigtamin" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "vitamin" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "putativ" ,
+        match-text "weakly conserved" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "putative" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ysine" ,
+        match-text "widely conserved" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word TRUE ,
+        whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "lysine" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type description ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "unknow protein" ,
+        match-text "xanthine" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -16171,19 +21269,22 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
-          whole-string FALSE ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "lacitehtopyh" ,
+        match-text "xenopus" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -16193,20 +21294,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
-          whole-string FALSE ,
+          replace "hypothetical protein" ,
+          whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "protein of" ,
-        match-location equals ,
+        match-text "xray structure" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -16215,174 +21319,191 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "g:t" ,
-        match-location equals ,
+        match-text "yeast" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Archaeal" ,
-        match-location equals ,
+        match-text "YeeEYedE" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "YeeE/YedE" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "ABC-type polysaccharide" ,
-        match-location equals ,
+        match-text "Yersinia" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type remove-organism-name ,
     replace {
       replace-func
         simple-replace {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Calcium" ,
-        match-location equals ,
+        match-text "YjgPYjgQ" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "YjgP/YjgQ" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Na+" ,
-        match-location equals ,
+        match-text "ypothetical" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "hypothetical" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Ni" ,
-        match-location equals ,
+        match-text "ysine" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "lysine" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Oxalate" ,
-        match-location equals ,
+        match-text "ytochrome" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "cytochrome" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Maltose" ,
-        match-location equals ,
+        match-text "yypothetical" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -16391,29 +21512,42 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "hypothetical" ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Protein putative protein" ,
+        match-text "zinc" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
+        ignore-words {
+          {
+            synonyms {
+              "probable" ,
+              "putative" ,
+              "hypothetical" } ,
+            case-sensitive FALSE ,
+            whole-word TRUE } } ,
         whole-word FALSE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -16421,11 +21555,12 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note TRUE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Type II" ,
+        match-text "zinc finger" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -16435,20 +21570,23 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+          replace "zinc finger protein" ,
+          whole-string FALSE ,
+          weasel-to-putative TRUE } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "membrane protein of" ,
-        match-location equals ,
+        match-text "\" ,
+        match-location ends ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -16457,20 +21595,16 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type typo ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "membrane protein" ,
-          whole-string FALSE ,
-          weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text ":" ,
-        match-location starts ,
+        match-text "\\-PA" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -16479,13 +21613,16 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type inappropriate-symbol } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "sugar" ,
-        match-location equals ,
+        match-text "_" ,
+        match-location ends ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -16494,20 +21631,21 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
+  {
+    find
+      underscore NULL ,
+    rule-type database ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "galactose" ,
-        match-location equals ,
+        match-text "|" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -16516,51 +21654,52 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
-    replace {
-      replace-func
-        simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
-          weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type inappropriate-symbol ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hyppothetical" ,
+        match-text "familly" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical" ,
+          replace "family" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "hypotheticial" ,
+        match-text "hypotheitical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
@@ -16568,56 +21707,63 @@ Suspect-rule-set ::= {
           replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "organise" ,
+        match-text "hypopthetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type british ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "organize" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "isation" ,
+        match-text "hypothetetical" ,
         match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
-        whole-word FALSE ,
+        whole-word TRUE ,
         not-present FALSE ,
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type british ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "ization" ,
+          replace "hypothetical" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "Giardia" ,
-        match-location contains ,
+        match-text "no product string in file" ,
+        match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -16626,12 +21772,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type remove-organism-name } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type none ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "specific" ,
+        match-text "distantly" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -16641,7 +21790,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -16649,11 +21800,12 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "peptidyl-prolyl cis-trans" ,
+        match-text "protein distantly" ,
         match-location equals ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
@@ -16663,7 +21815,9 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type hypothetical ,
     replace {
       replace-func
@@ -16671,12 +21825,13 @@ Suspect-rule-set ::= {
           replace "hypothetical protein" ,
           whole-string TRUE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "inorganic phosphate" ,
-        match-location equals ,
+        match-text "ifunctional " ,
+        match-location starts ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -16685,20 +21840,41 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel TRUE } ,
-    rule-type hypothetical ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "hypothetical protein" ,
-          whole-string TRUE ,
+          replace "bifunctional " ,
+          whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note TRUE } } ,
+      move-to-note FALSE } ,
+    fatal FALSE } ,
   {
     find
       string-constraint {
-        match-text "likely" ,
-        match-location starts ,
+        match-text "refseq" ,
+        match-location contains ,
+        case-sensitive FALSE ,
+        ignore-space FALSE ,
+        ignore-punct TRUE ,
+        whole-word TRUE ,
+        not-present FALSE ,
+        is-all-caps FALSE ,
+        is-all-lower FALSE ,
+        is-all-punct FALSE ,
+        ignore-weasel TRUE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
+    rule-type none ,
+    fatal TRUE } ,
+  {
+    find
+      string-constraint {
+        match-text "casette" ,
+        match-location contains ,
         case-sensitive FALSE ,
         ignore-space FALSE ,
         ignore-punct FALSE ,
@@ -16707,12 +21883,15 @@ Suspect-rule-set ::= {
         is-all-caps FALSE ,
         is-all-lower FALSE ,
         is-all-punct FALSE ,
-        ignore-weasel FALSE } ,
+        ignore-weasel FALSE ,
+        is-first-cap FALSE ,
+        is-first-each-cap FALSE } ,
     rule-type typo ,
     replace {
       replace-func
         simple-replace {
-          replace "putative" ,
+          replace "cassette" ,
           whole-string FALSE ,
           weasel-to-putative FALSE } ,
-      move-to-note FALSE } } }
+      move-to-note FALSE } ,
+    fatal FALSE } }
diff --git a/c++/src/objects/medline/Medline_entry.cpp b/c++/src/objects/medline/Medline_entry.cpp
index 92439d0..bbabf4f 100644
--- a/c++/src/objects/medline/Medline_entry.cpp
+++ b/c++/src/objects/medline/Medline_entry.cpp
@@ -1,4 +1,4 @@
-/* $Id: Medline_entry.cpp 272611 2011-04-08 18:57:08Z ucko $
+/* $Id: Medline_entry.cpp 498027 2016-04-12 18:56:44Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -57,10 +57,10 @@ bool CMedline_entry::GetLabelV1(string* label, TLabelFlags flags) const
 {
     // Add Medline specific label, then treat as cit-art
     if ( IsSetPmid() ) {
-        *label += "PM" + NStr::IntToString(GetPmid().Get());
+        *label += "PM" + NStr::NumericToString(GetPmid().Get());
     }
     else if ( IsSetUid() ) {
-        *label += "NLM" + NStr::IntToString(GetUid());
+        *label += "NLM" + NStr::NumericToString(GetUid());
     }
     else {
         *label += "No Medline found";
diff --git a/c++/src/objects/medline/medline.def b/c++/src/objects/medline/medline.def
index b5465d3..0bf9fb5 100644
--- a/c++/src/objects/medline/medline.def
+++ b/c++/src/objects/medline/medline.def
@@ -1,2 +1,10 @@
 [-]
 _export = NCBI_MEDLINE_EXPORT
+
+[Medline-entry]
+uid._type = ncbi::TEntrezId
+uid._storage_type = ncbi::TIntId
+
+[DocRef]
+uid._type = ncbi::TEntrezId
+uid._storage_type = ncbi::TIntId
diff --git a/c++/src/objects/pub/Pub.cpp b/c++/src/objects/pub/Pub.cpp
index 2ea04f0..4ad65cd 100644
--- a/c++/src/objects/pub/Pub.cpp
+++ b/c++/src/objects/pub/Pub.cpp
@@ -1,4 +1,4 @@
-/* $Id: Pub.cpp 452468 2014-11-20 13:44:46Z bollin $
+/* $Id: Pub.cpp 498027 2016-04-12 18:56:44Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -116,10 +116,10 @@ bool CPub::GetLabel(string*        label,
 
     switch (Which()) {
     case e_Muid:
-        *label += "NLM" + NStr::IntToString(GetMuid());
+        *label += "NLM" + NStr::NumericToString(GetMuid());
         return true;
     case e_Pmid:
-        *label += "PM" + NStr::IntToString(GetPmid().Get());
+        *label += "PM" + NStr::NumericToString(GetPmid().Get());
         return true;
     case e_Equiv:
         return GetEquiv().GetLabel(label, flags, version);
diff --git a/c++/src/objects/pub/Pub_equiv.cpp b/c++/src/objects/pub/Pub_equiv.cpp
index 7547479..c9f8845 100644
--- a/c++/src/objects/pub/Pub_equiv.cpp
+++ b/c++/src/objects/pub/Pub_equiv.cpp
@@ -1,4 +1,4 @@
-/* $Id: Pub_equiv.cpp 452468 2014-11-20 13:44:46Z bollin $
+/* $Id: Pub_equiv.cpp 507570 2016-07-20 12:15:43Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -62,19 +62,17 @@ bool CPub_equiv::GetLabel(string* label, TLabelFlags flags,
     for(i = 0; i < 5; i++) {
         pubs[i] = 0;
     }
-    i = 0;
+    i = 1;
     
     // Get five pubs in the set of pubs, giving preference to e_Muid, 
     // e_Pmid, and e_Gen.
     ITERATE (list<CRef<CPub> >, it, Get()) {
         switch ((**it).Which()) {
         case CPub::e_Muid:
-            if (!pubs[3] || pubs[3]->Which() != CPub::e_Pmid) {
-                pubs[3] = *it;
-            }
+            pubs[3] = *it;
             break;
         case CPub::e_Pmid:
-            pubs[3] = *it;
+            pubs[0] = *it;
             break;
         case CPub::e_Gen:
             if ((**it).GetGen().IsSetSerial_number()) {
diff --git a/c++/src/objects/pub/pub.def b/c++/src/objects/pub/pub.def
index 520e4f4..8a3c60f 100644
--- a/c++/src/objects/pub/pub.def
+++ b/c++/src/objects/pub/pub.def
@@ -1,2 +1,6 @@
 [-]
 _export = NCBI_PUB_EXPORT
+
+[Pub]
+muid._type = ncbi::TEntrezId
+muid._storage_type = ncbi::TIntId
diff --git a/c++/src/objects/seq/Bioseq.cpp b/c++/src/objects/seq/Bioseq.cpp
index 9a7e9b1..662029b 100644
--- a/c++/src/objects/seq/Bioseq.cpp
+++ b/c++/src/objects/seq/Bioseq.cpp
@@ -1,4 +1,4 @@
-/* $Id: Bioseq.cpp 474093 2015-07-24 20:13:24Z ucko $
+/* $Id: Bioseq.cpp 502444 2016-05-24 18:46:25Z kans $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -210,6 +210,24 @@ void CBioseq::GetLabel(string* label, ELabelType type, bool worst) const
         CSeq_id worst_id;
         if (!worst) {
             id = GetId().begin()->GetPointer();
+            ITERATE (CBioseq::TId, id_itr, GetId()) {
+                const CSeq_id& sid = **id_itr;
+                switch (sid.Which()) {
+                    case CSeq_id::e_Other:
+                    case CSeq_id::e_Genbank:
+                    case CSeq_id::e_Embl:
+                    case CSeq_id::e_Ddbj:
+                        {
+                            const CTextseq_id& tsid = *sid.GetTextseq_Id ();
+                            if (tsid.IsSetAccession()) {
+                                id = &sid;
+                            }
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
         } else {
             const CSeq_id* wid =
                 FindBestChoice(GetId(), CSeq_id::WorstRank).GetPointer();
diff --git a/c++/src/objects/seq/Delta_ext.cpp b/c++/src/objects/seq/Delta_ext.cpp
index eb97f8d..4f3423a 100644
--- a/c++/src/objects/seq/Delta_ext.cpp
+++ b/c++/src/objects/seq/Delta_ext.cpp
@@ -1,4 +1,4 @@
-/* $Id: Delta_ext.cpp 437315 2014-06-05 13:07:19Z gotvyans $
+/* $Id: Delta_ext.cpp 514371 2016-09-21 15:22:54Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -90,7 +90,7 @@ CDelta_seq& CDelta_ext::AddLiteral(const CTempString& iupac_seq,
                                    CSeq_inst::EMol mol, bool do_pack)
 {
     CRef<CDelta_seq> seg(new CDelta_seq());
-    seg->SetLiteral().SetLength(iupac_seq.size());
+    seg->SetLiteral().SetLength((CSeq_literal::TLength)iupac_seq.size());
 
     switch (mol) {
     case CSeq_inst::eMol_aa:
@@ -128,7 +128,7 @@ public:
     SIZE_TYPE GetOverhead(TCoding coding) const
         { return coding == CSeqUtil::e_not_set ? 96 : 128; }
     
-    virtual bool GapsOK(TCodingType coding_type) const { return m_GapsOK; }
+    virtual bool GapsOK(TCodingType) const { return m_GapsOK; }
 
     char* NewSegment(TCoding coding, TSeqPos length);
 
diff --git a/c++/src/objects/seq/Linkage_evidence.cpp b/c++/src/objects/seq/Linkage_evidence.cpp
index 27d648a..fc5909f 100644
--- a/c++/src/objects/seq/Linkage_evidence.cpp
+++ b/c++/src/objects/seq/Linkage_evidence.cpp
@@ -1,4 +1,4 @@
-/* $Id: Linkage_evidence.cpp 436426 2014-05-28 12:53:09Z bollin $
+/* $Id: Linkage_evidence.cpp 498903 2016-04-20 15:50:10Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -61,7 +61,7 @@ bool CLinkage_evidence::GetLinkageEvidence (
     // basically just a wrapper for the other function which does
     // the convenience of splitting the string
     vector<string> linkage_evidence_vec;
-    NStr::Tokenize( linkage_evidence, ";", linkage_evidence_vec );
+    NStr::Split(linkage_evidence, ";", linkage_evidence_vec, NStr::fSplit_NoMergeDelims);
     return GetLinkageEvidence( output_result, linkage_evidence_vec );
 }
 
diff --git a/c++/src/objects/seq/Seq_gap.cpp b/c++/src/objects/seq/Seq_gap.cpp
index 3963714..abd4237 100644
--- a/c++/src/objects/seq/Seq_gap.cpp
+++ b/c++/src/objects/seq/Seq_gap.cpp
@@ -1,4 +1,4 @@
-/* $Id: Seq_gap.cpp 499433 2016-04-26 14:13:30Z ivanov $
+/* $Id: Seq_gap.cpp 514371 2016-09-21 15:22:54Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -56,7 +56,7 @@ namespace
         ITERATE_0_IDX(ii, sValue.length()) {
             const char ch = sValue[ii];
             if (isupper(ch)) {
-                newString.push_back(tolower(ch));
+                newString.push_back((unsigned char)tolower(ch));
             }
             else if (ch == ' ' || ch == '_') {
                 newString.push_back('-');
diff --git a/c++/src/objects/seq/Seq_inst.cpp b/c++/src/objects/seq/Seq_inst.cpp
index b2a372f..3963364 100644
--- a/c++/src/objects/seq/Seq_inst.cpp
+++ b/c++/src/objects/seq/Seq_inst.cpp
@@ -1,4 +1,4 @@
-/* $Id: Seq_inst.cpp 489361 2016-01-12 17:31:56Z choi $
+/* $Id: Seq_inst.cpp 519218 2016-11-14 16:06:51Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -79,6 +79,90 @@ string CSeq_inst::GetMoleculeClass(CSeq_inst::EMol mol)
 }
 
 
+#define CONVERT_NA_CODING_TO_STR(encoding) \
+    case CSeq_data::e_##encoding: \
+        CSeqConvert::Convert(seq_data.Get##encoding().Get(), CSeqUtil::e_##encoding, 0, length, str, CSeqUtil::e_Iupacna); \
+        break;
+
+#define CONVERT_AA_CODING_TO_STR(encoding) \
+    case CSeq_data::e_##encoding: \
+        CSeqConvert::Convert(seq_data.Get##encoding().Get(), CSeqUtil::e_##encoding, 0, length, str, CSeqUtil::e_Iupacaa); \
+        break;
+
+
+bool CSeq_inst::ConvertDeltaToRaw()
+{
+    if (!IsSetRepr() || GetRepr() != objects::CSeq_inst::eRepr_delta ||
+        !IsSetExt() || !GetExt().IsDelta() || !IsSetMol())
+    {
+        return false;
+    }
+
+    // can only be done if there are no seq-loc objects
+    ITERATE(CSeq_ext::TDelta::Tdata, it, GetExt().GetDelta().Get())
+    {
+        if ((*it)->IsLoc()) {
+            return false;
+        }
+    }
+
+    size_t orig_len = GetLength();
+    string iupacna;
+    NON_CONST_ITERATE(objects::CSeq_ext::TDelta::Tdata, it, SetExt().SetDelta().Set())
+    {
+        if ((*it)->IsLiteral())
+        {
+            const CSeq_literal& seq_literal = (*it)->GetLiteral();
+            TSeqPos length = seq_literal.GetLength();
+            if ((*it)->GetLiteral().IsSetSeq_data())
+            {
+                const CSeq_data& seq_data = seq_literal.GetSeq_data();
+                string str;
+                switch (seq_data.Which())
+                {
+                case CSeq_data::e_Iupacna:
+                    str = seq_data.GetIupacna();
+                    break;
+                CONVERT_NA_CODING_TO_STR(Ncbi2na)
+                CONVERT_NA_CODING_TO_STR(Ncbi4na)
+                CONVERT_NA_CODING_TO_STR(Ncbi8na)
+                case objects::CSeq_data::e_Iupacaa:
+                    str = seq_data.GetIupacaa();
+                    break;
+                CONVERT_AA_CODING_TO_STR(Ncbi8aa);
+                CONVERT_AA_CODING_TO_STR(Ncbieaa);
+                CONVERT_AA_CODING_TO_STR(Ncbistdaa);
+                default:
+                    break;
+                }
+                iupacna += str;
+            }
+
+            if (!seq_literal.IsSetSeq_data() || seq_literal.GetSeq_data().IsGap())
+            {                
+                if (IsAa()) {
+                    iupacna += string(length, 'X');
+                } else {
+                    iupacna += string(length, 'N');
+                }
+            }
+        }
+    }
+
+    if (orig_len != iupacna.length()) {
+        SetLength(iupacna.length());
+    }
+    SetRepr(objects::CSeq_inst::eRepr_raw);
+    if (IsAa()) {
+        SetSeq_data().SetIupacaa() = objects::CIUPACaa(iupacna);
+    } else {
+        SetSeq_data().SetIupacna() = objects::CIUPACna(iupacna);
+    }
+    ResetExt();
+    return true;
+}
+
+
 END_objects_SCOPE // namespace ncbi::objects::
 
 END_NCBI_SCOPE
diff --git a/c++/src/objects/seq/Seq_literal.cpp b/c++/src/objects/seq/Seq_literal.cpp
index c4024e1..06a93b6 100644
--- a/c++/src/objects/seq/Seq_literal.cpp
+++ b/c++/src/objects/seq/Seq_literal.cpp
@@ -1,4 +1,4 @@
-/* $Id: Seq_literal.cpp 429786 2014-03-19 15:22:12Z mozese2 $
+/* $Id: Seq_literal.cpp 497282 2016-04-05 18:01:48Z kiryutin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -53,7 +53,7 @@ CSeq_literal::~CSeq_literal(void)
 {
 }
 
-CSeq_literal::EBridgeableStatus CSeq_literal::IsBridgeable() const
+CSeq_literal::EBridgeableStatus CSeq_literal::GetBridgeability() const
 {
     if (!IsSetSeq_data()) {
         return e_MaybeBridgeable;
diff --git a/c++/src/objects/seq/seq.def b/c++/src/objects/seq/seq.def
index 245e883..a0aa31c 100644
--- a/c++/src/objects/seq/seq.def
+++ b/c++/src/objects/seq/seq.def
@@ -12,3 +12,7 @@ length._type = TSeqPos
 
 [Seq-literal]
 length._type = TSeqPos
+
+[Annot-id]
+ncbi._type = ncbi::TEntrezId
+ncbi._storage_type = ncbi::TIntId
diff --git a/c++/src/objects/seq/seq_align_mapper_base.cpp b/c++/src/objects/seq/seq_align_mapper_base.cpp
index 44d55e5..f57b20c 100644
--- a/c++/src/objects/seq/seq_align_mapper_base.cpp
+++ b/c++/src/objects/seq/seq_align_mapper_base.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_align_mapper_base.cpp 481221 2015-10-07 18:25:55Z grichenk $
+/*  $Id: seq_align_mapper_base.cpp 501097 2016-05-11 14:35:58Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -353,40 +353,57 @@ void CSeq_align_Mapper_Base::x_Init(const CDense_seg& denseg)
         CopyContainer<CDense_seg::TScores, TScores>(
             denseg.GetScores(), m_SegsScores);
     }
+    // Check sequence types.
+    bool have_nuc = false;
+    bool have_prot = false;
+    set<CSeq_id_Handle> unknown;
+    for (size_t row = 0; row < m_Dim; ++row) {
+        const CSeq_id& seq_id = *denseg.GetIds()[row];
+        CSeq_id_Handle idh = CSeq_id_Handle::GetHandle(seq_id);
+        CSeq_loc_Mapper_Base::ESeqType seq_type =
+            m_LocMapper.GetSeqTypeById(idh);
+        switch ( seq_type ) {
+        case CSeq_loc_Mapper_Base::eSeq_nuc:
+            have_nuc = true;
+            break;
+        case CSeq_loc_Mapper_Base::eSeq_prot:
+            have_prot = true;
+            break;
+        default:
+            // Collect sequences with unknown types.
+            unknown.insert(idh);
+            break;
+        }
+    }
+    if (have_prot  &&  have_nuc) {
+        NCBI_THROW(CAnnotMapperException, eBadAlignment,
+            "Dense-segs with mixed sequence types are not supported");
+    }
+    if ((have_nuc  ||  have_prot)  &&  !unknown.empty()) {
+        CSeq_loc_Mapper_Base::ESeqType seq_type = have_nuc ?
+            CSeq_loc_Mapper_Base::eSeq_nuc : CSeq_loc_Mapper_Base::eSeq_prot;
+        // If there are sequences of unknown types, assume they are the same as
+        // the known ones - dense-seg can not contain mixed types.
+        ITERATE(set<CSeq_id_Handle>, it, unknown) {
+            m_LocMapper.SetSeqTypeById(*it, seq_type);
+        }
+    }
+
+    int width = have_prot ? 3 : 1;
     ENa_strand strand = eNa_strand_unknown;
     for (size_t seg = 0;  seg < numseg;  seg++) {
         // Create new segment.
         SAlignment_Segment& alnseg = x_PushSeg(denseg.GetLens()[seg], m_Dim);
-        bool have_prot = false;
-        bool have_nuc = false;
-        for (unsigned int row = 0;  row < m_Dim;  row++) {
+        for (size_t row = 0; row < m_Dim; ++row) {
             if ( m_HaveStrands ) {
                 strand = denseg.GetStrands()[seg*m_Dim + row];
             }
             const CSeq_id& seq_id = *denseg.GetIds()[row];
-
-            int width = 1;
-            CSeq_loc_Mapper_Base::ESeqType seq_type =
-                m_LocMapper.GetSeqTypeById(seq_id);
-            if (seq_type == CSeq_loc_Mapper_Base::eSeq_prot) {
-                have_prot = true;
-                width = 3;
-            }
-            else /*if (seq_type == CSeq_loc_Mapper_Base::eSeq_nuc)*/ {
-                // Treat unknown type as nuc.
-                have_nuc = true;
-            }
             int start = denseg.GetStarts()[seg*m_Dim + row]*width;
             alnseg.AddRow(row, seq_id, start, m_HaveStrands, strand);
         }
-        if (have_prot  &&  have_nuc) {
-            NCBI_THROW(CAnnotMapperException, eBadAlignment,
-                "Dense-segs with mixed sequence types are not supported");
-        }
         // For proteins segment length needs to be adjusted.
-        if ( have_prot ) {
-            alnseg.m_Len *= 3;
-        }
+        alnseg.m_Len *= width;
     }
 }
 
diff --git a/c++/src/objects/seq/seq_id_handle.cpp b/c++/src/objects/seq/seq_id_handle.cpp
index c8b57dd..4cfb502 100644
--- a/c++/src/objects/seq/seq_id_handle.cpp
+++ b/c++/src/objects/seq/seq_id_handle.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_id_handle.cpp 430230 2014-03-24 20:35:20Z grichenk $
+/*  $Id: seq_id_handle.cpp 499612 2016-04-26 18:53:35Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -149,7 +149,6 @@ void CSeq_id_Handle::GetMatchingHandles(TMatches& matches) const
 
 void CSeq_id_Handle::GetReverseMatchingHandles(TMatches& matches) const
 {
-    GetMatchingHandles(matches);
     GetMapper().GetReverseMatchingHandles(*this, matches);
 }
 
@@ -164,7 +163,6 @@ void CSeq_id_Handle::GetMatchingHandles(TMatches& matches,
 void CSeq_id_Handle::GetReverseMatchingHandles(TMatches& matches,
                                                EAllowWeakMatch allow_weak_match) const
 {
-    GetMatchingHandles(matches, allow_weak_match);
     GetMapper().GetReverseMatchingHandles(*this, matches, allow_weak_match);
 }
 
diff --git a/c++/src/objects/seq/seq_id_tree.cpp b/c++/src/objects/seq/seq_id_tree.cpp
index e7ed6b5..42e15f5 100644
--- a/c++/src/objects/seq/seq_id_tree.cpp
+++ b/c++/src/objects/seq/seq_id_tree.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_id_tree.cpp 488780 2016-01-05 19:38:09Z vasilche $
+/*  $Id: seq_id_tree.cpp 514371 2016-09-21 15:22:54Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -675,7 +675,7 @@ void s_RestoreNumber(string& str, size_t pos, size_t len, TIntId number)
     char* start = &str[pos];
     char* ptr = start + len;
     while ( number ) {
-        *--ptr = '0' + number % 10;
+        *--ptr = (char)('0' + number % 10);
         number /= 10;
     }
     while ( ptr > start ) {
@@ -763,6 +763,14 @@ CSeq_id_Textseq_Info::ParseAcc(const string& acc,
 }
 
 
+void CSeq_id_Textseq_Info::RestoreAccession(string& acc, TPacked param) const
+{
+    acc = GetAccPrefix();
+    acc.resize(acc.size() + GetAccDigits(), '0');
+    s_RestoreNumber(acc, GetAccPrefix().size(), GetAccDigits(), param);
+}
+
+
 void CSeq_id_Textseq_Info::Restore(CTextseq_id& id, TPacked param) const
 {
     if ( !id.IsSetAccession() ) {
@@ -1072,9 +1080,10 @@ void CSeq_id_Textseq_Tree::x_FindMatchByAcc(TSeq_id_MatchList& id_list,
 }
 
 
-void CSeq_id_Textseq_Tree::x_FindRevMatchByAcc(TSeq_id_MatchList& id_list,
-                                               const string& acc,
-                                               const TVersion* ver) const
+void
+CSeq_id_Textseq_Tree::x_FindRevMatchByAccPacked(TSeq_id_MatchList& id_list,
+                                                const string& acc,
+                                                const TVersion* ver) const
 {
     if ( !m_PackedMap.empty() ) {
         if ( TPackedKey key = CSeq_id_Textseq_Info::ParseAcc(acc, ver) ) {
@@ -1086,15 +1095,22 @@ void CSeq_id_Textseq_Tree::x_FindRevMatchByAcc(TSeq_id_MatchList& id_list,
             if ( key.IsSetVersion() ) {
                 // no version too
                 key.ResetVersion();
-                TPackedMap_CI it = m_PackedMap.find(key);
-                if ( it != m_PackedMap.end() ) {
+                TPackedMap_CI itm = m_PackedMap.find(key);
+                if ( itm != m_PackedMap.end() ) {
                     TPacked packed = CSeq_id_Textseq_Info::Pack(key, acc);
-                    id_list.insert(CSeq_id_Handle(it->second, packed));
+                    id_list.insert(CSeq_id_Handle(itm->second, packed));
                 }
             }
         }
     }
+}
 
+
+void
+CSeq_id_Textseq_Tree::x_FindRevMatchByAccNonPacked(TSeq_id_MatchList& id_list,
+                                                   const string& acc,
+                                                   const TVersion* ver) const
+{
     for ( TStringMapCI vit = m_ByAcc.find(acc);
           vit != m_ByAcc.end() && NStr::EqualNocase(vit->first, acc);
           ++vit ) {
@@ -1109,6 +1125,17 @@ void CSeq_id_Textseq_Tree::x_FindRevMatchByAcc(TSeq_id_MatchList& id_list,
 }
 
 
+inline
+void
+CSeq_id_Textseq_Tree::x_FindRevMatchByAcc(TSeq_id_MatchList& id_list,
+                                          const string& acc,
+                                          const TVersion* ver) const
+{
+    x_FindRevMatchByAccPacked(id_list, acc, ver);
+    x_FindRevMatchByAccNonPacked(id_list, acc, ver);
+}
+
+
 void CSeq_id_Textseq_Tree::x_FindMatchByName(TSeq_id_MatchList& id_list,
                                              const string& name,
                                              const CTextseq_id* tid) const
@@ -1142,9 +1169,9 @@ void CSeq_id_Textseq_Tree::x_FindMatchByName(TSeq_id_MatchList& id_list,
 }
 
 
-void CSeq_id_Textseq_Tree::x_FindRevMatchByName(TSeq_id_MatchList& id_list,
-                                                const string& name,
-                                                const CTextseq_id* tid) const
+void CSeq_id_Textseq_Tree::x_FindRevMatchByName(TSeq_id_MatchList& /*id_list*/,
+                                                const string&      /*name*/,
+                                                const CTextseq_id* /*tid*/) const
 {
     /*
     for ( TStringMapCI vit = m_ByName.find(name);
@@ -1333,13 +1360,20 @@ void CSeq_id_Textseq_Tree::FindReverseMatch(const CSeq_id_Handle& id,
                 id_list.insert(CSeq_id_Handle(it->second, id.GetPacked()));
             }
         }
+        if ( !m_ByAcc.empty() ) {
+            // look for non-packed variants that may have set name or revision
+            string acc;
+            info->RestoreAccession(acc, id.GetPacked());
+            x_FindRevMatchByAccNonPacked
+                (id_list, acc, info->IsSetVersion()? &info->GetVersion(): 0);
+        }
         return;
     }
 
     CConstRef<CSeq_id> orig_id = id.GetSeqId();
     const CTextseq_id& orig_tid = x_Get(*orig_id);
 
-    if ( !mine ) {
+    if ( true || !mine ) { // this code should be enough
         TReadLockGuard guard(m_TreeLock);
         // search only existing accessions
         if ( orig_tid.IsSetAccession() ) {
@@ -1350,85 +1384,6 @@ void CSeq_id_Textseq_Tree::FindReverseMatch(const CSeq_id_Handle& id,
         }
         return;
     }
-
-    // mine -> full search and create (TODO: do we really need this?)
-    CRef<CSeq_id> tmp(new CSeq_id);
-    tmp->Assign(*orig_id);
-    CTextseq_id& tid = const_cast<CTextseq_id&>(x_Get(*tmp));
-    bool A = orig_tid.IsSetAccession();
-    bool N = orig_tid.IsSetName();
-    bool v = orig_tid.IsSetVersion();
-    bool r = orig_tid.IsSetRelease();
-
-    if ( A  &&  (N  ||  v  ||  r) ) {
-        // A only
-        tid.Reset();
-        tid.SetAccession(orig_tid.GetAccession());
-        if ( CSeq_id_Handle h = FindInfo(*tmp) ) {
-            id_list.insert(h);
-        }
-        if ( v  &&  (N  ||  r) ) {
-            // A.v
-            tid.SetVersion(orig_tid.GetVersion());
-            if ( CSeq_id_Handle h = FindInfo(*tmp) ) {
-                id_list.insert(h);
-            }
-        }
-        if ( N ) {
-            // Collect all alternative names
-            set<string> alt_names;
-            TSeq_id_MatchList name_matches;
-            FindMatch(id, name_matches);
-            ITERATE(TSeq_id_MatchList, mit, name_matches) {
-                CConstRef<CSeq_id> mid = mit->GetSeqId();
-                const CTextseq_id& tmid = x_Get(*mid);
-                if ( tmid.IsSetName() ) {
-                    alt_names.insert(tmid.GetName());
-                }
-            }
-
-            ITERATE(set<string>, name_it, alt_names) {
-                // N only
-                tid.Reset();
-                tid.SetName(*name_it);
-                id_list.insert(FindOrCreate(*tmp));
-                if ( v  ||  r ) {
-                    if ( r ) {
-                        // N.r
-                        tid.SetRelease(orig_tid.GetRelease());
-                        id_list.insert(FindOrCreate(*tmp));
-                        tid.ResetRelease();
-                    }
-                    // A + N
-                    tid.SetAccession(orig_tid.GetAccession());
-                    id_list.insert(FindOrCreate(*tmp));
-                    if ( v  &&  r ) {
-                        // A.v + N
-                        tid.SetVersion(orig_tid.GetVersion());
-                        id_list.insert(FindOrCreate(*tmp));
-                        // A + N.r
-                        tid.ResetVersion();
-                        tid.SetRelease(orig_tid.GetRelease());
-                        id_list.insert(FindOrCreate(*tmp));
-                    }
-                    else if ( v  &&  *name_it != orig_tid.GetName() ) {
-                        tid.SetVersion(orig_tid.GetVersion());
-                        id_list.insert(FindOrCreate(*tmp));
-                    }
-                }
-            }
-        }
-    }
-    else if ( N  &&  (v  ||  r) ) {
-        // N only
-        tid.Reset();
-        tid.SetName(orig_tid.GetName());
-        id_list.insert(FindOrCreate(*tmp));
-        if ( v  &&  r ) {
-            tid.SetRelease(orig_tid.GetRelease());
-            id_list.insert(FindOrCreate(*tmp));
-        }
-    }
 }
 
 
diff --git a/c++/src/objects/seq/seq_id_tree.hpp b/c++/src/objects/seq/seq_id_tree.hpp
index 4c2cf82..0b9ef7e 100644
--- a/c++/src/objects/seq/seq_id_tree.hpp
+++ b/c++/src/objects/seq/seq_id_tree.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJECTS_OBJMGR___SEQ_ID_TREE__HPP
 #define OBJECTS_OBJMGR___SEQ_ID_TREE__HPP
 
-/*  $Id: seq_id_tree.hpp 436198 2014-05-23 19:12:14Z vasilche $
+/*  $Id: seq_id_tree.hpp 502271 2016-05-23 18:52:46Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -37,7 +37,6 @@
 #include <corelib/ncbimtx.hpp>
 #include <corelib/ncbistr.hpp>
 #include <corelib/ncbi_limits.hpp>
-#include <corelib/hash_map.hpp>
 
 #include <objects/general/Date.hpp>
 #include <objects/general/Dbtag.hpp>
@@ -341,7 +340,7 @@ public:
         bool IsSetVersion(void) const {
             return (m_Hash & 1) != 0;
         }
-        TVersion GetVersion(void) const {
+        const TVersion& GetVersion(void) const {
             _ASSERT(IsSetVersion());
             return m_Version;
         }
@@ -377,9 +376,10 @@ public:
     bool IsSetVersion(void) const {
         return m_Key.IsSetVersion();
     }
-    TVersion GetVersion(void) const {
+    const TVersion& GetVersion(void) const {
         return m_Key.GetVersion();
     }
+    void RestoreAccession(string& acc, TPacked param) const;
     void Restore(CTextseq_id& id, TPacked param) const;
 
     static TKey ParseAcc(const string& acc, const TVersion* ver);
@@ -484,6 +484,12 @@ private:
                            const string& name,
                            const CTextseq_id* tid = 0) const;
 
+    void x_FindRevMatchByAccPacked(TSeq_id_MatchList& id_list,
+                                   const string& acc,
+                                   const TVersion* ver = 0) const;
+    void x_FindRevMatchByAccNonPacked(TSeq_id_MatchList& id_list,
+                                      const string& acc,
+                                      const TVersion* ver = 0) const;
     void x_FindRevMatchByAcc(TSeq_id_MatchList& id_list,
                              const string& acc,
                              const TVersion* ver = 0) const;
diff --git a/c++/src/objects/seq/seq_loc_from_string.cpp b/c++/src/objects/seq/seq_loc_from_string.cpp
index f0c4480..a7375f3 100644
--- a/c++/src/objects/seq/seq_loc_from_string.cpp
+++ b/c++/src/objects/seq/seq_loc_from_string.cpp
@@ -1,4 +1,4 @@
-/* $Id: seq_loc_from_string.cpp 463555 2015-03-30 15:36:47Z vasilche $
+/* $Id: seq_loc_from_string.cpp 514371 2016-09-21 15:22:54Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -60,7 +60,8 @@ namespace {
         virtual unsigned int GetInt() { return 0; }
         virtual string GetString() { return ""; }
 
-        virtual CRef<CSeq_loc> GetLocation(CSeq_id *id, CGetSeqLocFromStringHelper* helper) { return CRef<CSeq_loc>(NULL); }
+        virtual CRef<CSeq_loc> GetLocation(CSeq_id*, CGetSeqLocFromStringHelper*) { return CRef<CSeq_loc>(NULL); }
+        
         enum E_TokenType {
             e_Int = 0,
             e_String,
diff --git a/c++/src/objects/seq/seq_loc_mapper_base.cpp b/c++/src/objects/seq/seq_loc_mapper_base.cpp
index 975afec..eacacbc 100644
--- a/c++/src/objects/seq/seq_loc_mapper_base.cpp
+++ b/c++/src/objects/seq/seq_loc_mapper_base.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_loc_mapper_base.cpp 493266 2016-02-25 16:13:50Z ivanov $
+/*  $Id: seq_loc_mapper_base.cpp 514371 2016-09-21 15:22:54Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -166,9 +166,9 @@ to packed-ints.
 class CDefault_Mapper_Sequence_Info : public IMapper_Sequence_Info
 {
 public:
-    virtual TSeqType GetSequenceType(const CSeq_id_Handle& idh)
+    virtual TSeqType GetSequenceType(const CSeq_id_Handle&)
         { return CSeq_loc_Mapper_Base::eSeq_unknown; }
-    virtual TSeqPos GetSequenceLength(const CSeq_id_Handle& idh)
+    virtual TSeqPos GetSequenceLength(const CSeq_id_Handle&)
         { return kInvalidSeqPos; }
     virtual void CollectSynonyms(const CSeq_id_Handle& id,
                                  TSynonyms&            synonyms)
@@ -193,7 +193,6 @@ CMappingRange::CMappingRange(CSeq_id_Handle     src_id,
                              ENa_strand         dst_strand,
                              bool               ext_to,
                              int                frame,
-                             TSeqPos            dst_total_len,
                              TSeqPos            src_bioseq_len,
                              TSeqPos            dst_len)
     : m_Src_id_Handle(src_id),
@@ -206,7 +205,6 @@ CMappingRange::CMappingRange(CSeq_id_Handle     src_id,
       m_Reverse(!SameOrientation(src_strand, dst_strand)),
       m_ExtTo(ext_to),
       m_Frame(frame),
-      m_Dst_total_len(dst_total_len),
       m_Src_bioseq_len(src_bioseq_len),
       m_Dst_len(dst_len),
       m_Group(0)
@@ -462,14 +460,14 @@ CMappingRanges::AddConversion(CSeq_id_Handle    src_id,
                               ENa_strand        dst_strand,
                               bool              ext_to,
                               int               frame,
-                              TSeqPos           dst_total_len,
+                              TSeqPos           /*dst_total_len*/,
                               TSeqPos           src_bioseq_len,
                               TSeqPos           dst_len)
 {
     CRef<CMappingRange> cvt(new CMappingRange(
         src_id, src_from, src_length, src_strand,
         dst_id, dst_from, dst_strand,
-        ext_to, frame, dst_total_len, src_bioseq_len, dst_len )); 
+        ext_to, frame, src_bioseq_len, dst_len )); 
     AddConversion(cvt);
     return cvt;
 }
@@ -611,6 +609,21 @@ void CSeq_loc_Mapper_Message::ResetObject(void)
 }
 
 
+/////////////////////////////////////////////////////////////////////////////
+///
+///  CSeq_loc_Mapper_Options --
+///
+
+
+IMapper_Sequence_Info& CSeq_loc_Mapper_Options::GetSeqInfo(void) const
+{
+    if ( !m_SeqInfo ) {
+        m_SeqInfo.Reset(new CDefault_Mapper_Sequence_Info);
+    }
+    return *m_SeqInfo;
+}
+
+
 /////////////////////////////////////////////////////////////////////
 //
 // CSeq_loc_Mapper_Base
@@ -640,7 +653,7 @@ ENa_strand s_IndexToStrand(size_t idx)
     s_IndexToStrand(idx)
 
 
-CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(IMapper_Sequence_Info* seqinfo)
+CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(CSeq_loc_Mapper_Options options)
     : m_MergeFlag(eMergeNone),
       m_GapFlag(eGapPreserve),
       m_MiscFlags(fTrimSplicedSegs),
@@ -649,14 +662,13 @@ CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(IMapper_Sequence_Info* seqinfo)
       m_Mappings(new CMappingRanges),
       m_CurrentGroup(0),
       m_FuzzOption(0),
-      m_MapOptions(0),
-      m_SeqInfo(seqinfo ? seqinfo : new CDefault_Mapper_Sequence_Info)
+      m_MapOptions(options)
 {
 }
 
 
-CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(CMappingRanges* mapping_ranges,
-                                           IMapper_Sequence_Info* seq_info)
+CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(CMappingRanges*         mapping_ranges,
+                                           CSeq_loc_Mapper_Options options)
     : m_MergeFlag(eMergeNone),
       m_GapFlag(eGapPreserve),
       m_MiscFlags(fTrimSplicedSegs),
@@ -665,15 +677,14 @@ CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(CMappingRanges* mapping_ranges,
       m_Mappings(mapping_ranges),
       m_CurrentGroup(0),
       m_FuzzOption(0),
-      m_MapOptions(0),
-      m_SeqInfo(seq_info ? seq_info : new CDefault_Mapper_Sequence_Info)
+      m_MapOptions(options)
 {
 }
 
 
-CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_feat&  map_feat,
-                                           EFeatMapDirection dir,
-                                           IMapper_Sequence_Info* seq_info)
+CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_feat&        map_feat,
+                                           EFeatMapDirection       dir,
+                                           CSeq_loc_Mapper_Options options)
     : m_MergeFlag(eMergeNone),
       m_GapFlag(eGapPreserve),
       m_MiscFlags(fTrimSplicedSegs),
@@ -682,16 +693,15 @@ CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_feat&  map_feat,
       m_Mappings(new CMappingRanges),
       m_CurrentGroup(0),
       m_FuzzOption(0),
-      m_MapOptions(0),
-      m_SeqInfo(seq_info ? seq_info : new CDefault_Mapper_Sequence_Info)
+      m_MapOptions(options)
 {
     x_InitializeFeat(map_feat, dir);
 }
 
 
-CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_loc& source,
-                                           const CSeq_loc& target,
-                                           IMapper_Sequence_Info* seq_info)
+CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_loc&         source,
+                                           const CSeq_loc&         target,
+                                           CSeq_loc_Mapper_Options options)
     : m_MergeFlag(eMergeNone),
       m_GapFlag(eGapPreserve),
       m_MiscFlags(fTrimSplicedSegs),
@@ -700,16 +710,32 @@ CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_loc& source,
       m_Mappings(new CMappingRanges),
       m_CurrentGroup(0),
       m_FuzzOption(0),
-      m_MapOptions(0),
-      m_SeqInfo(seq_info ? seq_info : new CDefault_Mapper_Sequence_Info)
+      m_MapOptions(options)
 {
     x_InitializeLocs(source, target);
 }
 
 
-CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_align& map_align,
-                                           const CSeq_id&    to_id,
-                                           TMapOptions       opts,
+CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_align&       map_align,
+                                           const CSeq_id&          to_id,
+                                           CSeq_loc_Mapper_Options options)
+    : m_MergeFlag(eMergeNone),
+      m_GapFlag(eGapPreserve),
+      m_MiscFlags(fTrimSplicedSegs),
+      m_Partial(false),
+      m_LastTruncated(false),
+      m_Mappings(new CMappingRanges),
+      m_CurrentGroup(0),
+      m_FuzzOption(0),
+      m_MapOptions(options)
+{
+    x_InitializeAlign(map_align, to_id);
+}
+
+
+CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_align&      map_align,
+                                           const CSeq_id&         to_id,
+                                           TMapOptions            opts,
                                            IMapper_Sequence_Info* seq_info)
     : m_MergeFlag(eMergeNone),
       m_GapFlag(eGapPreserve),
@@ -719,13 +745,29 @@ CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_align& map_align,
       m_Mappings(new CMappingRanges),
       m_CurrentGroup(0),
       m_FuzzOption(0),
-      m_MapOptions(opts),
-      m_SeqInfo(seq_info ? seq_info : new CDefault_Mapper_Sequence_Info)
+      m_MapOptions(CSeq_loc_Mapper_Options(seq_info, opts))
 {
     x_InitializeAlign(map_align, to_id);
 }
 
 
+CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_align&       map_align,
+                                           size_t                  to_row,
+                                           CSeq_loc_Mapper_Options options)
+    : m_MergeFlag(eMergeNone),
+      m_GapFlag(eGapPreserve),
+      m_MiscFlags(fTrimSplicedSegs),
+      m_Partial(false),
+      m_LastTruncated(false),
+      m_Mappings(new CMappingRanges),
+      m_CurrentGroup(0),
+      m_FuzzOption(0),
+      m_MapOptions(options)
+{
+    x_InitializeAlign(map_align, to_row);
+}
+
+
 CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_align& map_align,
                                            size_t            to_row,
                                            TMapOptions       opts,
@@ -738,8 +780,7 @@ CSeq_loc_Mapper_Base::CSeq_loc_Mapper_Base(const CSeq_align& map_align,
       m_Mappings(new CMappingRanges),
       m_CurrentGroup(0),
       m_FuzzOption(0),
-      m_MapOptions(opts),
-      m_SeqInfo(seq_info ? seq_info : new CDefault_Mapper_Sequence_Info)
+      m_MapOptions(seq_info, opts)
 {
     x_InitializeAlign(map_align, to_row);
 }
@@ -978,24 +1019,27 @@ void CSeq_loc_Mapper_Base::x_InitializeLocs(const CSeq_loc& source,
     }
     // If both source and destination total length are known, check if
     // they match each other.
+    // NOTE: The actual lengths may change later if trimming at sequence
+    // length is enabled.
+    bool multiseq_src = !source.GetId();
+    bool multiseq_dst = !target.GetId();
     if (src_total_len != kInvalidSeqPos  &&  dst_total_len != kInvalidSeqPos) {
         if ( src_frame ) src_total_len -= src_frame - 1;
         if ( dst_frame ) dst_total_len -= dst_frame - 1;
-        // Check for incomplete and stop codons.
         if (src_type == eSeq_nuc  &&  dst_type == eSeq_prot) {
-            // Report overhanging bases if any
-            if (src_total_len == (dst_total_len + 1)*3) {
-                // Skip stop codon
+            // Report length mismatch except a single stop codon on a single bioseq.
+            if (src_total_len == (dst_total_len + 1)*3  &&  !multiseq_dst) {
+                // Extend destination to include stop codon
                 dst_total_len++;
             }
+            // Report and drop overhanging bases if any
             else if (src_total_len/3 == dst_total_len  &&  src_total_len % 3 != 0) {
                 ERR_POST_X(28, Info <<
                     "Source and destination lengths do not match, "
                     "dropping " << src_total_len % 3 <<
                     " overhanging bases on source location");
-                src_total_len -= src_total_len % 3;
             }
-            // Allow partial codon mismatch
+            // Allow partial codon mismatch, report more than one codon.
             if (dst_total_len*3 >= src_total_len + 3  ||
                 dst_total_len*3 + 3 <= src_total_len) {
                 ERR_POST_X(31, Warning <<
@@ -1003,9 +1047,9 @@ void CSeq_loc_Mapper_Base::x_InitializeLocs(const CSeq_loc& source,
             }
         }
         else if (dst_type == eSeq_nuc  &&  src_type == eSeq_prot) {
-            // Report overhanging bases if any
-            if (dst_total_len == (src_total_len + 1)*3) {
-                // Skip stop codon
+            // Report length mismatch except a single stop codon on a single bioseq.
+            if (dst_total_len == (src_total_len + 1)*3  &&  !multiseq_src) {
+                // Extend stop codon.
                 src_total_len++;
             }
             else if (dst_total_len/3 == src_total_len  &&  dst_total_len % 3 != 0) {
@@ -1013,7 +1057,6 @@ void CSeq_loc_Mapper_Base::x_InitializeLocs(const CSeq_loc& source,
                     "Source and destination lengths do not match, "
                     "dropping " << dst_total_len % 3 <<
                     " overhanging bases on destination location");
-                dst_total_len -= dst_total_len % 3;
             }
             // Allow partial codon mismatch
             if (src_total_len*3 >= dst_total_len + 3  ||
@@ -1048,18 +1091,39 @@ void CSeq_loc_Mapper_Base::x_InitializeLocs(const CSeq_loc& source,
     // to be different from its genomic couterpart.
     if ( rg.IsWhole() ) {
         src_start = 0;
-        src_len = kInvalidSeqPos;
+        // Use actual length if trimming is enabled or if the location
+        // references multiple sequences.
+        if ( multiseq_src  ||  m_MapOptions.GetTrimMappedLocation() ) {
+            src_len = GetSequenceLength(src_it.GetSeq_id());
+            if (src_type == eSeq_prot) {
+                src_len *= 3;
+            }
+        }
+        else {
+            src_len = kInvalidSeqPos;
+        }
     }
     else if ( !rg.Empty() ) {
         src_start = src_it.GetRange().GetFrom()*src_width;
         src_len = x_GetRangeLength(src_it)*src_width;
     }
+
     rg = dst_it.GetRange();
     TSeqPos dst_start = kInvalidSeqPos;
     TSeqPos dst_len = 0;
     if ( rg.IsWhole() ) {
         dst_start = 0;
-        dst_len = kInvalidSeqPos;
+        // Use actual length if trimming is enabled or if the location
+        // references multiple sequences.
+        if ( multiseq_dst  ||  m_MapOptions.GetTrimMappedLocation() ) {
+            dst_len = GetSequenceLength(dst_it.GetSeq_id());
+            if (dst_type == eSeq_prot) {
+                dst_len *= 3;
+            }
+        }
+        else {
+            dst_len = kInvalidSeqPos;
+        }
     }
     else if ( !rg.Empty() ) {
         dst_start = dst_it.GetRange().GetFrom()*dst_width;
@@ -1139,7 +1203,7 @@ void CSeq_loc_Mapper_Base::x_InitializeLocs(const CSeq_loc& source,
             dst_it.GetSeq_id(), dst_start, dst_len, dst_it.GetStrand(),
             dst_it.GetFuzzFrom(), dst_it.GetFuzzTo(),
             src_frame ? src_frame : dst_frame,
-            dst_total_len, src_bioseq_len);
+            src_bioseq_len);
         // Start new group on a gap in src or dst.
         // If the whole source or destination range was used, increment the
         // iterator.
@@ -1152,14 +1216,22 @@ void CSeq_loc_Mapper_Base::x_InitializeLocs(const CSeq_loc& source,
         last_src_id = src_it.GetSeq_id_Handle();
         last_src_reverse = IsReverse(src_it.GetStrand());
         if (src_len == 0  &&  ++src_it) {
-            TRange rg = src_it.GetRange();
-            if ( rg.Empty() ) {
+            TRange r = src_it.GetRange();
+            if ( r.Empty() ) {
                 src_start = kInvalidSeqPos;
                 src_len = 0;
             }
-            else if ( rg.IsWhole() ) {
+            else if ( r.IsWhole() ) {
                 src_start = 0;
-                src_len = kInvalidSeqPos;
+                if ( multiseq_src  ||  m_MapOptions.GetTrimMappedLocation() ) {
+                    src_len = GetSequenceLength(src_it.GetSeq_id());
+                    if (src_type == eSeq_prot) {
+                        src_len *= 3;
+                    }
+                }
+                else {
+                    src_len = kInvalidSeqPos;
+                }
             }
             else {
                 src_start = src_it.GetRange().GetFrom()*src_width;
@@ -1173,14 +1245,22 @@ void CSeq_loc_Mapper_Base::x_InitializeLocs(const CSeq_loc& source,
         last_dst_id = dst_it.GetSeq_id_Handle();
         last_dst_reverse = IsReverse(dst_it.GetStrand());
         if (dst_len == 0  &&  ++dst_it) {
-            TRange rg = dst_it.GetRange();
-            if ( rg.Empty() ) {
+            TRange r = dst_it.GetRange();
+            if ( r.Empty() ) {
                 dst_start = kInvalidSeqPos;
                 dst_len = 0;
             }
-            else if ( rg.IsWhole() ) {
+            else if ( r.IsWhole() ) {
                 dst_start = 0;
-                dst_len = kInvalidSeqPos;
+                if ( multiseq_dst  ||  m_MapOptions.GetTrimMappedLocation() ) {
+                    dst_len = GetSequenceLength(dst_it.GetSeq_id());
+                    if (dst_type == eSeq_prot) {
+                        dst_len *= 3;
+                    }
+                }
+                else {
+                    dst_len = kInvalidSeqPos;
+                }
             }
             else {
                 dst_start = dst_it.GetRange().GetFrom()*dst_width;
@@ -1338,12 +1418,10 @@ void CSeq_loc_Mapper_Base::x_InitializeAlign(const CSeq_align& map_align,
                 // Prefer to map from the second subrow to the first one
                 // if their ids are the same.
                 if ( x_IsSynonym((*it)->GetFirst_id(), to_ids) ) {
-                    m_MapOptions &= ~fAlign_Sparse_ToSecond;
-                    m_MapOptions |= fAlign_Sparse_ToFirst;
+                    m_MapOptions.SetAlign_Sparse_ToFirst();
                 }
                 else if ( x_IsSynonym((*it)->GetSecond_id(), to_ids) ) {
-                    m_MapOptions &= ~fAlign_Sparse_ToFirst;
-                    m_MapOptions |= fAlign_Sparse_ToSecond;
+                    m_MapOptions.SetAlign_Sparse_ToSecond();
                 }
                 x_InitSparse(sparse, row);
             }
@@ -1541,7 +1619,7 @@ void CSeq_loc_Mapper_Base::x_InitAlign(const CDense_seg& denseg,
 
         // Depending on the flags we may need to use whole range
         // for each dense-seg ignoring its segments.
-        if (m_MapOptions & fAlign_Dense_seg_TotalRange) {
+        if (m_MapOptions.GetAlign_Dense_seg_TotalRange()) {
             // Get total range for source and destination rows.
             // Both ranges must be not empty.
             TSeqRange r_src = denseg.GetSeqRange(row);
@@ -1972,7 +2050,7 @@ void CSeq_loc_Mapper_Base::x_InitSparse(const CSparse_seg& sparse,
                                         int to_row)
 {
     // Sparse-seg needs special row indexing.
-    bool to_second = (m_MapOptions & fAlign_Sparse_ToSecond) != 0;
+    bool to_second = m_MapOptions.GetAlign_Sparse_ToSecond();
 
     // Check the alignment for consistency. Adjust invalid values, show
     // warnings if this happens.
@@ -2062,14 +2140,13 @@ CSeq_loc_Mapper_Base::ESeqType
 CSeq_loc_Mapper_Base::GetSeqType(const CSeq_id_Handle& idh) const
 {
     // NOTE: Maping synonyms to the main id should be done by the caller.
-    _ASSERT(m_SeqInfo);
     // Check cached types.
     TSeqTypeById::const_iterator found = m_SeqTypes.find(idh);
     if (found != m_SeqTypes.end()) {
         return found->second;
     }
     // New sequence - check the type and cache it.
-    ESeqType seqtype = m_SeqInfo->GetSequenceType(idh);
+    ESeqType seqtype = m_MapOptions.GetSeqInfo().GetSequenceType(idh);
     if (seqtype != eSeq_unknown) {
         // Cache sequence type for all synonyms if any
         SetSeqTypeById(idh, seqtype);
@@ -2081,8 +2158,7 @@ CSeq_loc_Mapper_Base::GetSeqType(const CSeq_id_Handle& idh) const
 void CSeq_loc_Mapper_Base::CollectSynonyms(const CSeq_id_Handle& id,
                                            TSynonyms& synonyms) const
 {
-    _ASSERT(m_SeqInfo);
-    m_SeqInfo->CollectSynonyms(id, synonyms);
+    m_MapOptions.GetSeqInfo().CollectSynonyms(id, synonyms);
     if ( synonyms.empty() ) {
         synonyms.insert(id);
     }
@@ -2096,9 +2172,8 @@ CSeq_loc_Mapper_Base::CollectSynonyms(const CSeq_id_Handle& id) const
     if (primary_it != m_SynonymMap.end()) {
         return primary_it->second;
     }
-    _ASSERT(m_SeqInfo);
     TSynonyms synonyms;
-    m_SeqInfo->CollectSynonyms(id, synonyms);
+    m_MapOptions.GetSeqInfo().CollectSynonyms(id, synonyms);
     ITERATE(TSynonyms, syn, synonyms) {
         m_SynonymMap[*syn] = id;
         // Add matching (e.g. versionless) synonyms.
@@ -2115,13 +2190,12 @@ CSeq_loc_Mapper_Base::CollectSynonyms(const CSeq_id_Handle& id) const
 
 TSeqPos CSeq_loc_Mapper_Base::GetSequenceLength(const CSeq_id& id)
 {
-    _ASSERT(m_SeqInfo);
     CSeq_id_Handle idh = CollectSynonyms(CSeq_id_Handle::GetHandle(id));
     TLengthMap::const_iterator it = m_LengthMap.find(idh);
     if (it != m_LengthMap.end()) {
         return it->second;
     }
-    TSeqPos len = m_SeqInfo->GetSequenceLength(idh);
+    TSeqPos len = m_MapOptions.GetSeqInfo().GetSequenceLength(idh);
     m_LengthMap[idh] = len;
     return len;
 }
@@ -2162,7 +2236,7 @@ bool CSeq_loc_Mapper_Base::x_CheckSeqTypes(const CSeq_loc& loc,
         ESeqType it_type = GetSeqTypeById(idh);
         // Reset ret to false if there are unknown types.
         ret = ret && it_type != eSeq_unknown;
-        if ( !found_type ) {
+        if (!found_type  &&  it_type != eSeq_unknown) {
             seqtype = it_type;
             found_type = true;
         }
@@ -2170,9 +2244,19 @@ bool CSeq_loc_Mapper_Base::x_CheckSeqTypes(const CSeq_loc& loc,
             seqtype = eSeq_unknown; // Report multiple types as 'unknown'
         }
         // Adjust total length or reset it.
+        // kInvalidSeqPos indicates at least some ranges of unknown length
+        // have been already parsed. Once this happen, do not check other
+        // lengths.
         if (len != kInvalidSeqPos) {
             if ( it.GetRange().IsWhole() ) {
-                len = GetSequenceLength(it.GetSeq_id());
+                TSeqPos seq_len = GetSequenceLength(it.GetSeq_id());
+                if (seq_len == kInvalidSeqPos) {
+                    // Unknown length - stop checking other lengths.
+                    len = kInvalidSeqPos;
+                }
+                else {
+                    len += seq_len;
+                }
             }
             else {
                 len += it.GetRange().GetLength();
@@ -2320,7 +2404,6 @@ void CSeq_loc_Mapper_Base::x_NextMappingRange(const CSeq_id&   src_id,
                                               const CInt_fuzz* fuzz_from,
                                               const CInt_fuzz* fuzz_to,
                                               int              frame,
-                                              TSeqPos          dst_total_len,
                                               TSeqPos          src_bioseq_len )
 {
     TSeqPos cvt_src_start = src_start;
@@ -2331,7 +2414,7 @@ void CSeq_loc_Mapper_Base::x_NextMappingRange(const CSeq_id&   src_id,
 
     if (src_len == dst_len) {
         if (src_len == kInvalidSeqPos) {
-            // Mapping whole to whole - try to get real length.
+            // Mapping whole to whole - try to get actual lengths.
             src_len = GetSequenceLength(src_id);
             if (src_len != kInvalidSeqPos) {
                 src_len -= src_start;
@@ -2340,7 +2423,7 @@ void CSeq_loc_Mapper_Base::x_NextMappingRange(const CSeq_id&   src_id,
             if (dst_len != kInvalidSeqPos) {
                 dst_len -= dst_start;
             }
-            // GetSequenceLength() could fail to get the real length.
+            // GetSequenceLength() could fail to get the length.
             // We can still try to initialize the mapper but with care.
             // If a location is whole, its start must be 0 and strand unknown.
             _ASSERT(src_len != kInvalidSeqPos  ||
@@ -2412,7 +2495,7 @@ void CSeq_loc_Mapper_Base::x_NextMappingRange(const CSeq_id&   src_id,
     // Ready to add the conversion.
     x_AddConversion(src_id, cvt_src_start, src_strand,
         dst_id, cvt_dst_start, dst_strand, cvt_length, ext_to, frame, 
-        dst_total_len, src_bioseq_len, original_dst_len );
+        src_bioseq_len, original_dst_len);
 }
 
 
@@ -2425,7 +2508,6 @@ void CSeq_loc_Mapper_Base::x_AddConversion(const CSeq_id& src_id,
                                            TSeqPos        length,
                                            bool           ext_right,
                                            int            frame,
-                                           TSeqPos        dst_total_len,
                                            TSeqPos        src_bioseq_len,
                                            TSeqPos        dst_len)
 {
@@ -2433,16 +2515,52 @@ void CSeq_loc_Mapper_Base::x_AddConversion(const CSeq_id& src_id,
     if (m_DstRanges.size() <= size_t(dst_strand)) {
         m_DstRanges.resize(size_t(dst_strand) + 1);
     }
-    CSeq_id_Handle main_id = CollectSynonyms(CSeq_id_Handle::GetHandle(src_id));
+    CSeq_id_Handle src_idh = CSeq_id_Handle::GetHandle(src_id);
+    CSeq_id_Handle dst_idh = CSeq_id_Handle::GetHandle(dst_id);
+    CSeq_id_Handle main_id = CollectSynonyms(src_idh);
+
+    if ( m_MapOptions.GetTrimMappedLocation() ) {
+        TSeqPos src_seq_len = GetSequenceLength(src_id);
+        if (src_seq_len != kInvalidSeqPos && src_seq_len > 0) {
+            ESeqType src_type = GetSeqType(src_idh);
+            if (src_type == eSeq_prot) {
+                src_seq_len *= 3;
+            }
+            if (length > src_seq_len - src_start) {
+                TSeqPos trim = length - src_seq_len + src_start;
+                if ( !SameOrientation(src_strand, dst_strand) ) {
+                    dst_start += trim;
+                }
+                length -= trim;
+            }
+        }
+        TSeqPos dst_seq_len = GetSequenceLength(dst_id);
+        if (dst_seq_len != kInvalidSeqPos  &&  dst_seq_len > 0) {
+            ESeqType dst_type = GetSeqType(dst_idh);
+            if (dst_type == eSeq_prot) {
+                dst_seq_len *= 3;
+            }
+            if (length > dst_seq_len - dst_start) {
+                TSeqPos trim = length - dst_seq_len + dst_start;
+                if ( !SameOrientation(src_strand, dst_strand) ) {
+                    src_start += trim;
+                }
+                length -= trim;
+                if (dst_len != kInvalidSeqPos) {
+                    dst_len = dst_len > trim ? dst_len - trim : 0;
+                }
+            }
+        }
+    }
     CRef<CMappingRange> rg = m_Mappings->AddConversion(
         main_id, src_start, length, src_strand,
-        CSeq_id_Handle::GetHandle(dst_id), dst_start, dst_strand,
-        ext_right, frame, dst_total_len, src_bioseq_len, dst_len );
+        dst_idh, dst_start, dst_strand,
+        ext_right, frame, kInvalidSeqPos, src_bioseq_len, dst_len);
     if ( m_CurrentGroup ) {
         rg->SetGroup(m_CurrentGroup);
     }
     // Add destination range.
-    m_DstRanges[size_t(dst_strand)][CSeq_id_Handle::GetHandle(dst_id)]
+    m_DstRanges[size_t(dst_strand)][dst_idh]
         .push_back(TRange(dst_start, dst_start + length - 1));
 }
 
@@ -2954,9 +3072,9 @@ bool CSeq_loc_Mapper_Base::x_MapInterval(const CSeq_id&   src_id,
     // This should very *rarely* be needed
     if( ! m_Mappings.Empty() ) {
         // get first mapping
-        TRangeIterator rg_it = m_Mappings->BeginMappingRanges(src_idh, 0, 1);
-        if( rg_it && rg_it->second ) {
-            const CMappingRange &mapping = *rg_it->second;
+        TRangeIterator r_it = m_Mappings->BeginMappingRanges(src_idh, 0, 1);
+        if( r_it && r_it->second ) {
+            const CMappingRange &mapping = *r_it->second;
             // try to detect if we hit the case where we couldn't do a frame-shift
             if( ! mapping.m_Reverse && mapping.m_Frame > 1 && mapping.m_Dst_from == 0 &&
                 mapping.m_Dst_len <= static_cast<TSeqPos>(mapping.m_Frame - 1)  )
@@ -3506,6 +3624,7 @@ x_RangeToSeq_loc(const CSeq_id_Handle& idh,
         loc->SetPnt().SetId().Assign(*idh.GetSeqId());
         loc->SetPnt().SetPoint(from);
         if (strand_idx > 0) {
+
             loc->SetPnt().SetStrand(INDEX_TO_STRAND(strand_idx));
         }
         if ( rg_fuzz.first ) {
diff --git a/c++/src/objects/seq/sofa_map.cpp b/c++/src/objects/seq/sofa_map.cpp
index 036de1b..2fd8e2c 100644
--- a/c++/src/objects/seq/sofa_map.cpp
+++ b/c++/src/objects/seq/sofa_map.cpp
@@ -1,4 +1,4 @@
-/*  $Id: sofa_map.cpp 500108 2016-05-02 15:38:01Z ivanov $
+/*  $Id: sofa_map.cpp 520684 2016-11-30 18:52:55Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -52,9 +52,9 @@ void CSofaMap::x_Init()
     m_Map[ GT( e_Rna, eSubtype_mRNA ) ]         = SofaType( 234, "mRNA" );
     m_Map[ GT( e_Rna, eSubtype_ncRNA ) ]        = SofaType( 655, "ncRNA" );
     m_Map[ GT( e_Rna, eSubtype_otherRNA ) ]     = SofaType( 673, "transcript" );
-    m_Map[ GT( e_Rna, eSubtype_preRNA ) ]       = SofaType( 185, "primary_transcript" );
     m_Map[ GT( e_Rna, eSubtype_rRNA ) ]         = SofaType( 252, "rRNA" );
-    m_Map[ GT( e_Rna, eSubtype_scRNA ) ]        = SofaType( 13, "scRNA" );
+    m_Map[ GT( e_Rna, eSubtype_preRNA ) ]       = SofaType( 185, "primary_transcript" );
+    m_Map[ GT( e_Rna, eSubtype_scRNA ) ]        = SofaType( 13,  "scRNA" );
     m_Map[ GT( e_Rna, eSubtype_snRNA ) ]        = SofaType( 274, "snRNA" );
     m_Map[ GT( e_Rna, eSubtype_snoRNA ) ]       = SofaType( 275, "snoRNA" );
     m_Map[ GT( e_Rna, eSubtype_tRNA ) ]         = SofaType( 253, "tRNA" );
@@ -96,12 +96,12 @@ void CSofaMap::x_Init()
     m_Map[ GT( e_Imp, eSubtype_misc_signal ) ]  = SofaType( 5836, "regulatory_region" );
     m_Map[ GT( e_Imp, eSubtype_misc_structure ) ] = SofaType( 2, "sequence_secondary_structure" );
     m_Map[ GT( e_Imp, eSubtype_mobile_element ) ]= SofaType( 1037, "mobile_genetic_element" );
-    m_Map[ GT( e_Imp, eSubtype_modified_base ) ]= SofaType( 305, "modified_base_site" );
+    m_Map[ GT( e_Imp, eSubtype_modified_base ) ]= SofaType( 305, "modified_DNA_base" );
     m_Map[ GT( e_Imp, eSubtype_operon ) ]       = SofaType( 178, "operon" );
     m_Map[ GT( e_Imp, eSubtype_oriT ) ]         = SofaType( 724, "oriT" );
     m_Map[ GT( e_Imp, eSubtype_polyA_signal ) ] = SofaType( 551, "polyA_signal_sequence" );
     m_Map[ GT( e_Imp, eSubtype_polyA_site ) ]   = SofaType( 553, "polyA_site" );
-    m_Map[ GT( e_Imp, eSubtype_precursor_RNA ) ]= SofaType( 185, "primary_transcript" );
+    m_Map[ GT( e_Imp, eSubtype_preRNA ) ]       = SofaType( 185, "primary_transcript" );
     m_Map[ GT( e_Imp, eSubtype_prim_transcript ) ] = SofaType( 185, "primary_transcript" );
     m_Map[ GT( e_Imp, eSubtype_primer_bind ) ]  = SofaType( 5850, "primer_binding_site" );
     m_Map[ GT( e_Imp, eSubtype_promoter ) ]     = SofaType( 167, "promoter" );
@@ -112,7 +112,7 @@ void CSofaMap::x_Init()
     m_Map[ GT( e_Imp, eSubtype_satellite ) ]    = SofaType( 5, "satellite_DNA" );
     m_Map[ GT( e_Imp, eSubtype_sig_peptide ) ]  = SofaType( 418, "signal_peptide" );
     m_Map[ GT( e_Imp, eSubtype_site_ref ) ]       = SofaType( 408, "site" );
-    m_Map[ GT( e_Imp, eSubtype_source ) ]       = SofaType( 2000061, "databank_entry" );
+//    m_Map[ GT( e_Imp, eSubtype_source ) ]       = SofaType( 2000061, "databank_entry" );
     m_Map[ GT( e_Imp, eSubtype_stem_loop ) ]    = SofaType( 313, "stem_loop" );
     m_Map[ GT( e_Imp, eSubtype_telomere ) ]   = SofaType( 624, "telomere" );
     m_Map[ GT( e_Imp, eSubtype_terminator ) ]   = SofaType( 141, "terminator" );
@@ -140,9 +140,11 @@ void CSofaMap::x_Init()
 };
 
 
+//  ----------------------------------------------------------------------------
 string
 CSofaMap::FeatureToSofaType(
     const CSeq_feat& feat)
+//  ----------------------------------------------------------------------------
 {
     const CSeqFeatData& data = feat.GetData();
     CSeqFeatData::ESubtype subtype = data.GetSubtype();
@@ -156,61 +158,41 @@ CSofaMap::FeatureToSofaType(
             return "cross_link"; 
         }
     }
+
     if (subtype == CSeqFeatData::eSubtype_regulatory) {
+        typedef SStaticPair<const char*, const char*>  REGULATORY_ENTRY;
+        static const REGULATORY_ENTRY regulatoryMap_[] = {
+            { "attenuator", "attenuator" },
+            { "boundary_element", "insulator" },
+            { "CAAT_signal", "CAAT_signal" },
+            { "enhancer", "enhancer" },
+            { "enhancer_blocking_element", "insulator" },
+            { "GC_signal", "GC_rich_promoter_region" },
+            { "imprinting_control_region", "regulatory_region" },
+            { "locus_control_region", "locus_control_region" },
+            { "minus_10_signal", "minus_10_signal" },
+            { "minus_35_signal", "minus_35_signal" },
+            { "other", "regulatory_region" },
+            { "polyA_signal_sequence", "polyA_signal_sequence" },
+            { "promoter", "promoter" },
+            { "response_element", "regulatory_region" },
+            { "ribosome_binding_site", "Shine_Dalgarno_sequence" },
+            { "riboswitch", "riboswitch" },
+            { "silencer", "silencer" },
+            { "TATA_box", "TATA_box" },
+            { "terminator", "terminator" },
+        };
+        typedef CStaticArrayMap<string, string, PNocase> REGULATORY_MAP;
+        DEFINE_STATIC_ARRAY_MAP_WITH_COPY(REGULATORY_MAP, regulatoryMap, regulatoryMap_);
+
         string regulatoryClass = feat.GetNamedQual("regulatory_class");
-        if (regulatoryClass.empty()) {
-             return MappedName(data.Which(), subtype);
-       }
-        if (regulatoryClass == "attenuator") {
-            return "attenuator";
-        }
-        if (regulatoryClass == "CAAT_signal") {
-            return "CAAT_signal";
-        }
-        if (regulatoryClass == "enhancer") {
-            return "enhancer";
-        }
-        if (regulatoryClass == "enhancer_blocking_element") {
-            return "insulator";
-        }
-        if (regulatoryClass == "GC_signal") {
-            return "GC_rich_promoter_region";
-        }
-        if (regulatoryClass == "insulator") {
-            return "boundary_element";
-        }
-        if (regulatoryClass == "locus_control_region") {
-            return "locus_control_region";
-        }
-        if (regulatoryClass == "minus_35_signal") {
-            return "minus_35_signal";
-        }
-        if (regulatoryClass == "minus_10_signal") {
-            return "minus_10_signal";
-        }
-        if (regulatoryClass == "polyA_signal_sequence") {
-            return "polyA_signal_sequence";
-        }
-        if (regulatoryClass == "promoter") {
-            return "promoter";
-        }
-        if (regulatoryClass == "ribosome_binding_site") {
-            return "Shine_Dalgarno_sequence";
-        }
-        if (regulatoryClass == "riboswitch") {
-            return "riboswitch";
-        }
-        if (regulatoryClass == "silencer") {
-            return "silencer";
-        }
-        if (regulatoryClass == "TATA_box") {
-            return "TATA_box";
-        }
-        if (regulatoryClass == "terminator") {
-            return "terminator";
+        REGULATORY_MAP::const_iterator cit = regulatoryMap.find(regulatoryClass);
+        if (cit != regulatoryMap.end()) {
+            return cit->second;
         }
         return MappedName(data.Which(), subtype);
     }
+
     if (subtype == CSeqFeatData::eSubtype_ncRNA) {
         const CSeqFeatData::TRna& rna = data.GetRna();
         if ( !rna.IsSetExt() ) {
@@ -221,7 +203,8 @@ CSofaMap::FeatureToSofaType(
             return MappedName(data.Which(), subtype);
         }
         string ncrnaClass = ext.GetGen().GetClass();
-    }    
+    }   
+ 
     return MappedName(data.Which(), subtype);
 }
 
diff --git a/c++/src/objects/seqalign/Sparse_align.cpp b/c++/src/objects/seqalign/Sparse_align.cpp
index 36dec9e..663fea7 100644
--- a/c++/src/objects/seqalign/Sparse_align.cpp
+++ b/c++/src/objects/seqalign/Sparse_align.cpp
@@ -1,4 +1,4 @@
-/* $Id: Sparse_align.cpp 311373 2011-07-11 19:16:41Z grichenk $
+/* $Id: Sparse_align.cpp 514371 2016-09-21 15:22:54Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -51,7 +51,7 @@ CSparse_align::~CSparse_align(void)
 }
 
 
-void CSparse_align::Validate(bool full_test) const
+void CSparse_align::Validate(bool /*full_test*/) const
 {
     CheckNumRows();
     CheckNumSegs();
@@ -65,7 +65,8 @@ CSparse_align::TNumseg CSparse_align::CheckNumSegs(void) const {
     _SEQALIGN_ASSERT(GetLens().size() == numseg);
     _SEQALIGN_ASSERT(IsSetSecond_strands() ? GetSecond_strands().size() == numseg : true);
     _SEQALIGN_ASSERT(IsSetSeg_scores() ? GetSeg_scores().size() == numseg : true);
-    return numseg;
+    _SEQALIGN_ASSERT(numseg <= kMax_Int);
+    return (TNumseg)numseg;
 }    
 
 
diff --git a/c++/src/objects/seqalign/Sparse_seg.cpp b/c++/src/objects/seqalign/Sparse_seg.cpp
index 43bc4ef..536b774 100644
--- a/c++/src/objects/seqalign/Sparse_seg.cpp
+++ b/c++/src/objects/seqalign/Sparse_seg.cpp
@@ -1,4 +1,4 @@
-/* $Id: Sparse_seg.cpp 311373 2011-07-11 19:16:41Z grichenk $
+/* $Id: Sparse_seg.cpp 514371 2016-09-21 15:22:54Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -64,7 +64,8 @@ CSparse_seg::TDim CSparse_seg::CheckNumRows(void) const
 {
     size_t dim = GetRows().size();
     _SEQALIGN_ASSERT(IsSetRow_scores() ? GetRow_scores().size() == dim : true);
-    return dim+1; // extra 1 is for the consensus sequence (first-id)
+    _SEQALIGN_ASSERT(dim < kMax_Int);
+    return TDim(dim+1); // extra 1 is for the consensus sequence (first-id)
 }
 
 
diff --git a/c++/src/objects/seqalign/Spliced_seg.cpp b/c++/src/objects/seqalign/Spliced_seg.cpp
index 6c69786..74f74de 100644
--- a/c++/src/objects/seqalign/Spliced_seg.cpp
+++ b/c++/src/objects/seqalign/Spliced_seg.cpp
@@ -1,4 +1,4 @@
-/* $Id: Spliced_seg.cpp 430022 2014-03-21 14:07:20Z mozese2 $
+/* $Id: Spliced_seg.cpp 514371 2016-09-21 15:22:54Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -84,7 +84,7 @@ CSpliced_seg::GetSeqStrand(TDim row) const
     }
 }
 
-void CSpliced_seg::Validate(bool full_test) const
+void CSpliced_seg::Validate(bool /*full_test*/) const
 {
     bool prot = GetProduct_type() == eProduct_type_protein;
 
@@ -358,7 +358,7 @@ s_ExonToDenseg(const CSpliced_exon& exon,
 
     CDense_seg::TLens& lens = ds->SetLens();
     lens.reserve(product_lens.size());
-    for (unsigned int i = 0; i < product_lens.size(); ++i) {
+    for (size_t i = 0; i < product_lens.size(); ++i) {
         lens.push_back(max(product_lens[i], genomic_lens[i]));
     }
 
@@ -381,7 +381,7 @@ s_ExonToDenseg(const CSpliced_exon& exon,
 
     CDense_seg::TStarts& starts = ds->SetStarts();
     starts.reserve(product_starts.size() + genomic_starts.size());
-    for (unsigned int i = 0; i < lens.size(); ++i) {
+    for (size_t i = 0; i < lens.size(); ++i) {
         starts.push_back(product_starts[i]);  // product row first
         starts.push_back(genomic_starts[i]);
     }
@@ -394,13 +394,13 @@ s_ExonToDenseg(const CSpliced_exon& exon,
     if (!(product_strand == eNa_strand_plus
           && genomic_strand == eNa_strand_plus)) {
         CDense_seg::TStrands& strands = ds->SetStrands();
-        for (unsigned int i = 0; i < lens.size(); ++i) {
+        for (size_t i = 0; i < lens.size(); ++i) {
             strands.push_back(product_strand);
             strands.push_back(genomic_strand);
         }
     }
 
-    ds->SetNumseg(lens.size());
+    ds->SetNumseg((CDense_seg::TNumseg)lens.size());
 
     ds->Compact();  // join adjacent match/mismatch/diag parts
 
diff --git a/c++/src/objects/seqalign/Std_seg.cpp b/c++/src/objects/seqalign/Std_seg.cpp
index 7f83a12..e18cf46 100644
--- a/c++/src/objects/seqalign/Std_seg.cpp
+++ b/c++/src/objects/seqalign/Std_seg.cpp
@@ -1,4 +1,4 @@
-/* $Id: Std_seg.cpp 351790 2012-02-01 15:54:27Z dicuccio $
+/* $Id: Std_seg.cpp 514371 2016-09-21 15:22:54Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -68,7 +68,8 @@ CStd_seg::TDim CStd_seg::CheckNumRows() const
                    "CStd_seg::CheckNumRows():"
                    " ids.size is inconsistent with dim");
     }
-    return dim;
+    _ASSERT(dim <= kMax_Int);
+    return (TDim)dim;
 }
 
 
diff --git a/c++/src/objects/seqcode/seqcode.def b/c++/src/objects/seqcode/seqcode.def
index b5f0ef8..b1cd4ea 100644
--- a/c++/src/objects/seqcode/seqcode.def
+++ b/c++/src/objects/seqcode/seqcode.def
@@ -1,2 +1,10 @@
 [-]
 _export = NCBI_SEQCODE_EXPORT
+
+[Seq-map-table]
+E.table._type = ncbi::TEntrezId
+E.table._storage_type = ncbi::TIntId
+
+[Seq-code-table]
+E.comps._type = ncbi::TEntrezId
+E.comps._storage_type = ncbi::TIntId
diff --git a/c++/src/objects/seqfeat/BioSource.cpp b/c++/src/objects/seqfeat/BioSource.cpp
index 710ffe0..9ed35f1 100644
--- a/c++/src/objects/seqfeat/BioSource.cpp
+++ b/c++/src/objects/seqfeat/BioSource.cpp
@@ -1,4 +1,4 @@
-/* $Id: BioSource.cpp 489235 2016-01-11 17:03:30Z bollin $
+/* $Id: BioSource.cpp 518950 2016-11-09 16:44:44Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -130,9 +130,12 @@ static const TGenomeKey genome_key_to_subtype [] = {
     {  "chloroplast",               CBioSource::eGenome_chloroplast       },
     {  "chromatophore",             CBioSource::eGenome_chromatophore     },
     {  "chromoplast",               CBioSource::eGenome_chromoplast       },
+    {  "chromosome",                CBioSource::eGenome_chromosome        },
     {  "cyanelle",                  CBioSource::eGenome_cyanelle          },
+    {  "endogenous virus",          CBioSource::eGenome_endogenous_virus  },
     {  "endogenous_virus",          CBioSource::eGenome_endogenous_virus  },
     {  "extrachrom",                CBioSource::eGenome_extrachrom        },
+    {  "extrachromosomal",          CBioSource::eGenome_extrachrom        },
     {  "genomic",                   CBioSource::eGenome_genomic           },
     {  "hydrogenosome",             CBioSource::eGenome_hydrogenosome     },
     {  "insertion_seq",             CBioSource::eGenome_insertion_seq     },
@@ -146,8 +149,8 @@ static const TGenomeKey genome_key_to_subtype [] = {
     {  "plastid",                   CBioSource::eGenome_plastid           },
     {  "plastid:apicoplast",        CBioSource::eGenome_apicoplast        },
     {  "plastid:chloroplast",       CBioSource::eGenome_chloroplast       },
-    {  "plastid:chromatophore", CBioSource::eGenome_chromatophore         },
-    {  "plastid:chromoplast", CBioSource::eGenome_chromoplast             },
+    {  "plastid:chromatophore",     CBioSource::eGenome_chromatophore     },
+    {  "plastid:chromoplast",       CBioSource::eGenome_chromoplast       },
     {  "plastid:cyanelle",          CBioSource::eGenome_cyanelle          },
     {  "plastid:leucoplast",        CBioSource::eGenome_leucoplast        },
     {  "plastid:proplastid",        CBioSource::eGenome_proplastid        },
@@ -482,6 +485,9 @@ string CBioSource::GetBioprojectType (void) const
             case CBioSource::eGenome_plasmid_in_plastid:
                 return "ePlasmid";
                 break;
+            case CBioSource::eGenome_extrachrom:
+                return "eExtrachrom";
+                break;
         }
     }
 
@@ -537,7 +543,7 @@ string CBioSource::GetBioprojectLocation(void) const
                 return "eMacronuclear";
                 break;
             case CBioSource::eGenome_extrachrom:
-                return "eOtherLoc";
+                return "eNuclearProkaryote";
                 break;
             case CBioSource::eGenome_cyanelle:
                 return "eCyanelle";
@@ -561,7 +567,7 @@ string CBioSource::GetBioprojectLocation(void) const
                 return "eProplastid";
                 break;
             case CBioSource::eGenome_endogenous_virus:
-                return "eOtherLoc";
+                return "eOther";
                 break;
             case CBioSource::eGenome_hydrogenosome:
                 return "eHydrogenosome";
@@ -677,6 +683,7 @@ void CBioSource::UpdateWithBioSample(const CBioSource& biosample, bool force, bo
             if (GetOrg().IsSetOrgname() && GetOrg().GetOrgname().IsSetName()) {
                 SetOrg().SetOrgname().ResetName();
             }
+            RemoveOrgMod(COrgMod::eSubtype_old_name);
         } else if (NStr::EqualNocase((*it)->GetFieldName(), "Tax ID")) {
             try {
                 SetOrg().SetTaxId(atoi((*it)->GetSampleVal().c_str()));
@@ -1332,7 +1339,7 @@ static void s_GetWordListFromText(string& str, TWordList& word_list)
         return;
     }
     std::replace_if(str.begin(), str.end(), s_IsPunct, ' ');
-    NStr::Tokenize(str, " ", word_list, NStr::eMergeDelims);
+    NStr::Split(str, " ", word_list, NStr::fSplit_Tokenize);
 }
 
 
@@ -1486,6 +1493,301 @@ bool CBioSource::RemoveOrgMod(int subtype)
 }
 
 
+bool CBioSource::FixEnvironmentalSample()
+{
+    bool has_env_sample = false;
+    bool has_metagenomic = false;
+    bool any_change = false;
+
+    if (IsSetSubtype()) {
+        ITERATE(CBioSource::TSubtype, s, GetSubtype()) {
+            if ((*s)->IsSetSubtype()) {
+                if ((*s)->GetSubtype() == CSubSource::eSubtype_environmental_sample) {
+                    has_env_sample = true;
+                } else if ((*s)->GetSubtype() == CSubSource::eSubtype_metagenomic) {
+                    has_metagenomic = true;
+                }
+                if (has_env_sample && has_metagenomic) {
+                    break;
+                }
+            }
+        }
+    }
+
+    if (!has_env_sample && 
+        IsSetOrg() &&
+        GetOrg().IsSetTaxname() && 
+        NStr::StartsWith(GetOrg().GetTaxname(), "uncultured ")) {
+        //If taxname starts with uncultured, set environmental - sample to true
+        SetSubtype().push_back(CRef<CSubSource>(new CSubSource(CSubSource::eSubtype_environmental_sample, "")));
+        has_env_sample = true;
+        any_change = true;
+    }
+    
+    if (has_metagenomic && !has_env_sample) {
+        // If metagenomic, set environmental_sample
+        SetSubtype().push_back(CRef<CSubSource>(new CSubSource(CSubSource::eSubtype_environmental_sample, "")));
+        has_env_sample = true;
+        any_change = true;
+    }
+       
+    if (!has_env_sample &&
+        IsSetOrg() && GetOrg().IsSetOrgname() &&
+        GetOrg().GetOrgname().IsSetDiv() &&
+        NStr::Equal(GetOrg().GetOrgname().GetDiv(), "ENV")) {
+        // Add environmental_sample to BioSource if BioSource.org.orgname.div == "ENV"
+        SetSubtype().push_back(CRef<CSubSource>(new CSubSource(CSubSource::eSubtype_environmental_sample, "")));
+        has_env_sample = true;
+        any_change = true;
+    }
+    
+    if (IsSetOrg() && GetOrg().IsSetOrgname() &&
+        GetOrg().GetOrgname().IsSetLineage() &&
+        NStr::Find(GetOrg().GetOrgname().GetLineage(), "metagenomes") != string::npos) {
+        // Add metagenomic(and environmental_sample) if BioSource.org.orgname.lineage contains "metagenomes"
+        if (!has_env_sample) {
+            SetSubtype().push_back(CRef<CSubSource>(new CSubSource(CSubSource::eSubtype_environmental_sample, "")));
+            has_env_sample = true;
+            any_change = true;
+        }
+        if (!has_metagenomic) {
+            SetSubtype().push_back(CRef<CSubSource>(new CSubSource(CSubSource::eSubtype_metagenomic, "")));
+            has_metagenomic = true;
+            any_change = true;
+        }
+    }
+
+    if (IsSetOrg() && GetOrg().IsSetOrgname() &&
+        GetOrg().GetOrgname().IsSetMod()) {
+        // Add metagenomic(and environmental_sample) if BioSource has /metagenome_source qualifier
+        bool has_metagenome_source = false;
+        ITERATE(COrgName::TMod, m, GetOrg().GetOrgname().GetMod()) {
+            if ((*m)->IsSetSubtype() && (*m)->GetSubtype() == COrgMod::eSubtype_metagenome_source) {
+                has_metagenome_source = true;
+                break;
+            }
+        }
+        if (has_metagenome_source) {
+            if (!has_env_sample) {
+                SetSubtype().push_back(CRef<CSubSource>(new CSubSource(CSubSource::eSubtype_environmental_sample, "")));
+                has_env_sample = true;
+                any_change = true;
+            }
+            if (!has_metagenomic) {
+                SetSubtype().push_back(CRef<CSubSource>(new CSubSource(CSubSource::eSubtype_metagenomic, "")));
+                has_metagenomic = true;
+                any_change = true;
+            }
+        }
+    }
+    return any_change;
+}
+
+
+bool CBioSource::RemoveNullTerms()
+{
+    bool any_change = false;
+
+    if (IsSetSubtype()) {
+        CBioSource::TSubtype::iterator s = SetSubtype().begin(); 
+        while (s != SetSubtype().end()) {
+            if ((*s)->IsSetName() &&
+                (NStr::EqualNocase((*s)->GetName(), "Missing") 
+                 || NStr::EqualNocase((*s)->GetName(), "N/A"))) {
+                s = SetSubtype().erase(s);
+                any_change = true;
+            } else {
+                ++s;
+            }
+        }
+        if (GetSubtype().empty()) {
+            ResetSubtype();
+            any_change = true;
+        }
+    }
+    if (IsSetOrg() && GetOrg().IsSetOrgname()
+        && GetOrg().GetOrgname().IsSetMod()) {
+        COrgName::TMod::iterator m = SetOrg().SetOrgname().SetMod().begin();
+        while (m != SetOrg().SetOrgname().SetMod().end()) {
+            if ((*m)->IsSetSubname() && 
+                (NStr::EqualNocase((*m)->GetSubname(), "Missing")
+                || NStr::EqualNocase((*m)->GetSubname(), "N/A"))) {
+                m = SetOrg().SetOrgname().SetMod().erase(m);
+                any_change = true;
+            } else {
+                ++m;
+            }
+        }
+        if (GetOrg().GetOrgname().GetMod().empty()) {
+            SetOrg().SetOrgname().ResetMod();
+            any_change = true;
+        }
+    }
+
+    return any_change;
+}
+
+
+bool CBioSource::IsViral(const string& lineage)
+{
+    if (NStr::StartsWith(lineage, "Viruses; ", NStr::eNocase)) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+
+bool CBioSource::IsViral() const
+{
+    if (IsSetOrg() && GetOrg().IsSetLineage()) {
+        return IsViral(GetOrg().GetLineage());
+    } else {
+        return false;
+    }
+}
+
+
+bool CBioSource::AllowSexQualifier(const string& lineage)
+{
+    bool isViral = IsViral(lineage);
+    bool isBacteria = false;
+    bool isArchaea = false;
+    bool isFungal = false;
+
+    if (NStr::StartsWith(lineage, "Bacteria; ", NStr::eNocase)) {
+        isBacteria = true;
+    } else if (NStr::StartsWith(lineage, "Archaea; ", NStr::eNocase)) {
+        isArchaea = true;
+    } else if (NStr::StartsWith(lineage, "Eukaryota; Fungi; ", NStr::eNocase)) {
+        isFungal = true;
+    }
+
+    if (isViral || isBacteria || isArchaea || isFungal) {
+        return false;
+    } else {
+        return true;
+    }
+}
+
+
+bool CBioSource::AllowSexQualifier() const
+{
+    if (!IsSetOrg() || !GetOrg().IsSetOrgname() || !GetOrg().GetOrgname().IsSetLineage()) {
+        return true;
+    } else {
+        return AllowSexQualifier(GetOrg().GetOrgname().GetLineage());
+    }
+}
+
+
+bool CBioSource::AllowMatingTypeQualifier(const string& lineage)
+{
+    bool isViral = IsViral(lineage);
+    bool isAnimal = false;
+    bool isPlant = false;
+
+    if (NStr::StartsWith(lineage, "Eukaryota; Metazoa; ", NStr::eNocase)) {
+        isAnimal = true;
+    } else if (NStr::StartsWith(lineage, "Eukaryota; Viridiplantae; Streptophyta; Embryophyta; ", NStr::eNocase)
+        || NStr::StartsWith(lineage, "Eukaryota; Rhodophyta; ", NStr::eNocase)
+        || NStr::StartsWith(lineage, "Eukaryota; stramenopiles; Phaeophyceae; ", NStr::eNocase)) {
+        isPlant = true;
+    }
+
+    if (isViral || isAnimal || isPlant) {
+        return false;
+    } else {
+        return true;
+    }
+}
+
+
+bool CBioSource::AllowMatingTypeQualifier() const
+{
+    if (!IsSetOrg() || !GetOrg().IsSetOrgname() || !GetOrg().GetOrgname().IsSetLineage()) {
+        return true;
+    } else {
+        return AllowMatingTypeQualifier(GetOrg().GetOrgname().GetLineage());
+    }
+}
+
+
+bool CBioSource::FixSexMatingTypeInconsistencies()
+{
+    bool any_change = false;
+    if (!IsSetSubtype()) {
+        return false;
+    }
+    TSubtype::iterator it = SetSubtype().begin();
+    while (it != SetSubtype().end()) {
+        bool remove = false;
+        if ((*it)->IsSetSubtype()) {
+            if ((*it)->GetSubtype() == CSubSource::eSubtype_sex && !AllowSexQualifier()) {
+                remove = true;
+            } else if ((*it)->GetSubtype() == CSubSource::eSubtype_mating_type) {
+                if ((*it)->IsSetName() && AllowSexQualifier()
+                     && CSubSource::IsValidSexQualifierValue((*it)->GetName())) {
+                    (*it)->SetSubtype(CSubSource::eSubtype_sex);
+                    any_change = true;
+                } else if (!AllowMatingTypeQualifier()) {
+                    remove = true;
+                } 
+            }
+        }
+        if (remove) {
+            it = SetSubtype().erase(it);
+            any_change = true;
+        } else {
+            ++it;
+        }
+    }
+
+    if (GetSubtype().size() == 0) {
+        ResetSubtype();
+        any_change = true;
+    }
+
+    return any_change;
+}
+
+
+bool CBioSource::RemoveUnexpectedViralQualifiers()
+{
+    if (!IsViral()  || !IsSetOrg() || !GetOrg().IsSetOrgname() || 
+        !GetOrg().GetOrgname().IsSetMod()) {
+        return false;
+    }
+
+    bool any_change = false;
+    COrgName::TMod::iterator m = SetOrg().SetOrgname().SetMod().begin();
+    while (m != SetOrg().SetOrgname().SetMod().end()){
+        if ((*m)->IsUnexpectedViralOrgModQualifier()) {
+            m = SetOrg().SetOrgname().SetMod().erase(m);
+            any_change = true;
+        } else {
+            ++m;
+        }
+    }
+    if (GetOrg().GetOrgname().GetMod().empty()) {
+        SetOrg().SetOrgname().ResetMod();
+        any_change = true;
+    }
+    return any_change;
+}
+
+
+bool CBioSource::FixGenomeForQualifiers()
+{
+    if (HasSubtype(CSubSource::eSubtype_plasmid_name) && (!IsSetGenome() || GetGenome() == eGenome_unknown)) {
+        SetGenome(eGenome_plasmid);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+
 #define MAKE_COMMON_INT(o1,o2,o3,Field) \
     if (o1.IsSet##Field() && o2.IsSet##Field() && o1.Get##Field() == o2.Get##Field()) o3.Set##Field(o1.Get##Field());
 
@@ -1532,6 +1834,19 @@ CRef<CBioSource> CBioSource::MakeCommon( const CBioSource& other) const
 }
 
 
+bool CBioSource::HasSubtype(CSubSource::TSubtype subtype) const
+{
+    if (!IsSetSubtype()) {
+        return false;
+    }
+    ITERATE(TSubtype, it, GetSubtype()) {
+        if ((*it)->IsSetSubtype() && (*it)->GetSubtype() == subtype) {
+            return true;
+        }
+    }
+    return false;
+}
+
 END_objects_SCOPE // namespace ncbi::objects::
 
 END_NCBI_SCOPE
diff --git a/c++/src/objects/seqfeat/Delta_item.cpp b/c++/src/objects/seqfeat/Delta_item.cpp
new file mode 100644
index 0000000..39239df
--- /dev/null
+++ b/c++/src/objects/seqfeat/Delta_item.cpp
@@ -0,0 +1,81 @@
+/* $Id: Delta_item.cpp 514371 2016-09-21 15:22:54Z ivanov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  .......
+ *
+ * File Description:
+ *   .......
+ *
+ * Remark:
+ *   This code was originally generated by application DATATOOL
+ *   using the following specifications:
+ *   'seqfeat.asn'.
+ */
+
+// standard includes
+#include <ncbi_pch.hpp>
+
+#include <objects/seq/Seq_literal.hpp>
+#include <objects/seq/Seq_data.hpp>
+// generated includes
+#include <objects/seqfeat/Delta_item.hpp>
+
+// generated classes
+
+BEGIN_NCBI_SCOPE
+
+BEGIN_objects_SCOPE // namespace ncbi::objects::
+
+// destructor
+CDelta_item::~CDelta_item(void)
+{
+}
+
+void CDelta_item::SetDeletion(void)
+{
+    SetSeq().SetThis();
+    SetAction(eAction_del_at);
+}
+
+void CDelta_item::SetDuplication(void)
+{
+    SetSeq().SetThis();
+    SetMultiplier() = 2;
+}
+
+void CDelta_item::SetInsertion(const CIUPACna& sequence, 
+                               const TSeqPos length)
+{
+    const TSeqPos seq_length = length ? length : (TSeqPos)sequence.Get().size();
+    SetSeq().SetLiteral().SetSeq_data().SetIupacna(sequence);
+    SetSeq().SetLiteral().SetLength(seq_length);
+    SetAction(eAction_ins_before);
+}
+
+END_objects_SCOPE // namespace ncbi::objects::
+
+END_NCBI_SCOPE
+
+/* Original file checksum: lines: 57, chars: 1727, CRC32: 1aff4916 */
diff --git a/c++/src/objects/seqfeat/Gb_qual.cpp b/c++/src/objects/seqfeat/Gb_qual.cpp
index f8b2275..0fc9b1e 100644
--- a/c++/src/objects/seqfeat/Gb_qual.cpp
+++ b/c++/src/objects/seqfeat/Gb_qual.cpp
@@ -1,4 +1,4 @@
-/* $Id: Gb_qual.cpp 493884 2016-03-02 14:18:51Z ivanov $
+/* $Id: Gb_qual.cpp 518672 2016-11-07 15:40:15Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -58,13 +58,13 @@ CGb_qual::~CGb_qual(void)
 }
 
 
-static const char * const valid_inf_categories [] = {
+static const char * valid_inf_categories [] = {
     "EXISTENCE",
     "COORDINATES",
     "DESCRIPTION"
 };
 
-static const char * const valid_inf_prefixes [] = {
+static const char * valid_inf_prefixes [] = {
     "ab initio prediction",
     "nucleotide motif",
     "profile",
@@ -177,7 +177,7 @@ bool CGb_qual::CleanupRptUnitRange(string& val)
 const CGb_qual::TLegalRepeatTypeSet &
 CGb_qual::GetSetOfLegalRepeatTypes(void)
 {
-    static char * const repeat_types[] = {
+    static const char * repeat_types[] = {
         "centromeric_repeat",
         "direct",
         "dispersed",
@@ -185,6 +185,7 @@ CGb_qual::GetSetOfLegalRepeatTypes(void)
         "flanking",
         "inverted",
         "long_terminal_repeat",
+        "nested",
         "non_LTR_retrotransposon_polymeric_tract",
         "other",
         "tandem",
@@ -210,7 +211,7 @@ bool CGb_qual::IsValidRptTypeValue(const string& val)
 
     // look for list of values
     vector<string> rpt_types;
-    NStr::Tokenize(val, ",", rpt_types);
+    NStr::Split(val, ",", rpt_types, NStr::fSplit_NoMergeDelims);
     ITERATE(vector<string>, it, rpt_types) {
         string v = (*it);
         NStr::TruncateSpacesInPlace(v);
@@ -234,7 +235,7 @@ bool CGb_qual::IsValidRptTypeValue(const string& val)
 const CGb_qual::TLegalPseudogeneSet &
 CGb_qual::GetSetOfLegalPseudogenes(void)
 {
-    static char * const pseudogenes[] = {
+    static const char * pseudogenes[] = {
         "allelic",
         "processed",
         "unitary",
@@ -262,6 +263,24 @@ bool CGb_qual::IsValidPseudogeneValue(const string& val)
 }
 
 
+const CGb_qual::TLegalRecombinationClassSet &
+CGb_qual::GetSetOfLegalRecombinationClassValues(void)
+{
+    static const char * misc_recombs[] = {
+        "chromosome_breakpoint",
+        "meiotic_recombination",
+        "mitotic_recombination",
+        "non_allelic_homologous_recombination"
+    };
+
+
+    DEFINE_STATIC_ARRAY_MAP_WITH_COPY(
+        TLegalRecombinationClassSet, sc_LegalRecombinationClass, misc_recombs);
+
+    return sc_LegalRecombinationClass;
+}
+
+
 // constructor
 CInferencePrefixList::CInferencePrefixList(void)
 {
diff --git a/c++/src/objects/seqfeat/Genetic_code_table.cpp b/c++/src/objects/seqfeat/Genetic_code_table.cpp
index dd7cd74..b57b0cf 100644
--- a/c++/src/objects/seqfeat/Genetic_code_table.cpp
+++ b/c++/src/objects/seqfeat/Genetic_code_table.cpp
@@ -1,4 +1,4 @@
-/* $Id: Genetic_code_table.cpp 498881 2016-04-20 13:36:43Z ivanov $
+/* $Id: Genetic_code_table.cpp 516784 2016-10-18 12:18:08Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -103,7 +103,7 @@ void CTrans_table::x_InitFsaTable (void)
     for (i = eBase_gap; i <= eBase_N; i++) {
         ch = charToBase [i];
         sm_BaseToIdx [(int) ch] = i;
-        ch = tolower ((unsigned char) ch);
+        ch = (unsigned char)tolower (ch);
         sm_BaseToIdx [(int) ch] = i;
     }
     sm_BaseToIdx [(int) 'U'] = eBase_T;
@@ -382,8 +382,12 @@ static bool s_ValidCodon(const string& codon)
     if ( codon.length() != 3 ) return false;
     
     for ( int i = 0; i < 3; ++i ) {
-        char ch = toupper((unsigned char) codon[i]);
-        if ( ch != 'A' && ch != 'G' && ch != 'C' && ch != 'T'  && ch != 'U' ) {
+        unsigned char ch = (unsigned char)toupper(codon[i]);
+        if ( ch != 'A' && 
+             ch != 'G' && 
+             ch != 'C' && 
+             ch != 'T' && 
+             ch != 'U' ) {
             return false;
         }
     }
@@ -672,67 +676,82 @@ const char * CGen_code_table_imp::sm_GenCodeTblMemStr [] =
     "Genetic-code-table ::= {\n",
     "{ name \"Standard\" , name \"SGC0\" , id 1 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"---M---------------M---------------M----------------------------\" } ,\n",
+    "sncbieaa \"---M------**--*----M---------------M----------------------------\" } ,\n",
     "{ name \"Vertebrate Mitochondrial\" , name \"SGC1\" , id 2 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSS**VVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"--------------------------------MMMM---------------M------------\" } ,\n",
+    "sncbieaa \"----------**--------------------MMMM----------**---M------------\" } ,\n",
     "{ name \"Yeast Mitochondrial\" , name \"SGC2\" , id 3 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CCWWTTTTPPPPHHQQRRRRIIMMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"----------------------------------MM----------------------------\" } ,\n",
+    "sncbieaa \"----------**----------------------MM----------------------------\" } ,\n",
     "{ name \"Mold Mitochondrial; Protozoan Mitochondrial; Coelenterate\n",
     "Mitochondrial; Mycoplasma; Spiroplasma\" ,\n",
     "name \"SGC3\" , id 4 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"--MM---------------M------------MMMM---------------M------------\" } ,\n",
+    "sncbieaa \"--MM------**-------M------------MMMM---------------M------------\" } ,\n",
     "{ name \"Invertebrate Mitochondrial\" , name \"SGC4\" , id 5 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSSSSVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"---M----------------------------MMMM---------------M------------\" } ,\n",
+    "sncbieaa \"---M------**--------------------MMMM---------------M------------\" } ,\n",
     "{ name \"Ciliate Nuclear; Dasycladacean Nuclear; Hexamita Nuclear\" ,\n",
     "name \"SGC5\" , id 6 ,\n",
     "ncbieaa  \"FFLLSSSSYYQQCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"-----------------------------------M----------------------------\" } ,\n",
+    "sncbieaa \"--------------*--------------------M----------------------------\" } ,\n",
     "{ name \"Echinoderm Mitochondrial; Flatworm Mitochondrial\" , name \"SGC8\" , id 9 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNNKSSSSVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"-----------------------------------M---------------M------------\" } ,\n",
+    "sncbieaa \"----------**-----------------------M---------------M------------\" } ,\n",
     "{ name \"Euplotid Nuclear\" , name \"SGC9\" , id 10 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CCCWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"-----------------------------------M----------------------------\" } ,\n",
+    "sncbieaa \"----------**-----------------------M----------------------------\" } ,\n",
     "{ name \"Bacterial, Archaeal and Plant Plastid\" , id 11 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"---M---------------M------------MMMM---------------M------------\" } ,\n",
+    "sncbieaa \"---M------**--*----M------------MMMM---------------M------------\" } ,\n",
     "{ name \"Alternative Yeast Nuclear\" , id 12 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CC*WLLLSPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"-------------------M---------------M----------------------------\" } ,\n",
+    "sncbieaa \"----------**--*----M---------------M----------------------------\" } ,\n",
     "{ name \"Ascidian Mitochondrial\" , id 13 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSSGGVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"---M------------------------------MM---------------M------------\" } ,\n",
+    "sncbieaa \"---M------**----------------------MM---------------M------------\" } ,\n",
     "{ name \"Alternative Flatworm Mitochondrial\" , id 14 ,\n",
     "ncbieaa  \"FFLLSSSSYYY*CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNNKSSSSVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"-----------------------------------M----------------------------\" } ,\n",
+    "sncbieaa \"-----------*-----------------------M----------------------------\" } ,\n",
     "{ name \"Blepharisma Macronuclear\" , id 15 ,\n",
     "ncbieaa  \"FFLLSSSSYY*QCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"-----------------------------------M----------------------------\" } ,\n",
+    "sncbieaa \"----------*---*--------------------M----------------------------\" } ,\n",
     "{ name \"Chlorophycean Mitochondrial\" , id 16 ,\n",
     "ncbieaa  \"FFLLSSSSYY*LCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"-----------------------------------M----------------------------\" } ,\n",
+    "sncbieaa \"----------*---*--------------------M----------------------------\" } ,\n",
     "{ name \"Trematode Mitochondrial\" , id 21 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNNKSSSSVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"-----------------------------------M---------------M------------\" } ,\n",
+    "sncbieaa \"----------**-----------------------M---------------M------------\" } ,\n",
     "{ name \"Scenedesmus obliquus Mitochondrial\" , id 22 ,\n",
     "ncbieaa  \"FFLLSS*SYY*LCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"-----------------------------------M----------------------------\" } ,\n",
+    "sncbieaa \"------*---*---*--------------------M----------------------------\" } ,\n",
     "{ name \"Thraustochytrium Mitochondrial\" , id 23 ,\n",
     "ncbieaa  \"FF*LSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"--------------------------------M--M---------------M------------\" } ,\n",
+    "sncbieaa \"--*-------**--*-----------------M--M---------------M------------\" } ,\n",
     "{ name \"Pterobranchia Mitochondrial\" , id 24 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSSKVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"---M---------------M---------------M---------------M------------\" } ,\n",
+    "sncbieaa \"---M------**-------M---------------M---------------M------------\" } ,\n",
     "{ name \"Candidate Division SR1 and Gracilibacteria\" , id 25 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CCGWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"---M-------------------------------M---------------M------------\" } ,\n",
+    "sncbieaa \"---M------**-----------------------M---------------M------------\" } ,\n",
     "{ name \"Pachysolen tannophilus Nuclear\" , id 26 ,\n",
     "ncbieaa  \"FFLLSSSSYY**CC*WLLLAPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
-    "sncbieaa \"-------------------M---------------M----------------------------\" } };\n",
+    "sncbieaa \"----------**--*----M---------------M----------------------------\" } ,\n",
+    "{ name \"Karyorelict Nuclear\" , id 27 ,\n",
+    "ncbieaa  \"FFLLSSSSYYQQCCWWLLLAPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
+    "sncbieaa \"--------------*--------------------M----------------------------\" } ,\n",
+    "{ name \"Condylostoma Nuclear\" , id 28 ,\n",
+    "ncbieaa  \"FFLLSSSSYYQQCCWWLLLAPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
+    "sncbieaa \"----------**--*--------------------M----------------------------\" } ,\n",
+    "{ name \"Mesodinium Nuclear\" , id 29 ,\n",
+    "ncbieaa  \"FFLLSSSSYYYYCC*WLLLAPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
+    "sncbieaa \"--------------*--------------------M----------------------------\" } ,\n",
+    "{ name \"Peritrich Nuclear\" , id 30 ,\n",
+    "ncbieaa  \"FFLLSSSSYYEECC*WLLLAPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
+    "sncbieaa \"--------------*--------------------M----------------------------\" } ,\n",
+    "{ name \"Blastocrithidia Nuclear\" , id 31 ,\n",
+    "ncbieaa  \"FFLLSSSSYYEECCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG\",\n",
+    "sncbieaa \"----------**-----------------------M----------------------------\" } };\n",
     0  // to indicate that there is no more data
 };
 
diff --git a/c++/src/objects/seqfeat/OrgMod.cpp b/c++/src/objects/seqfeat/OrgMod.cpp
index 5aeb7df..b7d3380 100644
--- a/c++/src/objects/seqfeat/OrgMod.cpp
+++ b/c++/src/objects/seqfeat/OrgMod.cpp
@@ -1,4 +1,4 @@
-/* $Id: OrgMod.cpp 500234 2016-05-03 15:01:20Z ivanov $
+/* $Id: OrgMod.cpp 515540 2016-10-03 16:03:50Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -127,7 +127,7 @@ bool COrgMod::IsMultipleValuesAllowed(TSubtype subtype)
 }
 
 
-bool COrgMod::IsDiscouraged(const TSubtype subtype)
+bool COrgMod::IsDiscouraged(const TSubtype subtype, bool indexer)
 {
     if (subtype == eSubtype_dosage
         || subtype == eSubtype_gb_acronym
@@ -135,7 +135,7 @@ bool COrgMod::IsDiscouraged(const TSubtype subtype)
         || subtype == eSubtype_gb_synonym
         || subtype == eSubtype_old_lineage
         || subtype == eSubtype_old_name
-        || subtype == eSubtype_metagenome_source) {
+        || (subtype == eSubtype_metagenome_source && !indexer)) {
         return true;
     } else {
         return false;
@@ -203,7 +203,7 @@ DEFINE_STATIC_FAST_MUTEX(s_InstitutionCollectionCodeMutex);
 static void s_ProcessInstitutionCollectionCodeLine(const CTempString& line)
 {
     vector<string> tokens;
-    NStr::Tokenize(line, "\t", tokens);
+    NStr::Split(line, "\t", tokens, NStr::fSplit_NoMergeDelims);
     if (tokens.size() != 3) {
 //        ERR_POST_X(1, Warning << "Bad format in institution_codes.txt entry " << line
 //                   << "; disregarding");
@@ -656,7 +656,7 @@ string COrgMod::FixStrain( const string& strain)
     string new_val = strain;
     vector<string> words;
     vector<string> results;
-    NStr::Tokenize(strain, ";", words);
+    NStr::Split(strain, ";", words, NStr::fSplit_NoMergeDelims);
     FOR_EACH_STRING_IN_VECTOR(itr, words) {
         string str = *itr;
         NStr::TruncateSpacesInPlace(str);
@@ -671,6 +671,25 @@ string COrgMod::FixStrain( const string& strain)
 }
 
 
+const char* sm_BadStrainValues[] = {
+    "yes",
+    "no",
+    "-",
+    "microbial"
+};
+
+bool COrgMod::IsStrainValid(const string& strain)
+{
+    size_t max = sizeof(sm_BadStrainValues) / sizeof(const char*);
+    for (size_t i = 0; i < max; i++) {
+        if (NStr::EqualNocase(strain, sm_BadStrainValues[i])) {
+            return false;
+        }
+    }
+    return true;
+}
+
+
 const char* sm_KnownHostWords[] = {
   "alfalfa",
   "almond",
@@ -898,6 +917,69 @@ bool COrgMod::FuzzyStrainMatch( const string& strain1, const string& strain2 )
 }
 
 
+bool COrgMod::RemoveAbbreviation()
+{
+    bool any_change = false;
+
+    if (IsSetSubtype() && IsSetSubname()) {
+        string& val = SetSubname();
+        switch (GetSubtype()) {
+            case eSubtype_strain:
+            case eSubtype_serovar:
+                if (NStr::StartsWith(val, "subsp. ")) {
+                    val = val.substr(7);
+                    any_change = true;
+                }
+                if (NStr::StartsWith(val, "serovar ")) {
+                    val = val.substr(8);
+                    any_change = true;
+                }
+                break;
+            case eSubtype_sub_species:
+                if (NStr::StartsWith(val, "subsp. ")) {
+                    val = val.substr(7);
+                    any_change = true;
+                }
+                break;
+            default:
+                break;
+        }
+    }
+    return any_change;
+}
+
+
+static const COrgMod::TSubtype sUnexpectedViralOrgModQualifiers[] = {
+    COrgMod::eSubtype_breed,
+    COrgMod::eSubtype_cultivar,
+    COrgMod::eSubtype_specimen_voucher
+};
+
+static const size_t sNumUnexpectedViralOrgModQualifiers = sizeof(sUnexpectedViralOrgModQualifiers) / sizeof(COrgMod::TSubtype);
+
+bool COrgMod::IsUnexpectedViralOrgModQualifier(COrgMod::TSubtype subtype)
+{
+    bool rval = false;
+
+    for (size_t i = 0; i < sNumUnexpectedViralOrgModQualifiers && !rval; i++) {
+        if (subtype == sUnexpectedViralOrgModQualifiers[i]) {
+            rval = true;
+        }
+    }
+    return rval;
+}
+
+
+bool COrgMod::IsUnexpectedViralOrgModQualifier() const
+{
+    if (IsSetSubtype() && IsUnexpectedViralOrgModQualifier(GetSubtype())) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+
 END_objects_SCOPE // namespace ncbi::objects::
 
 END_NCBI_SCOPE
diff --git a/c++/src/objects/seqfeat/OrgName.cpp b/c++/src/objects/seqfeat/OrgName.cpp
index 948f556..f84ad28 100644
--- a/c++/src/objects/seqfeat/OrgName.cpp
+++ b/c++/src/objects/seqfeat/OrgName.cpp
@@ -1,4 +1,4 @@
-/* $Id: OrgName.cpp 452696 2014-11-24 15:23:55Z bollin $
+/* $Id: OrgName.cpp 498903 2016-04-20 15:50:10Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -128,21 +128,21 @@ void COrgName::x_SetAttribFlag( const string& name )
 void COrgName::x_ResetAttribFlag( const string& name )
 {
     if( !name.empty() && IsSetAttrib() ) {
-	const string& attr = GetAttrib();
-	list< CTempString > lVals;
-	NStr::Split( attr, s_flagDelim, lVals );
-	for( list< CTempString >::iterator i = lVals.begin(), li = lVals.end(); i != li; ) {
-	    NStr::TruncateSpacesInPlace( *i );
-	    if( NStr::EqualNocase( *i, name ) ) {
-		i = lVals.erase( i );
-	    } else {
-		++i;
-	    }
-	}
-	SetAttrib( NStr::Join( lVals, s_flagDelim ) );
-	if( SetAttrib().empty() ) {
-	    ResetAttrib();
-	}
+        const string& attr = GetAttrib();
+        list< CTempString > lVals;
+        NStr::Split(attr, s_flagDelim, lVals, NStr::fSplit_Tokenize);
+        for( list< CTempString >::iterator i = lVals.begin(), li = lVals.end(); i != li; ) {
+            NStr::TruncateSpacesInPlace( *i );
+            if( NStr::EqualNocase( *i, name ) ) {
+                i = lVals.erase( i );
+            } else {
+                ++i;
+            }
+        }
+        SetAttrib( NStr::Join( lVals, s_flagDelim ) );
+        if( SetAttrib().empty() ) {
+            ResetAttrib();
+        }
     }
 }
 
@@ -151,7 +151,7 @@ bool COrgName::x_GetAttribFlag( const string& name ) const
     if( !name.empty() && IsSetAttrib() ) {
 	const string& attr = GetAttrib();
 	list< CTempString > lVals;
-	NStr::Split( attr, s_flagDelim, lVals );
+	NStr::Split(attr, s_flagDelim, lVals, NStr::fSplit_Tokenize);
 	NON_CONST_ITERATE( list< CTempString >, i, lVals ) {
 	    NStr::TruncateSpacesInPlace( *i );
 	    if( NStr::EqualNocase( *i, name ) ) {
diff --git a/c++/src/objects/seqfeat/RNA_ref.cpp b/c++/src/objects/seqfeat/RNA_ref.cpp
index f5b3e77..490acd2 100644
--- a/c++/src/objects/seqfeat/RNA_ref.cpp
+++ b/c++/src/objects/seqfeat/RNA_ref.cpp
@@ -1,4 +1,4 @@
-/* $Id: RNA_ref.cpp 500107 2016-05-02 15:37:38Z ivanov $
+/* $Id: RNA_ref.cpp 499355 2016-04-25 19:42:55Z dicuccio $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objects/seqfeat/SeqFeatData.cpp b/c++/src/objects/seqfeat/SeqFeatData.cpp
index 5c2961f..20ec544 100644
--- a/c++/src/objects/seqfeat/SeqFeatData.cpp
+++ b/c++/src/objects/seqfeat/SeqFeatData.cpp
@@ -1,4 +1,4 @@
-/* $Id: SeqFeatData.cpp 500232 2016-05-03 15:00:20Z ivanov $
+/* $Id: SeqFeatData.cpp 514391 2016-09-21 15:38:23Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -188,7 +188,8 @@ static const TProtInfoPair kProtInfoPairs[] = {
     PROT_INFO_PAIR(preprotein, preprotein, "Prot", "proprotein"),
     PROT_INFO_PAIR(mature, mat_peptide_aa, "Prot", "mat_peptide"),
     PROT_INFO_PAIR(signal_peptide, sig_peptide_aa, "Prot", "sig_peptide"),
-    PROT_INFO_PAIR(transit_peptide, transit_peptide_aa, "Prot", "transit_peptide")
+    PROT_INFO_PAIR(transit_peptide, transit_peptide_aa, "Prot", "transit_peptide"),
+    PROT_INFO_PAIR(propeptide, propeptide, "Prot", "propeptide")
 };
 
 typedef CStaticPairArrayMap<CProt_ref::EProcessed,
@@ -476,6 +477,7 @@ static const TFeatKey feat_key_to_subtype [] = {
     {  "prim_transcript",    CSeqFeatData::eSubtype_prim_transcript     },
     {  "primer_bind",        CSeqFeatData::eSubtype_primer_bind         },
     {  "promoter",           CSeqFeatData::eSubtype_promoter            },
+    {  "propeptide",         CSeqFeatData::eSubtype_propeptide          },
     {  "proprotein",         CSeqFeatData::eSubtype_preprotein          },
     {  "protein_bind",       CSeqFeatData::eSubtype_protein_bind        },
     {  "rRNA",               CSeqFeatData::eSubtype_rRNA                },
@@ -512,7 +514,7 @@ CSeqFeatData::SubtypeNameToValue(const string & sName)
     // if this assertion fails, it means this function might be out
     // of date.  Don't just fix the assert, make sure the function is
     // up to date.
-    _ASSERT( 104 == CSeqFeatData::eSubtype_max );
+    _ASSERT( 105 == CSeqFeatData::eSubtype_max );
 
     TFeatMap::const_iterator find_iter =
         sm_FeatKeys.find(sName.c_str());
@@ -537,7 +539,7 @@ static TSubtypeValueToNameMap* s_CreateSubtypeValueToNameMap(void)
     // if this assertion fails, it means this function might be out
     // of date.  Don't just fix the assert, make sure the function is
     // up to date.
-    _ASSERT( 104 == CSeqFeatData::eSubtype_max );
+    _ASSERT( 105 == CSeqFeatData::eSubtype_max );
 
     auto_ptr<TSubtypeValueToNameMap> pAnswerMap( new TSubtypeValueToNameMap );
     // created from inverse of sm_FeatKeys
@@ -723,7 +725,8 @@ static const SSubtypeInfo s_subtype_info[] = {
     SUBTYPE_INFO(               e_Imp,              eSubtype_telomere, 101),
     SUBTYPE_INFO(               e_Imp,          eSubtype_assembly_gap, 102),
     SUBTYPE_INFO(               e_Imp,            eSubtype_regulatory, 103),
-    SUBTYPE_INFO(           e_not_set,                   eSubtype_max, 104),
+    SUBTYPE_INFO(              e_Prot,            eSubtype_propeptide, 104),
+    SUBTYPE_INFO(           e_not_set,                   eSubtype_max, 105),
     SUBTYPE_INFO(           e_not_set,                   eSubtype_any, 255)
 };
 static const size_t s_subtype_count =
@@ -765,6 +768,7 @@ void CSeqFeatData::s_InitSubtypesTable(void)
     for (int sub = eSubtype_prot; sub <= eSubtype_transit_peptide_aa; ++sub) {
         table[ESubtype(sub)] = e_Prot;
     }
+    table[eSubtype_propeptide] = e_Prot;
     for (int sub = eSubtype_preRNA; sub <= eSubtype_otherRNA; ++sub) {
         table[ESubtype(sub)] = e_Rna;
     }
@@ -776,6 +780,7 @@ void CSeqFeatData::s_InitSubtypesTable(void)
     for ( const SImportEntry* p = kImportTable; p != kImportTableEnd; ++p ) {
         table[p->m_Subtype] = e_Imp;
     }
+    table[eSubtype_propeptide] = e_Prot;
 
     sx_SubtypesTableInitialized = true;
 
@@ -805,7 +810,6 @@ void CSeqFeatData::s_InitSubtypesTable(void)
     // check if type/subtype values didn't change
     for ( size_t i = 0; i < s_subtype_count; ++i ) {
         const SSubtypeInfo& info = s_subtype_info[i];
-        _ASSERT(info.m_Subtype == info.m_Value);
         _ASSERT(info.m_Type == GetTypeFromSubtype(info.m_Subtype));
     }
 #endif    
@@ -1716,6 +1720,7 @@ START_SUBTYPE(misc_recomb)
     ADD_QUAL(map);
     ADD_QUAL(note);
     ADD_QUAL(old_locus_tag);
+    ADD_QUAL(recombination_class);
     ADD_QUAL(standard_name);
     ADD_QUAL(usedin);
 END_SUBTYPE
@@ -2087,6 +2092,7 @@ START_SUBTYPE(rep_origin)
     ADD_QUAL(evidence);
     ADD_QUAL(exception);
     ADD_QUAL(experiment);
+    ADD_QUAL(function);
     ADD_QUAL(gene);
     ADD_QUAL(gene_synonym);
     ADD_QUAL(inference);
@@ -2807,74 +2813,74 @@ START_SUBTYPE(mobile_element)
 END_SUBTYPE
 
 START_SUBTYPE(biosrc)
-ADD_QUAL(PCR_primers);
-ADD_QUAL(altitude);
-ADD_QUAL(bio_material);
-ADD_QUAL(cell_line);
-ADD_QUAL(cell_type);
-ADD_QUAL(chloroplast);
-ADD_QUAL(chromoplast);
-ADD_QUAL(chromosome);
-ADD_QUAL(citation);
-ADD_QUAL(clone);
-ADD_QUAL(clone_lib);
-ADD_QUAL(collected_by);
-ADD_QUAL(collection_date);
-ADD_QUAL(country);
-ADD_QUAL(cultivar);
-ADD_QUAL(culture_collection);
-ADD_QUAL(cyanelle);
-ADD_QUAL(db_xref);
-ADD_QUAL(dev_stage);
-ADD_QUAL(ecotype);
-ADD_QUAL(environmental_sample);
-ADD_QUAL(exception);
-ADD_QUAL(focus);
-ADD_QUAL(frequency);
-ADD_QUAL(germline);
-ADD_QUAL(haplogroup);
-ADD_QUAL(haplotype);
-ADD_QUAL(host);
-ADD_QUAL(identified_by);
-ADD_QUAL(isolate);
-ADD_QUAL(isolation_source);
-ADD_QUAL(kinetoplast);
-ADD_QUAL(lab_host);
-ADD_QUAL(label);
-ADD_QUAL(lat_lon);
-ADD_QUAL(linkage_group);
-ADD_QUAL(macronuclear);
-ADD_QUAL(map);
-ADD_QUAL(mating_type);
-ADD_QUAL(metagenomic);
-ADD_QUAL(mitochondrion);
-ADD_QUAL(mol_type);
-ADD_QUAL(note);
-ADD_QUAL(organelle);
-ADD_QUAL(organism);
-ADD_QUAL(plasmid);
-ADD_QUAL(pop_variant);
-ADD_QUAL(proviral);
-ADD_QUAL(rearranged);
-ADD_QUAL(segment);
-ADD_QUAL(sequenced_mol);
-ADD_QUAL(serotype);
-ADD_QUAL(serovar);
-ADD_QUAL(sex);
-ADD_QUAL(specimen_voucher);
-ADD_QUAL(strain);
-ADD_QUAL(sub_clone);
-ADD_QUAL(sub_species);
-ADD_QUAL(sub_strain);
-ADD_QUAL(tissue_lib);
-ADD_QUAL(tissue_type);
-ADD_QUAL(transgenic);
-ADD_QUAL(transposon);
-ADD_QUAL(type_material);
-ADD_QUAL(usedin);
-ADD_QUAL(variety);
-ADD_QUAL(virion);
-ADD_QUAL(whole_replicon);
+    ADD_QUAL(PCR_primers);
+    ADD_QUAL(altitude);
+    ADD_QUAL(bio_material);
+    ADD_QUAL(cell_line);
+    ADD_QUAL(cell_type);
+    ADD_QUAL(chloroplast);
+    ADD_QUAL(chromoplast);
+    ADD_QUAL(chromosome);
+    ADD_QUAL(citation);
+    ADD_QUAL(clone);
+    ADD_QUAL(clone_lib);
+    ADD_QUAL(collected_by);
+    ADD_QUAL(collection_date);
+    ADD_QUAL(country);
+    ADD_QUAL(cultivar);
+    ADD_QUAL(culture_collection);
+    ADD_QUAL(cyanelle);
+    ADD_QUAL(db_xref);
+    ADD_QUAL(dev_stage);
+    ADD_QUAL(ecotype);
+    ADD_QUAL(environmental_sample);
+    ADD_QUAL(exception);
+    ADD_QUAL(focus);
+    ADD_QUAL(frequency);
+    ADD_QUAL(germline);
+    ADD_QUAL(haplogroup);
+    ADD_QUAL(haplotype);
+    ADD_QUAL(host);
+    ADD_QUAL(identified_by);
+    ADD_QUAL(isolate);
+    ADD_QUAL(isolation_source);
+    ADD_QUAL(kinetoplast);
+    ADD_QUAL(lab_host);
+    ADD_QUAL(label);
+    ADD_QUAL(lat_lon);
+    ADD_QUAL(linkage_group);
+    ADD_QUAL(macronuclear);
+    ADD_QUAL(map);
+    ADD_QUAL(mating_type);
+    ADD_QUAL(metagenomic);
+    ADD_QUAL(mitochondrion);
+    ADD_QUAL(mol_type);
+    ADD_QUAL(note);
+    ADD_QUAL(organelle);
+    ADD_QUAL(organism);
+    ADD_QUAL(plasmid);
+    ADD_QUAL(pop_variant);
+    ADD_QUAL(proviral);
+    ADD_QUAL(rearranged);
+    ADD_QUAL(segment);
+    ADD_QUAL(sequenced_mol);
+    ADD_QUAL(serotype);
+    ADD_QUAL(serovar);
+    ADD_QUAL(sex);
+    ADD_QUAL(specimen_voucher);
+    ADD_QUAL(strain);
+    ADD_QUAL(sub_clone);
+    ADD_QUAL(sub_species);
+    ADD_QUAL(sub_strain);
+    ADD_QUAL(tissue_lib);
+    ADD_QUAL(tissue_type);
+    ADD_QUAL(transgenic);
+    ADD_QUAL(transposon);
+    ADD_QUAL(type_material);
+    ADD_QUAL(usedin);
+    ADD_QUAL(variety);
+    ADD_QUAL(virion);
+    ADD_QUAL(whole_replicon);
 END_SUBTYPE
 
 //START_SUBTYPE(clone)
@@ -2950,6 +2956,34 @@ START_SUBTYPE(regulatory)
     ADD_QUAL(standard_name);
 END_SUBTYPE
 
+START_SUBTYPE(propeptide)
+    ADD_QUAL(EC_number);
+    ADD_QUAL(allele);
+    ADD_QUAL(calculated_mol_wt);
+    ADD_QUAL(citation);
+    ADD_QUAL(db_xref);
+    ADD_QUAL(derived_from);
+    ADD_QUAL(evidence);
+    ADD_QUAL(exception);
+    ADD_QUAL(experiment);
+    ADD_QUAL(function);
+    ADD_QUAL(gene);
+    ADD_QUAL(gene_synonym);
+    ADD_QUAL(inference);
+    ADD_QUAL(label);
+    ADD_QUAL(locus_tag);
+    ADD_QUAL(map);
+    ADD_QUAL(name);
+    ADD_QUAL(note);
+    ADD_QUAL(old_locus_tag);
+    ADD_QUAL(product);
+    ADD_QUAL(protein_id);
+    ADD_QUAL(pseudo);
+    ADD_QUAL(pseudogene);
+    ADD_QUAL(standard_name);
+    ADD_QUAL(usedin);
+END_SUBTYPE
+
 #undef START_SUBTYPE
 #undef ADD_QUAL
 #undef END_SUBTYPE
@@ -3093,6 +3127,7 @@ static const TQualPair kQualPairs[] = {
     { CSeqFeatData::eQual_pseudo, "pseudo" },
     { CSeqFeatData::eQual_pseudogene, "pseudogene" },
     { CSeqFeatData::eQual_rearranged, "rearranged" },
+    { CSeqFeatData::eQual_recombination_class, "recombination_class" },
     { CSeqFeatData::eQual_region_name, "region_name" },
     { CSeqFeatData::eQual_regulatory_class, "regulatory_class" },
     { CSeqFeatData::eQual_replace, "replace" },
@@ -3180,6 +3215,529 @@ CSeqFeatData::EQualifier CSeqFeatData::GetQualifierType(const string& qual, NStr
 }
 
 
+// xref info table
+DEFINE_STATIC_MUTEX(sx_InitXrefTablesMutex);
+typedef vector<CSeqFeatData::ESubtype> TSubtypeVector;
+typedef map<CSeqFeatData::ESubtype, TSubtypeVector> TSubtypeXrefMap;
+
+#define ADD_XREF_PAIR(x, y) \
+    table[eSubtype_##x].push_back(eSubtype_##y); \
+    table[eSubtype_##y].push_back(eSubtype_##x);
+
+static CSafeStatic<TSubtypeXrefMap> sx_XrefAllowedSubtypesTable;
+static bool sx_XrefAllowedSubtypesTableInitialized = false;
+static CSafeStatic<TSubtypeXrefMap> sx_XrefProhibitedSubtypesTable;
+static bool sx_XrefProhibitedSubtypesTableInitialized = false;
+
+
+void CSeqFeatData::s_InitXrefAllowedSubtypesTable(void)
+{
+    if (sx_XrefAllowedSubtypesTableInitialized) {
+        return;
+    }
+    CMutexGuard guard(sx_InitXrefTablesMutex);
+    if (sx_XrefAllowedSubtypesTableInitialized) {
+        return;
+    }
+
+    TSubtypeXrefMap& table = *sx_XrefAllowedSubtypesTable;
+
+    ADD_XREF_PAIR(ncRNA, preRNA)
+    ADD_XREF_PAIR(S_region, mRNA)
+    ADD_XREF_PAIR(gene, preRNA)
+    ADD_XREF_PAIR(J_segment, gene)
+    ADD_XREF_PAIR(exon, tmRNA)
+    ADD_XREF_PAIR(N_region, exon)
+    ADD_XREF_PAIR(V_region, cdregion)
+    ADD_XREF_PAIR(intron, preRNA)
+    ADD_XREF_PAIR(V_segment, preRNA)
+    ADD_XREF_PAIR(otherRNA, polyA_signal)
+    ADD_XREF_PAIR(S_region, exon)
+    ADD_XREF_PAIR(gene, tmRNA)
+    ADD_XREF_PAIR(otherRNA, preRNA)
+    ADD_XREF_PAIR(exon, preRNA)
+    ADD_XREF_PAIR(5UTR, intron)
+    ADD_XREF_PAIR(mRNA, tmRNA)
+    ADD_XREF_PAIR(3UTR, intron)
+    ADD_XREF_PAIR(5UTR, preRNA)
+    ADD_XREF_PAIR(otherRNA, polyA_site)
+    ADD_XREF_PAIR(N_region, cdregion)
+    ADD_XREF_PAIR(N_region, gene)
+    ADD_XREF_PAIR(V_region, mRNA)
+    ADD_XREF_PAIR(V_segment, mRNA)
+    ADD_XREF_PAIR(cdregion, mRNA)
+    ADD_XREF_PAIR(gene, ncRNA)
+    ADD_XREF_PAIR(C_region, mRNA)
+    ADD_XREF_PAIR(exon, tRNA)
+    ADD_XREF_PAIR(gene, mRNA)
+    ADD_XREF_PAIR(exon, misc_RNA)
+    ADD_XREF_PAIR(ncRNA, polyA_signal)
+    ADD_XREF_PAIR(3UTR, preRNA)
+    ADD_XREF_PAIR(preRNA, rRNA)
+    ADD_XREF_PAIR(exon, mRNA)
+    ADD_XREF_PAIR(gene, rRNA)
+    ADD_XREF_PAIR(intron, otherRNA)
+    ADD_XREF_PAIR(V_segment, cdregion)
+    ADD_XREF_PAIR(N_region, preRNA)
+    ADD_XREF_PAIR(J_segment, preRNA)
+    ADD_XREF_PAIR(5UTR, exon)
+    ADD_XREF_PAIR(gene, polyA_site)
+    ADD_XREF_PAIR(preRNA, tRNA)
+    ADD_XREF_PAIR(polyA_signal, preRNA)
+    ADD_XREF_PAIR(D_segment, cdregion)
+    ADD_XREF_PAIR(V_region, preRNA)
+    ADD_XREF_PAIR(cdregion, tmRNA)
+    ADD_XREF_PAIR(N_region, intron)
+    ADD_XREF_PAIR(V_region, exon)
+    ADD_XREF_PAIR(5UTR, gene)
+    ADD_XREF_PAIR(gene, tRNA)
+    ADD_XREF_PAIR(TATA_signal, gene)
+    ADD_XREF_PAIR(D_segment, mRNA)
+    ADD_XREF_PAIR(tRNA, tmRNA)
+    ADD_XREF_PAIR(V_segment, exon)
+    ADD_XREF_PAIR(V_segment, intron)
+    ADD_XREF_PAIR(cdregion, gene)
+    ADD_XREF_PAIR(mRNA, preRNA)
+    ADD_XREF_PAIR(gene, otherRNA)
+    ADD_XREF_PAIR(enhancer, gene)
+    ADD_XREF_PAIR(misc_RNA, polyA_signal)
+    ADD_XREF_PAIR(ncRNA, polyA_site)
+    ADD_XREF_PAIR(intron, rRNA)
+    ADD_XREF_PAIR(35_signal, gene)
+    ADD_XREF_PAIR(misc_RNA, preRNA)
+    ADD_XREF_PAIR(10_signal, gene)
+    ADD_XREF_PAIR(preRNA, tmRNA)
+    ADD_XREF_PAIR(intron, ncRNA)
+    ADD_XREF_PAIR(misc_RNA, polyA_site)
+    ADD_XREF_PAIR(5UTR, mRNA)
+    ADD_XREF_PAIR(J_segment, cdregion)
+    ADD_XREF_PAIR(C_region, cdregion)
+    ADD_XREF_PAIR(intron, misc_RNA)
+    ADD_XREF_PAIR(TATA_signal, preRNA)
+    ADD_XREF_PAIR(exon, ncRNA)
+    ADD_XREF_PAIR(3UTR, gene)
+    ADD_XREF_PAIR(S_region, preRNA)
+    ADD_XREF_PAIR(exon, rRNA)
+    ADD_XREF_PAIR(mRNA, regulatory)
+    ADD_XREF_PAIR(J_segment, intron)
+    ADD_XREF_PAIR(intron, tRNA)
+    ADD_XREF_PAIR(S_region, cdregion)
+    ADD_XREF_PAIR(V_region, gene)
+    ADD_XREF_PAIR(C_region, intron)
+    ADD_XREF_PAIR(C_region, exon)
+    ADD_XREF_PAIR(D_segment, intron)
+    ADD_XREF_PAIR(C_region, preRNA)
+    ADD_XREF_PAIR(3UTR, mRNA)
+    ADD_XREF_PAIR(intron, mRNA)
+    ADD_XREF_PAIR(J_segment, mRNA)
+    ADD_XREF_PAIR(mRNA, polyA_site)
+    ADD_XREF_PAIR(V_segment, gene)
+    ADD_XREF_PAIR(3UTR, exon)
+    ADD_XREF_PAIR(V_region, intron)
+    ADD_XREF_PAIR(D_segment, exon)
+    ADD_XREF_PAIR(J_segment, exon)
+    ADD_XREF_PAIR(gene, promoter)
+    ADD_XREF_PAIR(D_segment, preRNA)
+    ADD_XREF_PAIR(gene, misc_RNA)
+    ADD_XREF_PAIR(exon, gene)
+    ADD_XREF_PAIR(N_region, mRNA)
+    ADD_XREF_PAIR(exon, otherRNA)
+    ADD_XREF_PAIR(C_region, gene)
+    ADD_XREF_PAIR(S_region, gene)
+    ADD_XREF_PAIR(D_segment, gene)
+    ADD_XREF_PAIR(gene, polyA_signal)
+    ADD_XREF_PAIR(intron, tmRNA)
+    ADD_XREF_PAIR(gene, intron)
+    ADD_XREF_PAIR(gene, regulatory)
+    ADD_XREF_PAIR(mRNA, polyA_signal)
+    ADD_XREF_PAIR(polyA_site, preRNA)
+    ADD_XREF_PAIR(S_region, intron)
+
+    // sort for binary_search
+    NON_CONST_ITERATE(TSubtypeXrefMap, iter, table) {
+        sort(iter->second.begin(), iter->second.end());
+    }
+
+    sx_XrefAllowedSubtypesTableInitialized = true;
+
+
+}
+
+void CSeqFeatData::s_InitXrefProhibitedSubtypesTable(void)
+{
+    if (sx_XrefProhibitedSubtypesTableInitialized) {
+        return;
+    }
+    CMutexGuard guard(sx_InitXrefTablesMutex);
+    if (sx_XrefProhibitedSubtypesTableInitialized) {
+        return;
+    }
+
+    TSubtypeXrefMap& table = *sx_XrefProhibitedSubtypesTable;
+
+    ADD_XREF_PAIR(3UTR, promoter)
+    ADD_XREF_PAIR(enhancer, rRNA)
+    ADD_XREF_PAIR(3UTR, 5UTR)
+    ADD_XREF_PAIR(cdregion, cdregion)
+    ADD_XREF_PAIR(otherRNA, otherRNA)
+    ADD_XREF_PAIR(35_signal, D_segment)
+    ADD_XREF_PAIR(polyA_site, regulatory)
+    ADD_XREF_PAIR(N_region, promoter)
+    ADD_XREF_PAIR(cdregion, regulatory)
+    ADD_XREF_PAIR(35_signal, misc_RNA)
+    ADD_XREF_PAIR(mRNA, otherRNA)
+    ADD_XREF_PAIR(V_region, polyA_signal)
+    ADD_XREF_PAIR(35_signal, J_segment)
+    ADD_XREF_PAIR(rRNA, rRNA)
+    ADD_XREF_PAIR(C_region, otherRNA)
+    ADD_XREF_PAIR(TATA_signal, V_segment)
+    ADD_XREF_PAIR(ncRNA, regulatory)
+    ADD_XREF_PAIR(intron, polyA_site)
+    ADD_XREF_PAIR(5UTR, C_region)
+    ADD_XREF_PAIR(intron, intron)
+    ADD_XREF_PAIR(35_signal, V_segment)
+    ADD_XREF_PAIR(5UTR, D_segment)
+    ADD_XREF_PAIR(10_signal, S_region)
+    ADD_XREF_PAIR(J_segment, tRNA)
+    ADD_XREF_PAIR(V_region, promoter)
+    ADD_XREF_PAIR(5UTR, rRNA)
+    ADD_XREF_PAIR(35_signal, C_region)
+    ADD_XREF_PAIR(polyA_signal, tRNA)
+    ADD_XREF_PAIR(J_segment, enhancer)
+    ADD_XREF_PAIR(cdregion, ncRNA)
+    ADD_XREF_PAIR(10_signal, rRNA)
+    ADD_XREF_PAIR(J_segment, tmRNA)
+    ADD_XREF_PAIR(mRNA, ncRNA)
+    ADD_XREF_PAIR(N_region, regulatory)
+    ADD_XREF_PAIR(TATA_signal, cdregion)
+    ADD_XREF_PAIR(10_signal, polyA_site)
+    ADD_XREF_PAIR(10_signal, V_segment)
+    ADD_XREF_PAIR(S_region, tmRNA)
+    ADD_XREF_PAIR(S_region, misc_RNA)
+    ADD_XREF_PAIR(mRNA, tRNA)
+    ADD_XREF_PAIR(TATA_signal, exon)
+    ADD_XREF_PAIR(10_signal, tRNA)
+    ADD_XREF_PAIR(35_signal, cdregion)
+    ADD_XREF_PAIR(35_signal, tRNA)
+    ADD_XREF_PAIR(cdregion, otherRNA)
+    ADD_XREF_PAIR(35_signal, enhancer)
+    ADD_XREF_PAIR(10_signal, tmRNA)
+    ADD_XREF_PAIR(35_signal, V_region)
+    ADD_XREF_PAIR(C_region, C_region)
+    ADD_XREF_PAIR(enhancer, promoter)
+    ADD_XREF_PAIR(3UTR, tmRNA)
+    ADD_XREF_PAIR(D_segment, regulatory)
+    ADD_XREF_PAIR(35_signal, otherRNA)
+    ADD_XREF_PAIR(otherRNA, regulatory)
+    ADD_XREF_PAIR(V_region, V_region)
+    ADD_XREF_PAIR(35_signal, rRNA)
+    ADD_XREF_PAIR(J_segment, S_region)
+    ADD_XREF_PAIR(misc_RNA, ncRNA)
+    ADD_XREF_PAIR(V_region, polyA_site)
+    ADD_XREF_PAIR(S_region, tRNA)
+    ADD_XREF_PAIR(V_segment, rRNA)
+    ADD_XREF_PAIR(N_region, misc_RNA)
+    ADD_XREF_PAIR(J_segment, misc_RNA)
+    ADD_XREF_PAIR(mRNA, mRNA)
+    ADD_XREF_PAIR(5UTR, V_segment)
+    ADD_XREF_PAIR(N_region, tmRNA)
+    ADD_XREF_PAIR(N_region, ncRNA)
+    ADD_XREF_PAIR(3UTR, enhancer)
+    ADD_XREF_PAIR(TATA_signal, tmRNA)
+    ADD_XREF_PAIR(D_segment, tRNA)
+    ADD_XREF_PAIR(enhancer, preRNA)
+    ADD_XREF_PAIR(D_segment, polyA_site)
+    ADD_XREF_PAIR(3UTR, cdregion)
+    ADD_XREF_PAIR(ncRNA, rRNA)
+    ADD_XREF_PAIR(promoter, tmRNA)
+    ADD_XREF_PAIR(N_region, polyA_signal)
+    ADD_XREF_PAIR(S_region, otherRNA)
+    ADD_XREF_PAIR(35_signal, S_region)
+    ADD_XREF_PAIR(10_signal, V_region)
+    ADD_XREF_PAIR(misc_RNA, regulatory)
+    ADD_XREF_PAIR(C_region, promoter)
+    ADD_XREF_PAIR(otherRNA, tRNA)
+    ADD_XREF_PAIR(J_segment, promoter)
+    ADD_XREF_PAIR(polyA_site, tmRNA)
+    ADD_XREF_PAIR(preRNA, promoter)
+    ADD_XREF_PAIR(otherRNA, rRNA)
+    ADD_XREF_PAIR(10_signal, D_segment)
+    ADD_XREF_PAIR(35_signal, promoter)
+    ADD_XREF_PAIR(enhancer, tRNA)
+    ADD_XREF_PAIR(10_signal, misc_RNA)
+    ADD_XREF_PAIR(rRNA, regulatory)
+    ADD_XREF_PAIR(10_signal, N_region)
+    ADD_XREF_PAIR(5UTR, enhancer)
+    ADD_XREF_PAIR(TATA_signal, promoter)
+    ADD_XREF_PAIR(D_segment, tmRNA)
+    ADD_XREF_PAIR(misc_RNA, otherRNA)
+    ADD_XREF_PAIR(D_segment, V_region)
+    ADD_XREF_PAIR(35_signal, preRNA)
+    ADD_XREF_PAIR(3UTR, otherRNA)
+    ADD_XREF_PAIR(polyA_signal, promoter)
+    ADD_XREF_PAIR(S_region, regulatory)
+    ADD_XREF_PAIR(misc_RNA, misc_RNA)
+    ADD_XREF_PAIR(10_signal, cdregion)
+    ADD_XREF_PAIR(5UTR, S_region)
+    ADD_XREF_PAIR(10_signal, J_segment)
+    ADD_XREF_PAIR(ncRNA, otherRNA)
+    ADD_XREF_PAIR(otherRNA, tmRNA)
+    ADD_XREF_PAIR(cdregion, polyA_signal)
+    ADD_XREF_PAIR(J_segment, polyA_site)
+    ADD_XREF_PAIR(cdregion, enhancer)
+    ADD_XREF_PAIR(J_segment, J_segment)
+    ADD_XREF_PAIR(regulatory, tmRNA)
+    ADD_XREF_PAIR(S_region, polyA_site)
+    ADD_XREF_PAIR(35_signal, tmRNA)
+    ADD_XREF_PAIR(D_segment, polyA_signal)
+    ADD_XREF_PAIR(35_signal, exon)
+    ADD_XREF_PAIR(intron, regulatory)
+    ADD_XREF_PAIR(enhancer, enhancer)
+    ADD_XREF_PAIR(10_signal, polyA_signal)
+    ADD_XREF_PAIR(rRNA, tmRNA)
+    ADD_XREF_PAIR(D_segment, ncRNA)
+    ADD_XREF_PAIR(N_region, tRNA)
+    ADD_XREF_PAIR(cdregion, preRNA)
+    ADD_XREF_PAIR(enhancer, regulatory)
+    ADD_XREF_PAIR(D_segment, promoter)
+    ADD_XREF_PAIR(5UTR, V_region)
+    ADD_XREF_PAIR(35_signal, polyA_signal)
+    ADD_XREF_PAIR(10_signal, intron)
+    ADD_XREF_PAIR(J_segment, polyA_signal)
+    ADD_XREF_PAIR(V_region, otherRNA)
+    ADD_XREF_PAIR(polyA_site, polyA_site)
+    ADD_XREF_PAIR(mRNA, promoter)
+    ADD_XREF_PAIR(enhancer, ncRNA)
+    ADD_XREF_PAIR(tRNA, tRNA)
+    ADD_XREF_PAIR(3UTR, V_region)
+    ADD_XREF_PAIR(C_region, S_region)
+    ADD_XREF_PAIR(D_segment, S_region)
+    ADD_XREF_PAIR(D_segment, N_region)
+    ADD_XREF_PAIR(polyA_site, tRNA)
+    ADD_XREF_PAIR(C_region, misc_RNA)
+    ADD_XREF_PAIR(10_signal, regulatory)
+    ADD_XREF_PAIR(35_signal, polyA_site)
+    ADD_XREF_PAIR(5UTR, misc_RNA)
+    ADD_XREF_PAIR(J_segment, rRNA)
+    ADD_XREF_PAIR(5UTR, polyA_site)
+    ADD_XREF_PAIR(misc_RNA, tmRNA)
+    ADD_XREF_PAIR(C_region, J_segment)
+    ADD_XREF_PAIR(V_segment, polyA_signal)
+    ADD_XREF_PAIR(V_region, misc_RNA)
+    ADD_XREF_PAIR(V_region, regulatory)
+    ADD_XREF_PAIR(10_signal, mRNA)
+    ADD_XREF_PAIR(misc_RNA, rRNA)
+    ADD_XREF_PAIR(TATA_signal, V_region)
+    ADD_XREF_PAIR(J_segment, N_region)
+    ADD_XREF_PAIR(ncRNA, promoter)
+    ADD_XREF_PAIR(S_region, polyA_signal)
+    ADD_XREF_PAIR(D_segment, rRNA)
+    ADD_XREF_PAIR(polyA_site, rRNA)
+    ADD_XREF_PAIR(V_region, tRNA)
+    ADD_XREF_PAIR(D_segment, D_segment)
+    ADD_XREF_PAIR(J_segment, otherRNA)
+    ADD_XREF_PAIR(V_segment, polyA_site)
+    ADD_XREF_PAIR(5UTR, otherRNA)
+    ADD_XREF_PAIR(exon, exon)
+    ADD_XREF_PAIR(exon, intron)
+    ADD_XREF_PAIR(promoter, promoter)
+    ADD_XREF_PAIR(cdregion, polyA_site)
+    ADD_XREF_PAIR(V_region, enhancer)
+    ADD_XREF_PAIR(TATA_signal, misc_RNA)
+    ADD_XREF_PAIR(TATA_signal, rRNA)
+    ADD_XREF_PAIR(3UTR, J_segment)
+    ADD_XREF_PAIR(J_segment, regulatory)
+    ADD_XREF_PAIR(intron, polyA_signal)
+    ADD_XREF_PAIR(C_region, N_region)
+    ADD_XREF_PAIR(N_region, enhancer)
+    ADD_XREF_PAIR(TATA_signal, enhancer)
+    ADD_XREF_PAIR(preRNA, preRNA)
+    ADD_XREF_PAIR(3UTR, misc_RNA)
+    ADD_XREF_PAIR(C_region, D_segment)
+    ADD_XREF_PAIR(V_segment, otherRNA)
+    ADD_XREF_PAIR(5UTR, N_region)
+    ADD_XREF_PAIR(35_signal, mRNA)
+    ADD_XREF_PAIR(3UTR, TATA_signal)
+    ADD_XREF_PAIR(V_region, ncRNA)
+    ADD_XREF_PAIR(10_signal, preRNA)
+    ADD_XREF_PAIR(enhancer, otherRNA)
+    ADD_XREF_PAIR(10_signal, exon)
+    ADD_XREF_PAIR(3UTR, V_segment)
+    ADD_XREF_PAIR(misc_RNA, tRNA)
+    ADD_XREF_PAIR(cdregion, exon)
+    ADD_XREF_PAIR(10_signal, TATA_signal)
+    ADD_XREF_PAIR(5UTR, polyA_signal)
+    ADD_XREF_PAIR(tmRNA, tmRNA)
+    ADD_XREF_PAIR(5UTR, cdregion)
+    ADD_XREF_PAIR(35_signal, 35_signal)
+    ADD_XREF_PAIR(TATA_signal, intron)
+    ADD_XREF_PAIR(ncRNA, ncRNA)
+    ADD_XREF_PAIR(promoter, tRNA)
+    ADD_XREF_PAIR(3UTR, ncRNA)
+    ADD_XREF_PAIR(35_signal, N_region)
+    ADD_XREF_PAIR(N_region, otherRNA)
+    ADD_XREF_PAIR(C_region, tRNA)
+    ADD_XREF_PAIR(5UTR, 5UTR)
+    ADD_XREF_PAIR(N_region, S_region)
+    ADD_XREF_PAIR(TATA_signal, regulatory)
+    ADD_XREF_PAIR(V_segment, tRNA)
+    ADD_XREF_PAIR(ncRNA, tRNA)
+    ADD_XREF_PAIR(5UTR, ncRNA)
+    ADD_XREF_PAIR(3UTR, S_region)
+    ADD_XREF_PAIR(V_segment, regulatory)
+    ADD_XREF_PAIR(3UTR, D_segment)
+    ADD_XREF_PAIR(35_signal, 5UTR)
+    ADD_XREF_PAIR(3UTR, C_region)
+    ADD_XREF_PAIR(cdregion, intron)
+    ADD_XREF_PAIR(cdregion, rRNA)
+    ADD_XREF_PAIR(TATA_signal, TATA_signal)
+    ADD_XREF_PAIR(35_signal, intron)
+    ADD_XREF_PAIR(N_region, rRNA)
+    ADD_XREF_PAIR(35_signal, TATA_signal)
+    ADD_XREF_PAIR(mRNA, rRNA)
+    ADD_XREF_PAIR(10_signal, 10_signal)
+    ADD_XREF_PAIR(C_region, V_segment)
+    ADD_XREF_PAIR(rRNA, tRNA)
+    ADD_XREF_PAIR(TATA_signal, tRNA)
+    ADD_XREF_PAIR(TATA_signal, otherRNA)
+    ADD_XREF_PAIR(C_region, rRNA)
+    ADD_XREF_PAIR(35_signal, ncRNA)
+    ADD_XREF_PAIR(3UTR, N_region)
+    ADD_XREF_PAIR(3UTR, polyA_site)
+    ADD_XREF_PAIR(S_region, TATA_signal)
+    ADD_XREF_PAIR(V_region, V_segment)
+    ADD_XREF_PAIR(N_region, N_region)
+    ADD_XREF_PAIR(cdregion, promoter)
+    ADD_XREF_PAIR(D_segment, J_segment)
+    ADD_XREF_PAIR(5UTR, tmRNA)
+    ADD_XREF_PAIR(enhancer, exon)
+    ADD_XREF_PAIR(S_region, S_region)
+    ADD_XREF_PAIR(5UTR, regulatory)
+    ADD_XREF_PAIR(enhancer, misc_RNA)
+    ADD_XREF_PAIR(exon, polyA_signal)
+    ADD_XREF_PAIR(3UTR, rRNA)
+    ADD_XREF_PAIR(gene, gene)
+    ADD_XREF_PAIR(TATA_signal, polyA_site)
+    ADD_XREF_PAIR(enhancer, polyA_site)
+    ADD_XREF_PAIR(5UTR, tRNA)
+    ADD_XREF_PAIR(enhancer, polyA_signal)
+    ADD_XREF_PAIR(D_segment, otherRNA)
+    ADD_XREF_PAIR(C_region, polyA_site)
+    ADD_XREF_PAIR(J_segment, TATA_signal)
+    ADD_XREF_PAIR(polyA_signal, polyA_site)
+    ADD_XREF_PAIR(10_signal, enhancer)
+    ADD_XREF_PAIR(TATA_signal, ncRNA)
+    ADD_XREF_PAIR(promoter, regulatory)
+    ADD_XREF_PAIR(S_region, V_segment)
+    ADD_XREF_PAIR(S_region, V_region)
+    ADD_XREF_PAIR(J_segment, ncRNA)
+    ADD_XREF_PAIR(TATA_signal, polyA_signal)
+    ADD_XREF_PAIR(C_region, enhancer)
+    ADD_XREF_PAIR(ncRNA, tmRNA)
+    ADD_XREF_PAIR(D_segment, V_segment)
+    ADD_XREF_PAIR(C_region, polyA_signal)
+    ADD_XREF_PAIR(polyA_site, promoter)
+    ADD_XREF_PAIR(35_signal, regulatory)
+    ADD_XREF_PAIR(enhancer, mRNA)
+    ADD_XREF_PAIR(preRNA, regulatory)
+    ADD_XREF_PAIR(10_signal, 3UTR)
+    ADD_XREF_PAIR(10_signal, C_region)
+    ADD_XREF_PAIR(polyA_signal, regulatory)
+    ADD_XREF_PAIR(C_region, tmRNA)
+    ADD_XREF_PAIR(3UTR, polyA_signal)
+    ADD_XREF_PAIR(regulatory, regulatory)
+    ADD_XREF_PAIR(V_segment, V_segment)
+    ADD_XREF_PAIR(10_signal, 35_signal)
+    ADD_XREF_PAIR(D_segment, enhancer)
+    ADD_XREF_PAIR(V_segment, ncRNA)
+    ADD_XREF_PAIR(V_segment, promoter)
+    ADD_XREF_PAIR(V_segment, misc_RNA)
+    ADD_XREF_PAIR(D_segment, TATA_signal)
+    ADD_XREF_PAIR(N_region, V_region)
+    ADD_XREF_PAIR(N_region, polyA_site)
+    ADD_XREF_PAIR(C_region, ncRNA)
+    ADD_XREF_PAIR(5UTR, promoter)
+    ADD_XREF_PAIR(C_region, TATA_signal)
+    ADD_XREF_PAIR(exon, polyA_site)
+    ADD_XREF_PAIR(D_segment, misc_RNA)
+    ADD_XREF_PAIR(S_region, rRNA)
+    ADD_XREF_PAIR(S_region, ncRNA)
+    ADD_XREF_PAIR(S_region, promoter)
+    ADD_XREF_PAIR(5UTR, TATA_signal)
+    ADD_XREF_PAIR(N_region, TATA_signal)
+    ADD_XREF_PAIR(V_region, rRNA)
+    ADD_XREF_PAIR(otherRNA, promoter)
+    ADD_XREF_PAIR(exon, promoter)
+    ADD_XREF_PAIR(polyA_signal, rRNA)
+    ADD_XREF_PAIR(V_segment, tmRNA)
+    ADD_XREF_PAIR(J_segment, V_region)
+    ADD_XREF_PAIR(cdregion, tRNA)
+    ADD_XREF_PAIR(enhancer, intron)
+    ADD_XREF_PAIR(regulatory, tRNA)
+    ADD_XREF_PAIR(C_region, regulatory)
+    ADD_XREF_PAIR(polyA_signal, tmRNA)
+    ADD_XREF_PAIR(misc_RNA, promoter)
+    ADD_XREF_PAIR(J_segment, V_segment)
+    ADD_XREF_PAIR(N_region, V_segment)
+    ADD_XREF_PAIR(intron, promoter)
+    ADD_XREF_PAIR(V_segment, enhancer)
+    ADD_XREF_PAIR(10_signal, otherRNA)
+    ADD_XREF_PAIR(TATA_signal, mRNA)
+    ADD_XREF_PAIR(S_region, enhancer)
+    ADD_XREF_PAIR(3UTR, tRNA)
+    ADD_XREF_PAIR(V_region, tmRNA)
+    ADD_XREF_PAIR(C_region, V_region)
+    ADD_XREF_PAIR(3UTR, regulatory)
+    ADD_XREF_PAIR(10_signal, ncRNA)
+    ADD_XREF_PAIR(10_signal, 5UTR)
+    ADD_XREF_PAIR(polyA_signal, polyA_signal)
+    ADD_XREF_PAIR(3UTR, 3UTR)
+    ADD_XREF_PAIR(35_signal, 3UTR)
+    ADD_XREF_PAIR(enhancer, tmRNA)
+    ADD_XREF_PAIR(10_signal, promoter)
+    ADD_XREF_PAIR(5UTR, J_segment)
+    ADD_XREF_PAIR(cdregion, misc_RNA)
+    ADD_XREF_PAIR(exon, regulatory)
+    ADD_XREF_PAIR(mRNA, misc_RNA)
+    ADD_XREF_PAIR(promoter, rRNA)
+
+    // sort for binary_search
+    NON_CONST_ITERATE(TSubtypeXrefMap, iter, table) {
+        sort(iter->second.begin(), iter->second.end());
+    }
+
+    sx_XrefProhibitedSubtypesTableInitialized = true;
+}
+
+
+bool CSeqFeatData::AllowXref(ESubtype subtype1, ESubtype subtype2)
+{
+    if (!sx_XrefAllowedSubtypesTableInitialized) {
+        s_InitXrefAllowedSubtypesTable();
+    }
+    TSubtypeXrefMap::const_iterator iter = sx_XrefAllowedSubtypesTable->find(subtype1);
+    if (iter == sx_XrefAllowedSubtypesTable->end()) {
+        return false;
+    }
+    const TSubtypeVector& allowed = iter->second;
+    return binary_search(allowed.begin(), allowed.end(), subtype2);
+}
+
+
+bool CSeqFeatData::ProhibitXref(ESubtype subtype1, ESubtype subtype2)
+{
+    if (!sx_XrefProhibitedSubtypesTableInitialized) {
+        s_InitXrefProhibitedSubtypesTable();
+    }
+    TSubtypeXrefMap::const_iterator iter = sx_XrefProhibitedSubtypesTable->find(subtype1);
+    if (iter == sx_XrefProhibitedSubtypesTable->end()) {
+        return false;
+    }
+    const TSubtypeVector& allowed = iter->second;
+    return binary_search(allowed.begin(), allowed.end(), subtype2);
+}
+
+
 /////////////////// end of CSeqFeatData methods
 
 
@@ -3336,6 +3894,39 @@ CSeqFeatData::GetRegulatoryClass(const string & class_name )
     return eSubtype_bad;
 }
 
+
+vector<string> CSeqFeatData::GetRegulatoryClassList()
+{
+    vector<string> choices;
+
+    choices.push_back("promoter");
+    choices.push_back("ribosome_binding_site");
+    choices.push_back("attenuator");
+    choices.push_back("CAAT_signal");
+    choices.push_back("DNase_I_hypersensitive_site");
+    choices.push_back("enhancer");
+    choices.push_back("enhancer_blocking_element");
+    choices.push_back("GC_signal");
+    choices.push_back("imprinting_control_region");
+    choices.push_back("insulator");
+    choices.push_back("locus_control_region");
+    choices.push_back("LTR");
+    choices.push_back("matrix_attachment_region");
+    choices.push_back("minus_10_signal");
+    choices.push_back("minus_35_signal");
+    choices.push_back("polyA_signal_sequence");
+    choices.push_back("recoding_stimulatory_region");
+    choices.push_back("replication_regulatory_region");
+    choices.push_back("response_element");
+    choices.push_back("riboswitch");
+    choices.push_back("silencer");
+    choices.push_back("TATA_box");
+    choices.push_back("terminator");
+    choices.push_back("transcriptional_cis_regulatory_region");
+
+    return choices;
+}
+
 bool CSeqFeatData::IsDiscouragedSubtype(ESubtype subtype)
 {
     switch(subtype) {
@@ -3347,6 +3938,7 @@ bool CSeqFeatData::IsDiscouragedSubtype(ESubtype subtype)
         case eSubtype_conflict:
         case eSubtype_enhancer:
         case eSubtype_GC_signal:
+        case eSubtype_LTR:
         case eSubtype_misc_binding:
         case eSubtype_mutation:
         case eSubtype_polyA_signal:
@@ -3404,6 +3996,7 @@ static const SFeatListItem sc_ConfigItemInit[] = {
     {  CSeqFeatData::e_Prot,     CSeqFeatData::eSubtype_mat_peptide_aa,    "Mature Peptide AA", "Mat-Peptide AA"  },
     {  CSeqFeatData::e_Prot,     CSeqFeatData::eSubtype_sig_peptide_aa,    "Signal Peptide AA", "Sig-Peptide AA"  },
     {  CSeqFeatData::e_Prot,     CSeqFeatData::eSubtype_transit_peptide_aa,    "Transit Peptide AA", "Transit-Peptide AA"  },
+    {  CSeqFeatData::e_Prot,     CSeqFeatData::eSubtype_propeptide,    "ProPeptide", "ProPeptide"  },
 
     {  CSeqFeatData::e_Rna,     CSeqFeatData::eSubtype_any,   "RNA, All" , "RNA Master"  },
     {  CSeqFeatData::e_Rna,     CSeqFeatData::eSubtype_preRNA,  "precursor_RNA",   "precursor_RNA"  },
@@ -3794,6 +4387,7 @@ CSeqFeatData::GetSetOfRegulatorySubtypes(void)
         eSubtype_CAAT_signal,
         eSubtype_enhancer,
         eSubtype_GC_signal,
+        eSubtype_LTR,
         eSubtype_misc_signal,
         eSubtype_polyA_signal,
         eSubtype_promoter,
@@ -3820,6 +4414,7 @@ CSeqFeatData::EFeatureLocationAllowed CSeqFeatData::AllowedFeatureLocation(ESubt
         case eSubtype_mat_peptide_aa:
         case eSubtype_sig_peptide_aa:
         case eSubtype_transit_peptide_aa:
+        case eSubtype_propeptide:
         case eSubtype_bond:
         case eSubtype_psec_str:
             rval = eFeatureLocationAllowed_ProtOnly;
@@ -3913,10 +4508,10 @@ bool CSeqFeatData::AllowAdjacentIntervals(CSeqFeatData::ESubtype feat_subtype)
 
 bool CSeqFeatData::ShouldRepresentAsGbqual (CSeqFeatData::ESubtype feat_subtype, CSeqFeatData::EQualifier qual_type)
 {
-	// experiment and inference get their own panels
-	if (qual_type == CSeqFeatData::eQual_experiment || qual_type == CSeqFeatData::eQual_inference) {
-		return false;
-	}
+    // experiment and inference get their own panels
+    if (qual_type == CSeqFeatData::eQual_experiment || qual_type == CSeqFeatData::eQual_inference) {
+        return false;
+    }
     // pseudo and pseudogene are handled separately
     if (qual_type == CSeqFeatData::eQual_pseudogene || qual_type == CSeqFeatData::eQual_pseudo) {
         return false;
@@ -4012,10 +4607,10 @@ bool CSeqFeatData::ShouldRepresentAsGbqual (CSeqFeatData::ESubtype feat_subtype,
 
 bool CSeqFeatData::ShouldRepresentAsGbqual (CSeqFeatData::ESubtype feat_subtype, const CGb_qual& qual)
 {
-	if (!qual.IsSetQual()) {
-		return false;
-	}
-	return ShouldRepresentAsGbqual(feat_subtype, CSeqFeatData::GetQualifierType(qual.GetQual()));
+    if (!qual.IsSetQual()) {
+        return false;
+    }
+    return ShouldRepresentAsGbqual(feat_subtype, CSeqFeatData::GetQualifierType(qual.GetQual()));
 }
 
 END_objects_SCOPE // namespace ncbi::objects::
diff --git a/c++/src/objects/seqfeat/Seq_feat.cpp b/c++/src/objects/seqfeat/Seq_feat.cpp
index d79e44d..f32e737 100644
--- a/c++/src/objects/seqfeat/Seq_feat.cpp
+++ b/c++/src/objects/seqfeat/Seq_feat.cpp
@@ -1,4 +1,4 @@
-/* $Id: Seq_feat.cpp 490392 2016-01-25 17:20:58Z bollin $
+/* $Id: Seq_feat.cpp 518385 2016-11-02 17:27:05Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -250,6 +250,32 @@ CProt_ref& CSeq_feat::SetProtXref(void)
 }
 
 
+bool CSeq_feat::HasSeqFeatXref(const CSeqFeatXref::TId& id) const
+{
+    if (!IsSetXref()) {
+        return false;
+    }
+    ITERATE(CSeq_feat::TXref, xit, GetXref()) {
+        if ((*xit)->IsSetId() && (*xit)->GetId().Equals(id)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+
+bool CSeq_feat::AddSeqFeatXref(const CSeqFeatXref::TId& id)
+{
+    if (HasSeqFeatXref(id)) {
+        return false;
+    }
+    CRef<CSeqFeatXref> x1(new CSeqFeatXref());
+    x1->SetId().Assign(id);
+    SetXref().push_back(x1);
+    return true;
+}
+
+
 void CSeq_feat::AddQualifier(const string& qual_name, const string& qual_val)
 {
     CRef<CGb_qual> qual(new CGb_qual());
@@ -352,7 +378,7 @@ void CSeq_feat::RemoveExceptText(const string & exception_text)
     }
 
     list<CTempString> list_of_except_texts;
-    NStr::Split(GetExcept_text(), ",", list_of_except_texts);
+    NStr::Split(GetExcept_text(), ",", list_of_except_texts, NStr::fSplit_Tokenize);
 
     // remove occurrences of exception_text (case-insensitive)
     string new_except_texts; // build answer in this variable
@@ -414,8 +440,7 @@ CSeq_feat::GetTempExceptionTextSet(void) const
     const string & raw_exception_texts = GetExcept_text();
 
     vector<CTempStringEx> exception_parts;
-    NStr::Tokenize (raw_exception_texts, ",", exception_parts, 
-        NStr::eMergeDelims);
+    NStr::Split(raw_exception_texts, ",", exception_parts, NStr::fSplit_Tokenize);
 
     ITERATE( vector<CTempStringEx>, part_it, exception_parts ) {
         pAnswerSet->insert( NStr::TruncateSpaces_Unsafe(*part_it) );
diff --git a/c++/src/objects/seqfeat/SubSource.cpp b/c++/src/objects/seqfeat/SubSource.cpp
index cc59c0b..294980a 100644
--- a/c++/src/objects/seqfeat/SubSource.cpp
+++ b/c++/src/objects/seqfeat/SubSource.cpp
@@ -1,4 +1,4 @@
-/* $Id: SubSource.cpp 499841 2016-04-28 16:08:34Z ivanov $
+/* $Id: SubSource.cpp 520189 2016-11-23 16:34:24Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -93,6 +93,7 @@ CSubSource::TSubtype CSubSource::GetSubtypeValue(const string& str,
     string name = NStr::TruncateSpaces(str);
     NStr::ToLower(name);
     replace(name.begin(), name.end(), '_', '-');
+    replace(name.begin(), name.end(), ' ', '-');
 
     if ( NStr::EqualNocase(name, "note") ||
          NStr::EqualNocase(name, "subsource-note") ||
@@ -121,6 +122,7 @@ bool CSubSource::IsValidSubtypeName(const string& str,
     string name = NStr::TruncateSpaces(str);
     NStr::ToLower(name);
     replace(name.begin(), name.end(), '_', '-');
+    replace(name.begin(), name.end(), ' ', '-');
 
     if ( NStr::EqualNocase(name, "note") ||
          NStr::EqualNocase(name, "subsource-note") ||
@@ -348,7 +350,7 @@ bool CSubSource::IsCollectionDateAfterTime(const string& collection_date, time_t
     bad_format = false;
     bool in_future = false;
     vector<string> pieces;
-    NStr::Tokenize(collection_date, "/", pieces);
+    NStr::Split(collection_date, "/", pieces, NStr::fSplit_NoMergeDelims);
     if (pieces.size() > 2) {
         bad_format = true;
     } else {
@@ -401,7 +403,7 @@ void CSubSource::IsCorrectDateFormat(const string& date_string, bool& bad_format
     in_future = false;
 
     vector<string> pieces;
-    NStr::Tokenize(date_string, "/", pieces);
+    NStr::Split(date_string, "/", pieces, NStr::fSplit_NoMergeDelims);
     if (pieces.size() > 2) {
         bad_format = true;
         return;
@@ -450,14 +452,10 @@ size_t CSubSource::CheckDateFormat(const string& date_string)
 {
     size_t rval = eDateFormatFlag_ok;
     vector<string> pieces;
-    NStr::Tokenize(date_string, "/", pieces);
+    NStr::Split(date_string, "/", pieces, NStr::fSplit_NoMergeDelims);
     if (pieces.size() > 2) {
         rval |= eDateFormatFlag_bad_format;
     } else if (pieces.size() == 2) {
-        bool first_bad = false;
-        bool first_future = false;
-        bool second_bad = false;
-        bool second_future = false;
         rval |= CheckDateFormat(pieces[0]);
         rval |= CheckDateFormat(pieces[1]);
         if (rval == eDateFormatFlag_ok) {
@@ -506,9 +504,6 @@ size_t CSubSource::CheckDateFormat(const string& date_string)
 string CSubSource::GetCollectionDateProblem (const string& date_string)
 {
     string problem;
-    bool bad_format = false;
-    bool in_future = false;
-
     size_t rval = CheckDateFormat(date_string);
     if (rval & eDateFormatFlag_bad_format) {
         problem = "Collection_date format is not in DD-Mmm-YYYY format";
@@ -736,7 +731,6 @@ vector<string> CSubSource::x_GetDateTokens(const string& orig_date)
 {
     vector<string> tokens;
     string token_delimiters = " ,-/=_.";
-    size_t i;
 
     string cpy = orig_date;
     NStr::TruncateSpacesInPlace (cpy);
@@ -1148,9 +1142,9 @@ void CSubSource::IsCorrectLatLonFormat (string lat_lon, bool& format_correct, bo
             lon_value = 0.0 - ew;
         }
 
-    // make sure format is correct
+        // make sure format is correct
         vector<string> pieces;
-        NStr::Tokenize(lat_lon, " ", pieces);
+        NStr::Split(lat_lon, " ", pieces, NStr::fSplit_NoMergeDelims);
         if (pieces.size() > 3) {
             int precision_lat = x_GetPrecision(pieces[0]);
             int precision_lon = x_GetPrecision(pieces[2]);
@@ -1268,7 +1262,7 @@ static string s_GetNumFromLatLonToken (string token, const string& default_dir)
     bool last_is_sep = false;
 
     while (pos < token.length()) {
-        char ch = token[pos];
+        ch = token[pos];
         if (ch == ' ' || ch == ':' || ch == '-') {
             if (pos == prev_start) {
                 // too many separators
@@ -1314,12 +1308,18 @@ static string s_GetNumFromLatLonToken (string token, const string& default_dir)
                 pos++;
                 num_sep ++;
             } else {
-                if (num_sep > 1) {
-                    // already found minutes
+                if (num_sep == 1) {
+                    val += (this_val) / (60.0);
+                    prec += 2;
+                }
+                else if (num_sep == 2) {
+                    val += (this_val) / (3600.0);
+                    prec += 2;
+                }
+                else {
+                    // too many separators
                     return kEmptyStr;
                 }
-                val += (this_val) / (60.0);
-                prec += 2;
                 num_sep ++;
             }
             size_t p_pos = NStr::Find (num_str, ".");
@@ -1327,7 +1327,7 @@ static string s_GetNumFromLatLonToken (string token, const string& default_dir)
                 prec += num_str.substr(p_pos + 1).length();
             }
             pos++;
-            while (isspace((unsigned char)token[pos])) {
+            while (pos < token.size() && isspace((unsigned char)token[pos])) {
                 pos++;
             }
             prev_start = pos;
@@ -1574,6 +1574,7 @@ string CSubSource::FixLatLonFormat (string orig_lat_lon, bool guess)
     NStr::ReplaceInPlace (cpy, "WEST",      "W");
     NStr::ReplaceInPlace (cpy, " AND ",     " "); // treat AND like a space delimiter
     NStr::ReplaceInPlace (cpy, "_", " ");
+    NStr::ReplaceInPlace (cpy, "&", " ");
     NStr::ReplaceInPlace (cpy, "  ", " "); // double-spaces become single spaces
 
     size_t lat_pos = NStr::Find (cpy, "LAT");
@@ -1982,7 +1983,7 @@ string CSubSource::ValidateLatLonCountry (const string& input_countryname, strin
                                lat_value, lon_value);
     if (!format_correct) {
         // may have comma and then altitude, so just get lat_lon component */
-        size_t pos = NStr::Find(lat_lon, ",", 0, NPOS, NStr::eLast);
+        size_t pos = NStr::Find(lat_lon, ",", NStr::eNocase, NStr::eReverseSearch);
         if (pos != NPOS) {
             lat_lon = lat_lon.substr(0, pos);
             CSubSource::IsCorrectLatLonFormat (lat_lon, format_correct, precision_correct,
@@ -2052,7 +2053,6 @@ string CSubSource::ValidateLatLonCountry (const string& input_countryname, strin
     }
 
     CLatLonCountryId *id = x_CalculateLatLonId(lat_value, lon_value, country, province);
-
     CLatLonCountryId::TClassificationFlags flags = (id == NULL ? 0 : id->Classify(country, province));
 
     string wguess = id->GetGuessWater();
@@ -2333,7 +2333,7 @@ bool CSubSource::IsValidSexQualifierValue (const string& value)
     }
 
     vector<string> words;
-    NStr::Tokenize(str," ,/",words);
+    NStr::Split(str, " ,/", words, NStr::fSplit_NoMergeDelims);
     if (words.size() == 0) {
         return false;
     }
@@ -2371,7 +2371,7 @@ string CSubSource::FixSexQualifierValue (const string& value)
     }
 
     vector<string> words;
-    NStr::Tokenize(str," ,/",words);
+    NStr::Split(str, " ,/", words, NStr::fSplit_NoMergeDelims);
 
     if (words.size() == 0) {
         return kEmptyStr;
@@ -2557,7 +2557,7 @@ DEFINE_STATIC_FAST_MUTEX(s_CellLineContaminationMutex);
 static void s_ProcessCellLineLine(const CTempString& line)
 {
     vector<string> tokens;
-    NStr::Tokenize(line, "\t", tokens);
+    NStr::Split(line, "\t", tokens, NStr::fSplit_NoMergeDelims);
     if (tokens.size() < 4) {
         ERR_POST_X(1, Warning << "Not enough columns in cell_line entry " << line
                    << "; disregarding");
@@ -2684,7 +2684,6 @@ static const char* const s_Countries[] = {
     "Djibouti",
     "Dominica",
     "Dominican Republic",
-    "East Timor",
     "Ecuador",
     "Egypt",
     "El Salvador",
@@ -2867,6 +2866,7 @@ static const char* const s_Countries[] = {
     "Tanzania",
     "Tasman Sea",
     "Thailand",
+    "Timor-Leste",
     "Togo",
     "Tokelau",
     "Tonga",
@@ -2905,6 +2905,7 @@ static const char* const s_Former_Countries[] = {
     "British Guiana",
     "Burma",
     "Czechoslovakia",
+    "East Timor",
     "Korea",
     "Netherlands Antilles",
     "Serbia and Montenegro",
@@ -3388,10 +3389,10 @@ static const char* s_USAStates[] = {
 string CCountries::CapitalizeFirstLetterOfEveryWord (const string &phrase)
 {
     vector<string> words;
-    NStr::Tokenize(phrase," \t\r\n",words);
+    NStr::Split(phrase, " \t\r\n", words, NStr::fSplit_NoMergeDelims);
     for(vector<string>::iterator word = words.begin(); word != words.end(); ++word)
         if (!word->empty() && isalpha(word->at(0)))
-            word->at(0) = toupper(word->at(0));
+            word->at(0) = (unsigned char)toupper(word->at(0));
     return NStr::Join(words," ");
 }
 
@@ -3520,7 +3521,7 @@ void CCountries::x_RemoveDelimitersFromEnds(string& val, bool except_paren)
 vector<string> CCountries::x_Tokenize(const string& val)
 {
     vector<string> tokens;
-    NStr::Tokenize(val,",:()",tokens);
+    NStr::Split(val, ",:()", tokens, NStr::fSplit_NoMergeDelims);
     // special tokenizing - if tokens contain periods but resulting token is at least four characters long
     vector<string>::iterator it = tokens.begin();
     while (it != tokens.end()) {
@@ -3549,15 +3550,21 @@ vector<string> CCountries::x_Tokenize(const string& val)
 }
 
 
-bool s_ContainsWholeWord(const string& test, const string& word, NStr::ECase case_sense)
+bool s_ContainsWholeWord(const CTempString test, const CTempString word, NStr::ECase case_sense)
 {
-    size_t pos = NStr::Find(test, word, 0, NPOS, NStr::eFirst, case_sense);
+    size_t start = 0;
+    size_t tlen = test.length();
+    size_t wlen = word.length();
+
+    size_t pos = NStr::Find(test, word, case_sense);
     while (pos != NPOS) {
-        if ((pos == 0 || !isalpha((unsigned char)test[pos-1]))
-            && !isalpha((unsigned char)test[pos + word.length()])) {
+        size_t p = start + pos;
+        if ( (p == 0           || !isalpha((unsigned char)test[p - 1]))  && 
+             (p + wlen >= tlen || !isalpha((unsigned char)test[p + wlen])) ) {
             return true;
         }
-        pos = NStr::Find(test, word, pos + 1, NPOS, NStr::eFirst, case_sense);
+        start = p + 1;
+        pos = NStr::Find(CTempString(test, start, tlen - start), word, case_sense);
     }
     return false;
 }
@@ -4235,36 +4242,41 @@ void CSubSource::AutoFix()
    
 
 
+// NOTE (for two arrays below): If string A is a prefix of string B, string B should be placed
+// BEFORE string A. I.e. longer string should be earlier
 static const char * s_RemovableCultureNotes[] = {
- "[BankIt_uncultured16S_wizard]; [universal primers]; [tgge]",
- "[BankIt_uncultured16S_wizard]; [universal primers]; [dgge]",
- "[BankIt_uncultured16S_wizard]; [universal primers]",
- "[BankIt_cultured16S_wizard]",
- "[uncultured (using universal primers)]",
- "[uncultured (using universal primers) bacterial source]",
- "[cultured bacterial source]",
- "[enrichment culture bacterial source]",
- "[mixed bacterial source (cultured and uncultured)]",
- "[uncultured]; [universal primers]",
- "[mixed bacterial source]",
- "[virus wizard]",
- "[cDNA derived from mRNA, purified viral particles]",
- "[cDNA derived from mRNA, whole cell/tissue lysate]",
- "[cDNA derived from genomic RNA, whole cell/tissue lysate]",
- "[cDNA derived from genomic RNA, purified viral particles]",
- "[universal primers]",
- "[uncultured; wizard]",
- "[uncultured; wizard; spans unknown]",
- "[cultured; wizard]",
- "[cultured; wizard; spans unknown]",
- "[intergenic wizard]",
- "[intergenic wizard; spans unknown]",
- "[Microsatellite wizard]",
- "[Microsatellite wizard; multiple repeats]",
- "[D-loop wizard]",
- "[D-loop wizard; spans unknown]",
- "[D-loop wizard; spans known]",
- NULL
+    "[BankIt_uncultured16S_wizard]; [universal primers]; [tgge]",
+    "[BankIt_uncultured16S_wizard]; [universal primers]; [dgge]",
+    "[BankIt_uncultured16S_wizard]; [universal primers]",
+    "[BankIt_cultured16S_wizard]",
+    "[BankIt_organellerRNA_wizard]",
+    "[BankIt_ITS_wizard]; [rRNAITS_notfound]",
+    "[BankIt_ITS_wizard]",
+    "[uncultured (using universal primers)]",
+    "[uncultured (using universal primers) bacterial source]",
+    "[cultured bacterial source]",
+    "[enrichment culture bacterial source]",
+    "[mixed bacterial source (cultured and uncultured)]",
+    "[uncultured]; [universal primers]",
+    "[mixed bacterial source]",
+    "[virus wizard]",
+    "[cDNA derived from mRNA, purified viral particles]",
+    "[cDNA derived from mRNA, whole cell/tissue lysate]",
+    "[cDNA derived from genomic RNA, whole cell/tissue lysate]",
+    "[cDNA derived from genomic RNA, purified viral particles]",
+    "[universal primers]",
+    "[uncultured; wizard]",
+    "[uncultured; wizard; spans unknown]",
+    "[cultured; wizard]",
+    "[cultured; wizard; spans unknown]",
+    "[intergenic wizard]",
+    "[intergenic wizard; spans unknown]",
+    "[Microsatellite wizard]",
+    "[Microsatellite wizard; multiple repeats]",
+    "[D-loop wizard]",
+    "[D-loop wizard; spans unknown]",
+    "[D-loop wizard; spans known]",
+    NULL
 };
 
 static const char * s_ReplaceableCultureNotes[] = {
@@ -4278,6 +4290,24 @@ static const char * s_ReplaceableCultureNotes[] = {
  NULL
 };
 
+
+bool CSubSource::HasCultureNotes(const string& value)
+{
+    for (size_t i = 0; s_RemovableCultureNotes[i] != NULL; i++) {
+        size_t pos = NStr::FindNoCase(value, s_RemovableCultureNotes[i]);
+        if (pos != string::npos) {
+            return true;
+        }
+    }
+    for (size_t i = 0; s_ReplaceableCultureNotes[i] != NULL; i++) {
+        if (NStr::EqualNocase(value, s_ReplaceableCultureNotes[i])) {
+            return true;
+        }
+    }
+    return false;
+}
+
+
 void CSubSource::RemoveCultureNotes (string& value, bool is_species_level)
 {
     if (NStr::IsBlank(value)) {
@@ -4612,10 +4642,10 @@ CLatLonCountryId::~CLatLonCountryId(void)
 
 
 #include "lat_lon_country.inc"
-static const int k_NumLatLonCountryText = ArraySize(s_DefaultLatLonCountryText);
+static const size_t k_NumLatLonCountryText = ArraySize(s_DefaultLatLonCountryText);
 
 #include "lat_lon_water.inc"
-static const int k_NumLatLonWaterText = ArraySize(s_DefaultLatLonWaterText);
+static const size_t k_NumLatLonWaterText = ArraySize(s_DefaultLatLonWaterText);
 
 void CLatLonCountryMap::x_InitFromDefaultList(const char * const *list, int num)
 {
@@ -4634,7 +4664,7 @@ void CLatLonCountryMap::x_InitFromDefaultList(const char * const *list, int num)
             m_Scale = NStr::StringToDouble(line);
         } else {          
             vector<string> tokens;
-             NStr::Tokenize(line, "\t", tokens);
+             NStr::Split(line, "\t", tokens, NStr::fSplit_NoMergeDelims);
             if (tokens.size() > 3) {
                 double x = NStr::StringToDouble(tokens[1]);
                 for (size_t j = 2; j < tokens.size() - 1; j+=2) {
diff --git a/c++/src/objects/seqfeat/Trna_ext.cpp b/c++/src/objects/seqfeat/Trna_ext.cpp
index 254bb8d..7c130da 100644
--- a/c++/src/objects/seqfeat/Trna_ext.cpp
+++ b/c++/src/objects/seqfeat/Trna_ext.cpp
@@ -1,4 +1,4 @@
-/* $Id: Trna_ext.cpp 500112 2016-05-02 15:52:06Z ivanov $
+/* $Id: Trna_ext.cpp 514371 2016-09-21 15:22:54Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -76,8 +76,8 @@ bool CTrna_ext::ParseDegenerateCodon(CTrna_ext & tRNA, const string & codon)
         return false;
     }
 
-    int idx = intToChr.find(codon[2]);
-    if (idx == (int)string::npos) return false;
+    size_t idx = intToChr.find(codon[2]);
+    if (idx == string::npos) return false;
 
     const char *expanded_codon_letter = codonLetterExpand[idx];
     const char *iter = expanded_codon_letter;
diff --git a/c++/src/objects/seqfeat/Variation_ref.cpp b/c++/src/objects/seqfeat/Variation_ref.cpp
index 289d090..7ee67a1 100644
--- a/c++/src/objects/seqfeat/Variation_ref.cpp
+++ b/c++/src/objects/seqfeat/Variation_ref.cpp
@@ -1,4 +1,4 @@
-/* $Id: Variation_ref.cpp 450796 2014-10-30 16:55:03Z vasilche $
+/* $Id: Variation_ref.cpp 514371 2016-09-21 15:22:54Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -629,7 +629,7 @@ const CVariation_ref::TPub& CVariation_ref::GetPub(void) const
 }
 
 
-void CVariation_ref::SetPub(TPub& value)
+void CVariation_ref::SetPub(TPub& /*value*/)
 {
     NCBI_THROW(CException, eUnknown,
                "CVariation_ref::SetPub(): "
@@ -645,6 +645,103 @@ CVariation_ref::TPub& CVariation_ref::SetPub(void)
 }
 
 
+void CVariation_ref::SetSNV(const CSeq_data& nucleotide,
+                            const CRef<CDelta_item> offset) 
+{
+    auto& inst = SetData().SetInstance();
+    inst.SetType(CVariation_inst::eType_snv);
+    inst.SetDelta().clear();
+
+    if (offset.NotNull()) {
+        inst.SetDelta().push_back(offset);
+    }
+
+    auto delta_item = Ref(new CDelta_item());
+    auto& seq_literal = delta_item->SetSeq().SetLiteral();
+    seq_literal.SetSeq_data().Assign(nucleotide);
+    seq_literal.SetLength(1);
+    inst.SetDelta().push_back(delta_item);
+}
+
+
+void CVariation_ref::SetMNP(const CSeq_data& nucleotide,
+                            const TSeqPos length,
+                            const CRef<CDelta_item> offset)
+{
+    auto& inst = SetData().SetInstance();
+    inst.SetType(CVariation_inst::eType_mnp);
+    inst.SetDelta().clear();
+
+    if (offset.NotNull()) {
+        inst.SetDelta().push_back(offset);
+     }
+            
+     auto delta_item = Ref(new CDelta_item());
+     auto& seq_literal = delta_item->SetSeq().SetLiteral();
+     seq_literal.SetSeq_data().Assign(nucleotide);
+     seq_literal.SetLength(length);
+     inst.SetDelta().push_back(delta_item);
+}
+
+
+void CVariation_ref::SetMissense(const CSeq_data& amino_acid) 
+{
+    auto& inst = SetData().SetInstance();
+    inst.SetType(CVariation_inst::eType_prot_missense);
+    inst.SetDelta().clear();
+    auto delta_item = Ref(new CDelta_item());
+    delta_item->SetSeq().SetLiteral().SetSeq_data().Assign(amino_acid);
+    delta_item->SetSeq().SetLiteral().SetLength() = 1;
+    inst.SetDelta().push_back(delta_item);
+}
+
+
+
+void CVariation_ref::SetDuplication(const CRef<CDelta_item> start_offset,
+                                    const CRef<CDelta_item> stop_offset) 
+{
+    auto& inst = SetData().SetInstance();
+    inst.SetType(CVariation_inst::eType_ins);
+    inst.SetDelta().clear();
+    if (start_offset.NotNull()) {
+        inst.SetDelta().push_back(start_offset);
+    }
+    
+    auto delta_item = Ref(new CDelta_item());
+    delta_item->SetDuplication();
+    inst.SetDelta().push_back(delta_item);
+    if (stop_offset.NotNull()) {
+        inst.SetDelta().push_back(stop_offset);
+    }
+}
+
+
+
+void CVariation_ref::SetIdentity(CRef<CSeq_literal> seq_literal,
+                                 const CRef<CDelta_item> start_offset,
+                                 const CRef<CDelta_item> stop_offset)  
+{
+    auto& inst = SetData().SetInstance();
+    inst.SetType(CVariation_inst::eType_identity);
+    if (seq_literal->IsSetSeq_data()) {
+        inst.SetObservation(CVariation_inst::eObservation_asserted);
+    }
+    inst.SetDelta().clear();
+    
+    if (start_offset.NotNull()) {
+        inst.SetDelta().push_back(start_offset);
+    }
+    
+    auto delta_item = Ref(new CDelta_item());
+    delta_item->SetSeq().SetLiteral(*seq_literal);
+    inst.SetDelta().push_back(delta_item);
+    
+    if (stop_offset.NotNull()) {
+        inst.SetDelta().push_back(stop_offset);
+    }
+}
+
+
 //////////////////////////////////////////////////////////////////////////////
 
 bool CVariation_ref::IsSetLocation(void) const
@@ -884,6 +981,8 @@ void CVariation_ref::SetMNP(const vector<string>& replaces,
                   CVariation_inst::eType_mnp);
 }
 
+
+
 bool CVariation_ref::IsMNP() const
 {
     return GetData().IsInstance()  &&
diff --git a/c++/src/objects/seqfeat/ecnum_deleted.inc b/c++/src/objects/seqfeat/ecnum_deleted.inc
index f8373c4..d0c7931 100644
--- a/c++/src/objects/seqfeat/ecnum_deleted.inc
+++ b/c++/src/objects/seqfeat/ecnum_deleted.inc
@@ -1,4 +1,4 @@
-/*  $Id: ecnum_deleted.inc 493886 2016-03-02 14:19:14Z ivanov $
+/*  $Id: ecnum_deleted.inc 492647 2016-02-18 22:32:30Z kans $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objects/seqfeat/ecnum_replaced.inc b/c++/src/objects/seqfeat/ecnum_replaced.inc
index 0256c15..8caa3c2 100644
--- a/c++/src/objects/seqfeat/ecnum_replaced.inc
+++ b/c++/src/objects/seqfeat/ecnum_replaced.inc
@@ -1,4 +1,4 @@
-/*  $Id: ecnum_replaced.inc 493886 2016-03-02 14:19:14Z ivanov $
+/*  $Id: ecnum_replaced.inc 502608 2016-05-25 20:34:40Z kans $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -109,6 +109,7 @@ static const char* const kECNum_replaced[] = {
     "1.3.1.50	1.1.1.252",
     "1.3.1.52	1.3.8.5",
     "1.3.1.63	1.21.1.2",
+    "1.3.1.80	1.3.7.12",
     "1.3.1.n1	1.3.1.87",
     "1.3.2.1	1.3.8.1",
     "1.3.2.2	1.3.8.7",
@@ -237,7 +238,7 @@ static const char* const kECNum_replaced[] = {
     "1.13.1.11	1.13.99.1",
     "1.13.1.12	1.13.11.11",
     "1.13.1.13	1.13.11.12",
-    "1.13.11.21	1.14.99.36",
+    "1.13.11.21	1.13.11.63",
     "1.13.11.32	1.13.12.16",
     "1.13.11.44	1.13.11.60	5.4.4.6",
     "1.13.11.n1	1.13.11.74",
@@ -264,21 +265,28 @@ static const char* const kECNum_replaced[] = {
     "1.14.11.n1	1.14.11.39",
     "1.14.12.2	1.14.13.35",
     "1.14.12.6	1.14.13.66",
+    "1.14.12.20	1.14.15.17",
     "1.14.12.21	1.14.13.208",
     "1.14.12.n1	1.14.13.208",
     "1.14.13.3	1.14.14.9",
+    "1.14.13.15	1.14.15.15",
+    "1.14.13.17	1.14.14.23",
     "1.14.13.26	1.14.18.4",
     "1.14.13.45	1.14.18.2",
     "1.14.13.60	1.14.13.100",
     "1.14.13.86	1.14.13.136",
     "1.14.13.95	1.14.18.8",
+    "1.14.13.98	1.14.14.25",
+    "1.14.13.99	1.14.14.26",
+    "1.14.13.126	1.14.15.16",
     "1.14.13.132	1.14.14.17",
+    "1.14.13.159	1.14.14.24",
     "1.14.13.164	1.13.11.65",
     "1.14.13.169	1.14.18.5",
     "1.14.13.n1	1.14.13.124",
     "1.14.13.n2	1.14.13.125",
     "1.14.13.n3	1.14.13.127",
-    "1.14.13.n4	1.14.13.126",
+    "1.14.13.n4	1.14.15.16",
     "1.14.13.n9	1.14.13.149",
     "1.14.14.2	1.14.14.1",
     "1.14.14.4	1.14.15.7",
@@ -315,6 +323,7 @@ static const char* const kECNum_replaced[] = {
     "1.14.99.n3	1.14.99.42",
     "1.14.99.n5	1.13.11.70",
     "1.16.98.1	1.16.9.1",
+    "1.17.1.2	1.17.7.4",
     "1.17.1.6	1.17.98.1",
     "1.17.1.7	1.2.1.91",
     "1.17.4.3	1.17.7.1",
@@ -324,6 +333,7 @@ static const char* const kECNum_replaced[] = {
     "1.18.96.1	1.15.1.2",
     "1.18.99.1	1.12.7.2",
     "1.20.98.1	1.20.9.1",
+    "1.21.3.9	1.21.98.2",
     "1.21.99.2	1.21.98.1",
     "1.22.1.1	1.21.1.1",
     "1.97.1.3	1.12.98.4",
@@ -451,6 +461,7 @@ static const char* const kECNum_replaced[] = {
     "2.6.99.4	2.3.1.234",
     "2.7.1.37	2.7.11.1	2.7.11.8	2.7.11.9	2.7.11.10	2.7.11.11	2.7.11.12	2.7.11.13	2.7.11.21	2.7.11.22	2.7.11.24	2.7.11.25	2.7.11.30	2.7.12.1",
     "2.7.1.38	2.7.11.19",
+    "2.7.1.69	2.7.1.191",
     "2.7.1.70	2.7.11.1",
     "2.7.1.75	2.7.1.21",
     "2.7.1.96	2.7.1.86",
@@ -509,6 +520,7 @@ static const char* const kECNum_replaced[] = {
     "2.7.7.29	2.7.7.28",
     "2.7.7.54	6.3.2.40",
     "2.7.7.55	6.3.2.40",
+    "2.7.7.63	6.3.1.20",
     "2.7.7.n2	2.7.7.67",
     "2.7.7.n3	2.7.7.73",
     "2.7.7.n4	2.7.7.80",
@@ -911,7 +923,7 @@ static const char* const kECNum_replaced[] = {
     "4.3.1.5	4.3.1.23	4.3.1.24	4.3.1.25",
     "4.3.1.8	2.5.1.61",
     "4.3.1.21	4.3.1.9",
-    "4.3.1.26	1.21.3.9",
+    "4.3.1.26	1.21.98.2",
     "4.3.3.n1	4.1.99.20",
     "4.3.99.1	4.2.1.104",
     "4.4.1.7	2.5.1.18",
diff --git a/c++/src/objects/seqfeat/ecnum_replaced.txt b/c++/src/objects/seqfeat/ecnum_replaced.txt
index 920a25b..cc01d7d 100644
--- a/c++/src/objects/seqfeat/ecnum_replaced.txt
+++ b/c++/src/objects/seqfeat/ecnum_replaced.txt
@@ -76,6 +76,7 @@
 1.3.1.50	1.1.1.252
 1.3.1.52	1.3.8.5
 1.3.1.63	1.21.1.2
+1.3.1.80	1.3.7.12
 1.3.1.n1	1.3.1.87
 1.3.2.1	1.3.8.1
 1.3.2.2	1.3.8.7
@@ -204,7 +205,7 @@
 1.13.1.11	1.13.99.1
 1.13.1.12	1.13.11.11
 1.13.1.13	1.13.11.12
-1.13.11.21	1.14.99.36
+1.13.11.21	1.13.11.63
 1.13.11.32	1.13.12.16
 1.13.11.44	1.13.11.60	5.4.4.6
 1.13.11.n1	1.13.11.74
@@ -231,21 +232,28 @@
 1.14.11.n1	1.14.11.39
 1.14.12.2	1.14.13.35
 1.14.12.6	1.14.13.66
+1.14.12.20	1.14.15.17
 1.14.12.21	1.14.13.208
 1.14.12.n1	1.14.13.208
 1.14.13.3	1.14.14.9
+1.14.13.15	1.14.15.15
+1.14.13.17	1.14.14.23
 1.14.13.26	1.14.18.4
 1.14.13.45	1.14.18.2
 1.14.13.60	1.14.13.100
 1.14.13.86	1.14.13.136
 1.14.13.95	1.14.18.8
+1.14.13.98	1.14.14.25
+1.14.13.99	1.14.14.26
+1.14.13.126	1.14.15.16
 1.14.13.132	1.14.14.17
+1.14.13.159	1.14.14.24
 1.14.13.164	1.13.11.65
 1.14.13.169	1.14.18.5
 1.14.13.n1	1.14.13.124
 1.14.13.n2	1.14.13.125
 1.14.13.n3	1.14.13.127
-1.14.13.n4	1.14.13.126
+1.14.13.n4	1.14.15.16
 1.14.13.n9	1.14.13.149
 1.14.14.2	1.14.14.1
 1.14.14.4	1.14.15.7
@@ -282,6 +290,7 @@
 1.14.99.n3	1.14.99.42
 1.14.99.n5	1.13.11.70
 1.16.98.1	1.16.9.1
+1.17.1.2	1.17.7.4
 1.17.1.6	1.17.98.1
 1.17.1.7	1.2.1.91
 1.17.4.3	1.17.7.1
@@ -291,6 +300,7 @@
 1.18.96.1	1.15.1.2
 1.18.99.1	1.12.7.2
 1.20.98.1	1.20.9.1
+1.21.3.9	1.21.98.2
 1.21.99.2	1.21.98.1
 1.22.1.1	1.21.1.1
 1.97.1.3	1.12.98.4
@@ -418,6 +428,7 @@
 2.6.99.4	2.3.1.234
 2.7.1.37	2.7.11.1	2.7.11.8	2.7.11.9	2.7.11.10	2.7.11.11	2.7.11.12	2.7.11.13	2.7.11.21	2.7.11.22	2.7.11.24	2.7.11.25	2.7.11.30	2.7.12.1
 2.7.1.38	2.7.11.19
+2.7.1.69	2.7.1.191
 2.7.1.70	2.7.11.1
 2.7.1.75	2.7.1.21
 2.7.1.96	2.7.1.86
@@ -476,6 +487,7 @@
 2.7.7.29	2.7.7.28
 2.7.7.54	6.3.2.40
 2.7.7.55	6.3.2.40
+2.7.7.63	6.3.1.20
 2.7.7.n2	2.7.7.67
 2.7.7.n3	2.7.7.73
 2.7.7.n4	2.7.7.80
@@ -878,7 +890,7 @@
 4.3.1.5	4.3.1.23	4.3.1.24	4.3.1.25
 4.3.1.8	2.5.1.61
 4.3.1.21	4.3.1.9
-4.3.1.26	1.21.3.9
+4.3.1.26	1.21.98.2
 4.3.3.n1	4.1.99.20
 4.3.99.1	4.2.1.104
 4.4.1.7	2.5.1.18
diff --git a/c++/src/objects/seqfeat/ecnum_specific.inc b/c++/src/objects/seqfeat/ecnum_specific.inc
index 6cc5dc3..074a3cd 100644
--- a/c++/src/objects/seqfeat/ecnum_specific.inc
+++ b/c++/src/objects/seqfeat/ecnum_specific.inc
@@ -1,4 +1,4 @@
-/*  $Id: ecnum_specific.inc 493886 2016-03-02 14:19:14Z ivanov $
+/*  $Id: ecnum_specific.inc 514388 2016-09-21 15:37:12Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -81,7 +81,7 @@ static const char* const kECNum_specific[] = {
     "1.1.1.49	Glucose-6-phosphate dehydrogenase (NADP(+))",
     "1.1.1.50	3-alpha-hydroxysteroid 3-dehydrogenase (Si-specific)",
     "1.1.1.51	3(or 17)-beta-hydroxysteroid dehydrogenase",
-    "1.1.1.52	3-alpha-hydroxycholanate dehydrogenase (NAD(+) )",
+    "1.1.1.52	3-alpha-hydroxycholanate dehydrogenase (NAD(+))",
     "1.1.1.53	3-alpha(or 20-beta)-hydroxysteroid dehydrogenase",
     "1.1.1.54	Allyl-alcohol dehydrogenase",
     "1.1.1.55	Lactaldehyde reductase (NADPH)",
@@ -400,6 +400,10 @@ static const char* const kECNum_specific[] = {
     "1.1.1.388	Glucose-6-phosphate dehydrogenase (NAD(+))",
     "1.1.1.389	2-dehydro-3-deoxy-L-galactonate 5-dehydrogenase",
     "1.1.1.390	Sulfoquinovose 1-dehydrogenase",
+    "1.1.1.391	3-beta-hydroxycholanate 3-dehydrogenase (NAD(+))",
+    "1.1.1.392	3-alpha-hydroxycholanate dehydrogenase (NADP(+))",
+    "1.1.1.393	3-beta-hydroxycholanate 3-dehydrogenase (NADP(+))",
+    "1.1.1.394	Aurachin B dehydrogenase",
     "1.1.1.n4	(-)-trans-carveol dehydrogenase",
     "1.1.1.n5	3-methylmalate dehydrogenase",
     "1.1.1.n11	Succinic semialdehyde reductase",
@@ -595,9 +599,10 @@ static const char* const kECNum_specific[] = {
     "1.2.4.4	3-methyl-2-oxobutanoate dehydrogenase (2-methylpropanoyl-transferring)",
     "1.2.5.1	Pyruvate dehydrogenase (quinone)",
     "1.2.5.2	Aldehyde dehydrogenase (quinone)",
+    "1.2.5.3	Aerobic carbon monoxide dehydrogenase",
     "1.2.7.1	Pyruvate synthase",
     "1.2.7.3	2-oxoglutarate synthase",
-    "1.2.7.4	Carbon-monoxide dehydrogenase (ferredoxin)",
+    "1.2.7.4	Anaerobic carbon-monoxide dehydrogenase",
     "1.2.7.5	Aldehyde ferredoxin oxidoreductase",
     "1.2.7.6	Glyceraldehyde-3-phosphate dehydrogenase (ferredoxin)",
     "1.2.7.7	3-methyl-2-oxobutanoate dehydrogenase (ferredoxin)",
@@ -679,7 +684,6 @@ static const char* const kECNum_specific[] = {
     "1.3.1.77	Anthocyanidin reductase",
     "1.3.1.78	Arogenate dehydrogenase (NADP(+))",
     "1.3.1.79	Arogenate dehydrogenase (NAD(P)(+))",
-    "1.3.1.80	Red chlorophyll catabolite reductase",
     "1.3.1.81	(+)-pulegone reductase",
     "1.3.1.82	(-)-isopiperitenone reductase",
     "1.3.1.83	Geranylgeranyl diphosphate reductase",
@@ -710,6 +714,7 @@ static const char* const kECNum_specific[] = {
     "1.3.1.108	Caffeoyl-CoA reductase",
     "1.3.1.109	Butanoyl-CoA dehydrogenase (NAD(+),ferredoxin)",
     "1.3.1.110	Lactate dehydrogenase (NAD(+),ferredoxin)",
+    "1.3.1.111	Geranylgeranyl-bacteriochlorophyllide a reductase",
     "1.3.1.n2	Camalexin synthase",
     "1.3.1.n3	Curcumin reductase",
     "1.3.2.3	L-galactonolactone dehydrogenase",
@@ -742,6 +747,7 @@ static const char* const kECNum_specific[] = {
     "1.3.7.8	Benzoyl-CoA reductase",
     "1.3.7.9	4-hydroxybenzoyl-CoA reductase",
     "1.3.7.11	2,3-bis-O-geranylgeranyl-sn-glycero-phospholipid reductase",
+    "1.3.7.12	Red chlorophyll catabolite reductase",
     "1.3.8.1	Short-chain acyl-CoA dehydrogenase",
     "1.3.8.2	4,4'-diapophytoene desaturase (4,4'-diapolycopene-forming)",
     "1.3.8.3	(R)-benzylsuccinyl-CoA dehydrogenase",
@@ -1231,6 +1237,7 @@ static const char* const kECNum_specific[] = {
     "1.14.11.47	50S ribosomal protein L16 3-hydroxylase",
     "1.14.11.48	Xanthine dioxygenase",
     "1.14.11.49	Uridine-5'-phosphate dioxygenase",
+    "1.14.11.50	(-)-deoxypodophyllotoxin synthase",
     "1.14.11.n2	Methylcytosine dioxygenase",
     "1.14.11.n3	L-proline cis-4-hydroxylase",
     "1.14.11.n4	Ankyrin-repeat-histidine dioxagenase",
@@ -1251,7 +1258,6 @@ static const char* const kECNum_specific[] = {
     "1.14.12.17	Nitric oxide dioxygenase",
     "1.14.12.18	Biphenyl 2,3-dioxygenase",
     "1.14.12.19	3-phenylpropanoate dioxygenase",
-    "1.14.12.20	Pheophorbide a oxygenase",
     "1.14.12.22	Carbazole 1,9a-dioxygenase",
     "1.14.12.23	Nitroarene dioxygenase",
     "1.14.12.24	2,4-dinitrotoluene dioxygenase",
@@ -1260,7 +1266,7 @@ static const char* const kECNum_specific[] = {
     "1.14.13.4	Melilotate 3-monooxygenase",
     "1.14.13.5	Imidazoleacetate 4-monooxygenase",
     "1.14.13.6	Orcinol 2-monooxygenase",
-    "1.14.13.7	Phenol 2-monooxygenase",
+    "1.14.13.7	Phenol 2-monooxygenase (NADPH)",
     "1.14.13.8	Flavin-containing monooxygenase",
     "1.14.13.9	Kynurenine 3-monooxygenase",
     "1.14.13.10	2,6-dihydroxypyridine 3-monooxygenase",
@@ -1268,9 +1274,7 @@ static const char* const kECNum_specific[] = {
     "1.14.13.12	Benzoate 4-monooxygenase",
     "1.14.13.13	Calcidiol 1-monooxygenase",
     "1.14.13.14	Trans-cinnamate 2-monooxygenase",
-    "1.14.13.15	Cholestanetriol 26-monooxygenase",
     "1.14.13.16	Cyclopentanone monooxygenase",
-    "1.14.13.17	Cholesterol 7-alpha-monooxygenase",
     "1.14.13.18	4-hydroxyphenylacetate 1-monooxygenase",
     "1.14.13.19	Taxifolin 8-monooxygenase",
     "1.14.13.20	2,4-dichlorophenol 6-monooxygenase",
@@ -1344,8 +1348,6 @@ static const char* const kECNum_specific[] = {
     "1.14.13.94	Lithocholate 6-beta-hydroxylase",
     "1.14.13.96	5-beta-cholestane-3-alpha,7-alpha-diol 12-alpha-hydroxylase",
     "1.14.13.97	Taurochenodeoxycholate 6-alpha-hydroxylase",
-    "1.14.13.98	Cholesterol 24-hydroxylase",
-    "1.14.13.99	24-hydroxycholesterol 7-alpha-hydroxylase",
     "1.14.13.100	25/26-hydroxycholesterol 7-alpha-hydroxylase",
     "1.14.13.101	Senecionine N-oxygenase",
     "1.14.13.102	Psoralen synthase",
@@ -1372,7 +1374,6 @@ static const char* const kECNum_specific[] = {
     "1.14.13.123	Germacrene A hydroxylase",
     "1.14.13.124	Phenylalanine N-monooxygenase",
     "1.14.13.125	Tryptophan N-monooxygenase",
-    "1.14.13.126	Vitamin D(3) 24-hydroxylase",
     "1.14.13.127	3-(3-hydroxy-phenyl)propanoic acid hydroxylase",
     "1.14.13.128	7-methylxanthine demethylase",
     "1.14.13.129	Beta-carotene 3-hydroxylase",
@@ -1404,7 +1405,6 @@ static const char* const kECNum_specific[] = {
     "1.14.13.156	1,8-cineole 2-endo-monooxygenase",
     "1.14.13.157	1,8-cineole 2-exo-monooxygenase",
     "1.14.13.158	Amorpha-4,11-diene 12 monooxygenase",
-    "1.14.13.159	Vitamin D 25-hydroxylase",
     "1.14.13.160	(2,2,3-trimethyl-5-oxocyclopent-3-enyl)acetyl-CoA 1,5-monooxygenase",
     "1.14.13.161	(+)-camphor 6-exo-hydroxylase",
     "1.14.13.162	2,5-diketocamphane 1,2-monooxygenase",
@@ -1453,6 +1453,14 @@ static const char* const kECNum_specific[] = {
     "1.14.13.207	Ipsdienol synthase",
     "1.14.13.208	Benzoyl-CoA 2,3-epoxidase",
     "1.14.13.209	Salicyloyl-CoA 5-hydroxylase",
+    "1.14.13.210	4-methyl-5-nitrocatechol 5-monooxygenase",
+    "1.14.13.211	Rifampicin monooxygenase",
+    "1.14.13.212	1,3,7-trimethyluric acid 5-monooxygenase",
+    "1.14.13.213	Bursehernin 5'-monooxygenase",
+    "1.14.13.214	(-)-4'-demethyl-deoxypodophyllotoxin 4-hydroxylase",
+    "1.14.13.215	Protoasukamycin 4-monooxygenase",
+    "1.14.13.216	Asperlicin C monooxygenase",
+    "1.14.13.217	Protodeoxyviolaceinate monooxygenase",
     "1.14.13.n5	Dihomomethionine N-hydroxylase",
     "1.14.13.n6	Hexahomomethionine N-hydroxylase",
     "1.14.13.n7	4-nitrophenol 2-hydroxylase",
@@ -1472,6 +1480,13 @@ static const char* const kECNum_specific[] = {
     "1.14.14.17	Squalene monooxygenase",
     "1.14.14.18	Heme oxygenase (biliverdin-producing)",
     "1.14.14.19	Steroid 17-alpha-monooxygenase",
+    "1.14.14.20	Phenol 2-monooxygenase (FADH(2))",
+    "1.14.14.21	Dibenzothiophene monooxygenase",
+    "1.14.14.22	Dibenzothiophene sulfone monooxygenase",
+    "1.14.14.23	Cholesterol 7-alpha-monooxygenase",
+    "1.14.14.24	Vitamin D 25-hydroxylase",
+    "1.14.14.25	Cholesterol 24-hydroxylase",
+    "1.14.14.26	24-hydroxycholesterol 7-alpha-hydroxylase",
     "1.14.15.1	Camphor 5-monooxygenase",
     "1.14.15.3	Alkane 1-monooxygenase",
     "1.14.15.4	Steroid 11-beta-monooxygenase",
@@ -1485,6 +1500,9 @@ static const char* const kECNum_specific[] = {
     "1.14.15.12	Pimeloyl-[acyl-carrier protein] synthase",
     "1.14.15.13	Pulcherriminic acid synthase",
     "1.14.15.14	Methyl-branched lipid omega-hydroxylase",
+    "1.14.15.15	Cholestanetriol 26-monooxygenase",
+    "1.14.15.16	Vitamin D(3) 24-hydroxylase",
+    "1.14.15.17	Pheophorbide a oxygenase",
     "1.14.16.1	Phenylalanine 4-monooxygenase",
     "1.14.16.2	Tyrosine 3-monooxygenase",
     "1.14.16.3	Anthranilate 3-monooxygenase",
@@ -1563,6 +1581,7 @@ static const char* const kECNum_specific[] = {
     "1.14.21.8	Pseudobaptigenin synthase",
     "1.14.21.9	Mycocyclosin synthase",
     "1.14.21.10	Fumitremorgin C synthase",
+    "1.14.21.11	(-)-pluviatolide synthase",
     "1.14.99.1	Prostaglandin-endoperoxide synthase",
     "1.14.99.2	Kynurenine 7,8-hydroxylase",
     "1.14.99.4	Progesterone monooxygenase",
@@ -1615,7 +1634,6 @@ static const char* const kECNum_specific[] = {
     "1.16.8.1	Cob(II)yrinic acid a,c-diamide reductase",
     "1.16.9.1	Iron:rusticyanin reductase",
     "1.17.1.1	CDP-4-dehydro-6-deoxyglucose reductase",
-    "1.17.1.2	4-hydroxy-3-methylbut-2-enyl diphosphate reductase",
     "1.17.1.3	Leucoanthocyanidin reductase",
     "1.17.1.4	Xanthine dehydrogenase",
     "1.17.1.5	Nicotinate dehydrogenase",
@@ -1634,6 +1652,7 @@ static const char* const kECNum_specific[] = {
     "1.17.7.1	(E)-4-hydroxy-3-methylbut-2-enyl-diphosphate synthase (ferredoxin)",
     "1.17.7.2	7-hydroxymethyl chlorophyll a reductase",
     "1.17.7.3	(E)-4-hydroxy-3-methylbut-2-enyl-diphosphate synthase (flavodoxin)",
+    "1.17.7.4	4-hydroxy-3-methylbut-2-enyl diphosphate reductase",
     "1.17.98.1	Bile-acid 7-alpha-dehydroxylase",
     "1.17.99.1	4-methylphenol dehydrogenase (hydroxylating)",
     "1.17.99.2	Ethylbenzene hydroxylase",
@@ -1668,12 +1687,12 @@ static const char* const kECNum_specific[] = {
     "1.21.3.6	Aureusidin synthase",
     "1.21.3.7	Tetrahydrocannabinolic acid synthase",
     "1.21.3.8	Cannabidiolic acid synthase",
-    "1.21.3.9	Dichlorochromopyrrolate synthase",
     "1.21.4.1	D-proline reductase (dithiol)",
     "1.21.4.2	Glycine reductase",
     "1.21.4.3	Sarcosine reductase",
     "1.21.4.4	Betaine reductase",
     "1.21.98.1	Cyclic dehypoxanthinyl futalosine synthase",
+    "1.21.98.2	Dichlorochromopyrrolate synthase",
     "1.21.99.1	Beta-cyclopiazonate dehydrogenase",
     "1.21.99.3	Thyroxine 5-deiodinase",
     "1.21.99.4	Thyroxine 5'-deiodinase",
@@ -1986,6 +2005,8 @@ static const char* const kECNum_specific[] = {
     "2.1.1.320	Type II protein arginine methyltransferase",
     "2.1.1.321	Type III protein arginine methyltransferase",
     "2.1.1.322	Type IV protein arginine methyltransferase",
+    "2.1.1.323	(-)-pluviatolide 4-O-methyltransferase",
+    "2.1.1.324	dTDP-4-amino-2,3,4,6-tetradeoxy-D-glucose N,N-dimethyltransferase",
     "2.1.1.n1	Resorcinol O-methyltransferase",
     "2.1.1.n4	Thiocyanate methyltransferase",
     "2.1.1.n7	5-pentadecatrienyl resorcinol O-methyltransferase",
@@ -2617,7 +2638,7 @@ static const char* const kECNum_specific[] = {
     "2.4.1.319	Beta-1,4-mannooligosaccharide phosphorylase",
     "2.4.1.320	1,4-beta-mannosyl-N-acetylglucosamine phosphorylase",
     "2.4.1.321	Cellobionic acid phosphorylase",
-    "2.4.1.322	Desvancosaminyl-vancomycin vancosaminetransferase",
+    "2.4.1.322	Devancosaminyl-vancomycin vancosaminetransferase",
     "2.4.1.323	7-deoxyloganetic acid glucosyltransferase",
     "2.4.1.324	7-deoxyloganetin glucosyltransferase",
     "2.4.1.325	TDP-N-acetylfucosamine:lipid II N-acetylfucosaminyltransferase",
@@ -2936,6 +2957,7 @@ static const char* const kECNum_specific[] = {
     "2.6.1.107	Beta-methylphenylalanine transaminase",
     "2.6.1.108	(5-formylfuran-3-yl)methyl phosphate transaminase",
     "2.6.1.109	8-amino-3,8-dideoxy-alpha-D-manno-octulosonate transaminase",
+    "2.6.1.110	dTDP-4-dehydro-2,3,6-trideoxy-D-glucose 4-aminotransferase",
     "2.6.3.1	Oximinotransferase",
     "2.6.99.1	dATP(dGTP)--DNA purinetransferase",
     "2.6.99.2	Pyridoxine 5'-phosphate synthase",
@@ -3004,7 +3026,6 @@ static const char* const kECNum_specific[] = {
     "2.7.1.66	Undecaprenol kinase",
     "2.7.1.67	1-phosphatidylinositol 4-kinase",
     "2.7.1.68	1-phosphatidylinositol-4-phosphate 5-kinase",
-    "2.7.1.69	Protein-N(pi)-phosphohistidine--sugar phosphotransferase",
     "2.7.1.71	Shikimate kinase",
     "2.7.1.72	Streptomycin 6-kinase",
     "2.7.1.73	Inosine kinase",
@@ -3097,6 +3118,24 @@ static const char* const kECNum_specific[] = {
     "2.7.1.188	2-epi-5-epi-valiolone 7-kinase",
     "2.7.1.189	Autoinducer-2 kinase",
     "2.7.1.190	Aminoglycoside 2''-phosphotransferase",
+    "2.7.1.191	Protein-N(pi)-phosphohistidine--D-mannose phosphotransferase",
+    "2.7.1.192	Protein-N(pi)-phosphohistidine--N-acetylmuramate phosphotransferase",
+    "2.7.1.193	Protein-N(pi)-phosphohistidine--N-acetyl-D-glucosamine phosphotransferase",
+    "2.7.1.194	Protein-N(pi)-phosphohistidine--L-ascorbate phosphotransferase",
+    "2.7.1.195	Protein-N(pi)-phosphohistidine--2-O-alpha-mannosyl-D-glycerate phosphotransferase",
+    "2.7.1.196	Protein-N(pi)-phosphohistidine--N,N'-diacetylchitobiose phosphotransferase",
+    "2.7.1.197	Protein-N(pi)-phosphohistidine--D-mannitol phosphotransferase",
+    "2.7.1.198	Protein-N(pi)-phosphohistidine--D-sorbitol phosphotransferase",
+    "2.7.1.199	Protein-N(pi)-phosphohistidine--D-glucose phosphotransferase",
+    "2.7.1.200	Protein-N(pi)-phosphohistidine--galactitol phosphotransferase",
+    "2.7.1.201	Protein-N(pi)-phosphohistidine--trehalose phosphotransferase",
+    "2.7.1.202	Protein-N(pi)-phosphohistidine--D-fructose phosphotransferase",
+    "2.7.1.203	Protein-N(pi)-phosphohistidine--D-glucosaminate phosphotransferase",
+    "2.7.1.204	Protein-N(pi)-phosphohistidine--D-galactose phosphotransferase",
+    "2.7.1.205	Protein-N(pi)-phosphohistidine--D-cellobiose phosphotransferase",
+    "2.7.1.206	Protein-N(pi)-phosphohistidine--L-sorbose phosphotransferase",
+    "2.7.1.207	Protein-N(pi)-phosphohistidine--lactose phosphotransferase",
+    "2.7.1.208	Protein-N(pi)-phosphohistidine--maltose phosphotransferase",
     "2.7.2.1	Acetate kinase",
     "2.7.2.2	Carbamate kinase",
     "2.7.2.3	Phosphoglycerate kinase",
@@ -3208,7 +3247,6 @@ static const char* const kECNum_specific[] = {
     "2.7.7.60	2-C-methyl-D-erythritol 4-phosphate cytidylyltransferase",
     "2.7.7.61	Citrate lyase holo-[acyl-carrier protein] synthase",
     "2.7.7.62	Adenosylcobinamide-phosphate guanylyltransferase",
-    "2.7.7.63	Lipoate--protein ligase",
     "2.7.7.64	UTP-monosaccharide-1-phosphate uridylyltransferase",
     "2.7.7.65	Diguanylate cyclase",
     "2.7.7.66	Malonate decarboxylase holo-[acyl-carrier protein] synthase",
@@ -3235,6 +3273,7 @@ static const char* const kECNum_specific[] = {
     "2.7.7.87	L-threonylcarbamoyladenylate synthase",
     "2.7.7.88	GDP polyribonucleotidyltransferase",
     "2.7.7.89	[Glutamate--ammonia ligase]-adenylyl-L-tyrosine phosphorylase",
+    "2.7.7.90	CMP-8-amino-3,8-dideoxy-manno-octulosonate cytidylyltransferase",
     "2.7.7.n1	Adenosine monophosphate-protein transferase",
     "2.7.7.n6	Guanine phosphate-protein transferase",
     "2.7.8.1	Ethanolaminephosphotransferase",
@@ -3495,6 +3534,7 @@ static const char* const kECNum_specific[] = {
     "3.1.1.96	D-aminoacyl-tRNA deacylase",
     "3.1.1.97	Methylated diphthine methylhydrolase",
     "3.1.1.98	[Wnt protein] O-palmitoleoyl-L-serine hydrolase",
+    "3.1.1.99	6-deoxy-6-sulfogluconolactonase",
     "3.1.1.n2	Protein-S-isoprenylcysteine alpha-carbonyl methylesterase",
     "3.1.2.1	Acetyl-CoA hydrolase",
     "3.1.2.2	Palmitoyl-CoA hydrolase",
@@ -3618,6 +3658,8 @@ static const char* const kECNum_specific[] = {
     "3.1.3.96	Pseudouridine 5'-phosphatase",
     "3.1.3.97	3',5'-nucleoside bisphosphate phosphatase",
     "3.1.3.98	Geranyl diphosphate phosphohydrolase",
+    "3.1.3.99	IMP-specific 5'-nucleotidase",
+    "3.1.3.100	Thiamine phosphate phosphatase",
     "3.1.4.1	Phosphodiesterase I",
     "3.1.4.2	Glycerophosphocholine phosphodiesterase",
     "3.1.4.3	Phospholipase C",
@@ -3913,6 +3955,7 @@ static const char* const kECNum_specific[] = {
     "3.2.1.193	Ginsenosidase type I",
     "3.2.1.194	Ginsenosidase type IV",
     "3.2.1.195	20-O-multi-glycoside ginsenosidase",
+    "3.2.1.196	Limit dextrin alpha-1,6-maltotetraose-hydrolase",
     "3.2.1.n1	Blood group B branched chain alpha-1,3-galactosidase",
     "3.2.1.n2	Blood group B linear chain alpha-1,3-galactosidase",
     "3.2.1.n3	Dictyostelium lysozyme A",
@@ -4696,6 +4739,7 @@ static const char* const kECNum_specific[] = {
     "3.7.1.20	3-fumarylpyruvate hydrolase",
     "3.7.1.21	6-oxocyclohex-1-ene-1-carbonyl-CoA hydratase",
     "3.7.1.22	3D-(3,5/4)-trihydroxycyclohexane-1,2-dione acylhydrolase (decyclizing)",
+    "3.7.1.23	Maleylpyruvate hydrolase",
     "3.8.1.1	Alkylhalidase",
     "3.8.1.2	(S)-2-haloacid dehalogenase",
     "3.8.1.3	Haloacetate dehalogenase",
@@ -4708,6 +4752,7 @@ static const char* const kECNum_specific[] = {
     "3.8.1.11	2-haloacid dehalogenase (configuration-retaining)",
     "3.9.1.1	Phosphoamidase",
     "3.9.1.2	Protein arginine phosphatase",
+    "3.9.1.3	Phosphohistidine phosphatase",
     "3.10.1.1	N-sulfoglucosamine sulfohydrolase",
     "3.10.1.2	Cyclamate sulfohydrolase",
     "3.11.1.1	Phosphonoacetaldehyde hydrolase",
@@ -4863,6 +4908,7 @@ static const char* const kECNum_specific[] = {
     "4.1.2.55	2-dehydro-3-deoxy-phosphogluconate/2-dehydro-3-deoxy-6-phosphogalactonate aldolase",
     "4.1.2.56	2-amino-4,5-dihydroxy-6-oxo-7-(phosphonooxy)heptanoate synthase",
     "4.1.2.57	Sulfofructosephosphate aldolase",
+    "4.1.2.58	2-dehydro-3,6-dideoxy-6-sulfogluconate aldolase",
     "4.1.2.n2	2-hydroxyphytanoyl-CoA lyase",
     "4.1.3.1	Isocitrate lyase",
     "4.1.3.3	N-acetylneuraminate lyase",
@@ -5043,6 +5089,8 @@ static const char* const kECNum_specific[] = {
     "4.2.1.159	dTDP-4-dehydro-6-deoxy-alpha-D-glucopyranose 2,3-dehydratase",
     "4.2.1.160	2,5-diamino-6-(5-phospho-D-ribosylamino)pyrimidin-4(3H)-one isomerase/dehydratase",
     "4.2.1.161	Bisanhydrobacterioruberin hydratase",
+    "4.2.1.162	6-deoxy-6-sulfo-D-gluconate dehydratase",
+    "4.2.1.163	2-oxo-hept-4-ene-1,7-dioate hydratase",
     "4.2.2.1	Hyaluronate lyase",
     "4.2.2.2	Pectate lyase",
     "4.2.2.3	Mannuronate-specific alginate lyase",
@@ -5229,6 +5277,7 @@ static const char* const kECNum_specific[] = {
     "4.2.99.20	2-succinyl-6-hydroxy-2,4-cyclohexadiene-1-carboxylate synthase",
     "4.2.99.21	Isochorismate lyase",
     "4.2.99.22	Tuliposide A-converting enzyme",
+    "4.2.99.23	Tuliposide B-converting enzyme",
     "4.3.1.1	Aspartate ammonia-lyase",
     "4.3.1.2	Methylaspartate ammonia-lyase",
     "4.3.1.3	Histidine ammonia-lyase",
@@ -5314,7 +5363,7 @@ static const char* const kECNum_specific[] = {
     "4.6.1.15	FAD-AMP lyase (cyclizing)",
     "4.6.1.16	tRNA-intron lyase",
     "4.7.1.1	Alpha-D-ribose 1-methylphosphonate 5-phosphate C-P-lyase",
-    "4.99.1.1	Ferrochelatase",
+    "4.99.1.1	Protoporphyrin ferrochelatase",
     "4.99.1.2	Alkylmercury lyase",
     "4.99.1.3	Sirohydrochlorin cobaltochelatase",
     "4.99.1.4	Sirohydrochlorin ferrochelatase",
@@ -5680,6 +5729,7 @@ static const char* const kECNum_specific[] = {
     "6.3.1.17	Beta-citrylglutamate synthase",
     "6.3.1.18	Gamma-glutamylanilide synthase",
     "6.3.1.19	Prokaryotic ubiquitin-like protein ligase",
+    "6.3.1.20	Lipoate--protein ligase",
     "6.3.2.1	Pantoate--beta-alanine ligase (AMP-forming)",
     "6.3.2.2	Glutamate--cysteine ligase",
     "6.3.2.3	Glutathione synthase",
diff --git a/c++/src/objects/seqfeat/ecnum_specific.txt b/c++/src/objects/seqfeat/ecnum_specific.txt
index 26ec599..4442b0f 100644
--- a/c++/src/objects/seqfeat/ecnum_specific.txt
+++ b/c++/src/objects/seqfeat/ecnum_specific.txt
@@ -48,7 +48,7 @@
 1.1.1.49	Glucose-6-phosphate dehydrogenase (NADP(+))
 1.1.1.50	3-alpha-hydroxysteroid 3-dehydrogenase (Si-specific)
 1.1.1.51	3(or 17)-beta-hydroxysteroid dehydrogenase
-1.1.1.52	3-alpha-hydroxycholanate dehydrogenase (NAD(+) )
+1.1.1.52	3-alpha-hydroxycholanate dehydrogenase (NAD(+))
 1.1.1.53	3-alpha(or 20-beta)-hydroxysteroid dehydrogenase
 1.1.1.54	Allyl-alcohol dehydrogenase
 1.1.1.55	Lactaldehyde reductase (NADPH)
@@ -367,6 +367,10 @@
 1.1.1.388	Glucose-6-phosphate dehydrogenase (NAD(+))
 1.1.1.389	2-dehydro-3-deoxy-L-galactonate 5-dehydrogenase
 1.1.1.390	Sulfoquinovose 1-dehydrogenase
+1.1.1.391	3-beta-hydroxycholanate 3-dehydrogenase (NAD(+))
+1.1.1.392	3-alpha-hydroxycholanate dehydrogenase (NADP(+))
+1.1.1.393	3-beta-hydroxycholanate 3-dehydrogenase (NADP(+))
+1.1.1.394	Aurachin B dehydrogenase
 1.1.1.n4	(-)-trans-carveol dehydrogenase
 1.1.1.n5	3-methylmalate dehydrogenase
 1.1.1.n11	Succinic semialdehyde reductase
@@ -562,9 +566,10 @@
 1.2.4.4	3-methyl-2-oxobutanoate dehydrogenase (2-methylpropanoyl-transferring)
 1.2.5.1	Pyruvate dehydrogenase (quinone)
 1.2.5.2	Aldehyde dehydrogenase (quinone)
+1.2.5.3	Aerobic carbon monoxide dehydrogenase
 1.2.7.1	Pyruvate synthase
 1.2.7.3	2-oxoglutarate synthase
-1.2.7.4	Carbon-monoxide dehydrogenase (ferredoxin)
+1.2.7.4	Anaerobic carbon-monoxide dehydrogenase
 1.2.7.5	Aldehyde ferredoxin oxidoreductase
 1.2.7.6	Glyceraldehyde-3-phosphate dehydrogenase (ferredoxin)
 1.2.7.7	3-methyl-2-oxobutanoate dehydrogenase (ferredoxin)
@@ -646,7 +651,6 @@
 1.3.1.77	Anthocyanidin reductase
 1.3.1.78	Arogenate dehydrogenase (NADP(+))
 1.3.1.79	Arogenate dehydrogenase (NAD(P)(+))
-1.3.1.80	Red chlorophyll catabolite reductase
 1.3.1.81	(+)-pulegone reductase
 1.3.1.82	(-)-isopiperitenone reductase
 1.3.1.83	Geranylgeranyl diphosphate reductase
@@ -677,6 +681,7 @@
 1.3.1.108	Caffeoyl-CoA reductase
 1.3.1.109	Butanoyl-CoA dehydrogenase (NAD(+),ferredoxin)
 1.3.1.110	Lactate dehydrogenase (NAD(+),ferredoxin)
+1.3.1.111	Geranylgeranyl-bacteriochlorophyllide a reductase
 1.3.1.n2	Camalexin synthase
 1.3.1.n3	Curcumin reductase
 1.3.2.3	L-galactonolactone dehydrogenase
@@ -709,6 +714,7 @@
 1.3.7.8	Benzoyl-CoA reductase
 1.3.7.9	4-hydroxybenzoyl-CoA reductase
 1.3.7.11	2,3-bis-O-geranylgeranyl-sn-glycero-phospholipid reductase
+1.3.7.12	Red chlorophyll catabolite reductase
 1.3.8.1	Short-chain acyl-CoA dehydrogenase
 1.3.8.2	4,4'-diapophytoene desaturase (4,4'-diapolycopene-forming)
 1.3.8.3	(R)-benzylsuccinyl-CoA dehydrogenase
@@ -1198,6 +1204,7 @@
 1.14.11.47	50S ribosomal protein L16 3-hydroxylase
 1.14.11.48	Xanthine dioxygenase
 1.14.11.49	Uridine-5'-phosphate dioxygenase
+1.14.11.50	(-)-deoxypodophyllotoxin synthase
 1.14.11.n2	Methylcytosine dioxygenase
 1.14.11.n3	L-proline cis-4-hydroxylase
 1.14.11.n4	Ankyrin-repeat-histidine dioxagenase
@@ -1218,7 +1225,6 @@
 1.14.12.17	Nitric oxide dioxygenase
 1.14.12.18	Biphenyl 2,3-dioxygenase
 1.14.12.19	3-phenylpropanoate dioxygenase
-1.14.12.20	Pheophorbide a oxygenase
 1.14.12.22	Carbazole 1,9a-dioxygenase
 1.14.12.23	Nitroarene dioxygenase
 1.14.12.24	2,4-dinitrotoluene dioxygenase
@@ -1227,7 +1233,7 @@
 1.14.13.4	Melilotate 3-monooxygenase
 1.14.13.5	Imidazoleacetate 4-monooxygenase
 1.14.13.6	Orcinol 2-monooxygenase
-1.14.13.7	Phenol 2-monooxygenase
+1.14.13.7	Phenol 2-monooxygenase (NADPH)
 1.14.13.8	Flavin-containing monooxygenase
 1.14.13.9	Kynurenine 3-monooxygenase
 1.14.13.10	2,6-dihydroxypyridine 3-monooxygenase
@@ -1235,9 +1241,7 @@
 1.14.13.12	Benzoate 4-monooxygenase
 1.14.13.13	Calcidiol 1-monooxygenase
 1.14.13.14	Trans-cinnamate 2-monooxygenase
-1.14.13.15	Cholestanetriol 26-monooxygenase
 1.14.13.16	Cyclopentanone monooxygenase
-1.14.13.17	Cholesterol 7-alpha-monooxygenase
 1.14.13.18	4-hydroxyphenylacetate 1-monooxygenase
 1.14.13.19	Taxifolin 8-monooxygenase
 1.14.13.20	2,4-dichlorophenol 6-monooxygenase
@@ -1311,8 +1315,6 @@
 1.14.13.94	Lithocholate 6-beta-hydroxylase
 1.14.13.96	5-beta-cholestane-3-alpha,7-alpha-diol 12-alpha-hydroxylase
 1.14.13.97	Taurochenodeoxycholate 6-alpha-hydroxylase
-1.14.13.98	Cholesterol 24-hydroxylase
-1.14.13.99	24-hydroxycholesterol 7-alpha-hydroxylase
 1.14.13.100	25/26-hydroxycholesterol 7-alpha-hydroxylase
 1.14.13.101	Senecionine N-oxygenase
 1.14.13.102	Psoralen synthase
@@ -1339,7 +1341,6 @@
 1.14.13.123	Germacrene A hydroxylase
 1.14.13.124	Phenylalanine N-monooxygenase
 1.14.13.125	Tryptophan N-monooxygenase
-1.14.13.126	Vitamin D(3) 24-hydroxylase
 1.14.13.127	3-(3-hydroxy-phenyl)propanoic acid hydroxylase
 1.14.13.128	7-methylxanthine demethylase
 1.14.13.129	Beta-carotene 3-hydroxylase
@@ -1371,7 +1372,6 @@
 1.14.13.156	1,8-cineole 2-endo-monooxygenase
 1.14.13.157	1,8-cineole 2-exo-monooxygenase
 1.14.13.158	Amorpha-4,11-diene 12 monooxygenase
-1.14.13.159	Vitamin D 25-hydroxylase
 1.14.13.160	(2,2,3-trimethyl-5-oxocyclopent-3-enyl)acetyl-CoA 1,5-monooxygenase
 1.14.13.161	(+)-camphor 6-exo-hydroxylase
 1.14.13.162	2,5-diketocamphane 1,2-monooxygenase
@@ -1420,6 +1420,14 @@
 1.14.13.207	Ipsdienol synthase
 1.14.13.208	Benzoyl-CoA 2,3-epoxidase
 1.14.13.209	Salicyloyl-CoA 5-hydroxylase
+1.14.13.210	4-methyl-5-nitrocatechol 5-monooxygenase
+1.14.13.211	Rifampicin monooxygenase
+1.14.13.212	1,3,7-trimethyluric acid 5-monooxygenase
+1.14.13.213	Bursehernin 5'-monooxygenase
+1.14.13.214	(-)-4'-demethyl-deoxypodophyllotoxin 4-hydroxylase
+1.14.13.215	Protoasukamycin 4-monooxygenase
+1.14.13.216	Asperlicin C monooxygenase
+1.14.13.217	Protodeoxyviolaceinate monooxygenase
 1.14.13.n5	Dihomomethionine N-hydroxylase
 1.14.13.n6	Hexahomomethionine N-hydroxylase
 1.14.13.n7	4-nitrophenol 2-hydroxylase
@@ -1439,6 +1447,13 @@
 1.14.14.17	Squalene monooxygenase
 1.14.14.18	Heme oxygenase (biliverdin-producing)
 1.14.14.19	Steroid 17-alpha-monooxygenase
+1.14.14.20	Phenol 2-monooxygenase (FADH(2))
+1.14.14.21	Dibenzothiophene monooxygenase
+1.14.14.22	Dibenzothiophene sulfone monooxygenase
+1.14.14.23	Cholesterol 7-alpha-monooxygenase
+1.14.14.24	Vitamin D 25-hydroxylase
+1.14.14.25	Cholesterol 24-hydroxylase
+1.14.14.26	24-hydroxycholesterol 7-alpha-hydroxylase
 1.14.15.1	Camphor 5-monooxygenase
 1.14.15.3	Alkane 1-monooxygenase
 1.14.15.4	Steroid 11-beta-monooxygenase
@@ -1452,6 +1467,9 @@
 1.14.15.12	Pimeloyl-[acyl-carrier protein] synthase
 1.14.15.13	Pulcherriminic acid synthase
 1.14.15.14	Methyl-branched lipid omega-hydroxylase
+1.14.15.15	Cholestanetriol 26-monooxygenase
+1.14.15.16	Vitamin D(3) 24-hydroxylase
+1.14.15.17	Pheophorbide a oxygenase
 1.14.16.1	Phenylalanine 4-monooxygenase
 1.14.16.2	Tyrosine 3-monooxygenase
 1.14.16.3	Anthranilate 3-monooxygenase
@@ -1530,6 +1548,7 @@
 1.14.21.8	Pseudobaptigenin synthase
 1.14.21.9	Mycocyclosin synthase
 1.14.21.10	Fumitremorgin C synthase
+1.14.21.11	(-)-pluviatolide synthase
 1.14.99.1	Prostaglandin-endoperoxide synthase
 1.14.99.2	Kynurenine 7,8-hydroxylase
 1.14.99.4	Progesterone monooxygenase
@@ -1582,7 +1601,6 @@
 1.16.8.1	Cob(II)yrinic acid a,c-diamide reductase
 1.16.9.1	Iron:rusticyanin reductase
 1.17.1.1	CDP-4-dehydro-6-deoxyglucose reductase
-1.17.1.2	4-hydroxy-3-methylbut-2-enyl diphosphate reductase
 1.17.1.3	Leucoanthocyanidin reductase
 1.17.1.4	Xanthine dehydrogenase
 1.17.1.5	Nicotinate dehydrogenase
@@ -1601,6 +1619,7 @@
 1.17.7.1	(E)-4-hydroxy-3-methylbut-2-enyl-diphosphate synthase (ferredoxin)
 1.17.7.2	7-hydroxymethyl chlorophyll a reductase
 1.17.7.3	(E)-4-hydroxy-3-methylbut-2-enyl-diphosphate synthase (flavodoxin)
+1.17.7.4	4-hydroxy-3-methylbut-2-enyl diphosphate reductase
 1.17.98.1	Bile-acid 7-alpha-dehydroxylase
 1.17.99.1	4-methylphenol dehydrogenase (hydroxylating)
 1.17.99.2	Ethylbenzene hydroxylase
@@ -1635,12 +1654,12 @@
 1.21.3.6	Aureusidin synthase
 1.21.3.7	Tetrahydrocannabinolic acid synthase
 1.21.3.8	Cannabidiolic acid synthase
-1.21.3.9	Dichlorochromopyrrolate synthase
 1.21.4.1	D-proline reductase (dithiol)
 1.21.4.2	Glycine reductase
 1.21.4.3	Sarcosine reductase
 1.21.4.4	Betaine reductase
 1.21.98.1	Cyclic dehypoxanthinyl futalosine synthase
+1.21.98.2	Dichlorochromopyrrolate synthase
 1.21.99.1	Beta-cyclopiazonate dehydrogenase
 1.21.99.3	Thyroxine 5-deiodinase
 1.21.99.4	Thyroxine 5'-deiodinase
@@ -1953,6 +1972,8 @@
 2.1.1.320	Type II protein arginine methyltransferase
 2.1.1.321	Type III protein arginine methyltransferase
 2.1.1.322	Type IV protein arginine methyltransferase
+2.1.1.323	(-)-pluviatolide 4-O-methyltransferase
+2.1.1.324	dTDP-4-amino-2,3,4,6-tetradeoxy-D-glucose N,N-dimethyltransferase
 2.1.1.n1	Resorcinol O-methyltransferase
 2.1.1.n4	Thiocyanate methyltransferase
 2.1.1.n7	5-pentadecatrienyl resorcinol O-methyltransferase
@@ -2584,7 +2605,7 @@
 2.4.1.319	Beta-1,4-mannooligosaccharide phosphorylase
 2.4.1.320	1,4-beta-mannosyl-N-acetylglucosamine phosphorylase
 2.4.1.321	Cellobionic acid phosphorylase
-2.4.1.322	Desvancosaminyl-vancomycin vancosaminetransferase
+2.4.1.322	Devancosaminyl-vancomycin vancosaminetransferase
 2.4.1.323	7-deoxyloganetic acid glucosyltransferase
 2.4.1.324	7-deoxyloganetin glucosyltransferase
 2.4.1.325	TDP-N-acetylfucosamine:lipid II N-acetylfucosaminyltransferase
@@ -2903,6 +2924,7 @@
 2.6.1.107	Beta-methylphenylalanine transaminase
 2.6.1.108	(5-formylfuran-3-yl)methyl phosphate transaminase
 2.6.1.109	8-amino-3,8-dideoxy-alpha-D-manno-octulosonate transaminase
+2.6.1.110	dTDP-4-dehydro-2,3,6-trideoxy-D-glucose 4-aminotransferase
 2.6.3.1	Oximinotransferase
 2.6.99.1	dATP(dGTP)--DNA purinetransferase
 2.6.99.2	Pyridoxine 5'-phosphate synthase
@@ -2971,7 +2993,6 @@
 2.7.1.66	Undecaprenol kinase
 2.7.1.67	1-phosphatidylinositol 4-kinase
 2.7.1.68	1-phosphatidylinositol-4-phosphate 5-kinase
-2.7.1.69	Protein-N(pi)-phosphohistidine--sugar phosphotransferase
 2.7.1.71	Shikimate kinase
 2.7.1.72	Streptomycin 6-kinase
 2.7.1.73	Inosine kinase
@@ -3064,6 +3085,24 @@
 2.7.1.188	2-epi-5-epi-valiolone 7-kinase
 2.7.1.189	Autoinducer-2 kinase
 2.7.1.190	Aminoglycoside 2''-phosphotransferase
+2.7.1.191	Protein-N(pi)-phosphohistidine--D-mannose phosphotransferase
+2.7.1.192	Protein-N(pi)-phosphohistidine--N-acetylmuramate phosphotransferase
+2.7.1.193	Protein-N(pi)-phosphohistidine--N-acetyl-D-glucosamine phosphotransferase
+2.7.1.194	Protein-N(pi)-phosphohistidine--L-ascorbate phosphotransferase
+2.7.1.195	Protein-N(pi)-phosphohistidine--2-O-alpha-mannosyl-D-glycerate phosphotransferase
+2.7.1.196	Protein-N(pi)-phosphohistidine--N,N'-diacetylchitobiose phosphotransferase
+2.7.1.197	Protein-N(pi)-phosphohistidine--D-mannitol phosphotransferase
+2.7.1.198	Protein-N(pi)-phosphohistidine--D-sorbitol phosphotransferase
+2.7.1.199	Protein-N(pi)-phosphohistidine--D-glucose phosphotransferase
+2.7.1.200	Protein-N(pi)-phosphohistidine--galactitol phosphotransferase
+2.7.1.201	Protein-N(pi)-phosphohistidine--trehalose phosphotransferase
+2.7.1.202	Protein-N(pi)-phosphohistidine--D-fructose phosphotransferase
+2.7.1.203	Protein-N(pi)-phosphohistidine--D-glucosaminate phosphotransferase
+2.7.1.204	Protein-N(pi)-phosphohistidine--D-galactose phosphotransferase
+2.7.1.205	Protein-N(pi)-phosphohistidine--D-cellobiose phosphotransferase
+2.7.1.206	Protein-N(pi)-phosphohistidine--L-sorbose phosphotransferase
+2.7.1.207	Protein-N(pi)-phosphohistidine--lactose phosphotransferase
+2.7.1.208	Protein-N(pi)-phosphohistidine--maltose phosphotransferase
 2.7.2.1	Acetate kinase
 2.7.2.2	Carbamate kinase
 2.7.2.3	Phosphoglycerate kinase
@@ -3175,7 +3214,6 @@
 2.7.7.60	2-C-methyl-D-erythritol 4-phosphate cytidylyltransferase
 2.7.7.61	Citrate lyase holo-[acyl-carrier protein] synthase
 2.7.7.62	Adenosylcobinamide-phosphate guanylyltransferase
-2.7.7.63	Lipoate--protein ligase
 2.7.7.64	UTP-monosaccharide-1-phosphate uridylyltransferase
 2.7.7.65	Diguanylate cyclase
 2.7.7.66	Malonate decarboxylase holo-[acyl-carrier protein] synthase
@@ -3202,6 +3240,7 @@
 2.7.7.87	L-threonylcarbamoyladenylate synthase
 2.7.7.88	GDP polyribonucleotidyltransferase
 2.7.7.89	[Glutamate--ammonia ligase]-adenylyl-L-tyrosine phosphorylase
+2.7.7.90	CMP-8-amino-3,8-dideoxy-manno-octulosonate cytidylyltransferase
 2.7.7.n1	Adenosine monophosphate-protein transferase
 2.7.7.n6	Guanine phosphate-protein transferase
 2.7.8.1	Ethanolaminephosphotransferase
@@ -3462,6 +3501,7 @@
 3.1.1.96	D-aminoacyl-tRNA deacylase
 3.1.1.97	Methylated diphthine methylhydrolase
 3.1.1.98	[Wnt protein] O-palmitoleoyl-L-serine hydrolase
+3.1.1.99	6-deoxy-6-sulfogluconolactonase
 3.1.1.n2	Protein-S-isoprenylcysteine alpha-carbonyl methylesterase
 3.1.2.1	Acetyl-CoA hydrolase
 3.1.2.2	Palmitoyl-CoA hydrolase
@@ -3585,6 +3625,8 @@
 3.1.3.96	Pseudouridine 5'-phosphatase
 3.1.3.97	3',5'-nucleoside bisphosphate phosphatase
 3.1.3.98	Geranyl diphosphate phosphohydrolase
+3.1.3.99	IMP-specific 5'-nucleotidase
+3.1.3.100	Thiamine phosphate phosphatase
 3.1.4.1	Phosphodiesterase I
 3.1.4.2	Glycerophosphocholine phosphodiesterase
 3.1.4.3	Phospholipase C
@@ -3880,6 +3922,7 @@
 3.2.1.193	Ginsenosidase type I
 3.2.1.194	Ginsenosidase type IV
 3.2.1.195	20-O-multi-glycoside ginsenosidase
+3.2.1.196	Limit dextrin alpha-1,6-maltotetraose-hydrolase
 3.2.1.n1	Blood group B branched chain alpha-1,3-galactosidase
 3.2.1.n2	Blood group B linear chain alpha-1,3-galactosidase
 3.2.1.n3	Dictyostelium lysozyme A
@@ -4663,6 +4706,7 @@
 3.7.1.20	3-fumarylpyruvate hydrolase
 3.7.1.21	6-oxocyclohex-1-ene-1-carbonyl-CoA hydratase
 3.7.1.22	3D-(3,5/4)-trihydroxycyclohexane-1,2-dione acylhydrolase (decyclizing)
+3.7.1.23	Maleylpyruvate hydrolase
 3.8.1.1	Alkylhalidase
 3.8.1.2	(S)-2-haloacid dehalogenase
 3.8.1.3	Haloacetate dehalogenase
@@ -4675,6 +4719,7 @@
 3.8.1.11	2-haloacid dehalogenase (configuration-retaining)
 3.9.1.1	Phosphoamidase
 3.9.1.2	Protein arginine phosphatase
+3.9.1.3	Phosphohistidine phosphatase
 3.10.1.1	N-sulfoglucosamine sulfohydrolase
 3.10.1.2	Cyclamate sulfohydrolase
 3.11.1.1	Phosphonoacetaldehyde hydrolase
@@ -4830,6 +4875,7 @@
 4.1.2.55	2-dehydro-3-deoxy-phosphogluconate/2-dehydro-3-deoxy-6-phosphogalactonate aldolase
 4.1.2.56	2-amino-4,5-dihydroxy-6-oxo-7-(phosphonooxy)heptanoate synthase
 4.1.2.57	Sulfofructosephosphate aldolase
+4.1.2.58	2-dehydro-3,6-dideoxy-6-sulfogluconate aldolase
 4.1.2.n2	2-hydroxyphytanoyl-CoA lyase
 4.1.3.1	Isocitrate lyase
 4.1.3.3	N-acetylneuraminate lyase
@@ -5010,6 +5056,8 @@
 4.2.1.159	dTDP-4-dehydro-6-deoxy-alpha-D-glucopyranose 2,3-dehydratase
 4.2.1.160	2,5-diamino-6-(5-phospho-D-ribosylamino)pyrimidin-4(3H)-one isomerase/dehydratase
 4.2.1.161	Bisanhydrobacterioruberin hydratase
+4.2.1.162	6-deoxy-6-sulfo-D-gluconate dehydratase
+4.2.1.163	2-oxo-hept-4-ene-1,7-dioate hydratase
 4.2.2.1	Hyaluronate lyase
 4.2.2.2	Pectate lyase
 4.2.2.3	Mannuronate-specific alginate lyase
@@ -5196,6 +5244,7 @@
 4.2.99.20	2-succinyl-6-hydroxy-2,4-cyclohexadiene-1-carboxylate synthase
 4.2.99.21	Isochorismate lyase
 4.2.99.22	Tuliposide A-converting enzyme
+4.2.99.23	Tuliposide B-converting enzyme
 4.3.1.1	Aspartate ammonia-lyase
 4.3.1.2	Methylaspartate ammonia-lyase
 4.3.1.3	Histidine ammonia-lyase
@@ -5281,7 +5330,7 @@
 4.6.1.15	FAD-AMP lyase (cyclizing)
 4.6.1.16	tRNA-intron lyase
 4.7.1.1	Alpha-D-ribose 1-methylphosphonate 5-phosphate C-P-lyase
-4.99.1.1	Ferrochelatase
+4.99.1.1	Protoporphyrin ferrochelatase
 4.99.1.2	Alkylmercury lyase
 4.99.1.3	Sirohydrochlorin cobaltochelatase
 4.99.1.4	Sirohydrochlorin ferrochelatase
@@ -5647,6 +5696,7 @@
 6.3.1.17	Beta-citrylglutamate synthase
 6.3.1.18	Gamma-glutamylanilide synthase
 6.3.1.19	Prokaryotic ubiquitin-like protein ligase
+6.3.1.20	Lipoate--protein ligase
 6.3.2.1	Pantoate--beta-alanine ligase (AMP-forming)
 6.3.2.2	Glutamate--cysteine ligase
 6.3.2.3	Glutathione synthase
diff --git a/c++/src/objects/seqfeat/institution_codes.inc b/c++/src/objects/seqfeat/institution_codes.inc
index 9da0917..d4800d5 100644
--- a/c++/src/objects/seqfeat/institution_codes.inc
+++ b/c++/src/objects/seqfeat/institution_codes.inc
@@ -1,4 +1,4 @@
-/*  $Id: institution_codes.inc 497803 2016-04-11 13:56:31Z ivanov $
+/*  $Id: institution_codes.inc 520430 2016-11-28 18:25:59Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -33,6 +33,7 @@
 static const char* const kInstitutionCollectionCodeList[] = {
 "A	s	Arnold Arboretum, Harvard University",
 "AA	s	Ministry of Science, Academy of Sciences",
+"AAC	c	Arignar Anna College",
 "AAH	s	Arnold Arboretum, Harvard University",
 "AAPI	s	Plant Industry Laboratory",
 "AAR	s	Reliquae Aaronsohnianae",
@@ -147,6 +148,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "AJOU	s	Ajou University, Biological Sciences Department",
 "AK	s	Auckland War Memorial Museum",
 "AKPM	s	Akita Prefectural Museum",
+"AKSU	h	Aksaray University",
 "AKU<JPN>	c	Faculty of Agriculture",
 "AKU<NZ>	s	University of Auckland, School of Biological Sciences",
 "AL	s	Universite d'Alger",
@@ -539,6 +541,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "BISH	s	Bishop Museum, Department of Natural Sciences",
 "BITU	s	Department of Biology, Faculty of Science, Toyama University",
 "BIUB	s	Mongolian Academy of Sciences",
+"BJ	h	Bi Jie University",
 "BJA	s	University of Burundi, Biology Department",
 "BJFC	s	Beijing Forestry University",
 "BJM	s	Beijing Natural History Museum",
@@ -555,7 +558,9 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "BLGA	s	Burgenlandisches Landesmuseum",
 "BLH	s	Cranbrook Institute of Science",
 "BLIH	s	Biological Laboratory Imperial Household of Japan",
+"BLMAR	h	Bureau of Land Management Arcata Field Office",
 "BLMLK	s	Bureau of Land Management",
+"BLMPR	h	Bureau of Land Management, Prineville Field Office",
 "BLT	s	Belfast Natural History and Philosophical Society",
 "BLUZ	s	Museo de Biologia",
 "BLWG	c	Bayerische Landesanstalt fur Weinbau und Gartenbau",
@@ -586,6 +591,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "BNA<GBR>	s	British (Empire) Naturalists' Association",
 "BNBE	s	YMCA Hostel",
 "BNFF	s	Banff Museum",
+"BNFH	h	U.S. Forest Service, Bitterroot National Forest",
 "BNH	s	Nassau Botanical Gardens, Department of Agriculture",
 "BNHD	s	Bengal Natural History Museum",
 "BNHM<CHN>	s	Beijing Natural History Museum",
@@ -670,6 +676,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "BRSL	s	Wroclaw University, Botany Department",
 "BRSMG	s	Department of Geology",
 "BRSN	s	University of Wales, Bangor Research Unit",
+"BRSU	h	Bryansk State University",
 "BRTN	s	Brighton Natural History Society",
 "BRU	s	Brown University",
 "BRUN	s	Brunei Forestry Centre",
@@ -686,6 +693,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "BSE	s	Moyse's Hall Museum",
 "BSHC	s	Botanical Survey of India, Sikkim Himalayan Circle",
 "BSI	s	Botanical Survey of India, Western Circle, Ministry of Environment and Forests",
+"BSID	h	Botanical Survey of India",
 "BSIP	s	Ministry of Natural Resources, Department of Forests, Environment, and Conservation",
 "BSIS	s	Botanical Survey of India, Industrial Section",
 "BSJO	s	Botanical Survey of India, Arid Zone Circle",
@@ -712,6 +720,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "BTN	s	Booth Museum of Natural History",
 "BTT	s	Burton-upon-Trent Natural History and Archaeological Society",
 "BTU	s	Technische Universitaet Berlin",
+"BU	h	Brock University",
 "BUA	s	University of Baghdad, Plant Protection Department",
 "BUAG	s	University of Agronomical Sciences and Veterinary Medicine, Botany and Plant Physiology Department",
 "BUC	s	Universitatea din Bucuresti",
@@ -732,15 +741,18 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "BUNS	s	University of Novi Sad, Department of Biology and Ecology",
 "BUPL	s	Bucknell University, Biology Department",
 "BURD	s	University of Burdwan, Botany Department",
+"BURI	h	Banasthali University",
 "BURP	s	Burpee Museum of Natural History",
 "BUS	s	University of Miami, Biology Department",
 "BUT	s	Butler University",
 "BUTC	s	Boston University",
 "BVC	s	Buena Vista College",
+"BVS	h	Transylvania University of Brasov",
 "BYBS	s	Bungay Botanical Society",
 "BYDG	s	Technical-Agriculture Academy, Department of Botany and Ecology",
 "BYU	s	Monte L. Bean Life Science Museum",
 "BZ	s	Herbarium Bogoriense",
+"BZCM	h	Bozhou Vocational and Technical College",
 "BZF	s	Forest Research and Development Center and Nature Conservation",
 "BZM	s	Museum fur Naturkunde, Berlin",
 "BZT	s	Biological Institute Titograd",
@@ -770,6 +782,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CALI	s	University of Calicut, Botany Department",
 "CALP	s	University of the Philippines at Los Banos",
 "CALU	c	Collection of Algae in Leningrad, St. Petersburg, State University",
+"CALVIN	h	Calvin College",
 "CAM<AUST>	s	Central Australian Museum",
 "CAM<UK>	s	St. John's College",
 "CAME	s	Universita di Camerino, Dipartimento de Botanica ed Ecologia",
@@ -786,6 +799,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CANU	s	University of Canterbury, Department of Plant and Microbial Sciences",
 "CAPM	c	Collection of Animal Pathogenic Microorganisms",
 "CAR	s	Museo de Historia Natural La Salle, Departamento de Botanica",
+"CARAN	h	Herbarium Carautanum",
 "CARD	s	Caribbean Agricultural Research Institute",
 "CARE	s	Caribbean Epidemiology Centre",
 "CARI	s	Cukurova Agricultural Research Institute",
@@ -816,6 +830,8 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CASMB	s	Centre of Advanced Study in Marine Biology",
 "CASS	s	Chinese Academy of Sciences, Shenyang",
 "CAT	s	Universita di Catania, Dipartimento di Botanica e Orto Botanico",
+"CATA	h	Catalina Island Conservancy",
+"CATH	h	Catholicate College",
 "CATIE	s	Tropical Agricultural Research and Training Center (CATIE), Plant Production Department",
 "CAU	s	China Agricultural University",
 "CAUP<COL>	s	Universidad del Cauca",
@@ -836,6 +852,8 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CBM:ZC	s	Natural History Museum and Institute, Zoological Collection",
 "CBMAI	c	Brazilian Collection of Microorganisms from the Environment and Industry (Colecao Brasileira de Microrganismos de Ambiente e Industria)",
 "CBNM	s	Cedar Breaks National Monument",
+"CBNSA	h	Conservatoire botanique national Sud-Atlantique",
+"CBPF	h	Conservatoire Botanique Pierre Fabre",
 "CBS	sc	Centraalbureau voor Schimmelcultures, Fungal and Yeast Collection",
 "CBSIZA	s	Caspian Biological Station Institute of Zoology",
 "CBTCCCAS	c	The Cell Bank of Type Culture Collection of Chinese Academy of Sciences",
@@ -859,6 +877,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CCCC	s	Carthage College",
 "CCCIEB	c	Culture Collections of Microorgansisms of Center of Genetic Engineering and Biotechnology",
 "CCCM	c	Canadian Center for the Culture of Microorganisms",
+"CCCR	h	Federal University of Tocantins",
 "CCCryo<DEU>	c	Culture Collection of Cryophilic Algae",
 "CCCS	c	Culture Collection of Ciliates and their Symbionts",
 "CCCZ	s	University of Malawi",
@@ -879,6 +898,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CCG<GHN>	s	University of Cape Coast, Botany Department",
 "CCGB	c	Cole(e7)o de Culturas do G(ea)ero Bacillus e G(ea)eros Correlatos",
 "CCGVCC	c	China Centre for General Viruses Culture Collection",
+"CCH	h	University of Arizona South, Agricultural Extension Service",
 "CCIAL	c	Cultures Cells for Institute Adolfo Lutz",
 "CCIBSO	c	Culture Collection IBSO",
 "CCIM	c	Culture Collection of Industrial Microorganisms",
@@ -890,6 +910,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CCMCU	c	Culture Collection of Microorganisms",
 "CCMF	c	University of Portsmouth",
 "CCMGE	s	Chernyshev Central Museum of Geological Explorations,Collections of the Department of Herpetology, Zoological Institute of the Russian Academy of Sciences",
+"CCMH	h	Concordia College",
 "CCMI	c	Culture Collection of Industrial Microorganisms",
 "CCML	s	Coleccion Ictiologica del Departamento de Ciencias Marinas de la Universidad de la Laguna",
 "CCMM	c	Moroccan Coordinated Collections of Microorganisms",
@@ -912,6 +933,8 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CCTCC	c	China Center for Type Culture Collection",
 "CCTM	c	Centre de Collection de Type Microbien, Institut de Microbiologie, Universite de Lausanne",
 "CCTR	c	Culture Collection Trutnov",
+"CCTS	h	Universidade Federal de Sao Carlos",
+"CCTU	c	Culture Collection of Tabriz University",
 "CCUF	s	Universidade Federal de Alagoas, Centro de Ciencias Biologicas",
 "CCUG	c	Culture Collection, University of Goteborg, Department of Clinical Bacteriology",
 "CCVC	s	Centenary College, Vertebrate Collection",
@@ -964,8 +987,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CETESB	c	Setor de Pesquisa Tecnologica de Sistemas de Tratamento de Efluentes Domesticos",
 "CEU	s	Collage of Eastern Utah",
 "CFB	s	Northern Forestry Centre, Canadian Forest Service",
+"CFBH	s	Celio F.B. Haddad Herpetological Collection, Departamento de  Zoologia, Universidade Estadual Paulista",
 "CFBP	c	Collection Francaise des Bacteries Phytopathogenes",
+"CFCC	cb	China Forestry Culture Collection Center",
 "CFI	s	Genetic Resources and Biotechnology (CENARGEN), EMBRAPA",
+"CFIA	h	Canadian Food Inspection Agency",
 "CFMR	sc	Center for Forest Mycology Research",
 "CFN	s	Clifton College, Biology Department",
 "CFNL	s	Universidad Autonoma de Nuevo Leon",
@@ -1084,6 +1110,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CKE	s	Calke Abbey",
 "CL	s	Babes-Bolyai University",
 "CLA	s	Universitatea de Stiinte Agricole si Medicina Veterinara",
+"CLARK	h	Dr. Charles F. and Wilhelmina Husser Clark Herbarium",
 "CLCB	s	Laboratorul de Ecologie",
 "CLCC	s	Augustana University College",
 "CLD	s	Cleveland Literary and Philosophical Society",
@@ -1132,6 +1159,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CMMC	c	China Marine Microbe Collection",
 "CMMED<USA-HI>	c	Center for Marine Microbial Ecology & Diversity Collection",
 "CMMEX	s	Universidad Autonoma de Baja California",
+"CMMF	h	Jardin botanique de Montreal",
 "CMMI	s	Chinese Academy of Traditional Medicine",
 "CMML	s	Colorado State University Herbarium",
 "CMN	s	Canadian Museum of Nature",
@@ -1151,9 +1179,14 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CMNH	s	The Cleveland Museum of Natural History",
 "CMNS	s	Museum of Natural History, Shanghai",
 "CMNZ	s	Canterbury Museum",
+"CMPH	h	Colegio de Postgraduados",
+"CMPR	h	Centre for Medicinal Plants Research",
+"CMS	h	Christian Missionary Society College",
 "CMSK	s	City Museum, Sheffield",
 "CMSU	s	Central Missouri State University",
 "CMU	s	Chiang Mai University",
+"CMUB	h	Chiang Mai University",
+"CMUH	h	Central Mindanao University",
 "CMUT	s	Chiang Mai University",
 "CMV	s	Centre Marie-Victorin",
 "CMW	c	Forestry and Agricultural Biotechnology Institute, University of Pretoria, Pretoria",
@@ -1175,6 +1208,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CNE	s	Victoria Jubilee Museum",
 "CNEN-LABPC	c	Laboratorio de Pocos de Caldas",
 "CNF	s	Croatian Mycological Society",
+"CNH	h	Canakkale Onsekiz Mart University",
 "CNHM<CRO>	s	Croatian Natural History Museum, Botany Department",
 "CNHM<USA-OH>	s	Cincinnati Museum of Natural History",
 "CNHP	s	Beijing Natural History Museum",
@@ -1184,15 +1218,20 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CNM<ESP>	s	Centro Nacional de Microbiologia",
 "CNMC	s	Colorado National Monument",
 "CNMS	s	Colombo National Museum",
+"CNMT	h	Universidade Federal de Mato Grosso",
+"CNPO	h	Embrapa Pecuaria Sul",
 "CNPS	s	Centro Nacional de Pesquisas da Soja",
 "CNPSo	c	Culture Collection of Diazotrophic and Plant Growth Promoting Bacteria of Embrapa Soja",
+"CNR	h	Crimean Natural Reserve",
 "CNRO	s	Centre National de Recherches Oceanographiques",
 "CNRS	s	Centre National de la Recherche Scientifique",
 "CNRZ	c	Centre National de Recherches Zootechniques",
 "CNS<AUS>	s	Australian Tropical Herbarium",
+"CNSF	h	Centre National de Semences Forestieres",
 "CNU<CHN>	s	Capital Normal University, College of Life Sciences",
 "CNU<KOR-TJ>	s	Chungnam National University",
 "CNU<KOR>	s	Chonbuk National University",
+"CNUK	h	Chungnam National University",
 "CNWGRGL	b	Chinese National Waterfowl Germplasm Resources Gene Library",
 "CO	s	Museum National d'Histoire Naturelle, Department of Marine Biology",
 "COA	s	Herbario, Universidad de Cordoba - Jardin Botanico de Cordoba",
@@ -1200,6 +1239,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "COAD	c	Colecao Octavio de Almeida Drumond",
 "COAH	s	Herbario Amazonico Colombiano (Instituto Amazonico de Investigaciones Cientificas SINCHI)",
 "COCA	s	Comision Tecnico Consultiva de Coeficientes de Agostadero (COTECOCA)",
+"COCAZ	h	Coconino National Forest Herbarium",
 "COCH	s	Universidad Mayor de San Simon, Departamento de Botanica",
 "COCO	s	Colorado College, Biology Department",
 "CODAGEM	s	Universidad Autonoma del Estado de Mexico",
@@ -1320,13 +1360,18 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CSU<USA-CO>	s	Colorado State University",
 "CSU<USA-OK>	s	University of Central Oklahoma, Biology Department",
 "CSUC	s	California State University, Chico, Vertebrate Museum",
+"CSUCI	h	California State University Channel Islands",
 "CSUF	s	California State University, Fresno",
+"CSUH	h	Chelyabinsk State University",
 "CSULB	s	California State University, Long Beach",
 "CSUN	s	California State University, Northridge",
+"CSUNIV	h	Charleston Southern University",
 "CSUR	c	Collection de Souches de l'Unite des Rickettsies",
+"CSUSB	h	California State University, San Bernardino",
 "CSUTC	s	Colorado State University, Mammalogy Teaching Collection",
 "CSVFC	s	Caradoc and Severn Valley Field Club",
 "CT	s	University of Cape Town, Botany Department",
+"CTC	h	Chongqing Normal University",
 "CTES	s	Instituto de Botanica del Nordeste",
 "CTESN	s	Universidad Nacional del Nordeste",
 "CTM<TUN>	c	Centre de Biotechnologie de Sfax culture collection",
@@ -1361,6 +1406,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CUP	s	Cornell University, Plant Pathology Herbarium",
 "CUP<CHN>	s	Catholic University of Peking",
 "CUP<CZE>	s	Charles University",
+"CURLA	h	Centro Universitario Regional del Litoral Atlantico",
 "CUS	s	Cusino Wildlife Research Station, Natural Resources Department",
 "CUSC	s	Clemson University, Vertebrate Collections",
 "CUVC<COL>	s	Universidad del Valle, Departamento de Biologia",
@@ -1385,6 +1431,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "CYP	s	Ministry of Agriculture, Natural Resources and Environment, Forestry Department",
 "CZAA	s	Catedra de Zoologia Agricola",
 "CZACC	s	Coleccion Zoologia, Academia de Ciencias de Cuba",
+"CZH	h	Hanshan Normal University",
 "CZIP	s	Universidad de Magallanes, Instituto de la Patagonia (Chile)",
 "CZL	s	Centro de Zoologia",
 "CZRMA	s	Coleccion Zoologica Regional (Mammalia) del Instituto de Historia Natural y Ecologia",
@@ -1396,6 +1443,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DACL	s	London Research Centre",
 "DACT	c	Dept. Agricult. Chem. Technol.",
 "DAFH	s	Department of Agriculture and Fisheries",
+"DAG	h	Mountain Botanical Garden of the  Dagestan Scientific Centre",
 "DAKAR	s	Universite Cheikh Anta Diop, Departement de Biologie Vegetale",
 "DAL	s	Dalhousie University, Biology Department",
 "DANV	s	Umweltamt Darmstadt",
@@ -1405,9 +1453,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DARI	s	Insect Collection, New South Wales Department of Agriculture",
 "DAS	s	Agriculture and Agri-Food Canada",
 "DASF	s	Department of Agriculture, Stock and Fisheries",
+"DAU	h	University of Daugavpils",
 "DAV	s	University of California, Plant Biology",
 "DAVFP	s	Pacific Forestry Centre, Canadian Forest Service",
 "DAVH	s	University of California, Environmental Horticulture Department",
+"DAWES	h	The Dawes Arboretum",
 "DBAI	s	Instituto de Ciencias Biologicas",
 "DBAU	s	Universidade Santa Ursula",
 "DBC	s	University College, Botany Department",
@@ -1442,6 +1492,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DCR	s	Doncaster Museum and Art Gallery",
 "DD	s	Forest Research Institute, Indian Council of Forestry Research and Education, Systematic Botany Discipline",
 "DDFF	s	Departamento de Defensa Fitossanitarista",
+"DDMS	h	Fundacao Universidade Federal da Grande Dourados",
 "DE	s	Debrecen University, Botany Department",
 "DE-CSIRO	c	CSIRO Insect Pathogen Culture Collection",
 "DEBU	s	Ontario Insect Collection, University of Guelph",
@@ -1450,7 +1501,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DEE	s	McManus Galleries, Natural History Department",
 "DEES	s	Universidade de Sao Paulo, Piracicaba",
 "DEFS	s	Universidade de Sao Paulo",
-"DEI	s	Deutsches Entomologisches Institut im ZALF",
+"DEI	s	Senckenberg Deutsches Entomologisches Institut",
 "DEIB	s	Deutsches Entomologisches Institut",
 "DEK	s	Northern Illinois University, Biological Sciences Department",
 "DELS	s	University of Delaware, Plant Science Department",
@@ -1461,6 +1512,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DENH	s	University of New Hampshire",
 "DERM	s	Intermountain Experiment Station",
 "DES	sb	Desert Botanical Garden, Research Department",
+"DEV	h	St. Joseph's College",
 "DEVA	s	Death Valley National Park",
 "DEWV	s	Davis and Elkins College, Biology and Environmental Science Department",
 "DEZA	s	Dipartimento di Entomologia e Zoologia Agraria dell'Universita",
@@ -1485,6 +1537,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DGR:Herp	s	Division of Genomic Resources, University of New Mexico, herpetology tissue collection",
 "DGR:Mamm	s	Division of Genomic Resources, University of New Mexico, mammal tissue collection",
 "DGS	s	The Manx Museum",
+"DGU	h	Daegu University",
 "DGUB	c	Department of Genetics, University of Bratislava",
 "DH	s	Hobart and William Smith Colleges, Biology Department",
 "DHISUB	s	Department of Hydrobiology and Ichthyology, Sofia Univiversity",
@@ -1494,6 +1547,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DHNS	s	Dunbartonshire Natural History Society",
 "DI	s	Universite de Bourgogne, Laboratoire de Phytobiologie Cellulaire",
 "DIA	s	Museu do Dundo",
+"DIAM	h	Universidade Federal dos Vales do Jequitinhonha e Mucuri",
 "DIN	s	Museum National d'Histoire Naturelle",
 "DINH	s	Delta Institute of Natural History",
 "DINO	s	Dinosaur National Monument",
@@ -1504,6 +1558,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DIX	s	Dixie College, Natural History Museum",
 "DKG	s	Juniper Hall Field Centre",
 "DLF	s	Stetson University, Biology Department",
+"DLU	h	Da Lat University",
 "DLY	s	Dudley and Midland Geological and Scientific Society and Field Club",
 "DM<NZ>	s	Dominion Museum",
 "DM<USA-UT>	s	The Dinosaur Museum",
@@ -1515,6 +1570,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DMCU	c	Microbiology Department, Faculty of Science",
 "DMDC	s	Douala Museum",
 "DMFS	s	Crichton Royal Institution Museum",
+"DMHN	h	The University of Newcastle",
 "DMIV	c	Department of Microbiology and Immunology",
 "DMKKU1	c	Department of Microbiology, Faculty of Medicine",
 "DMKKU2	c	Department of Microbiology, Faculty of Medical Science",
@@ -1540,11 +1596,13 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DMUR	c	Department of Mycology",
 "DMVB	c	Department of Microbiology, Veterinary Branch of National Strain Collection",
 "DNA	s	Department of Natural Resources, Environment and the Arts",
+"DNAP	h	Department of Primary Industry and Fisheries",
 "DNATAX	b	DNA-TAX",
 "DNHM<CHN>	s	Dalian Museum of Natural History",
 "DNHM<USA-UT>	s	Dinosaur Natural History Museum",
 "DNPM	s	Setor de Paleontologia do Departamento Nacional de Producao Mineral",
 "DNS	s	Dundee Naturalists' Society",
+"DNZ	h	Donetsk Botanical Garden of the National Academy of Sciences of Ukraine",
 "DO	s	Societe d'Agriculture Sciences et Arts",
 "DOA	c	Department Of Agriculture, Thailand",
 "DOMO	s	Collegio Mellerio Rosmini",
@@ -1574,10 +1632,12 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DSIR	s	Department of Scientific and Industrial Research",
 "DSM	c	Deutsche Sammlung von Mikroorganismen und Zellkulturen GmbH",
 "DSM<TZA>	s	University of Dar es Salaam, Botany Department",
+"DSMZ	c	Deutsche Sammlung von Mikroorganismen und Zellkulture",
 "DSP	s	Fitzsimon's Snake Park",
 "DSSC<USA-CA>	b	Drosophila Species Stock Center",
 "DSU	s	Dnipropetrovsk National University, Department of Geobotany, Soil, and Ecology",
 "DSY	s	Dewsbury Museum",
+"DTE	h	Centro de Investigaciones Cientificas y Transferencia de Tecnologia a la Produccion (CICyTTP-CONICET)",
 "DTIC	s	Departamento Parasitologia",
 "DTN	s	Darlington and Teesdale Naturalists' Field Club",
 "DU	s	Duke University Vertebrate Collection",
@@ -1585,12 +1645,15 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DUBN	s	Dublin Naturalists' Field Club",
 "DUE	s	University of Dundee",
 "DUF	s	University of Dicle, Biological Department, Botany",
+"DUGAND	h	Universidad del Atlantico",
 "DUH	s	University of Delhi, Botany Department",
 "DUIS	s	Universitaet Duisburg, Fachbereich 6, Botanik",
 "DUKE	s	Duke University, Biology Department",
 "DUL	s	University of Minnesota, Biology Department",
 "DUM<IND>	c	Delhi University Mycological Herbarium",
 "DUM<TUR>	s	Zooligical Museum of Science and Art Faculty",
+"DUOF	h	Duzce University",
+"DUP	h	Dumlupinar University",
 "DUR	s	Southeastern Oklahoma State University, Biological Sciences Department",
 "DUSS	s	Universitaet Duesseldorf",
 "DVBID	c	Division Vector-Borne Infectious Diseases",
@@ -1602,6 +1665,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "DVZUT	s	Department of Vertebrate Zoology",
 "DWC	s	West Chester University, Biology Department",
 "DWN	s	Darwen Library",
+"DWP	h	Disney Wilderness Preserve/The Nature Conservancy",
 "DWT	c	Wood Technology and Forest Research Division",
 "DWU	s	Dakota Wesleyan University, Biology Department",
 "DZCU	s	Calcutta University",
@@ -1621,6 +1685,8 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "EA	s	National Museums of Kenya",
 "EAA	s	Estonian Agricultural University",
 "EAC	s	Universidade Federal do Ceara, Departamento de Biologia",
+"EAFM	h	Instituto Federal de Educacao, Ciencia e Tecnologia do Amazonas",
+"EALA	h	Jardin Botanique d'Eala",
 "EAN	s	Universidade Federal da Paraiba, Campus III - CCA, Departamento de Fitotecnia",
 "EAP	s	Escuela Agricola Panamericana",
 "EAPZ	s	Escuela Agricola Panamericana",
@@ -1633,6 +1699,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "EBE	s	Eastbourne Museum",
 "EBF	s	Hubei Forestry Institute",
 "EBH	s	Botanical Society of Edinburgh",
+"EBL	h	Ecosystem Research and Development Bureau",
 "EBMC	s	Universidad de Chile",
 "EBMTV	s	Estacion de Biologia Marina del Instituto Tecnologico de Veracruz",
 "EBNHS	s	Edinburgh Natural History Society",
@@ -1643,6 +1710,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ECACC	c	European Collection of Authenticated Cell Cultures",
 "ECENT	s	East Central University",
 "ECH	s	Elmira College",
+"ECK	h	Buffalo State College",
 "ECM	s	Hubei College of Traditional Chinese Medicine, Department of Chinese Materia Medica",
 "ECNB	s	Escuela Nacional Ciencias",
 "ECO-SC-M	s	Coleccion Mastozoologica de El Colegio de la Frontera Sur Unidad San Cristobal de las Casas, Chiapas",
@@ -1654,9 +1722,14 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ECOSUR	s	El Colegio de la Frontera Sur (Mexico)",
 "ECSC	s	East Central University, Biology Department",
 "ECSFI	s	East China Sea Fisheries Institute",
+"ECU	h	Edith Cowan University",
+"ECUAMZ	h	Universidad Estatal Amazonica",
+"ECUH	h	East Carolina University",
+"ECWP	h	Emirates Centre for Wildlife Propagation",
 "EDC	s	Hubei Institute for Drug Control",
 "EDH	s	Plinian Society",
 "EDNC	s	Raleigh, North Carolina Department of Agriculture",
+"EDTU	h	Trakya Universitesi",
 "EEBP	s	Estacao Experimental de Biologia e Piscicultura de Pirassununga",
 "EELM	s	Estacion Experimental Agricola de la Molina",
 "EERU	s	Economic Entomology  Research Unit",
@@ -1684,6 +1757,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "EKU	s	Eastern Kentucky University",
 "EKY	s	Eastern Kentucky University, Biological Sciences Department",
 "ELCAK	s	Entomological Laboratory, College of Agriculture",
+"ELH	h	Bureau of Land Management, Eagle Lake Field Office",
 "ELM	s	East London Museum",
 "ELMF	s	Augusta, Maine Forest Service",
 "ELN	s	Elgin Museum",
@@ -1700,6 +1774,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "EMEC	s	Essig Museum of Entomology",
 "EMET	s	Faculty of Agriculture, Entomology Museum",
 "EMMA	s	Universidad Politecnica de Madrid, Unidad Docente Botanica, Departamento Silvopascicultura",
+"EMNH	h	The Everhart Museum of Natural History, Science & Art",
 "EMPARN	c	Empresa de Pesquisa Agropecuaria do Rio Grande do Norte",
 "EMU	s	Eastern Michigan University, T. L. Hankinson Vertebrate Museum",
 "EMUS	s	Utah State University",
@@ -1709,6 +1784,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ENCB<MEX-Mexico City>	s	Instituto Politecnico Nacional",
 "ENG	s	Royal Holloway College, University of London, Botany Department",
 "ENIH	s	National Institute of Health",
+"ENLC	h	Eastern Nevada Landscape Coalition",
 "ENMU	s	Eastern New Mexico University, Natural History Museum",
 "ENMUNHM	s	Eastern New Mexico University, Natural History Museum",
 "ENP	s	Everglades National Park",
@@ -1725,10 +1801,12 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "EPM	s	Epsom College Museum",
 "EPN	s	Escuela Polytecnica Nacional",
 "EPRL	s	University of Puerto Rico",
+"EPU	h	Centre de Formation et de Recherche en Conservation Forestiere",
 "ER	s	Universitaet Erlangen-Nuernberg, Geobotanik",
 "ERA	s	Universidad Nacional de Entre Rios, Botanica Sistematica",
 "ERAEP	c	Radiation Ecology Section, Biological Science Division, Office of Atomic Energy for Peace",
 "ERCB	s	Yerevan State University, Botany Department",
+"ERCH	h	Erciyes University",
 "ERCULE	c	European Rumen Ciliate Culture Collection, Rowett Research Institute",
 "ERE	s	Institute of Botany of the National Academy of Sciences of Armenia, Department of Plant Taxonomy and Geography",
 "EREM	s	Institute of Botany of the National Academy of Sciences of Armenia, Mycology Department",
@@ -1754,7 +1832,10 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ETH<CHE>	c	Kultursammlungen der Eidgenosische Technische Hochschule",
 "ETH<ETH>	s	Addis Ababa University, Biology Department",
 "ETHZ	s	Eidgenoessische Technische Hochschule-Zentrum",
+"ETL	h	Lake Forest College",
 "ETN	s	Eton College Museum",
+"ETNH	h	Jarvis Christian College",
+"ETON	h	Eton College Museum",
 "ETST	s	Texas A&M University, Biology Department",
 "ETSU	s	East Tennessee State University, Biological Sciences Department",
 "EU	s	Hubei University, Biology Department",
@@ -1764,13 +1845,16 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "EUSL	c	Eastern University",
 "EVA	c	European Virus Archive",
 "EVCV	s	Erster Vorarlberger Coleopterische Verein",
+"EVE	h	The Evergreen State College",
 "EVMU	s	Everhart Museum, Natural History Department",
 "EWH	s	Ewha Womans University",
+"EWM	h	Elizabeth Winston Mize Herbarium",
 "EWNHM	s	Ewha Womens University, Natural History Museum",
 "EX	c	The Culture Collection of Extremophilic Fungi",
 "EXN	s	Exton Hall",
 "EXR	s	University of Exeter, Biological Sciences Department",
 "F	s	Field Museum of Natural History, Botany Department",
+"FAA	h	Universidad Nacional del Centro de la Provincia de Buenos Aires",
 "FABR	s	Harmas de J. H. Fabre",
 "FACHB	c	Freshwater Algae Culture Collection",
 "FACS	s	Fujian Agricultural College",
@@ -1818,10 +1902,12 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "FDNR	s	Florida Department of Natural Resources",
 "FDUC	s	Fairleigh Dickinson University [collection transferred to FSCA].",
 "FDVC	s	De La Villa, Francisco",
+"FEN	h	Lycee Felix Esclangon, Region PACA",
 "FER	s	Universita de Ferrara, Dipartimento di Biologia - Sezione di Botanica",
 "FERM	c	Patent and Bio-Resource Center, National Institute of Advanced Industrial Science and Technology (AIST)",
 "FEZA	s	Universidad Nacional Autonoma de Mexico, Carrera de Biologia",
 "FFB	s	Atlantic Forestry Centre, Canadian Forest Service",
+"FFBNM	h	Florissant Fossil Beds National Monument",
 "FFCL	s	Nossa Senhora do Patrocinia",
 "FFR	s	Forfar Museum and Art Gallery, Meffan Institute",
 "FFS	s	University of Stellenbosch",
@@ -1884,6 +1970,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "FMR	c	Facultad de Medicina",
 "FMRI	s	Central Marine Fisheries Marine Research Institute",
 "FMSS	s	Parque Zoological Nacional \"Finca Modelo\", Natural History Museum",
+"FMUH	h	Francis Marion University",
 "FNCC	c	Food and Nutrition Culture Collection",
 "FNFR	s	Fishlake National Forest",
 "FNLO	s	Fremont National Forest",
@@ -1893,6 +1980,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "FNPS	s	South Florida Collections Management Center, Everglades National Park",
 "FNU<CHN>	s	Fujian Normal University",
 "FNU<JPN>	s	Nagasaki University - Fisheries",
+"FOF	h	National University of Laos",
 "FOR	s	Forssa Museum of Natural History",
 "FOSJ	s	Fisheries and Oceans Biological Station",
 "FPDB	s	Universidad de Puerto Rico, Departamento de Ciencias Marinas",
@@ -1942,6 +2030,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "FTCMU	c	Department of Food Science and Technology, Faculty of Agriculture",
 "FTG	sb	Fairchild Tropical Botanic Garden",
 "FTI	c	Centro de Biotecnologia e Quimica-CEBIQ",
+"FTOH	h	Forestry Training Institute, Olmotonyi",
 "FTS	s	Fuzhou Teachers College, Biology Department",
 "FTU	s	University of Central Florida, Biology Department",
 "FU<CHN>	s	Fudan University, Department of Biology",
@@ -1951,9 +2040,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "FUEL	s	Universidade Estadual de Londrina, Departamento de Biologia Animal e Vegetal",
 "FUGR	s	Furman University, Biology Department",
 "FUH	s	Firat Ueniversitesi",
+"FUK	h	Fukui Botanical Garden",
 "FULD	s	Verein fuer Naturkunde in Osthessen",
 "FUMH	s	Ferdowsi University",
 "FUMT	s	University of Tokyo",
+"FURB	h	Universidade Regional de Blumenau",
 "FUS	s	Fudan University, Biology Department",
 "FUSC	c	Flinders University Smut Collection",
 "FVCC	s	Flathead Valley Community College, Biology Department",
@@ -1971,12 +2062,14 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "GABAS	s	Centre d'Etude et de Conservation des Resources Vegetales",
 "GAC	s	Guangxi Agricultural University, Forestry Department",
 "GACP	s	Guizhou Agricultural College, Department of Plant Protection",
+"GADI	h	Grootfontein Agricultural Development Institute",
 "GAES	s	Georgia Agricultural Experiment Station",
 "GAFS	s	Ganzhou Forestry School",
 "GAI	s	Folk Museum",
 "GALW	s	National University of Ireland, Galway, Botany Department",
 "GAM<USA-GA>	s	University of Georgia",
 "GAM<VEN>	c	Grupo Actinomicetales Merida Facultad de Medicina",
+"GAP	h	Conservatoire Botanique National Alpin",
 "GAS	s	Georgia Southern University, Department of Biology",
 "GAT	s	Institute of Plant Genetics and Crop Plant Research",
 "GAUA	s	Guangxi University",
@@ -1987,6 +2080,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "GB	s	Goeteborg University, Department of Plant and Environmental Sciences",
 "GBFM	s	Universidad de Panama",
 "GBG<SWE>	b	Goteburg Botanical Garden",
+"GBH	h	Herbarium of Geo. B. Hinton",
 "GBNM	s	Glacier Bay National Park and Preserve Museum",
 "GBY	s	Grimsby Arts and Natural History",
 "GC<GHN>	s	University of Ghana, Botany Department",
@@ -1997,8 +2091,10 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "GCNP	s	Grand Canyon National Park",
 "GCRL	s	Gulf Coast Research Laboratory",
 "GCTP	s	Global Colosseum",
+"GCU	h	Gachon University",
 "GDA	s	Universidad de Granada",
 "GDAC	s	Universidad de Granada, Departamento de Biologia Vegetal, Botanica",
+"GDB	h	Herbarium de Gerard de Belair",
 "GDGM	s	Guangdong Institute of Microbiology",
 "GDMA	s	Medical University of Gdansk, Department of Biology and Pharmaceutical Botany",
 "GDMCC	c	Guangdong Microbial Culture Collection Center",
@@ -2019,6 +2115,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "GFND	s	University of North Dakota, Biology Department",
 "GFRC	s	Golestan Fisheries Research Centre",
 "GFS	s	Guizhou Forestry School",
+"GFT	h	Grumeti Fund Tanzania",
 "GFW	s	Ernst-Moritz-Arndt-Universitaet, Botanisches Institut und Botanischer Garten",
 "GGB	s	Gesneriad Gardens",
 "GGM	s	Gosudarstvennyi Geologicheskii Musei - State Geological Museum",
@@ -2033,10 +2130,12 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "GI	s	Justus-Liebig-Universitat Giessen",
 "GI-SPS	s	Geological Institute, Section of Palaeontology and Stratigraphy",
 "GIFU<JPN>	s	Herbarium of Gifu Pharmaceutical University",
+"GINCO	h	Agriculture and Agri-Food Canada",
 "GIUV	s	Geological Institute, University of Vienna",
 "GJO	s	Steiermaerkisches Landesmuseum Joanneum, Botany Department",
 "GKAR	s	Karoo National Botanical Garden",
 "GL	s	University of Glasgow, Botany Department",
+"GLA	h	George Landis Arboretum",
 "GLAC	s	Glacier National Park, Glacier Collection",
 "GLAHM	s	University of Glasgow, Hunterian Museum",
 "GLAM	s	Art Gallery and Museum, Natural History Department",
@@ -2058,6 +2157,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "GMBL	s	College of Charleston",
 "GMC	s	Guangxi Medical College",
 "GMCE	s	Grosvenor Museum",
+"GMDRC	h	Granite Mountains Desert Research Center",
 "GMH	s	Sammlung Jacobi des Geiseltalmuseum Halle",
 "GMHH	s	Geological Museum of Heilongjang Province",
 "GML<USA-IL>	s	Gorgas Memorial Laboratory",
@@ -2066,6 +2166,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "GMNH-PV	s	Paleo-Vertebrate Collection",
 "GMNH<SWTZ>	s	Museum d'Histoire Naturelle",
 "GMNH<USA-GA>	s	Georgia Museum of Natural History",
+"GMNHJ	h	Gunma Museum of Natural History",
 "GMNP	s	Gros Morne National Park",
 "GMS	s	Hopkins Marine Station, Stanford University, Biological Sciences Department",
 "GMU	s	N. P. Ogariov Mordovia State University, Department of Botany and Plant Physiology",
@@ -2074,6 +2175,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "GMUM	s	Institut fuer Palaeontologie und Geologisches Museum der Universitat",
 "GMUV	s	Geological Museum, University of Vienna",
 "GNA	s	Gannan Arboretum of Jiangxi",
+"GNDUH	h	Guru Nanak Dev University",
 "GNE	c	Genentech",
 "GNHM	s	Goulandris Natural History Museum",
 "GNHNA	s	Gallery of Natural History and Native Art",
@@ -2089,6 +2191,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "GOE<GBR>	s	Goole Scientific Society",
 "GOET	s	Herbarium Universitat Gottingen",
 "GOFS	s	Free State National Botanical Garden",
+"GOPU	h	Gaziosmanpasa University",
 "GOW	s	Clydebank High School",
 "GP	s	Instituto de Geociencias, Universidade de Sao Paulo",
 "GPA	s	Grande Prairie Regional College, Science Department",
@@ -2118,6 +2221,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "GRSM	s	Great Smoky Mountains National Park",
 "GRSU	s	Yanka Kupala Grodno State University, Department of Botany",
 "GRSW	s	Desert Ecological Research Unit",
+"GRTE	h	Grand Teton National Park",
 "GSAT	s	The Geological Survey of Alabama",
 "GSC	s	Geological Survey of Canada",
 "GSDNM	s	Great Sand Dunes National Monument",
@@ -2136,14 +2240,18 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "GTNP	s	Grand Teton National Park",
 "GTV	s	Gregorio T. Velasquez Phycological Herbarium",
 "GU	s	Gotland University, Department of Biology",
+"GU-IITG	s	for Gauhati University- Indian Institute of Technology Guwahati",
 "GUA	s	DIVEA, DEP, FEEMA, FEEMA",
 "GUAD	s	Institut National de la Recherche Agronomique and Parc National de Guadeloupe",
 "GUADA	s	Universidad Autonoma de Guadalajara",
 "GUAM	s	University of Guam, Biology Department",
 "GUAT	s	Herbario Ulises Roja",
 "GUAY	s	Universidad de Guayaquil",
+"GUBH	h	Gauhati University",
 "GUBIOTJT	c	Freshwater microalgae collection and culture laboratory",
+"GUCM	h	Guangzhou University of Chinese Medicine",
 "GUH	s	HNB Garhwal University, Botany Department",
+"GUL	h	Suleyman Demirel University",
 "GUM	s	Glasgow University Museum (Hunter Museum)",
 "GUM<IRN>	s	Mycological herbarium of University of Guilan",
 "GUMACC	c	Gotheburg University Marine Algal Culture Collection",
@@ -2175,25 +2283,32 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HACC	s	Academia de Ciencias Camagueey",
 "HACW	s	Department of Fishery, Huazhong Agriculture Collection",
 "HAF	s	Hainan Forestry Institute",
+"HAH	h	Hoyt Arboretum",
+"HAI	h	University of Haifa",
 "HAJB	s	Jardin Botanico Nacional",
+"HAJU	h	Herbario Dr. Armando Jesus Urquiola",
 "HAK	s	Hokkaido University, Faculty of Fisheries",
 "HAKS	s	Hakgala Botanic Gardens",
 "HAL	s	Martin-Luther-Universitaet",
 "HALA	s	University of Alabama, Biological Sciences Department",
+"HALE	h	Haleakala National Park",
 "HALLE	s	Zoologisches Institut der Martin-Luther Universitaet",
 "HALLST	s	Botanische Station",
+"HALN	h	State Agency for Environmental Protection Saxony-Anhalt",
 "HALX	s	Halifax Literary and Philosophical Society",
 "HAM	s	Royal Botanical Gardens",
 "HAMAB	s	Instituto de Pesquisas Cientificas e Tecnologicas do Estado do Amapa",
 "HAMBI	c	HAMBI Culture Collection",
 "HAMU	s	University of Newcastle upon Tyne",
 "HAN	s	Universitaet Hannover",
+"HANC	h	National Aquarium of Cuba",
 "HANU	s	Harbin Normal University, Biology Department",
 "HAO	s	Universidad Privada Antenor Orrego",
 "HAQ	s	Institut der Technische Hochschule (RWTH), Institut fuer Biologie I",
 "HAS	s	Fundacao Zoobotanica do Rio Grande do Sul",
 "HAST	s	Research Center for Biodiversity, Academia Sinica",
 "HASU	s	Universidade do Vale do Rio dos Sinos - CCS/ Centro 2",
+"HAU	h	Alzahra University",
 "HAUH	s	Haryana Agricultural University",
 "HAVI	s	Eastern Mennonite University, Biology Department",
 "HAVO	s	Hawaii Volcanoes National Park",
@@ -2201,6 +2316,8 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HAX	s	Belle Vue Museum",
 "HAY	s	California State University, Biological Sciences Department",
 "HB	s	Herbarium Bradeanum",
+"HBA	h	National Botanic Garden of Latvia",
+"HBARC	h	Bhabha Atomic Research Centre",
 "HBAU	s	Hebei Agricultural University",
 "HBAUD	s	Hebei Agricultural University, Handan Branch, Agriculture Department",
 "HBBS	s	Museo Civico di Scienze Naturali",
@@ -2215,13 +2332,17 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HBNU	s	Hebei Normal University, Biology Department",
 "HBOM	s	Harbor Branch Oceanographic Museum",
 "HBR	s	Universidade Federal de Santa Catarina",
+"HBRA	h	Universidade Federal do Para, Campus Braganca",
 "HBUM	s	College of Life Sciences Hebei Univesity, Baoding",
 "HC	s	Hangchow Christian College",
 "HCAT	s	University of Tabriz, Landscape Department",
 "HCB	s	Universidade de Santa Cruz do Sul, Departamento de Biologia",
 "HCCA	s	Hastings College",
+"HCCN	h	National Institute of Agricultural Science and Technology",
 "HCCV	s	Hastings College, Collection of Vertebrates",
+"HCDAL	h	Universidade Regional do Cariri",
 "HCEN	s	Universidad Nacional del Centro del Peru",
+"HCF	h	Universidade Tecnologica Federal do Parana",
 "HCH	s	Lewis-Clark State College, Natural Sciences Department",
 "HCHM	s	Hope College, Biology Department",
 "HCIB	s	Centro de Investigaciones Biologicas del Noroeste, S. C.",
@@ -2230,9 +2351,12 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HCMZ	s	Hope College",
 "HCNHSC	s	Ohio Historical Society, Natural History Synoptic Collection",
 "HCOA	s	College of the Atlantic, Herbarium",
+"HCOM	h	Centre d'Oceanologie de Marseille - University of Aix-Marseille II",
 "HCT	s	Taiwan Forestry Research Institute",
 "HCTR	s	Hoogstraal Center for Tick Research",
+"HDCF	h	Department of Forestry Science",
 "HDD	s	Tolson Museum, Natural History Department",
+"HDJF	h	Universidade Federal dos Vales do Jequitinhonha e Mucuri",
 "HDOA	s	Hawaii Department of Agriculture",
 "HDSM	s	University of Massachusetts Dartmouth",
 "HDTC	s	Huddersfield Technical College",
@@ -2244,6 +2368,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HEH	s	Escuela Nacional de Ciencias Forestales, Departamento de Investigacion Forestal Aplicada",
 "HEID	s	Universitaet Heidelberg, Heidelberger Institut fuer Pflanzenwissenschaften",
 "HEL	s	University of Helsinki, Section of Botany",
+"HEM	h	Universidad de Ciencias y Artes de Chiapas",
 "HEMS	s	Haslemere Educational Museum",
 "HENA	s	Escuela Nacional de Agricultura",
 "HEND	s	Henderson State University, Biology Department",
@@ -2252,16 +2377,22 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HEPH	s	Jardim Botanico de Brasilia",
 "HER<CAN>	c	Felix d'Herelle Reference Center for Bacterial Viruses",
 "HER<ZAF>	s	Hermanus Botanical Society",
+"HERBAM	h	Universidade do Estado de Mato Grosso",
+"HERT	h	Fundacao Universidade Estadual do Ceara",
 "HERZ	s	Herzen State Pedagogical University of Russia, Department of Botany",
 "HERZU	s	Universidad del Zulia",
+"HEUS	h	Universidad de Sucre",
 "HF	s	Universidade Federal do Para",
 "HFB	s	Hainan Forestry Bureau",
 "HFBG	s	Forestry Botanical Garden of Heilongjiang",
 "HFCC	c	Flagellate Culture Collection, University of Cologne",
 "HFD	s	Hereford Museum",
+"HFLA	h	Sapienza University of Rome - Scuola di Specializzazione in Beni Naturali e Territoriali",
+"HFN	h	Herbarium Frisicum",
 "HFP	c	Hokkaido Forest Products Research Institute",
 "HFR	s	Finnish Forest Research Institute",
 "HFRI	s	Hunan Forestry Research Institute",
+"HFSL	h	Centro de Ensino, Faculdade Sao Lucas Ltda.",
 "HFU	s	Herbarium of Fayoum University",
 "HFV	s	Universidad Austral de Chile, Instituto de Produccion y Sanidad Vegetal",
 "HFX	s	Bankfield Museum and Art Gallery",
@@ -2269,8 +2400,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HGCRL	s	Gulf Coast Research Laboratory",
 "HGI	s	Universitat de Girona, Unitat de Biologia Vegetal",
 "HGM	s	Hunan Geological Museum",
+"HGOM	h	Universidad Autonoma del Estado de Hidalgo",
 "HGS	s	Public Museum and Art Gallery, St. John's Place",
 "HGTC	s	Huanggang Teachers College, Biology Department",
+"HGU	h	Khakass State University",
+"HH	h	Instituto de Investigaciones de la Amazonia Peruana",
 "HHBG	s	Hangzhou Botanical Garden",
 "HHC	s	University of Helsinki, Horticulture Department",
 "HHH	s	Hartwick College",
@@ -2279,6 +2413,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HHUA	s	Universidad Nacional de Huanuco Hermilio Valdizan",
 "HHUF	s	Hirosaki University, Laboratory of Plant Pathology",
 "HIB	s	Wuhan Institute of Botany",
+"HIBG	h	Hiroshima Botanical Garden",
 "HIC	s	University of Kentucky, Department of Entomology, Hymenoptera Institute Collection",
 "HIFP	s	French Institute",
 "HILL	s	Sir Harold Hillier Gardens",
@@ -2288,9 +2423,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HIPC	s	Instituto Superior Pedagogico Jose Marti, Departamento de Biologia",
 "HIRO	s	Hiroshima University, Biological Science Department",
 "HIRU	s	Okayama University of Science",
+"HISA	h	Universidade Estadual Paulista",
 "HITBC	s	Xishuangbanna Tropical Botanical Garden, Chinese Academy of Sciences",
 "HIUW	s	Hygiene-Institut der Universitaet",
 "HIWNT	s	Hampshire and Isle of Wight Naturalists' Trust Ltd.",
+"HJBC	h	Jardin Botanico Culiacan",
 "HJBL	s	Escuela Nacional de Ciencias Forestales",
 "HJBS	s	Fundacio Jardi Botanic de Soller",
 "HK	s	Agriculture, Fisheries, and Conservation Department",
@@ -2299,32 +2436,41 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HKFRS	s	Hong Kong Fisheries Research Station",
 "HKGL	s	Naturwissenschaftliche Sammlungen des Kantons Glarus",
 "HKI	c	Hans-Knoll Institute",
+"HKM	h	University of Comoros",
+"HKS	h	Research Center of Agricultural and Natural Resources Kurdistan Province",
 "HKU	s	University of Hong Kong, Ecology and Biodiversity Department",
 "HKUCC	c	The University of Hong Kong Culture Collection",
 "HL	s	Houghton Lake Wildlife Research Station, Natural Resources Department",
 "HLA	s	Harold L. Lyon Arboretum",
 "HLCM	s	Heilongjiang College of Traditional Chinese Medicine, Department of Chinese Materia Medica",
 "HLD	s	Hessisches Landesmuseum",
+"HLDG	h	Las Cruces Biological Station, Organization for Tropical Studies",
 "HLL	s	Queen's Gardens, College of Higher Education, Natural Science Department",
 "HLMA	s	Town Docks Museum, Hull City Corporation",
 "HLMD	s	Hessisches Landesmuseum Darmstadt",
 "HLNM	s	Heilongjiang Provincial Museum",
 "HLO	s	Vlastivedne Muzeum v Hlohovci",
+"HLSD	h	Hillsdale College",
 "HLU	s	University of Hull, Botany Department",
 "HLUC	s	Universita degli Studi della Basilicata, Dipartimento di Biologia Difesa e Biotecnologie Agroforestali",
 "HLUL	s	University of Hull",
 "HLX	s	Ovenden Naturalists' Society",
 "HM<DEU>	s	Humbolt Museum",
 "HM<USA-NE>	s	Hastings Museum",
+"HMAR	h	Universidade Federal do Ceara",
 "HMAS	sc	Institute of Microbiology, Academia Sinica",
 "HMC	s	Jardin Botanico de Las Tunas",
 "HME	s	Haslemere Educational Museum",
+"HMGBH	h	Giardini Botanici Hanbury / Hanbury Botanic Gardens",
 "HMH	s	Hoebarth Museum Horn",
+"HMIM	h	Jardi Botanic Marimurtra",
 "HMJAU	sc	Herbarium of Mycology of Jilin Agricultural University",
 "HMLN	s	District Museum",
 "HMM	s	Horsham Museum",
+"HMMNH	h	Macedonian Museum of Natural History",
 "HMN	s	Humbolt Museum fur Naturkunde, East Berlin",
 "HMNH	s	Hayashibara Museum of Natural History",
+"HMNR	h	Mordovian State Nature Reserve",
 "HMNS	s	Houston Museum of Natural Science",
 "HMNT	s	Hancock Museum, Newcastle University",
 "HMP	s	Hornonitrianske muzeum, Department of Natural History",
@@ -2333,22 +2479,28 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HN	s	National Center for Natural Sciences and Technology, Botany Department",
 "HNBU	s	Institut de l'Environnement et de Recherche Agricola (INERA)",
 "HNCMB	c	Hungarian National Collection of Medical Bacteria",
+"HNG	h	Universite. Gamal Abdel Nasser de Conakry",
 "HNH	s	Dartmouth College, Biological Sciences Department",
 "HNHH	s	Heilongjiang Natural History Museum",
 "HNHM<HUN>	s	Hungarian Natural History Museum (Termeszettudomanyi Muzeum)",
 "HNHM<HUN>:Moll	c	Hungarian Natural History Museum (Termeszettudomanyi Muzeum), Mollusca Collection",
 "HNHM<KOR>	s	Hannam University, Department of Biology",
+"HNHPS	h	Hunan Hupingshan National Nature Reserve",
 "HNHR	s	University of California, Hastings Natural History Reservation",
 "HNIP	s	Hanoi College of Pharmacy",
+"HNL	h	Conseil National des Sciences",
+"HNM	h	Ecole Normale Superieure de Nouakchott",
 "HNMN	s	Universidad Centroamericana",
 "HNN	s	Horniman Museum of Natural History",
 "HNNU	s	Hunan Normal University, Botany Department",
+"HNPGBI	h	Seed and Plant Improvement Institute",
 "HNR	s	Heilongjiang Academy of Sciences",
 "HNT	s	Huntington Botanical Gardens",
 "HNTS	s	Vlastivedne muzeum",
 "HNU<CHN>	s	Hunan Normal University",
 "HNU<VNM>	s	Vietnam National University, Department of Botany",
 "HNUB	s	Northeastern University, Biology Department",
+"HNUL	h	Northwestern University Inc.",
 "HNWP	s	Northwest Plateau Institute of Biology, Chinese Academy of Sciences",
 "HNWU	s	Nebraska Wesleyan University, Biology Department",
 "HO	s	Tasmanian Museum & Art Gallery",
@@ -2357,11 +2509,16 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HOMP	s	Okresni muzeum Pribram Brezove Hory",
 "HON	s	Sichuan Grassland Research Institute",
 "HOU	s	University of Houston",
+"HOXA	h	Estacion biologica del Jardin Botanico de Missouri",
+"HPAN	h	University of the State of Mato Grosso, UNEMAT",
+"HPBR	h	Universidade Regional Integrada do Alto Uruguai e das Missoes",
 "HPC	s	Howard Payne University, Biology Department",
 "HPD	s	Hampstead Scientific Society",
 "HPDL	s	Hampstead Public Library",
 "HPH	s	Monroe County Department of Parks",
+"HPL	h	Jardim Botanico Plantarum",
 "HPM	s	Houston Museum of Natural Science",
+"HPNP	h	Pumat National Park",
 "HPP	s	University of Helsinki, Plant Biology Department",
 "HPPR	s	Instituto Superior Pedagogico de Pinar del Rio, Departamento de Biologia",
 "HPSU	s	Portland State University, Biology Department",
@@ -2372,20 +2529,26 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HR	s	Muzeum Vychodnich Cech",
 "HRB	s	IBGE",
 "HRCB	s	Universidade Estadual Paulista",
+"HREC	h	Hopland Research & Extension Center",
 "HRJ	s	Universidade do Estado do Rio de Janeiro, Departamento de Biologia Animal e Vegetal",
 "HRP	s	Universidad Nacional de La Patagonia, Departamento Biologia General",
 "HSB	s	Universidad Mayor Real y Pontificia de San Francisco Xavier de Chuquisaca",
+"HSBU	h	Shahid Beheshti University",
 "HSC	s	Humboldt State University, Biological Sciences Department",
 "HSCC	c	Culture Collection of the Research and Development Department",
 "HSI	s	University of Helsinki, Silviculture Department",
 "HSIB	s	Shanxi Institute of Biology, Botany Department",
 "HSIC	s	Ministry of Natural Resources, Solomon Islands",
 "HSM	s	Christ's Hospital, Biology Department",
+"HSMC	h	Whyte Thorne Botanic Garden",
 "HSNU	s	East China Normal University, Biology Department",
+"HSP	h	Instituto Cientifico Michael Owen Dillon",
 "HSS	s	Development, Technological and Investigacion Service, Forest Production Department",
+"HSTM	h	Universidade Federal do Oeste do Para",
 "HSU<USA-CA>	s	Humboldt State University",
 "HSU<USA-TX>	s	Hardin-Simmons University, Biology Department",
 "HSUCV	s	Hardin-Simmons University, Collection of Vertebrates",
+"HSUD	h	Station of Nature Research and Environmental Education",
 "HSUE	s	Natural History Museum, Addis Ababa",
 "HSUMZ	s	Henderson State University, Museum of Zoology",
 "HSUVM	s	Humboldt State University Vertebrate Museum",
@@ -2398,23 +2561,31 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HTO	s	Universidade Federal do Tocantins, Nucleo de Estudos Ambientais",
 "HTTU	s	Tennessee Technological University, Biology Department",
 "HTU	s	University of Taiz, Biology Department",
+"HTW	h	Universidad Nacional de la Patagonia San Juan Bosco",
 "HU	s	University of Zhejiang",
 "HUA	s	Universidad de Antioquia, Centro de Investigaciones",
 "HUAA	s	Universidad Autonoma de Aquascalientes, Departamento de Biologia",
 "HUAL	s	Universidad de Almeria, Departamento de Biologia Vegetal y Ecologia",
 "HUAP	s	Herbario, Universidad Autonoma de Puebla",
+"HUAZ	h	Universidad de la Amazonia",
 "HUB	s	Hacettepe University, Botany Department",
 "HUBE	s	Golden West College, Biology/Life Sciences Department",
 "HUBO	s	Universita degli Studi di Bologna",
 "HUC	s	Universidad de Cordoba, Departamento de Biologia",
 "HUCM	s	Hunan College of Traditional Chinese Medicine, Department of Chinese Materia Medica",
 "HUCP	s	Pontifica Universidade Catolica do Parana, Departamento de Ciencias Biologicas",
+"HUCS	h	University of  Caxias do Sul",
 "HUDC	s	Howard University, Biology Department",
 "HUE	s	Hunan Education College, Biology Department",
 "HUEF	s	Hacettepe Ueniversitesi",
 "HUEFS	s	Universidade Estadual de Feira de Santana, Departamento de Ciencias Biologicas",
+"HUEG	h	Universidade Estadual de Goias",
 "HUEM	s	Universidade Estadual de Maringa, Departamento de Biologia",
+"HUESB	h	Universidade Estadual do Sudoeste da Bahia-Campus de Jequie",
+"HUESBVC	h	Universidade Estadual do Sudoeste da Bahia-Vitoria  da Conquista",
 "HUF	s	Hunan Forestry School",
+"HUFABC	h	Universidade Federal do ABC",
+"HUFSJ	h	Universidade Federal de Sao Joao del-Rei",
 "HUFU	s	Universidade Federal de Uberlandia, Instituto de Biologia",
 "HUIC	s	Hacettepe University Ichthyological Collection",
 "HUIF	s	Hunan Forestry Institute",
@@ -2424,20 +2595,31 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "HUL	s	Fine Arts Museum",
 "HULE	s	Universidad Nacional Autonoma de Nicaragua, Departamento de Biologia",
 "HUM	s	Humbolt University Zoologischen Museum",
+"HUMC	h	Universidade de Mogi das Cruzes",
 "HUMO	s	Universidad Autonoma del Estado de Morelos, Centro de Educacion Ambiental e Investigacion Sierra de Huautla",
 "HUMP	s	Muzeum v Humpolci",
 "HUMZ	s	Hokkaido University, Laboratory of Marine Zoology",
+"HUNEB	h	Universidade do Estado da Bahia",
+"HUNT	h	Huntington University",
+"HUP	h	Hazara University",
 "HUPG	s	State University of Ponta Grossa, Departamento de Biologia",
 "HUQ	s	Universidad del Quindio",
+"HURB	h	Universidade Federal do Reconcavo da Bahia",
 "HURG	s	Universidade do Rio Grande, Departamento de Ciencias Morfo-Biologicas",
+"HUS	h	Siauliai University",
 "HUSA	s	Universidad Nacional de San Agustin de Arequipa, Facultad de Ciencias Biologicas y Agropecuarias, Area de Biomedicas",
+"HUSC	h	Universidade Santa Cecilia - UNISANTA",
 "HUSEC<DEU>	c	Konsiliarlabor fur Hamolytisch-Uramisches Syndrom",
 "HUST	s	Hunan University of Science and Technology, School of Life Sciences",
 "HUT<JPN>	c	HUT Culture Collection",
 "HUT<PER>	s	Herbarium Truxillense, Universidad Nacional de La Libertad-Trujillo",
 "HUTB	s	Hainan University",
+"HUTI	h	Universidad Tecnologica Indoamerica",
 "HUTM	s	Hunan Academy of Traditional Chinese Medicine and Pharmacy",
+"HUTO	s	Fundacao Universidade do Tocantins , UNITINS",
 "HUTPL	s	Universidad Tecnica Particular De Loja",
+"HUVA	h	Universidade Estadual Vale do Acarau",
+"HVASF	h	Universidade Federal do Vale do Sao Francisco",
 "HVR	s	Universidade de Tras-os-Montes e Alto Douro",
 "HWA	s	Southwest Agricultural University, Department of Biological Basic Courses",
 "HWB	s	Harrow School, Biology Department",
@@ -2476,11 +2658,16 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "IAPG	s	Institute of Animal Physiology and Genetics, Academy of Sciences of the Czech Republic",
 "IARI	sb	Indian Agricultural Research Institute",
 "IASI	s	Universitatea Agronomica, Disciplina de Botanica",
+"IAUGH	h	Islamic Azad University Garmsar",
+"IAUH	h	Islamic Azad University",
+"IAUM	h	Islamic Azad University of Mashhad",
+"IAUNT	h	Islamica Azad University, North Tehran Branch",
 "IAV	sb	Institut Agronomique et Veterinaire Hassan II, Departement d'Ecologie Vegetale",
 "IAVH	s	Instituto de Ivestigacion de los Recursos Biologicos Alexander von Humboldt",
 "IB	s	Universitaet Innsbruck",
 "IBA<ESP>	s	Instituto Asturiano de Taxonomia y Ecologia Vegetal",
 "IBA<POL>	c	Collection of Microorganisms Producing Antibiotics",
+"IBAR	h	Ibaraki University",
 "IBAUNC	s	Universidad Nacional de Cuyo, Instituto de Biologia Animal",
 "IBE	s	Institute for Botanical Exploration",
 "IBE<ESP>	s	Institut de Biologia Evolutiva, (CSIC-UPF)",
@@ -2583,6 +2770,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "IEMM	s	Instituto de Ecologia",
 "IENU	s	Istituto di Entomologia, Universita degli Studi",
 "IEPA	s	Istituto di Entomologia Agraria dell'Universita",
+"IER	h	Institut d'Economie Rurale",
 "IEUC	s	Istituto di Entomologia Agraria dell'Universita Cattolica",
 "IEUP	s	Istituto di Entomologia, Universita degli Studi",
 "IEVB	s	Institut de Zoologie [Institut Ed. Van Beneden]",
@@ -2600,6 +2788,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "IFM<JPN>	c	Research Center for Pathogenic Fungi and Microbial Toxicoses, Chiba University",
 "IFO	c	Institute for Fermentation",
 "IFP	s	Institute of Applied Ecology, Academia Sinica",
+"IFRD	h	Research Institute of Resource Insects",
 "IFRDCC	c	International Fungal Research and Development Culture Collection",
 "IFREMER	s	Institut Francais pour l'Etude de la Mer",
 "IFRI	s	Indian Forest Research Institute",
@@ -2612,6 +2801,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "IGCU	s	Instituto de Geologia, Ciudad Universitaria",
 "IGESALQ	c	Colecao Microorganismos",
 "IGF	s	Instituto di Geologia e Paleontologia",
+"IGGDC	h	Institute of Geology and Geophysics, Chinese Academy of Sciences",
 "IGL	s	Institute fuer Geowissenschaften Leoben",
 "IGM<MEX>	s	Instituto de Geologia",
 "IGM<MNG>	s	Geological Institute, Mongolian Academy of Sciences",
@@ -2650,6 +2840,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "IMAU	c	Inner Mongolia Agricultural University, Key Laboratory of Dairy Biotechnology and Engineering",
 "IMC	s	Sichuan Academy of Traditional Chinese Medicine and Pharmacy",
 "IMCC	c	Inha Microbe Culture Collection, Inha University",
+"IMCN	s	Instituto Vallecaucano de Investigaciones Cientificas",
 "IMD	c	Industrial Microbiology Dublin",
 "IMD<CHN>	s	Institute of Medicinal Plant Development, Chinese Academy of Medical Sciences",
 "IMDC	s	Inner Mongolia Institute for Drug Control",
@@ -2689,8 +2880,10 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "IND-M	s	La Unidad de Investigacion \"Federico Medem\"-Inderena (Colombia)",
 "INDRE	c	Pathogen Fungi and Actinomycetes Collection",
 "INEGI	s	Instituto Nacional de Estadistica Geografia e Informatica, Departamento de Botanica",
+"INEP	h	Institute of the Industrial Ecology Problems of the North of Kola Science Center of the Russian Academy of Sciences.",
 "INER	s	Istituto Nazionale di Entomologia",
 "INFYB	s	Instituto Nacional de Farmacologia y Bromatologia, Farmacobotanica",
+"INGU	h	Ingush State University",
 "INH	s	Institut National d'Horticulture, Departement de Sciences Biologiques",
 "INHM	s	Iraq Natural History Museum",
 "INHS	s	Illinois Natural History Survey",
@@ -2715,6 +2908,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "INRA	b	Institut National de la Recherche Agronomique",
 "INRA:CGAB	cb	Institut National de la Recherche Agronomique, Collection of Germplasms of Agaricus bisporus",
 "Insitute of Biology and Soil Science, Russian Academy of Sciences	s	Insitute of Biology and Soil Science, Russian Academy of Sciences",
+"INU	h	Inonu University",
 "INV	s	Inverness Museum and Art Gallery",
 "INVA	s	Invergordon Academy",
 "INVAM	c	International Culture Collection of (Vesicular) Arbuscular Mycorrhizal Fungi",
@@ -2763,7 +2957,9 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "IPTB	s	Instituto de Pesquisas Tecnologicas",
 "IPUW	s	Institut fuer Palaeontologie der Universitaet Wien",
 "IPW	s	Instutut fuer Palaeontologie der Uinversitaet Wurzburg",
+"IQW	h	Senckenberg Forschungsinstitut und Naturmuseen",
 "IRAG	s	Institut National de la Recherche Agronomique de Antilles et Guyane",
+"IRAI	h	Parque da Ciencia Newton Freire Maia",
 "IRAN	sc	Iranian Research Institute of Plant Protection, Department of Botany",
 "IRBR	s	Universidad de Oriente, Departamento de Biologia",
 "IRCW	s	Madison, University of Wisconsin",
@@ -2792,6 +2988,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ISC<FRA>	c	International Salmonella Centre (W.H.O.)",
 "ISC<USA-IA>	s	Iowa State University, Botany Department",
 "ISCM	s	Institut Scientifique Cheripen",
+"ISE	h	Universidade Federal de Sergipe, Campus Professor Alberto Carvalho",
 "ISEA	s	Institute of Systematics and Evolution of Animals",
 "ISEAK	s	Instytut Systematyki i Ewolucji Zwierz",
 "ISEM	s	Institut des Sciences de l'Evolution Montpellier 	",
@@ -2799,8 +2996,10 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ISH	s	Institut fuer Seefischerei",
 "ISI	s	Geological Museum, Indian Statistical Institute",
 "ISIS	s	Naturforschende Gesellschaft Isis",
+"ISKW	h	Ishikawa Museum of Natural History",
 "ISL	s	Quaid-I-Azam University, Biological Sciences Department",
 "ISM	s	Illinois State Museum",
+"ISMAR	h	Consiglio Nazionale delle Ricerche, Istituto di Scienze  Marine",
 "ISMC	s	Indiana Department of Natural Resources",
 "ISNHC	s	State Historical Society of Iowa",
 "ISNP	s	Istituto Sperimentale per la Nutrizione delle Piante",
@@ -2826,6 +3025,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ITALSL	c	Secao de Leite e Derivados",
 "ITALSM	c	Secao de Microbiologia",
 "ITBCC	c	Institute of Technology Bandung Culture Collection",
+"ITBZC	s	Institute of Tropical Biology, Zoology Collection",
 "ITC	b	International Transit Centre",
 "ITCC<IND>	c	Indian Type Culture Collection",
 "ITCC<ITA>	s	Istituto Tecnico Stattale \"Camillo Cavour\"",
@@ -2839,6 +3039,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ITHA	s	Instituut voor Tropische Hygiene",
 "ITIC	s	Universidad de El Salvador, Escuela de Biologia",
 "ITLJ	s	National Institute of Agro-environmental Sciences",
+"ITMH	h	Muhimbili University of Health and Allied Sciences",
 "ITMM	s	Instituto Tecnologico de Monterrey",
 "IU	s	Indiana University",
 "IUI	s	Inha University, Biology Department",
@@ -2850,6 +3051,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "IVAU	s	Instituut Voor Aardwetenschappen",
 "IVB	s	Institute of  Vertebrate Biology, Academy of Sciences of the Czech Republic",
 "IVF	s	Chinese Academy of Agricultural Sciences",
+"IVGU	h	Ivanovo State University",
 "IVIC	s	Instituto Venezolano de Investigaciones Cientificas",
 "IVPP	s	Institute of Vertebrate Paleontology and Paleoanthropology",
 "IZ<BRA>	c	Departamento de Tecnologia Rural",
@@ -2894,7 +3096,9 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "JAUM	s	Jardin Botanico Joaquin Antonio Uribe",
 "JAY	s	Fondation Cognacq-Jay",
 "JBAG	s	Jardin Botanico Atlantico, Ayuntamiento de Gijon",
+"JBB	h	Jardin Botanico Jose Celestino Mutis",
 "JBC<MEX>	b	Francisco Javier Clavijero Botanic Garden",
+"JBCC	h	Alaska State Museum",
 "JBG	s	Johannesburg Botanic Garden",
 "JBGP	s	Jardin Botanico Guillermo Pineres",
 "JBL	s	Jardin Botanico Lankester, Universidad de Costa Rica",
@@ -2913,11 +3117,13 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "JEL	c	Joyce E. Longcore Chytrid Collection at the University of Maine",
 "JEL<LVA>	s	Latvian Agricultural Academy, Plant Protection Department",
 "JEPS	s	University of California, Jepson Herbarium",
+"JES	h	Universidad Autonoma Chapingo",
 "JESW	s	John Evelyn Society's Museum",
 "JEY	s	Boys' Grammar School, Victoria College",
 "JF	s	Jonkershoek Forestry Research Centre, Environment Affairs Department",
 "JFBM	s	James Ford Bell Museum of Natural History",
 "JHH	s	New York State Herbarium",
+"JHS	h	Regional Research Institute",
 "JHWU	s	Wittenberg University, Biology Department",
 "JIC	b	John Innes Centre",
 "JII	s	John Innes Institute",
@@ -2928,6 +3134,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "JLFC	s	Forestry College of Beihua University, Forestry Department",
 "JLMP	s	Jilin Academy of Traditional Chinese Medicine and Materia Medica",
 "JM	s	Jura Museum, Eichstatt",
+"JME	h	Jura-Museum Eichstatt",
 "JMM	s	Earlham College, Joseph Moore Museum",
 "JMRC	c	Jena Microbial Resource Collection",
 "JMRC:SF	c	Jena Microbial Resource Collection, Subcollection Fungi",
@@ -2937,13 +3144,18 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "JNR	s	Jiulian Mountain Nature Reserve, Administration Department",
 "JNU<CHN>	s	Ji Nan University",
 "JNU<KOR>	s	Chonbuk National University, Faculty of Biological Sciences",
+"JNUB	h	Jeju National University",
 "JOE	s	University of Joensuu, Biology Department",
+"JOI	h	Universidade da Regiao de Joinville",
+"JOMU	h	John Muir National Historic Site",
 "JONK	s	Jonkershoek Herbarium",
+"JOTR	h	Joshua Tree National Park",
 "JP	s	Phyletisches Museum Jena",
 "JPB	s	Universidade Federal da Paraiba, Cidade Universitaria, Departamento de Sistematica e Ecologia",
 "JPMP	s	Janus Pannonius Museum",
 "JPU	s	Janus Pannonius University, Botany Department",
 "JRAU	s	University of Johannesburg, Department of Botany and Plant Biotechnology",
+"JROH	h	Jasper Ridge Biological Preserve, Stanford University",
 "JRY	s	Jersey College for Girls",
 "JSHC	s	Jay S. Haft Collection",
 "JSMPE	s	Joint Soviet Mongolian Paleontolgical Expedition",
@@ -2976,6 +3188,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "KAI	s	Henan University, Biology Department",
 "KAMA	s	Yokohama University",
 "KANA	s	Kanazawa University",
+"KAND	h	Kandalaksha State Nature Reserve",
 "KANU	s	University of Kansas",
 "KAR	s	University of Tehran, Horticulture Department",
 "KARI	s	Kenya Agricultural Research Institute",
@@ -3017,12 +3230,15 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "KEP	s	Forest Research Institute Malaysia",
 "KESC	s	Keene State College, Department of Biology",
 "KEVO	s	University of Turku",
+"KF	h	Kerman University of Medical Sciences",
+"KFBG	h	Kadoorie Farm and Botanic Garden",
 "KFCC	c	Korean Federation of Culture Collection",
 "KFI	s	Hongnung Arboretum, Silviculture Department",
 "KFRI	s	Kerala Forest Research Institute",
 "KFRS	s	Kanudi Fisheries Research Station",
 "KFTA	s	Saint Petersburg State S. M. Kirov Forest Technology Academy, Botany and Dendrology Department",
 "KFUH	s	King Faisal University, Chemistry and Botany Department",
+"KG	h	International Phytochemistry Research and Production Institute",
 "KGU	s	Geology and Mineralogy Museum",
 "KGY	s	Cliffe Castle Art Gallery and Museum",
 "KH	s	Korea National Arboretum",
@@ -3038,7 +3254,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "KHUS	s	Kyung Hee University, Biology Department",
 "KIEL	s	Christian-Albrechts-Universitaet Kiel",
 "KIFB	s	Korean Institute of Freshwater Biology",
+"KIOM	h	Korea Institute of Oriental Medicine",
+"KIP	h	Institut National pour l'Etude et la Recherche Agronomique",
 "KIRI	s	University of Rhode Island, Department of Biological Sciences",
+"KIS	h	Universite de Kisangani",
+"KISA	h	Institut Congolais  pour la Conservation de la Nature",
 "KIT	c	Laboratorium voor Tropische Hygiene",
 "KIUJ	s	Kyusu University",
 "KIZ	s	Kunming Institute of Zoology, Chinese Academy of Sciences",
@@ -3071,6 +3291,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "KMV	s	Kunming Municipal Museum",
 "KMVC	s	Krajske Muzeum Vychodnich Cech",
 "KNFY	s	Klamath National Forest, Resources Department",
+"KNH	h	Kongju National University",
 "KNHM	s	The Educational Science Museum [=Kuwait Natural History Museum?]",
 "KNK	s	Northern Kentucky University, Department of Biological Sciences",
 "KNL	s	Kinneil Museum",
@@ -3102,6 +3323,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "KRA	s	Jagiellonian University",
 "KRAM	s	Polish Academy of Sciences, Department of Plant Systematics",
 "KRAS	s	Krasnoyarsk State Pedagogical University, Department of Botany",
+"KRB	h	Kebun Raya Bogor",
 "KRDY	s	Kirkcaldy Museum and Art Gallery",
 "KRF	s	V. N. Sukachev Institute of Forest and Wood",
 "KRG	s	Westfield Museum",
@@ -3118,6 +3340,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "KSK	s	Fitz Part Museum and Art Gallery",
 "KSO	s	Tweedside Physical and Antiquarian Society Museum",
 "KSP	s	Pittsburg State University, Biology Department",
+"KSPI	h	Kostanay State Pedagogical Institute",
 "KSRV	s	Khosrov State Reserve",
 "KSTC	s	Emporia State University",
 "KSU	s	King Saud University, Botany and Microbiology Department",
@@ -3127,22 +3350,23 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "KTG	s	Kettering and District Naturalists' Society and Field Club",
 "KTU	s	University of Silesia, Department of Plant Systematics",
 "KTUH	s	Kuwait University, Botany and Microbiology Department",
-"KU	s	University of Kansas, Museum of Natural History",
+"KU	s	University of Kansas Natural History Museum",
 "KU-MACC	c	Kobe University Macroalgal Culture Collection",
-"KU:H	s	University of Kansas, Museum of Natural History, Herpetology Collection",
-"KU:I	s	University of Kansas, Museum of Natural History, Ichthyology collection",
-"KU:IP	s	University of Kansas, Museum of Natural History, Invertebrate Paleontology Collection",
-"KU:IT	sb	University of Kansas, Museum of Natural History, Ichthyology tissue collection",
-"KU:IZ	s	University of Kansas, Museum of Natural History, Invertebrate Zoology Collection",
-"KU:M	s	University of Kansas, Museum of Natural History, Mammology Collection",
-"KU:O	s	University of Kansas, Museum of Natural History, Ornithology Collection",
-"KU:PB	s	University of Kansas, Museum of Natural History, Paleobotany Collection",
-"KU:VP	s	University of Kansas, Museum of Natural History, Vertebrate Paleontology Collection",
+"KU:H	s	University of Kansas Natural History Museum, Herpetology Collection",
+"KU:I	s	University of Kansas Natural History Museum, Ichthyology collection",
+"KU:IP	s	University of Kansas Natural History Museum, Invertebrate Paleontology Collection",
+"KU:IT	sb	University of Kansas Natural History Museum, Ichthyology tissue collection",
+"KU:IZ	s	University of Kansas Natural History Museum, Invertebrate Zoology Collection",
+"KU:M	s	University of Kansas Natural History Museum, Mammology Collection",
+"KU:O	s	University of Kansas Natural History Museum, Ornithology Collection",
+"KU:PB	s	University of Kansas Natural History Museum, Paleobotany Collection",
+"KU:VP	s	University of Kansas Natural History Museum, Vertebrate Paleontology Collection",
 "KU<CHN>	s	Kwangsi University",
 "KUBL	s	Yoshida College, Biological Laboratory",
 "KUEC	s	Kyushu University Entomology Collection",
 "KUEL	s	Kyushu University, Entomology Laboratory",
 "KUFC	c	Kasetsart University Fungus Collection",
+"KUFS	h	Kabul University",
 "KUH	s	University of Karachi, Botany Department",
 "KUHE	s	Kyoto University, Graduate School of Human and Environmental Studies",
 "KUIC	s	Kagoshima University",
@@ -3157,11 +3381,13 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "KURS	s	Kursk State University, Department of Botany",
 "KUS	s	Korea University, Biology Department",
 "KUU	s	University of Science and Technology",
+"KUW	h	Kakatiya University",
 "KUZ<JPN>	s	Zoological Collection of the Kyoto University",
 "KUZC	s	Kyushu University, Zoological Collection",
 "KVCH	s	Kivach Nature Reserve",
 "KW	s	National Academy of Sciences of Ukraine",
 "KWHA	s	Ukrainian National Academy of Sciences",
+"KWHU	h	O. V. Fomin Botanical Garden of National Taras Schevchenko University of Kiev",
 "KWNU	s	Kangwon National University, Biology Department",
 "KWP	s	Kenelm W. Philip Collection, University of Alaska Museum of the North",
 "KWP:Ento	s	Kenelm W. Philip Collection, University of Alaska Museum of the North, Lepidoptera collection",
@@ -3216,6 +3442,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "LBRP	s	Laboratorio de Biodiversidade de Recursos Pesqueiros",
 "LBUCH	s	Laboratorio de Biologia",
 "LBV	s	CENAREST",
+"LC	h	Lewis & Clark College",
 "LCC<CAN>	c	Labatt Culture Collection, Technology Development",
 "LCC<POL>	c	University of Warmia and Mazury in Olsztyn",
 "LCDI	s	Luther College, Biology Department",
@@ -3247,7 +3474,9 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "LEB<LVA>	s	Entomological Society of Latvia",
 "LEC	s	Universita degli Studi di Lecce, Dipartimento di Biologia",
 "LECB	s	Saint Petersburg State University, Botany Department",
+"LEDLIE	h	Patricia Ledlie Herbarium",
 "LEF	s	Economic Forestry Institute of Liaoning Province",
+"LEH	h	Lehigh University",
 "LEI	s	Leicester Literary and Philosophical Society",
 "LeishCryoBank	c	International Cryobank of Leishmania",
 "LEIUG	s	Department of Geology Leicester University",
@@ -3293,8 +3522,10 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "LIM	s	Severoceske muzeum",
 "LIMFC	s	Limerick Field Club",
 "LIMK	s	Limerick Museum",
+"LIMO	h	Universite de Limoges",
 "LIN-SB	c	Limnological Institute, Siberian Branch, Russian Academy of Sciences",
 "LINC	s	Lincoln University, Plant Sciences Group",
+"LINCO	h	Linfield College",
 "LINF	s	Shanxi Normal University, Biology Department",
 "LINHM	s	Long Island Natural History Museum",
 "LINN	s	Linnean Society of London",
@@ -3318,10 +3549,13 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "LIVNFC	s	Liverpool Naturalists' Field Club",
 "LIVU	s	Hartley Botanical Laboratories",
 "LJC	c	Coleccion de fitopatogenos de cultivos horticolas",
+"LJF	h	Slovenian Forestry Institute",
 "LJM	s	Prirodoslovni Muzej Slovenije",
+"LJS	h	Scientific Research Centre",
 "LJU	s	University of Ljubljana, Botany Department",
 "LKHD	s	Lakehead University, Biology Department",
 "LL	s	University of Texas at Austin, Plant Resources Center",
+"LLANOS	h	Universidad de los Llanos",
 "LLC	s	Our Lady of the Lake University, Biology Department",
 "LLN	s	Lincolnshire Naturalists' Union",
 "LLO	s	Lloyd Library and Museum",
@@ -3337,13 +3571,16 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "LMKG	s	Landesmuseum fur Karnten",
 "LMND	s	Landessammlungen fuer Naturkunde",
 "LMNH	s	Museum d'Histoire naturelle",
+"LMO	h	Landesmuseum Natur und Mensch",
 "LMRZ	s	Livingstone Museum",
 "LMS	c	Carolina Biological Supply Company",
 "LMSZ	s	Latvian University, Museum of Systemic Zoology",
 "LMU	s	Eduardo Mondlane University, Department of Biological Sciences",
 "LMZG	s	Local Museum",
 "LNAF	s	Liaoning Academy of Forestry",
+"LNAU	h	Luhansk National Agrarian University",
 "LNCM	s	Liaoning College of Traditional Chinese Medicine",
+"LNCN	h	Lincoln Memorial University",
 "LNHS	s	London Natural History Society",
 "LNK	s	Landessammlungen fuer Naturkunde",
 "LNKD	s	Landessammlung fuer Naturkunde",
@@ -3365,6 +3602,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "LPA	s	Jardin Botanico Canario Viera y Clavijo",
 "LPAG	s	Universidad Nacional de La Plata, Area de Botanica",
 "LPB	s	Herbario Nacional de Bolivia",
+"LPC	h	Museo de La Plata",
 "LPD	s	Laboratorio de Botanica de la Direccion de Agricultura",
 "LPFU	s	Lehrstuhl fur Palaontologie",
 "LPL	s	The University",
@@ -3431,9 +3669,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "LUGO	s	Universidad de Satniago de Compostela, Departamento de Produccion Vegetal",
 "LUH	s	University of Lagos, Biological Sciences Department, Botany Unit",
 "LUH<NLD>	c	Leiden University Medical Center",
+"LUKI	h	Institut National pour l'Etude et la Recherche Agronomiques",
 "LUNZ	s	Lincoln University Entomology Research Museum",
 "LUQ	s	Laval University",
 "LUS	s	Lushan Botanical Garden",
+"LUSC	h	Universidade do Estado de Santa Catarina",
 "LUW	s	Landbouwuniversiteit Wageningen, Department of Entomology",
 "LUX	s	Musee national d'histoire naturelle",
 "LV	s	Catholic University of Leuven, Laboratory of Plant Systematics",
@@ -3443,6 +3683,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "LWA	s	Agricultural Experiment Station",
 "LWD	s	Museum Dzieduszyckich",
 "LWG	s	National Botanical Research Institute",
+"LWI	h	Centre de Recherche en Sciences Naturelles (CRSN/Lwiro)",
 "LWKS	s	Institute of Ecology of the Carpathians",
 "LWL<DEU>	s	LWL-Museum fuer Naturkunde",
 "LWL<DEU>:DNA	b	LWL-Museum fuer Naturkunde, LWL-DNA- und Gewebearchiv",
@@ -3536,7 +3777,10 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MAPA	s	Museu Anchieta Porto Alegra",
 "MAPR	s	University of Puerto Rico, Mayagueez Campus, Biology Department",
 "MAR	c	Grasslands Rhizobium Collection",
+"MARDI	h	Malaysian Agricultural Research and Development Institute",
 "MARE	s	Marmara University, Department of Pharmaceutical Botany",
+"MARI	h	Mari State University",
+"MARK	h	Cadi Ayyad University",
 "MARO	s	Marylhurst College",
 "MARS	s	Universite de Provence Centre St-Charles, case 4",
 "MARSSJ	s	Universite Paul Cezanne",
@@ -3545,6 +3789,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MASS	s	University of Massachusetts, Biology Department",
 "MATSU	s	Ehime University, Forestry Department",
 "MAU	s	Mauritius Sugar Industry Research Institute",
+"MAUAM	h	Universidad Autonoma de Madrid",
 "MAY	s	Adygean State University, Department of Botany",
 "MB<DEU-Berlin>	s	Museum of Natural History of Humboldt-University",
 "MB<DEU-Marburg>	s	Philipps-Universitaet, Spezielle Botanik",
@@ -3586,7 +3831,9 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MCCM<DEU>	c	Medical Culture Collection Marburg",
 "MCCM<IND>	s	Madras Christian College",
 "MCD	s	Muzeul Civilizatiei Dacice si Romane Deva",
+"MCDNL	h	McDaniel College",
 "MCES	s	Museum of the Center for Entomological Studies",
+"MCF	h	Sts. Cyril and Methodius University",
 "MCF-PVPH	s	Museo Carmen Funes",
 "MCFB	s	Museo de la Cienica Fundacion",
 "MCFM	s	Museo Civico \"Francesco Mina Palumbo\"",
@@ -3656,6 +3903,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MDFW	s	Massachusetts Division of Fisheries and Wildlife",
 "MDH<GBR>	s	Dorman Museum",
 "MDH<USA-MI>	c	Michigan Department of Health",
+"MDI	h	Malaysian Agricultural Research and Development Institute",
 "MDKY	s	Morehead State University, Biological and Environmental Sciences Department",
 "MDLA	s	Museu do Dundo",
 "MDM	s	Mifune Dinosaur Museum",
@@ -3672,6 +3920,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MEFLG	s	Museo Entomologico Francisco Luis Gallego",
 "MEL	s	Royal Botanic Gardens Melbourne",
 "MELG	s	Geology Department, University of Melbourne",
+"MELIT	h	Bogdan Khmel'nysckyi State Pedagogical University of Melitopol'",
 "MELU	s	University of Melbourne",
 "MEM	s	University of Memphis, Biology Department",
 "MEMO	s	Instituto Tecnologico y de Estudios Superiores de Monterrey, Departamento de Recursos Naturales",
@@ -3679,6 +3928,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MEPAN	s	Museum of Evolution, Polish Academy of Sciences",
 "MER	s	Universidad de Los Andes",
 "MERC	s	Universidad de Los Andes, Centro Jardin Botanico",
+"MERCA	h	Mercer Arboretum and Botanic Gardens",
 "MERF	s	Universidad de Los Andes",
 "MERL	s	Instituto Argentino de Investigaciones de las Zonas Aridas (CRICYTME)",
 "MESA	s	Mesa State College, Biology Department",
@@ -3733,6 +3983,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MH<CHE>	s	Naturhistorisches Museum, Basel",
 "MH<IND>	s	Tamil Nadu Agricultural University",
 "MHA	s	Main Botanical Garden of the Russian Academy of Sciences",
+"MHES	h	Museo de Historia Natural de El Salvador",
 "MHH	c	Institute of Virology",
 "MHL	s	Mildenhall and District Museum",
 "MHM	s	Malham Tarn Field Centre",
@@ -3770,6 +4021,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MIB	s	University of Milano - Bicocca, Department of Biotechnology and Biosciences",
 "MIB:ZPL	s	University of Milano - Bicocca, Department of Biotechnology and Biosciences, ZooPlantLab",
 "MIC	s	Mar Ivanios College (Zoology museum)",
+"MICG	h	Universidad de San Carlos de Guatemala",
 "MICH	s	University of Michigan",
 "MICKKU	c	MICKKU Culture Collection",
 "MID	s	Middlebury College, Biology Department",
@@ -3783,9 +4035,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MINC	s	Universidad Politecnica",
 "MINI	s	Muzeul de Istoria Naturala",
 "MIPV	s	Universita degli Studi di Milano, Laboratorio di Micologia e Batteriologia Fitopathologica",
+"MIRR	h	Museu Integrado de Roraima",
 "MISR	s	Macaulay Land Use Research Institute",
 "MISS	s	University of Mississippi, Department of Biology",
 "MISSA	s	Mississippi State University, Department of Biological Sciences",
+"MISU	h	Minot State University",
 "MIT	c	Massachusetts Institute of Technology",
 "MIWG	s	Museum of he Isle of Wight Geology",
 "MIZA	s	Museuo del Instituto de Zoologia Agricola",
@@ -3801,8 +4055,12 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MJS	s	Xiaolongshan Forestry Experiment Bureau",
 "MJSD	s	Museum-Jardin des Sciences",
 "MK	s	National Museum of Kenya",
+"MKMEL	h	Herbarium Melovskiorum",
+"MKNDC	h	Institute of Biology",
+"MKNH	h	Institute of Biology",
 "ML	s	Musee de Lectoure",
 "MLAV	s	Musees de Laval",
+"MLGU	h	Institut National pour l'Etude et la Recherche  Agronomiques",
 "MLLD	c	Microbiological Research Laboratory, Soil and Water Section, Department of Land Development",
 "MLMJI	c	Department of Plant Protection, Faculty of Agricultural Production",
 "MLP	s	Museo de La Plata",
@@ -3810,7 +4068,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MLS<AUS>	s	Marine Laboratory Sydney",
 "MLS<COL>	s	Museo del Instituto de La Salle",
 "MLS<GBR>	s	Lathallan Preparatory School",
-"MLUH	s	Martin Luther Universitaet",
+"MLUH	s	Martin Luther Universitat",
 "MLY	s	Arboretum Mlynany",
 "MLZ	s	Moore Laboratory of Zoology, Occidental College",
 "MLZ:Bird	s	Moore Laboratory of Zoology, Occidental College, Bird Collection",
@@ -3903,10 +4161,12 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MNSB	s	Museum of Natural Sciences",
 "MNSL	s	Museum of Natural Sciences",
 "MNUFR	s	Mongolian National University",
+"MNVD	h	Museum fur Naturkunde und Vorgeschichte Dessau",
 "MNVL	s	Museum d'Histoire Naturelle de Ville de Lille",
 "MNZ	s	Museum of New Zealand Te Papa Tongarewa",
 "MO	s	Missouri Botanical Garden",
 "MOAR	s	Morris Arboretum, University of Pennsylvania, Botany Department",
+"MOBR	h	Estacion de Investigaciones Marinas de Margarita, Fundacion La Salle de Ciencias Naturales",
 "MOC	s	Western Oregon University, Biology Department",
 "MOD	s	Universita degli Studi di Modena e Reggio Emilia, Dipartimento de Biologia Animale",
 "MODNR	s	Division of State Parks, Department of Natural Resources",
@@ -3927,6 +4187,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MOSM	s	All-Russian Research Institute of Medicinal and Aromatic Plants",
 "MOSN	s	Museo Ornitologico e di Scienze Naturali",
 "MOSP	s	Moscow State Pedagogical University, Botany Department",
+"MOSS	h	Universidade Federal Rural do Semi-Arido",
 "MOT	s	Mote Marine Laboratory",
 "MOTH	s	Museum of the Hemispheres",
 "MOUFPE	s	Oceanographic Museum of the Federal University of Pernambuco",
@@ -3945,6 +4206,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MPEG	s	Museu Paraense Emilio Goeldi",
 "MPEP	s	Musee de Paleontologie et de l'evolution",
 "MPGB	s	Museum of Portuguese Guinea",
+"MPH	h	Shahid Behershti University",
 "MPKV	c	Biological Nitrogen Fixation Project College of Agriculture",
 "MPL	s	Musee de Port Louis",
 "MPLN	s	Museo Provinciale di Storia Naturale",
@@ -4009,6 +4271,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MSEN	s	Montrose Natural History and Antiquarian Society",
 "MSF	s	Sauriermuseum Frick",
 "MSGP	s	Nusee des Services Geologiques du Portugal",
+"MSI	h	Marine Science Institute, University of the Philippines",
 "MSIE	s	Museum of Shanghai",
 "MSINR	s	Museum Sichuan Institute of Natural Resources",
 "MSIR	s	Mauritius Sugar Industry",
@@ -4052,9 +4315,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MT<RUS>	s	Mus. Tinro, Vladyvostok",
 "MTA	s	Maden Tetkik ve Arama Enstituesue",
 "MTCC	c	Microbial Type Culture Collection & Gene Bank",
+"MTCHT	h	Mar Thoma College",
 "MTD	s	Museum of Zoology Senckenberg Dresden",
 "MTD:T	s	Museum of Zoology Senckenberg Dresden, Tissue collection",
 "MTD:TD	s	Museum of Zoology Senckenberg Dresden, Herpetological Tissue Collection",
+"MTDO	h	Chiba University",
 "MTEC	s	Montana State University",
 "MTJB	s	Jardin botanique de Montreal",
 "MTKD	s	Staatliches Museum fuer Tierkunde",
@@ -4083,6 +4348,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MUFS	s	Department of Animal Science, Miyazaki  University",
 "MUGM	s	Museo de Ciencias Naturales, Coleccion \"Gustavo Orces\" (Ecuador)",
 "MUGT	s	Museo de Ciencias Naturales de la Universidad de Guayaquil",
+"MUH	h	Mirpur University of Science & Technology",
 "MUHW	s	Marshall University, Biological Sciences Department",
 "MUJ	s	Museo Javeriano de Historia Natural, Laboratoriao de Entomologia",
 "MUL	c	Department of Microbiology MUL-B 250",
@@ -4103,7 +4369,9 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MUSK	s	Muskegon Community College, Life Science Department",
 "MUSM	s	Museo de Historia Natural de la Universidad Nacional Mayor de San Marcos en Lima",
 "MUSN	s	Museo Universitario di Storia Naturale e della Strumentazione Scientifica",
+"MUST	h	Al-Mustansiriya University",
 "MUT<ITA>	c	Mycotheca Universitatis Taurinensis",
+"MUZ	h	King Abdulaziz City for Science and Technology",
 "MV	s	University of Montana Museum",
 "MVC	s	University of Charleston, Natural Sciences Department",
 "MVDA	s	Ministerio de Ganaderia y Agricultura",
@@ -4175,14 +4443,15 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "MZUC<CHL>	s	Museo de Zoologia, Universidad de Concepcion",
 "MZUC<ITA>	s	Universita di Cagliari",
 "MZUCR	s	Universidad de Costa Rica, Museo de Zoologia",
+"MZUEL	s	Museu de Zoologia da Universidade Estadual de Londrina",
 "MZUESC<BRA>	s	Museu de Zoologia da Universidade Estadual de Santa Cruz",
 "MZUF	s	Museo Zoologico La Specola, Universita di Firenze",
 "MZUN	s	Museo Zoologico di Universita degli Studi",
 "MZUNAP	s	Museo de Zoologia de la Universidad Nacional de la Amazonia Peruana",
 "MZUP<ITA-Padova>	s	Museo Zoologia",
 "MZUP<ITA-Parma>	s	Museo Zoologico di Universita degli Studi",
-"MZUR	s	Museo di Zoologia dell'Universita \"La Sapienza\"",
-"MZUR:BAU	s	Museo di Zoologia dell'Universita \"La Sapienza\", Zoological collection of the Department of Biology and Biotechnology",
+"MZUR	s	Museo di Zoologia dell'Universita di Roma \"La Sapienza\"",
+"MZUR:BAU	s	Museo di Zoologia dell'Universita di Roma \"La Sapienza\", Zoological collection of the Department of Biology and Biotechnology",
 "MZUS	s	Musee de Zoologie de l'Universite de Strasbourg",
 "MZUSP	s	Museu de Zoologia da Universidade de Sao Paulo",
 "MZUT<ITA-Torino>	s	Museo di Zoologia, Instituto di Zoologia e Anatomia Comparata Universita di Torino",
@@ -4198,6 +4467,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NAC	s	Nagano Nature Conservation Research Institute",
 "NAI	s	University of Nairobi, Botany Department",
 "NAIC	s	National Agricultural Insect Collection",
+"NAKU	h	Namik Kemal University",
 "NAM	s	Facultes Universitaires Notre-Dame de la Paix",
 "NAN	s	Nantong Teachers College, Biology Department",
 "NAP<CHN>	s	Institute of Zoology, Academia Sinica (formerly National Academy of Peiping)",
@@ -4267,12 +4537,14 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NCMA	s	Raleigh, North Carolina Department of Environmental Health and Natural Resources",
 "NCMH	c	The North Carolina Memorial Hostital",
 "NCMK	s	Norwich Castle Museum",
+"NCP	h	National  Collection of Passiflora",
 "NCPF	c	National Collection of Pathogenic Fungi",
 "NCPPB	c	National Collection of Plant Pathogenic Bacteria",
 "NCPV	c	National Collection of Pathogenic Viruses",
 "NCS	s	North Carolina State University",
 "NCSC<THA>	c	National Center of Streptococcus Collection, Department of Microbiology, Faculty of Medical Science",
 "NCSC<USA-NC>	s	North Carolina State University, Botany Department",
+"NCSLG	h	North Carolina State University",
 "NCSM	s	North Carolina Museum of Natural Sciences",
 "NCSU	s	North Carolina State University Collections",
 "NCTC	c	National Collection of Type Cultures",
@@ -4294,6 +4566,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NE	s	University of New England",
 "NEB	s	University of Nebraska State Museum",
 "NEBC	s	Harvard University",
+"NEBK	h	University of Nebraska at Kearney",
 "NEFI	s	Northeastern Forestry University, Forestry Department",
 "NEM	c	Faculte de Medecine Necker-Enfants Malades",
 "NEMO	s	Truman State University",
@@ -4303,6 +4576,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NEPCC	c	North East Pacific Culture Collection",
 "NESH	s	University of Nevada",
 "NEU	s	Universite de Neuchatel, Laboratoire de botanique evolutive",
+"NEUN	h	Near East University",
 "NEW	s	University of Newcastle",
 "NEWHM	s	Hancock Museum",
 "NEZ	s	Museum, Zoology Department, University of New England",
@@ -4316,14 +4590,18 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NFRDI	c	National Fisheries Research & Development Institute",
 "NFRI	c	Norwegian Forest Research Institute",
 "NFRN	s	Canadian Forest Service, NRCan",
+"NGBB	h	Nezahat Gokyigit Botanik Bahcesi",
+"NGCPR	h	Naoroji Godrej Centre for Plant Research",
 "NGI	s	Nanjing Geographical Institute",
 "NGM	s	Bromley House Library",
 "NGMC	s	National Geological Museum of China",
 "NGR	c	Plant Pathology",
 "NH	s	South African National Biodiversity Institute",
 "NHA	s	University of New Hampshire, Plant Biology Department",
+"NHCP	h	National Bureau of Plant Genetic Resources",
 "NHES	s	Connecticut Agricultural Experiment Station, Entomology Department",
 "NHG	s	Naturhistorische Gesellschaft e. V., Abteilung Botanik",
+"NHI	h	Natural History Institute",
 "NHIC	s	Ontario Ministry of Natural Resources",
 "NHL	c	National Institute of Hygienic Sciences",
 "NHM<CHE>	s	Naturhistorisches Museum, Bern",
@@ -4335,6 +4613,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NHMC<GRC>	s	Natural History Museum of Crete, University of Crete, Department of Botany",
 "NHMC<MMR>	s	Natural History Museum, Rangoon",
 "NHME	s	Natuurhistorisch Museum",
+"NHMF	h	Natural History Museum Fribourg",
 "NHMG<CHN>	s	Natural History Museum of Guangxi",
 "NHMG<SWE>	s	Goteborgs Naturhistoriska Museet",
 "NHMK	s	Landesmuseum fuer Karnten",
@@ -4345,11 +4624,14 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NHMR<HRV>	s	Natural History Museum Rijeka",
 "NHMR<ISL>	s	Natural History Museum, Reykjavik",
 "NHMR<NLD>	s	Natuurhistorisch Museum",
-"NHMUK	s	Natural History Museum, London",
+"NHMS	h	Natural History Museum Split",
+"NHMTU	s	Natural History Museum, Tribhuvan University",
+"NHMUK	sb	Natural History Museum, London",
 "NHMUK<PAK>	s	Natural History Museum, Karachi",
 "NHMW	s	Naturhistorisches Museum, Wien",
 "NHNC	s	La Chaux-de-Fons",
 "NHNE	s	New England College, Biology Department",
+"NHR	h	Institute of Scientific and Technological Research (IRST)",
 "NHRI	s	Islandic Museum of Natural History",
 "NHRM	s	Naturhistoriska Rijkmuseet",
 "NHRS	s	Swedish Museum of Natural History, Entomology Collections",
@@ -4377,6 +4659,9 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NIG	s	Nanjing Geographical Institute",
 "NIGL	s	Nanjing Institute of Geography and Limnology",
 "NIGP	s	Naking Institute of Geology and Palaeontology",
+"NIHHS	h	National Institute of Horticultural and Herbal Science, RDA",
+"NIM	h	Museum d'histoire naturelle de Nimes",
+"NIMM	h	National Institute of Medicinal Materials",
 "NINF	s	Newfoundland Insectarium",
 "NIO	s	National Institute of Oceanography",
 "NIOCC	c	National Institute of Oceanography Culture Collection",
@@ -4414,6 +4699,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NMBA<CHE>	s	Naturhistorisches Museum, Basel",
 "NMBE	s	Naturhistorisches Museum der Burgergemeinde Bern",
 "NMBO	s	National Museum, Bloemfontein",
+"NMBT	h	Natuurmuseum Brabant",
 "NMBZ	s	Natural History Museum of Zimbabwe",
 "NMC	s	New Mexico State University, Department of Biology",
 "NMC<CAN>	s	Canadian Museum of Nature",
@@ -4454,6 +4740,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NMNH<IND>	s	National Museum of Natural History, New Delhi",
 "NMNHI	s	National Museum of Natural History, New Delhi",
 "NMNK	s	National Museum of Nepal",
+"NMNL	h	Natuurmuseum Nijmegen e.o.",
 "NMNS	s	National Museum of Natural Science",
 "NMNW	s	National Museum of Namibia",
 "NMNZ	s	National Museum of New Zealand",
@@ -4477,6 +4764,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NMPG<DEU>	s	Museum der Natur-Gotha",
 "NMPI	s	Division of Plant Industry",
 "NMQR	s	National Museum, Bloemfontein",
+"NMR	h	Semyung University",
 "NMRC<USA-MD>	c	Naval Medical Research Center",
 "NMRC<USA-MD>:RDD	c	Naval Medical Research Center, Rickettsial Diseases Division",
 "NMS	s	National Museums of Scotland",
@@ -4556,6 +4844,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NPSC	s	Northern Prairie Science Center",
 "NPT	s	Newport Museum and Art Gallery",
 "NPWRC	s	Northern Prairie Research Center",
+"NR	h	Institute of Forest Ecology Slovak Academy of Sciences",
 "NRC	c	Division of Biological Sciences, National Research Council of Canada",
 "NRC<EGY>	s	National Research Centre",
 "NRCC	s	National Research Council of Canada",
@@ -4568,6 +4857,9 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "NRNZ	s	Northland Regional Museum",
 "NRPSU	c	Department of Agro-industry, Faculty of Natural Resources",
 "NRRL	c	Agricultural Research Service Culture Collection",
+"NRRL:MOLD	sc	Agricultural Research Service Culture Collection, ",
+"NRRL:PROK	sc	Agricultural Research Service Culture Collection, ",
+"NRRL:YEAST	sc	Agricultural Research Service Culture Collection, ",
 "NRS	s	Naturhistoriska Riksmuseet",
 "NRWC	s	N. R. Whitney Collection",
 "NRZM	c	German Reference Center for Meningococci",
@@ -4666,6 +4958,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "OAMB	s	Open Air Museum of Ethnography and Natural Sciences",
 "OAX	s	Instituto Politecnico Nacional (CIIDIR-Oax., I.P.N.)",
 "OAXM	s	Centro Interdisciplinario de Estudios, Coleccion Mastozoologica (Mexico)",
+"OB	h	Station Umwelt- und Natur Oberhausen",
 "OBG<OMN>	s	The Oman Botanic Garden",
 "OBI	s	California Polytechnic State University, Biological Sciences Department",
 "OBPF	s	Planting Fields Arboretum State Historic Park",
@@ -4675,6 +4968,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "OCM	c	Oregon Collection of Methanogens",
 "OCNF	s	Ochoco National Forest",
 "OCSA	s	Veterinary Research Institute",
+"OCU	h	Oklahoma City University",
 "ODAC	s	Oregon Department of Agriculture",
 "ODU	s	Old Dominion University, Department of Biological Sciences",
 "OFC	s	Orielton Field Centre",
@@ -4684,6 +4978,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "OGU	s	Odesskij Gosudarstvennij Universitet",
 "OH	s	Agricultural Museum of Praha",
 "OHBR	s	Ontario Hydro",
+"OHHI	h	Orel State University",
 "OHM	s	Oldham Microscopical and Natural History Society",
 "OHN	s	Regionherbariet i Oskarshamn",
 "OHSC	s	Ohio Historical Society",
@@ -4700,8 +4995,10 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "OLM	s	Vlastivedne muzeum v Olomouci",
 "OLML	s	Oberoesterreichisches Landesmuseum",
 "OLP	s	Univerzity Palackeho, Katedra biologie",
+"OLS	h	University of Warmia and Mazury",
 "OLTC	s	Teachers Training College, Botany Department",
 "OLV	s	Olivet College, Biology Department",
+"OLYM	h	Olympic National Park",
 "OM	s	Otago Museum",
 "OMA	s	University of Nebraska Omaha, Biology Department",
 "OMC<NZL>	s	Catalogues in Otago Museum",
@@ -4718,6 +5015,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "OMPB	s	Osservatorio per le Malattie delle Piante per la Regione Emilia-Romagna",
 "OMPG	s	Osservatorio per le Malattie delle Piante per le Province di Genova e La Spezia",
 "OMPS	s	Osservatorio per le Malattie delle Piante per la Sardegna",
+"OMSK	h	Omsk Pedagogical Univeristy",
 "OMSKM	s	Omsk State Agrarian University, Department of Forestry and Plant Conservation",
 "OMUB	s	Ondokuz Mayis University, Biology Department",
 "ON	s	Oman Natural History Museum",
@@ -4757,6 +5055,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "OSM<USA-OH>	s	Ohio State University Museum",
 "OSMC	s	St. Martin's College, Biology Department",
 "OSN	s	Museum am Schoelerberg, Natur und Umwelt",
+"OSTR	h	University of Ostrava",
 "OSU<USA-OH>	s	Ohio State University",
 "OSU<USA-OK>	s	Oklahoma State University, Collection of Vertebrates",
 "OSUC	s	Oregon State University",
@@ -4765,6 +5064,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "OSUMZ	s	Ohio State University, Museum of Biological Diversity",
 "OSUO	s	Oregon State University, School of Oceanography",
 "OSUS	s	Oklahoma State University",
+"OSW	h	State University of New York at Oswego",
 "OSWY	s	Oswestry Museum",
 "OTA	s	University of Otago, Botany Department",
 "OTF	s	Canadian Forest Service",
@@ -4786,6 +5086,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "OXF	s	University of Oxford, Department of Plant Sciences",
 "OXM	s	Magdalen College Library",
 "P	s	Herbier National de Paris",
+"PA	h	Universidade Federal do Oeste do Para",
 "PAC	s	Pennsylvania State University, Biology Department",
 "PACA	s	Instituto Anchietano de Pesquisas/UNISINOS",
 "PACMA	s	Pennsylvania State University, Biology Department",
@@ -4798,6 +5099,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "PAMC	c	Polar and Alpine Microbial Collection",
 "PAMG	s	Empresa de Pesquisa Agropecuaria de Minas Gerais (EPAMIG), Departamento de Pesquisa",
 "PAMP	s	Universidad de Navarra, Departamento de Botanica",
+"PAMUH	h	Pamukkale University",
 "PAN	s	Panjab University, Botany Department",
 "PAP	s	Musee de Tahiti et des Iles",
 "PAR	s	Museo de Ciencias Naturales y Antropologicas Prof. Antonio Serrano, Departamento de Botanica",
@@ -4813,6 +5115,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "PAUP	s	Punjab Agricultural University",
 "PAV	s	Universita di Pavia, Dipartimento de Ecologia del Territorio",
 "PAY	s	Paisley Philosophical Institute",
+"PBB	h	Research Center for the Conservation of Natural Resources University and Phu An Botanic Gardens",
 "PBC<USA-HI>	c	Pacific Bacterial Collection",
 "PBF	c	Perum Bio Farma",
 "PBH	s	Peterborough City Museum",
@@ -4823,6 +5126,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "PBZT	s	Parc Botanique et Zoologique de Tsimbazaza",
 "PC	s	Museum National d'Histoire Naturelle",
 "PCC	c	Pasteur Culture Collection of Cyanobacteria",
+"PCE	h	Hugh Nicholson and Tony Abbott Herbarium",
 "PCH	s	Prestwich and Pilkington Botanical Society",
 "PCM<IND>	s	Presidency College, Botany Department",
 "PCM<POL>	c	Polish Collection of Microorganisms",
@@ -4847,6 +5151,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "PEM<ZAF>	s	Port Elizabeth Museum",
 "PEN	s	Penrith Museum",
 "PENN	s	University of Pennsylvania Herbarium",
+"PER	h	City Museum",
 "PERM	s	University of Perm, Botany Department",
 "PERTH	s	Western Australian Herbarium",
 "PERU	s	Universita di Perugia, Dipartimento di Biologia Vegetale",
@@ -4863,6 +5168,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "PFRA	s	Tree Nursery",
 "PFRS	s	Pacific Southwest Forest and Range Experiment Station",
 "PFSS	s	Petrified Forest National Park",
+"PG	h	Plant Gateway",
 "PGC	c	Peterhof Genetic Collection of Microalgae",
 "PGFA	s	Pyatigorsk State Pharmaceutical Academy, Botany Department",
 "PGL	s	Preussiche Geologische Landesanstalt",
@@ -4874,13 +5180,18 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "PGSC<USA-NC>	c	Pseudomonas Genetic Stock Center",
 "PH	s	Academy of Natural Sciences, Botany Department",
 "PHA	s	Pharmaceutical Society of Great Britain",
+"PHARM	h	Southern Cross University",
 "PHBL	c	Philip Harris Biological Ltd.",
 "PHEL	s	Plant Health and Environment Laboratory",
+"PHEO	h	Karadag Natural Reserve",
 "PHG	s	Peper Harow",
+"PHH	h	University of Science,Ho Chi Minh City Vietnam National University",
 "PHIL	s	University of the Sciences in Philadelphia, Biological Sciences Department",
 "PI<DEU>	s	Institut und Museum fuer Geologie und Palaeontologie",
 "PI<ITA>	s	Universita di Pisa, Dipartimento di Scienze Botaniche",
 "PI<RUS>	s	Paleontological Institute",
+"PIAGR	h	University of Pisa",
+"PICRC	h	Palau International Coral Reef Center",
 "PIHG	s	Florida Department of Agriculture and Consumer Services",
 "PIHU	s	Paleontological Institut of Helsingfors",
 "PIKN	s	Koronivia Research Station",
@@ -4895,8 +5206,12 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "PKDC	s	Divisao de Museu de Historia Natural",
 "PKM	s	V. G. Belinsk Pedagogical Institute of Penza",
 "PL	s	Zapadoceske muzeum",
+"PLAT	h	State University of New York, College at Plattsburgh",
+"PLES	h	Plyos State Museum",
 "PLFV	s	Principality of Liechtenstein",
 "PLH	s	Plymouth City Museum and Art Gallery",
+"PLP	h	Institute of Himalayan Bioresource Technology",
+"PLU	h	Pacific Lutheran University",
 "PLY	sc	Plymouth Institution and Athenaeum",
 "PLYMOUTH	c	Plymouth Culture Collection",
 "PLYP	s	University of Plymouth, Department of Biological Sciences",
@@ -4938,6 +5253,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "PMV	s	Provincial Museum",
 "PNBG	s	University of the Philippines",
 "PNCM-BIOTECH	c	Philippine National Collection of Microorganisms",
+"PND	h	Dr. Shivaram Karantha  Pilikula Nisarga Dhama",
 "PNG	s	Division of Primary Industry",
 "PNGM	s	National Museum and Art Gallery, Port Moresby",
 "PNH	s	Philippine National Herbarium",
@@ -4964,6 +5280,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "POZM	s	Adam Mickiewicz University, Department of Plant Ecology and Environment Protection",
 "POZNB	s	Agricultural Academy, Botany Department",
 "POZW	s	Adam Mickiewicz University",
+"PPC	h	Palawan State University",
 "PPCC<AUS>	c	Plant Pathology Culture Collection",
 "PPCC<NZL>	s	Plant Protection Centre Collection",
 "PPCD	s	West Virginia Department of Agriculture",
@@ -4983,10 +5300,12 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "PPL	s	Agricultural Development and Advisory Service, Harpenden Laboratory",
 "PPNP	s	Point Pelee National Park",
 "PPPO	s	Pusat Penelitian dan Pengembangan Oseanologi",
-"PPPPB	c	South African Plant Pathogenic and Plant Protecting Bacteria",
+"PPPPB	c	ARC-Plant Protection Research Institute, Plant Pathogenic and Plant Protecting Bacteria",
 "PPRI	c	ARC-Plant Protection Research Institute, National Collection of Fungi: Culture Collection",
+"PPRL	h	USDA-ARS Poisonous Plant Research Lab",
 "PPRZ	s	Plant Protection Research Institute",
 "PPSIO	s	P. P. Shirshov Institute of Oceanology",
+"PPU	h	Perm State Teacher Training University",
 "PQFC	b	Phu Qui's Fruit Tree Center-Vietnam",
 "PR	s	National Museum in Prague, Department of Botany",
 "PRA	s	Institute of Botany, Academy of Sciences",
@@ -5006,6 +5325,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "PRV	s	Porvoo Museum of Natural History",
 "PSAE	s	Alberta Environmental Centre",
 "PSGB	s	University of Bradford, Pharmacy Department",
+"PSK	h	Pskov State University",
 "PSM	s	University of Puget Sound, James R. Slater Museum of Natural History",
 "PSO	s	Universidad de Narino",
 "PSP	s	Parasitic Seed Plants",
@@ -5045,6 +5365,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "PURC	s	Purdue University",
 "PUS	s	Puslinch House",
 "PUSC	s	University of Southern Colorado, Life Sciences Department",
+"PVB	h	Institute of Ecology of the Volga River Basin, Russian Academy of Science",
 "PVF	c	Pusat Veterinaria Farma",
 "PVGB	c	Plant Virus GenBank",
 "PVHR	s	Universite Paris VI",
@@ -5054,6 +5375,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "PVSJ	s	Museo do Ciencias Naturles",
 "PW	s	Paleontological Collections",
 "PWRC	s	Patuxent Wildlife Research Center",
+"PWU	h	V.G.Korolenko Poltava National Pedagogical University",
 "PY	s	Centro de Estudios y Colecciones Biologicas para la Conservacion",
 "PYCC	c	Portuguese Yeast Culture Collection",
 "PYU	s	Yunnan University, Laboratory of Pteridophyta",
@@ -5118,6 +5440,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "RAMK	s	Ramkhamhaeng University, Biology Department",
 "RAMM	s	Royal Albert Memorial Museum, Leisure and Tourism Department",
 "RANG	s	Yangon University",
+"RANK	h	Research Center of Agriculture and Natural Resources of Kermanshah province",
 "RARS	s	Regina Research Station",
 "RAS	s	Union of Burma Applied Research Institute, Pharmaceutical Department",
 "RAU	s	Laboratoire de Biologie Vegetale",
@@ -5143,13 +5466,16 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "RCR	s	Rochester Public Museum",
 "RCS	s	Royal College of Surgeons",
 "RCSL	s	Royal College of Surgeons",
+"RCVC	h	Universidad Nacional de Rio Cuarto",
 "RDAF	s	Research Department South East Asian Fisheries Development Centre",
 "RDG	s	Reading Museum and Archive Service",
 "RDS	s	Royal Dublin Society",
 "RE	s	Liaoning Reed Science Institute",
 "RED	s	University of Redlands, Biology Department",
 "REDM	s	Reading Museum and Archive Service",
+"REED	h	Reed College",
 "REG	s	Universitaet Regensburg, Regensburgische Botanische Gesellschaft",
+"REGGIO	h	Universita Mediterranea di Reggio Calabria",
 "RELC	s	INIFAP-SAGAR",
 "REN	s	Campus Scientifique de Beaulieu, Laboratoire de Botanique",
 "RENO	s	University of Nevada, Environmental and Resource Sciences Department",
@@ -5159,11 +5485,13 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "REU	s	Universite de la Reunion",
 "RFA	s	Universidade Federal do Rio de Janeiro, Departamento de Botanica",
 "RFE	s	Radcliffe Literary and Scientific Society Museum",
+"RFFP	h	Universidade do Estado do Rio de Janeiro",
 "RFNS	s	Rochdale Field Naturalists' Society",
 "RGM	s	Nationaal Natuurhistorisch Museum Leiden",
 "RGMC	s	Musee Royal de l'Afrique Centrale",
 "RGY	s	Rugby School Natural History Society Museum",
 "Rh-EF	s	Museum of Grannat",
+"RHK	h	St. Berchmans College",
 "RHLCY	s	Reservoir of Heilongtan",
 "RHM	s	Public Reference Library",
 "RHMC	s	Red House Museum",
@@ -5193,6 +5521,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "RIVE<USA-WI>	s	University of Wisconsin, Biology Department",
 "RIY	s	National Agriculture and Water Research Center",
 "RIZ	s	Instituto de Zootecnia",
+"RKT	h	Regional Research Institute (Ayurveda)",
 "RLS	s	Royal Latin School",
 "RM<CAN>	s	McGill University, Redpath Museum",
 "RM<NZL>	c	Rumen Microorganisms",
@@ -5205,25 +5534,26 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "RMDRC	s	Rocky Mountain Dinosaur Resource Center",
 "RMF	c	Rocky Mountain Herbarium, Fungi",
 "RMFM	s	Richmond Marine Fossils Museum",
-"RMNH	s	Nationaal Natuurhistorisch Museum",
-"RMNH:ACA	s	Nationaal Natuurhistorisch Museum, Acari collection",
-"RMNH:AVES	s	Nationaal Natuurhistorisch Museum, bird collection",
-"RMNH:BRA	s	Nationaal Natuurhistorisch Museum, brachiopod collection",
-"RMNH:BRY	s	Nationaal Natuurhistorisch Museum, bryozoan collection",
-"RMNH:COEL	s	Nationaal Natuurhistorisch Museum, Coelomate collection",
-"RMNH:CRUS	s	Nationaal Natuurhistorisch Museum, crustacean collection",
-"RMNH:CRUS.D	s	Nationaal Natuurhistorisch Museum, decapod collection",
-"RMNH:INS	s	Nationaal Natuurhistorisch Museum, Insect collection",
-"RMNH:MAM	s	Nationaal Natuurhistorisch Museum, Mammal collection",
-"RMNH:MOL	s	Nationaal Natuurhistorisch Museum, mollusc collection",
-"RMNH:PISC	s	Nationaal Natuurhistorisch Museum, fish collection",
-"RMNH:POR	s	Nationaal Natuurhistorisch Museum, poriferan collection",
+"RMNH	s	Naturalis Biodiversity Center",
+"RMNH:ACA	s	Naturalis Biodiversity Center, Acari collection",
+"RMNH:AVES	s	Naturalis Biodiversity Center, bird collection",
+"RMNH:BRA	s	Naturalis Biodiversity Center, brachiopod collection",
+"RMNH:BRY	s	Naturalis Biodiversity Center, bryozoan collection",
+"RMNH:COEL	s	Naturalis Biodiversity Center, Coelomate collection",
+"RMNH:CRUS	s	Naturalis Biodiversity Center, crustacean collection",
+"RMNH:CRUS.D	s	Naturalis Biodiversity Center, decapod collection",
+"RMNH:INS	s	Naturalis Biodiversity Center, Insect collection",
+"RMNH:MAM	s	Naturalis Biodiversity Center, Mammal collection",
+"RMNH:MOL	s	Naturalis Biodiversity Center, mollusc collection",
+"RMNH:PISC	s	Naturalis Biodiversity Center, fish collection",
+"RMNH:POR	s	Naturalis Biodiversity Center, poriferan collection",
 "RMNHD	s	Naturalis Biodiversity Center",
 "RMNP	s	Riding Mountain National Park",
 "RMRC	b	Regional Medical Research Centre",
 "RMS	s	University of Wyoming Herbarium",
 "RMSC	s	Rocky Mountain Forest and Range Experiment Station",
 "RMSCC	c	Roche Molecular Systems Culture Collection",
+"RMTV	h	University of Rome Tor Vergata",
 "RMWC	s	Randolph-Macon Woman's College, Biology Department",
 "RNG	s	University of Reading",
 "RNMUT	s	Republic Nature Museum of Uzbekistan",
@@ -5242,6 +5572,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ROME	s	Royal Ontario Museum, Entomology Collection",
 "ROML	s	National University of Lesotho, Biology Department",
 "ROMO	s	Rocky Mountain National Park",
+"RON	h	Universidade Federal de Rondonia",
 "ROO	s	Agricultural Research Council-Range and Forage Institute",
 "ROPA	s	Sonoma State University, Biology Department",
 "ROPV	s	Istituto Sperimentale per la Patologia Vegetale",
@@ -5267,6 +5598,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "RSKK	c	Refik Saydam National Type Culture Collection-RSKK",
 "RSM<CAN>	s	Royal Saskatchewan Museum",
 "RSM<GBR>	s	Royal Scottish Museum",
+"RSU	h	Ryazan State University",
 "RSY	s	Buteshire Natural History Society, The Museum",
 "RTE	s	Holmesdale Natural History Club Museum",
 "RTHM	s	Munidipal Museum and Art Gallery",
@@ -5280,6 +5612,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "RUIC	s	Rutgers University",
 "RUMF	s	University Museum, University of the Ryukyus",
 "RUNYON	s	Robert Runyon Herbarium",
+"RUPP	h	Royal University of Phnom Penh",
 "RUSI	s	J.L.B. Smith Institute of Ichthyology (formerly of Rhodes University)",
 "RUSU	s	Universidade Santa Ursula",
 "RUT	s	Douglass College, Rutgers University, Biological Sciences Department",
@@ -5306,9 +5639,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SACON	s	Salim Ali Centre for Ornithology and Natural History",
 "SACS	s	Shenyang Agricultural College",
 "SACT	s	California State University, Biological Sciences Department",
+"SAF	h	Department of Agricultural and Forest Sciences",
 "SAFB	s	University of Saskatchewan, Forestry Department",
 "SAFU	s	University of San Francisco",
 "SAG	c	Sammlung von Algenkulturen at Universitat Gottingen",
+"SAG<CHL>	c	Coleccion de Micoligica Laboratorio Regional, Servicio Agricola y Ganadero",
 "SAIAB	sb	South African Institute of Aquatic Biodiversity",
 "SAIM	s	South African Institute for Medical Research",
 "SAIMR	s	South African Institute for Medical Research",
@@ -5324,6 +5659,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SAM<ZAF>	s	South African Museum",
 "SAMA	sb	South Australian Museum",
 "SAMC	s	Iziko Museum of Capetown",
+"SAMF	h	Samford University",
 "SAMU	s	Savaria Museum, Department of Natural History",
 "SAN	s	Forest Research Centre, Forest Department",
 "SANBI	s	South African National Biodiversity Institute",
@@ -5338,9 +5674,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SAPA	s	Hokkaido University Museum (Fungal collection)",
 "SAPCL	s	St. Andrews Presbyterian College, Biology Department",
 "SAPS	s	Hokkaido University Museum (Plant collection)",
+"SAPT	h	Hokkaido University Botanic Garden",
 "SAR	s	Department of Forestry",
 "SARA	s	Zemaljski Muzej Bosne I. Herzegovine",
 "SARAT	s	Department of Morphology and Systematic Botany",
+"SARBG	h	Saratov State University Botanical Garden",
 "SARC	s	Roanoke College, Biology Department",
 "SARI	s	Sakarya Agricultural Research Institute",
 "SAS	s	Sammlung Arnhardt des Museums Schloss Wilhelmsburg Schmalkalden",
@@ -5384,9 +5722,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SCB	s	Station Centrale de Boukoko",
 "SCCAP	c	Scandinavian Culture Collection of Algae and Protozoa",
 "SCCBC	s	Selkirk College, Environmental Sciences and Technologies Department",
+"SCCN	h	Scott Christian College",
 "SCDH	s	South Carolina Department of Health and Environmental Control",
 "SCFI	s	Sichuan Academy of Forestry",
 "SCFQ	s	Service canadien de la faune",
+"SCFS	h	University of California-Berkeley, Sagehen Creek Field Station",
 "SCH	s	Museum zu Allerheiligen",
 "SCHG	s	George Museum",
 "SCHN	s	Smith College, Biological Sciences Department",
@@ -5396,17 +5736,21 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SCN	s	Sociedad de Ciencias Naturales \"La Salle\"",
 "SCNHM	s	Southwestern College, Natural History Museum",
 "SCNU	s	Sichuan Normal University, Biology Department",
+"SCP	h	Sociedad Cientifica del Paraguay",
 "SCPS	s	Scarborough Philosophical and Archaeological Society Museum",
 "SCR	s	Scripps Institution of Oceanography, Herbarium",
 "SCS	s	Agriculture and Agri-Food Canada, Semiarid Prairie",
 "SCSC	s	Saint Cloud State University",
 "SCSFRI	s	South China Sea Fisheries Research Institute",
+"SCSG	h	South China Sea Institute of Oceanology, Academia Sinica",
 "SCSIO	s	South China Sea Institute of Oceanology, Academia Sinica",
 "SCSM	s	South Carolina State Museum",
 "SCT	s	Friend's School",
 "SCTCC	c	Sichuan Type Culture Collection",
 "SCU	s	Shandong Christian University",
 "SCUF	s	Universidade Federal de Santa Catarina",
+"SCUI	h	Suez Canal University",
+"SCV	b	State Collection of Viruses",
 "SCZ	s	Smithsonian Tropical Research Institute",
 "SD	s	Herbarium, San Diego Natural History Museum",
 "SDAKS	s	South Dakota State University",
@@ -5456,6 +5800,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SERC<USA-MD>	s	Smithsonian Environmental Research Center",
 "SERG	s	Institut de Recherche Agronomique de Guinee",
 "SERO	s	Sociedad para el Estudio de los Recursos Bioticos de Oaxaca",
+"SERTC	s	Southeastern Regional Taxonomic Center",
 "SES	s	Southeastern Shanxi Teachers School, Biochemistry Department",
 "SETON	s	Philmont Scout Ranch, Seton Memorial Library",
 "SEV	s	Universidad de Sevilla, Departamento de Biologia Vegetal y Ecologia",
@@ -5489,6 +5834,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SGGS	s	The Museum",
 "SGGW	s	Warsaw University of Life Sciences",
 "SGMA	s	Universidade Nova de Lisboa",
+"SGN	h	Southern Institute of Ecology",
 "SGO	s	Herbario, Museo Nacional de Historia Natural, Santiago",
 "SGSC	c	Salmonella Genetic Stock Centre",
 "SGWG	s	Sammlung der Sektion Geologische Wissenschaften der Ernst-Moritz-Arndt University",
@@ -5526,6 +5872,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SIAC<ITA>	s	Accademia dei Fisiocritici Onlus",
 "SIB	s	Sibiu Natural History Museum",
 "SIBAC	s	Southwest Institute of Biology",
+"SIBS	h	Institute of Biology of the Southern Seas",
 "SICH	s	Simpson College, Biology and Environmental Sciences Department",
 "SIEMEA	s	Severtsov Insitute for Evolutionary Morphology and Animal Ecology",
 "SIENA	s	Universita di Siena, Dipartimento di Scienze Ambientali \"G. Sarfatti\"",
@@ -5584,6 +5931,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SLU<CAN>	s	Laurentian University, Biology Department",
 "SLU<USA-LA>	s	Southeastern Louisiana University, Vertebrate Museum",
 "SLUB	s	St. Louis University Museum",
+"SLUBGH	h	Shah Abdul Latif University",
 "SLUM	s	Saint Louis University Museum Ichthylogy Collection",
 "SM<CHN>	s	Chongqing Municipal Academy of Chinese Materia Medica",
 "SM<DEU-Frankfurt>	s	Senckenberg Museum",
@@ -5631,6 +5979,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SMRS	s	Stavropol Museum of Regional Studies",
 "SMS	s	Missouri State University, Department of Biology",
 "SMSM	s	Sarawak Museum",
+"SMTP	s	Swedish Malaise Trap Project",
 "SMTWA	c	School of Medical Technology Western Australia",
 "SMU	s	St. Mary's University",
 "SMU<KOR>	s	Sangmiung University",
@@ -5652,6 +6001,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SNMBR	s	Staatliches Naturhistorisches Museum in Braunschweig",
 "SNMC	s	Slovenske Narodne Muzeum",
 "SNMG	s	Staatliches Museum fuer Naturkunde",
+"SNMH	h	Sree Narayana Mangalam College",
 "SNMNH	s	Saudi Arabian National Museum of Natural History",
 "SNOMNH	s	Sam Nobel Oklahoma Museum of Natural History",
 "SNP<MYS>	s	Sabah Parks, Botany Section",
@@ -5665,6 +6015,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SOA	s	Agricultural University of Plovdiv, Botany Department",
 "SOB	s	Husite Museum Tabor",
 "SOC	s	Southern Oregon University, Biology Department",
+"SOF	h	Sofyivka National Dendrological Park",
 "SOFM	s	National Museum of Natural History, Sofia",
 "SOFRI	b	Southern Fruit Research Institute  Vietnam",
 "SOGS	s	Pal. Coll, Sokoto State Government Palaeontological Collection",
@@ -5672,6 +6023,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SOKO	s	Okresni muzeum Sokolov (Regional Muzeum), Botany Department",
 "SOM	s	Bulgarian Academy of Sciences",
 "SOMF	s	Bulgarian Academy of Sciences",
+"SORO	h	Universidade Federal de Sao Carlos, campus Sorocaba",
 "SOSCMVNH	s	Southern Oregon State College, Museum of Vertebrate Natural History",
 "SOSN	s	Silesian Medical School in Katowice, Department of Pharmaceutical Botany",
 "SOSSRC	s	Save Our Seas Shark Research Center, Nova Southeastern University",
@@ -5698,10 +6050,13 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SPR	s	Springfield Science Museum, Natural Science Department",
 "SPRY	s	Burton Constable Foundation",
 "SPSF	s	Instituto Florestal",
+"SPSU	h	St. Petersburg State University",
 "SPT	s	Botanic Gardens Museum",
 "SPTS	s	Southport Scientific Society",
 "SPWH	s	Marine Biological Laboratory",
+"SQB	h	Societe quebecoise de bryologie",
 "SQF	s	Universidad de Chile, Laboratorio de Botanica, Escuela de Quimica y Farmacia",
+"SQUH	h	Sultan Qaboos University",
 "SR	s	Sichuan Institute of Natural Resources",
 "SRAICC	c	SRAI's culture collection",
 "SRCG	s	Baylor University",
@@ -5714,6 +6069,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SRP	s	Boise State University, Biology Department",
 "SRR	s	Koninklijke Shell (Shell Research N.V.)",
 "SRRC	c	Southern Regional Research Center, Agricultural Research Service, United States Department of Agriculture",
+"SRS	h	Universidade do Sul de Santa Catarina",
 "SRSC	s	Sul Ross State University, Department of Biology",
 "SRSU	s	Sul Ross State University",
 "SS	s	Universita di Sassari, Dipartimento di Botanica ed Ecologia Vegetale",
@@ -5762,10 +6118,12 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "STM<FRA>	c	Laboratoire des Symbioses Tropicales et Mediterraneennes",
 "STM<GBR>	s	Streatham Antiquarian and Natural History Society",
 "STMC	s	School of Tropical Medicine",
+"STNF	h	Shasta-Trinity National Forest",
 "STO	s	The Potteries Museum & Art Gallery",
 "STP	s	La Societe Guernesiaise, Priaulx Library",
 "STPCM	s	Island Museum, Candie Gardens",
 "STPE	s	Florida Marine Research Institute, Florida Department of Environmental Protection",
+"STPH	h	Direccao Geral do Ambiente, Cabinet of Environment, Ministry of Natural Resources and Environment",
 "STPS	s	St. Paul's School",
 "STR	s	Institut de Botanique",
 "STRI	sc	Smithsonian Tropical Research Institute",
@@ -5786,6 +6144,8 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SUD	s	Stroud and District Museum",
 "SUEL	s	Natural History Museum of Bakony Mountains",
 "SUF	s	Shimonoseki University of Fisheries",
+"SUFA	h	Sulaimania University",
+"SUFAF	h	Siirt University Flora and Fauna Center",
 "SUHC	s	Salisbury University, Department of Biology",
 "SUK	s	Shivaji University Kolhapur",
 "SUM<CZE>	s	Okresni vlastivedne muzeum v Sumperku",
@@ -5795,6 +6155,8 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SUNIV	s	University of Stockholm",
 "SUNY	s	State University of New York",
 "SUNYO	s	State University of New York at Oneonta",
+"SURCO	h	Universidad Surcolombiana",
+"SUU	h	Southern Utah University",
 "SUVA	s	University of the South Pacific",
 "SUVM	s	Shippensburg University, Vertebrate Museum",
 "SUWS	s	University of Wisconsin-Superior, Department of Biology and Earth Science",
@@ -5803,8 +6165,10 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SVER	s	Institute of Plant and Animal Ecology, Laboratory of Plant Ecology and Geobotany",
 "SVG	s	Arkeologisk museum i Stavanger",
 "SVIEC	c	Secao de Virus",
+"SVUTY	h	Sri Venkateswara University",
 "SVVC	s	Seminario Vescovile",
 "SWA	s	Swansea Museum",
+"SWAT	h	University of Swat Pakistan",
 "SWAU	s	Southwest Agricultural University, Horticulture Department",
 "SWBR	s	Sweet Briar College, Biology Department",
 "SWC<GBR>	s	Sammlung des Cambridge, University of Zoology",
@@ -5814,6 +6178,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SWF	s	Florida Gulf Coast University",
 "SWFC	s	Southwest Forestry College",
 "SWFSC	s	Southwest Fisheries Science Center",
+"SWGC	h	Grenfell Campus, Memorial University of Newfoundland",
 "SWIBASC	s	Academia Sinica",
 "SWMT	s	Rhodes College, Biology Department",
 "SWN	s	Saffron Walden Museum",
@@ -5822,9 +6187,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SWSL	s	USDA/ARS, Southern Weed Science Research Unit",
 "SWT	s	Southwest Texas State University, Department of Biology",
 "SWTN	s	Swinton and Pendlebury Botanical Society",
+"SWU	h	Sungshin Women's University",
 "SWU2	c	Department of Biology, Faculty of Science",
 "SXAU	s	Shanxi Agricultural University, Forestry Department",
 "SXDC	s	Shaanxi Institute for Drug Control",
+"SXIM	h	Shaanxi Institute of Microbiology",
 "SXMP	s	Shaanxi Academy of Traditional Chinese Medicine and Pharmacology",
 "SXU	s	Shanxi University, Biology Department",
 "SY	s	Shenyang Municipal Academy of Landscape Gardening",
@@ -5838,11 +6205,13 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SYRF	s	State University of New York",
 "SYS	s	Sun Yatsen University, Biology Department",
 "SYS:Z	s	Sun Yatsen University, Biology Department, Zoology Collection",
+"SYSBM	s	The Museum of Biology Sun Yat-sen University",
 "SYSU	s	National Sun Yat-Sen University, Department of Biological Sciences",
 "SYT	s	Stonyhurst College",
 "SZ	s	Sichuan University, Biological Department",
 "SZB	s	Haus der Natur",
 "SZCU	s	Department of Systematic Zoology",
+"SZCZ	h	University of Szczecin",
 "SZE<HUN>	s	Mora Ferenc Museum, Natural Science Department",
 "SZE<TUR>	s	Zoology Department, Aegean University, Science Faculty",
 "SZG	s	Shenzhen Fairy Lake Botanical Garden",
@@ -5853,6 +6222,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "SZPT	s	Shenzhen Polytechnic",
 "SZPT:ENT	s	Shenzhen Polytechnic, Entomology Collection",
 "SZU	s	University of Salzburg, Department of Organismic Biology",
+"SZUB	h	University of Szczecin",
 "T	s	Tavera, Department of Geology and Geophysics",
 "TA	s	Timescale Adventures Research and Interpretive Center",
 "TAA	s	Estonian Agricultural University, Institute of Agricultural and Environmental Sciences",
@@ -5863,10 +6233,12 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "TAFIRI	s	Tanzania Fisheries Research Institute",
 "TAI	s	National Taiwan University, Institute of Ecology and Evolutionary Biology",
 "TAIC	s	Texas A&M University-Kingsville, Department of Biology",
+"TAIE	h	Endemic Species Research Institute",
 "TAIF	s	Taiwan Forestry Research Institute",
 "TAIM	s	Taiwan Museum",
 "TAIU	s	Texas A&M University - Kingsville, Texas A&I Collections",
 "TAK	s	Lenin State University",
+"TAL	h	Jardin botanique de Talence",
 "TALE	s	Laboratoire Geologique",
 "TALL	s	Tallinn Botanic Garden, Department of Environmental Education",
 "TAM	s	Estonian Museum of Natural History, Botany Department",
@@ -5883,11 +6255,13 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "TAU<GRC>	s	Aristotle University of Thessaloniki, Biology Department",
 "TAU<ISR>	s	Tel-Aviv University",
 "TAUF	s	Aristotle University of Thessaloniki, Department of Forestry and Natural Environment",
+"TAWES	h	Maryland Department of Natural Resources",
 "TB	s	Tbilisi State University, Botany Department",
 "TBG<JPN>	b	Tsukuba Botanical Garden",
 "TBGT	s	Tropical Botanic Garden and Research Institute",
 "TBI	s	Georgian Academy of Sciences",
 "TBIP	s	Research Institute of Plant Protection",
+"TBPH	h	Iovel Kutateladze Institute of Pharmacochemistry",
 "TBY	s	Tenby Museum",
 "TCB	s	National Chung Hsing University, Botany Department",
 "TCC/USP	c	Trypanosomatid Culture Collection, University of Sao Paulo",
@@ -5927,6 +6301,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "TESC	s	The Evergreen State College",
 "TESRI	s	Taiwan Endemic Species Research Institute",
 "TEU	s	Teikyo University, Education Department",
+"TEUI	h	U.S. Forest Service Southwest Region, Terrestrial Ecological Unit Inventory",
 "TEX	s	University of Texas at Austin, Plant Resources Center",
 "TEXA	s	Blackland Experiment Station",
 "TF<JPN>	s	Forestry and Forest Products Research Institute",
@@ -5944,6 +6319,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "TGM	s	Janashia State Museum of Georgia",
 "TGPI	s	Tiraspolskij Gosudarstvennij Pedagogiceskij Institut",
 "TGRC	b	C.M. Rick Tomato Genetics Resource Center",
+"TGU	h	University of Montenegro",
 "TH	s	University of Tokyo",
 "THBC	s	Technische Hochschule",
 "THIB	s	Nicholls State University, Department of Biological Sciences",
@@ -6001,6 +6377,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "TMNH	s	Tianjin Museum of Natural History",
 "TMP<FIN>	s	Tampere Museums",
 "TMP<ZAF>	s	Transvaal Museum",
+"TMRC	h	Shahid Beheshti University of Medical Sciences",
 "TMS	s	Toleco Museum of Health and Natural History",
 "TMSA	s	Transvaal Museum",
 "TMTC	s	Taiwan Provincial Museum",
@@ -6027,8 +6404,10 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "TOLI	s	Universidad del Tolima, Departamento de Biologia",
 "TOM	s	Istituto Missioni Consolata",
 "TOM<CAN>	c	Tomicus collection Canadian Forest Service",
+"TON	h	Ministry of Agriculture and Food, Forestry and Fisheries",
 "TONG	s	Tonghua Teachers College, Biology Department",
 "TOR	s	Torquay Museum",
+"TOU	h	University of Tours",
 "TOYA	s	Toyama Science Museum, Botany Department",
 "TPI	s	The Pirbright Institute",
 "TPI:ENT	s	The Pirbright Institute, Entomology collection",
@@ -6047,6 +6426,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "TRO	s	Royal Horticultural Society of Cornwall",
 "TROM	s	University of Tromsoe, Botanical Department",
 "TROY	s	Troy State University, Department of Biological and Environmental Sciences",
+"TRPM	h	Tottori Prefectural Museum",
 "TRT	s	Royal Ontario Museum, Department of Natural History",
 "TRTC	s	Royal Ontario Museum, Center for Biodiversity and Conservation Biology",
 "TRTE	s	Erindale College, University of Toronto, Department of Biology",
@@ -6057,6 +6437,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "TSB	s	Universita degli Studi di Trieste, Dipartimento di Biologia",
 "TSC	s	Tarleton State University, Tarleton State Collection",
 "TsGM	s	Central Geological Museum",
+"TSH	h	University of Tsukuba",
 "TSM	s	Erbario, Museo Civico di Storia Naturale, Trieste",
 "TSMHN	s	Teylers Strichtina Museum",
 "TsNIGRI	s	Tsentralny Nauchno-Issledovatelskii Geolgo-Razvedochni Muzei (Chernyshev's Central Museum of Geological Exploration)",
@@ -6084,12 +6465,16 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "TUBSB	b	Tohoku University Brassica Seed Bank",
 "TUC	s	University of Arizona, Ecology and Evolutionary Biology Department",
 "TUCH	s	Tribhuvan University, Central Department of Botany",
+"TUCIM	c	TU Wien collection of industrial microorganisms",
+"TUCIM:	c	TU Wien collection of industrial microorganisms, ",
+"TUFC	s	Tottori University Fungal Culture Collection",
 "TUFIL	s	Tokyo University of Fisheries, Ichthyological Laboratory",
 "TUFT	s	Tufts University, Biology Department",
 "TUH	s	Tehran University, Department of Biology",
 "TULE	s	Tokyo University of Agriculture & Technology",
 "TULS	s	University of Tulsa",
 "TULV	s	Jardin Botanico Juan Maria Cespedes",
+"TUM	h	Technische Universitat Munchen",
 "TUMH	s	Tottori Fungus/Mushroom Resource and Research Center",
 "TUN	s	Universite de Tunis, Laboratoire de Biologie Vegetale",
 "TUNG	s	Tunghai University, Biology Department",
@@ -6109,6 +6494,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "TWC	s	Texas Wesleyan College, Museum of Zoology",
 "TWRA	s	Tennessee Wildlife Resources Agency",
 "TYF	s	Shangxi Forestry Institute",
+"TYM	h	Botanic Gardens of Toyama",
 "TZM	s	National Science Museum",
 "U	s	Nationaal Herbarium Nederland, Utrecht University branch",
 "UA<GRC>	s	Department of Historical Geology and Paleontology",
@@ -6156,6 +6542,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UAMZ	s	University of Alberta Museum of Zoology",
 "UAMZC	s	University of Arkansas, Museum Zoological Collections",
 "UANL	s	Universidad Autonoma de Nuevo Leon",
+"UAPC	h	University of Alberta",
 "UARK	s	University of Arkansas",
 "UAS	s	Universidad Autonoma de Sinaloa",
 "UAS-B	s	University of Agricultural Sciences Bangalore",
@@ -6176,6 +6563,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UBC:Fish	s	Beaty Biodiversity Museum, University of British Columbia, Fish Collection",
 "UBCC	c	University of Barcelona Culture Collection",
 "UBCZ	s	University of British Columbia, Spencer Entomological Museum",
+"UBDH	h	Universiti Brunei Darussalam",
 "UBJTL	s	Universidad Bogota Jorge Tadeo Lozano",
 "UBL	s	Universite du Benin",
 "UBOCC	c	Universite de Bretagne Occidentale",
@@ -6199,6 +6587,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UCFC	s	University of Central Florida",
 "UCGC	s	University of Colorado, Geological Museum",
 "UCGE	c	Unit Cell of Genetic Engineering, Department of Biochemistry",
+"UCH	h	Universidad Autonoma de Chiriqui",
 "UCHT	s	University of Tennessee, Chattanooga, Department of Biological and Environmental Sciences",
 "UCI	s	University of Ibadan, Botany and Microbiology Department",
 "UCJ	s	Universite d'Abidjan, Departemente de Botanique",
@@ -6211,6 +6600,10 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UCM<ESP>	s	Universidad Complutense Madrid",
 "UCM<UKR>	c	Ukrainian Collection of Microorganisms, Zabolotny Institute of Microbiology and Virology",
 "UCM<USA-CO>	s	University of Colorado Museum",
+"UCM<USA-CO>:Bird	s	University of Colorado Museum, University of Colorado Museum Bird Collection",
+"UCM<USA-CO>:Fish	s	University of Colorado Museum, University of Colorado Museum Fish collection",
+"UCM<USA-CO>:Herp	s	University of Colorado Museum, University of Colorado Museum Amplibian and Reptile collection",
+"UCM<USA-CO>:Mamm	s	University of Colorado Museum, University of Colorado Museum Mammal Collection",
 "UCMC	s	University of Colorado Museum",
 "UCME	s	Faculdad de Biologia, Departamento de Zoologia",
 "UCMM	s	Pontificia Universidad Catolica Madre y Maestra",
@@ -6247,6 +6640,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UEC	s	Universidade Estadual de Campinas, Departamento de Botanica",
 "UEFS	s	Laboratorio de Ictiologia",
 "UENF	s	Universidade Estadual do Norte Fluminense",
+"UESC	h	Universidade Estadual de Santa Cruz",
 "UESS	s	Universidad de El Salvador",
 "UEVH	s	Universidade de Evora, Departamento de Biologia",
 "UF	sb	University of Florida Museum of Natural History",
@@ -6258,6 +6652,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UF:Ornithology	s	University of Florida Museum of Natural History, Ornithology Skins and Skeletons Collection",
 "UF:Porifera	s	University of Florida Museum of Natural History, ",
 "UFA	s	Ufa Scientific Centre, Russian Academy of Sciences",
+"UFACPZ	h	Universidade Federal do Acre/Parque Zoobotanico",
 "UFC	s	Universidade Federal do Ceara, Departamento de Biologia",
 "UFES	s	Universidade Federal do Espirito Santo",
 "UFG	s	Universidade Federal de Goias, Unidade de Conservacao",
@@ -6279,9 +6674,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UFRJ<museum>	s	Departramento de Zoologia, Universidade Federal do Rio de Janeiro",
 "UFRJIM	c	Departamento de Microbiologia Medica",
 "UFRN	s	Universidade Federal do Rio Grande do Norte",
+"UFRR	h	Universidade Federal de Roraima",
 "UFS	s	Nyabyeya Forestry College, Department of Environmental Forestry",
 "UFSC	s	Universidade Federal de Santa Catarina",
 "UFScarCC	c	Freshwater Microalgae Collection Cultures",
+"UFU	h	Ural Federal University",
 "UFVB	s	Vicosa, Universidade Federal de Vicosa, Museum of Entomology",
 "UG<ESP>	s	Museo del Departamento de Estratigrafia y Paleontologia",
 "UG<GHA>	s	University of Ghana",
@@ -6306,6 +6703,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UIMNH	s	University of Illinois, Museum of Natural History",
 "UIS	s	Universidad Industrial de Santander, Departamento de Biologia",
 "UIS:H	s	Universidad Industrial de Santander, Departamento de Biologia, Collecion Herpetologica",
+"UISMHN	s	Universidad Industrial de Santander, Museo de Historia Natural",
 "UJAT	s	Universidad Juarez Autonoma de Tabasco",
 "UJB	c	University of Jaffna Botany",
 "UJIM	s	University of Jordan Insect Museum",
@@ -6326,7 +6724,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ULCI	s	Universidad de la Laguna",
 "ULF	s	Universite Laval, Departement des Sciences forestieres",
 "ULKY	s	University of Louisville",
-"ULLZ	s	University of Louisiana at Layafette, Zoological Collection",
+"ULLZ	s	University of Louisiana at Layafette Zoological Collection",
 "ULM	s	Universitaet Ulm, Abteilung Systematische Botanik und Oekologie",
 "ULMG	s	University of Leipzig",
 "ULN	s	University of Lagos",
@@ -6362,6 +6760,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UMKC	s	University of Missouri",
 "UMKL	s	University of Malaysia",
 "UMKU	s	Uganda Museum",
+"UMM	h	University of Maine at Machias",
 "UMML	s	University of Miami Marine Laboratory",
 "UMMP	s	University of Michigan",
 "UMMZ	s	University of Michigan, Museum of Zoology",
@@ -6377,6 +6776,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UMS	s	Universiti Malaysia Sabah",
 "UMSA	s	Instituto de Ecologia",
 "UMSP	s	University of Minnesota",
+"UMSS	s	Universidad Mayor de San Simon, Facultad de Ciencias y Tecnologia, Centro de Biodiversidad, Zoologia,Laboratorio de Ictiologia",
 "UMT	s	Mutare Museum",
 "UMUT	s	University Museum, University of Tokyo",
 "UMUTZ	s	Department of Zoology, University Museum",
@@ -6405,6 +6805,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UNAN	s	Universidad Nacional Autonoma de Nicaragua",
 "UNB	s	Connell Memorial Herbarium",
 "UNC-B	s	University of Northern Colorado",
+"UNCA	h	University of North Carolina at Asheville",
 "UNCB	s	Universidad Nacional de Colombia, Insituto de Ciencias Naturales de la Universidad Nacional",
 "UNCC<COL>	s	Universidad Nacional de Caldas, Museo de Historia Natural",
 "UNCC<USA-NC>	s	University of North Carolina, Biology Department",
@@ -6424,6 +6825,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UNIN	s	University of the North, Botany Department",
 "UNIP	s	Universidade Paulista, Laboratorio de Botanica",
 "UNIQEM	c	Institute of Microbiology, Russian Academy of Sciences",
+"UNITEC	h	Unitec Institute of Technology",
 "UNL<MEX>	s	Universidad Autonoma de Nuevo Leon",
 "UNL<PRT>	s	Centro de Estratigrafia e Paleobiologia da Universidade Nova de Lisboa",
 "UNL<USA-NE>	s	University of Nebraska State Museum",
@@ -6467,6 +6869,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UPA	s	University of Patras, Department of Plant Biology",
 "UPCB	s	Universidade Federal do Parana, Departamento de Botanica",
 "UPCC	c	Natural Sciences Research Institute Culture Collection",
+"UPCT	h	Universidad Politecnica De Cartagena",
 "UPEI	s	University of Prince Edward Island, Biology Department",
 "UPF	s	Universite de Polynesie Francaise Herbarium",
 "UPIE	b	Unidad de Patologia Infecciosa y Epidemiologia",
@@ -6478,7 +6881,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UPMSI	s	Marine Science Institute",
 "UPNA	s	Universidad Publica de Navarra, Departamento de Ciencias del Medio Natural",
 "UPNG	s	University of Papua New Guinea, Division of Biological Sciences",
-"UPOL<CZE>	s	University Palacky Olomouc",
+"UPOL	s	University Palacky Olomouc",
 "UPOS	s	Universidad Pablo de Olavide, Ciencias Ambientales (Botanica)",
 "UPP	s	Uppingham School Museum",
 "UPPC	s	University of the Philippines",
@@ -6550,6 +6953,8 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "USM<MYS>	s	Universiti Sains Malaysia",
 "USM<MYS>:VCRU	s	Universiti Sains Malaysia, Vector Control Research Unit",
 "USM<PER>	s	Universidad Nacional Mayor de San Marcos, Museo de Historia Natural, Herbario",
+"USMMC	s	Universiti Sains Malaysia Mollusc Collection",
+"USMP	h	Universiti Sains Malaysia",
 "USMS	s	University of Southern Mississippi, Department of Biological Sciences",
 "USNC	s	Smithsonian Institution, Paleobiology Department",
 "USNM	sb	National Museum of Natural History, Smithsonian Institution",
@@ -6572,6 +6977,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "USTF	s	Technologische Faculteit",
 "USTK	s	University of Science and Technology, Museum of Natural History",
 "USU	s	United States Department of Agriculture",
+"USUUB	h	Utah State University Uintah Basin",
 "USZ	s	Universidad Autonoma Gabriel Rene Moreno",
 "UT<USA-TN>	s	University of Tennessee",
 "UT<USA-UT>	s	University of Utah Herbarium",
@@ -6584,6 +6990,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UTD	s	University of Texas, Plant Resources Center",
 "UTE	s	University of Tartu",
 "UTEP	s	University of Texas at El Paso, Centennial Museum",
+"UTEP:Herp	s	University of Texas at El Paso, Centennial Museum, Herpetology Collection",
 "UTEX	c	The Culture Collection of Algae at the University of Texas Austin",
 "UTG	s	University of Tuebingen",
 "UTGD	s	Geology Department, The University of Tasmania",
@@ -6600,6 +7007,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UU<UKR>	s	Uzhgorod State University, Botany Department",
 "UU<USA-UT>	s	University of Utah, Department of Biology",
 "UUC	c	Janet A. Robertson Collection of Ureaplasma urealyticum Cultures",
+"UUDE	h	Buryat State University",
 "UUH	s	Institute of General and Experimental Biology, Department of Floristics and Geobotany",
 "UUVP	s	University of Utah, Vertebrate Paleontology",
 "UUZM	s	Uppsala University, Zoological Museum",
@@ -6621,6 +7029,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "UVV	s	Universita di Venezia, Dipartimento de Scienze Ambientali",
 "UW	s	University of Washington Fish Collection",
 "UWA	s	University of Western Australia, Botany Department",
+"UWAL	h	University of West Alabama",
 "UWBM	s	University of Washington, Burke Museum",
 "UWBM:Mamm	s	University of Washington, Burke Museum, Burke Museum's mammal collection",
 "UWBM:ORN	s	University of Washington, Burke Museum, Ornithology Collection",
@@ -6685,8 +7094,11 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "VER	s	Herbario, Museo Civico di Storia Naturale, Verona",
 "VETMED	s	University of Veterinary Medicine",
 "VF	s	Universidad de Valencia, Departamento de Biologia Vegetal, Botanica",
+"VFM	h	Forest Inventory and Planning Institute",
 "VFWD	s	Vermont Fish and Wildlife Department",
+"VFWO	h	U.S. Fish and Wildlife Service, Ventura Fish and Wildlife Office",
 "VGZ	s	Voronezh State Biosphere Reserve, Research Department",
+"VH	h	Vivekanand Arts Sardar Dalipsingh Commerce and Science College",
 "VHS<AUS>	c	Vegetation Health Service  ( Phytophthora cultures )",
 "VI<NOR>	c	Mykotektet, National Veterinary Institute",
 "VI<SWE>	s	Gotlands Fornsal",
@@ -6697,6 +7109,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "VICA	s	Agriculture Department",
 "VICF	s	Forestry Department",
 "VICH	s	Plant Protection Department",
+"VIES	h	Federal University of Espirito Santo",
 "VIL	s	Universite de Paris-Sud",
 "VIMS	s	Virginia Institute of Marine Science",
 "VIST	s	University of the Virgin Islands, Natural Resources Program",
@@ -6706,17 +7119,21 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "VKPM	c	Russian National Collection of Industrial Microorganisms",
 "VLA	s	Far Eastern Branch, Russian Academy of Sciences, Botany Department",
 "VM	s	Okresni vlastivedne muzeum",
+"VMI	h	Virginia Military Institute",
 "VMIL	s	Virginia Military Institute, Biology Department",
 "VMKSC	s	Kearney State University, Vertebrate Museum",
 "VMM	s	Vanderbilt Marine Museum",
 "VMNH	s	Virginia Museum of Natural History",
 "VMSL	s	I.N.T.A., E.E.A. San Luis, Pastizales Naturales",
 "VNC	s	Los Angeles Valley College, Life Sciences Department",
+"VNF	h	Vietnam Forestry Herbarium",
 "VNGA	s	Vorarlberger Naturschau",
 "VNIRO	s	Institute of Oceanography",
+"VNM	h	Institute of Tropical Biology",
 "VNMN	s	Vietnam National Museum of Nature",
 "VOA	s	Ostrobothnian Museum",
 "VOR	s	Voronezh State University, Biology and Plant Ecology Department",
+"VORB	h	Botanical Garden Dr. B.M. Kozo-Polyansky, Voronezh State University",
 "VORG	s	Voronezh State University, Faculty of Geography and Geoecology",
 "VPB	c	Veterinary Pathology and Bacteriology Collection",
 "VPCI	c	Fungal Culture Collection",
@@ -6733,7 +7150,8 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "VSM<SVK>	s	Eastern Slovakian (Vychodoslovenske) Museum, Natural History Department",
 "VSRI	s	N.I. Vavilov All-Russian Scientific Research Instiutte of Plant Industry",
 "VSUH	s	Virginia State University, Life Sciences Department",
-"VT	s	University of Vermont, Botany Department",
+"VT	s	Pringle Herbarium, University of Vermont",
+"VTA	h	Jardin Botanique de la Villa Thuret",
 "VTB	c	Banco de Celulas Humanas e Animais Laboratorio de Patologia Celular e Molecular",
 "VTCC	c	Vietnam Type Culture Collection, Center of Biotechnology",
 "VTT	c	VTT Biotechnology, Culture Collection",
@@ -6744,8 +7162,9 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "VYH	c	Finnish Environment Institute (SYKE)",
 "VYM	s	Muzeum Vyakovska",
 "W	s	Naturhistorisches Museum Wien, Department of Botany",
-"WA	s	Warsaw University, Department of Plant Systematics and Geography",
+"WA	s	Herbarium, Faculty of Biology, University of Warsaw",
 "WAB	s	Wabash College, Biological Sciences Department",
+"WABG	h	University of Warsaw Botanic Garden",
 "WAC	c	Department of Agriculture Western Australia Plant Pathogen Collection",
 "WACA<USA-AZ>	s	Walnut Canyon National Monument",
 "WACA<USA-OR>	s	Work Amber Collection",
@@ -6753,6 +7172,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "WADA	s	Western Australia Department of Agriculture",
 "WAG	s	Wageningen University",
 "WAHO	s	Institute of Horticultural Plant Breeding, Department of Biosystematics",
+"WAI	h	Waimea Valley",
 "WAIK	s	University of Waikato, Biological Sciences Department",
 "WAITE	c	Insect Pathology Pathogen Collection",
 "WAL	c	Wadsworth Anaerobe Laboratory, Wadsworth Hospital Center",
@@ -6760,6 +7180,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "WAMP	s	Western Australian Museum",
 "WAN	s	Forest Research Station",
 "WANF	s	Wasatch-Cache National Forest",
+"WAPA	h	War in the Pacific National Historical Park",
 "WAR	s	Warwickshire Museum, Natural History Department",
 "WARC	c	New Zealand Reference Culture Collection",
 "WARK	s	Western Illinois University, Biology Department",
@@ -6784,6 +7205,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "WCP	s	Walla Walla College, Biological Sciences Department",
 "WCR	s	Winchester City Museum",
 "WCRP	s	Winchester Public Library",
+"WCSBG	h	West China Subalpine Botanical Garden",
 "WCSU	s	Western Connecticut State University, Department of Biological and Environmental Sciences",
 "WCU	s	West China University of Medical Sciences",
 "WCUH	s	Western Carolina University, Department of Biology",
@@ -6805,6 +7227,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "WFU	s	Wake Forest University, Biology Department",
 "WFUVC	s	Wake Forest University, Vertebrate Collection",
 "WGC	s	State University of West Georgia, Biology Department",
+"WGCH	h	Wilton Garden Club",
 "WGD	s	Washington Game Department",
 "WGMM	s	Woodspring Museum",
 "WGRC	b	Wheat Genetics Resource Center",
@@ -6823,6 +7246,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "WIBF	s	West Indian Beetle Fauna Project Collection",
 "WIBG	s	Windward Islands Banana Grower's Association",
 "WICA	s	Wind Cave National Park",
+"WICH	h	Wichita State University",
 "WIES	s	Museum Wiesbaden",
 "WII	s	Wildlife Institute of India, Department of Habitat Ecology",
 "WILLI	s	The College of William and Mary, Department of Biology",
@@ -6834,6 +7258,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "WINF	s	Forestry and Rural Developmen Department",
 "WINFM	s	Forestry and Rural Developmen Department",
 "WINO	s	Saint Mary's College, Biology Department",
+"WINU	h	Winthrop University",
 "WIR	sb	N. I. Vavilov Institute of Plant Industry, Department of Introduction and Systematics",
 "WIS	s	University of Wisconsin, Botany Department",
 "WIU	s	Western Illinois University, Museum of Natural History",
@@ -6914,6 +7339,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "WUK	s	Northwestern Institute of Botany",
 "WUM	s	University of Witwatersrand",
 "WUME	s	Willamette University",
+"WUP	h	Department of Pharmacognosy, Universitat Wien",
 "WVA	s	West Virginia University, Biology Department",
 "WVBS	s	West Virginia Biological Survey",
 "WVDH	c	West Virginia Hygienic Laboratory",
@@ -6923,6 +7349,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "WVUC	s	West Virginia University",
 "WVW	s	West Virginia Wesleyan College, Biology Department",
 "WWB	s	Western Washington University, Biology Department",
+"WWC	h	Warren Wilson College",
 "WWF	s	Welder Wildlife Foundation",
 "WWM	s	Werner Wildlife Museum",
 "WWSP	s	Weymouth Woods Sandhills Nature Preserve",
@@ -6947,6 +7374,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "XJU	s	Xinjiang University, Biology Department",
 "XJUG	s	Xinjiang University, Geography Department",
 "XM	s	Xinjiang Medical College, Pharmacy Department",
+"XMU	s	Xiamen University",
 "XNC	s	Department of Biology, Xinxiang Normal College",
 "XOLO	s	Universidad Autonoma Chapingo, Departamento de Fitotecnia",
 "XTNM	s	Xinjiang Institute of Traditional Chinese and Minorities Medicine",
@@ -6962,6 +7390,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "YAK	s	Forest Survey and Design Institute",
 "YALT	s	The State Nikita Botanical Gardens, Flora and Vegetation",
 "YAM	s	Yamaguchi University, Plant Pathology Department",
+"YAMA	h	Yamagata Prefectural Museum",
 "YAR	s	Yaroslavl State University, Department of Biology and Ecology",
 "YBDC	s	Yibin Institute for Drug Control",
 "YBI	s	Institut National pour l'Etude et la Recherche Agronomique, Departement de Botanique",
@@ -7084,7 +7513,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ZMHB	s	Museum fuer Naturkunde der Humboldt-Universitat",
 "ZMHU	s	Zoologisches Museum der Humboldt Universitaet",
 "ZMJU	s	Zoological Museum, Jagiellonian University",
-"ZMK<DEU>	s	Zoologisches Museum der Universitaet Kiel",
+"ZMK<DEU>	s	Zoologisches Museum der Universitat Kiel",
 "ZMK<DNK>	s	Zoological Museum, Copenhagen",
 "ZMK<NOR>	s	Zoological Musem, Kristiania",
 "ZMKR	s	Koenigsberg Zoologisches Museum",
@@ -7103,6 +7532,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ZMMU:Mamm	s	Zoological Museum, Moscow Lomonosov State University, Mammal Collection",
 "ZMNH	s	Zhejiang Museum of Natural History",
 "ZMO	s	Zoology Museum, Oxford University",
+"ZMS	s	Zentralmuseum Senckenberg (SENCKENBERG world of biodiversity)",
 "ZMSZ	s	Zemaljski Mujski",
 "ZMT<CZE>	s	Zapadomoravske muzeum v Trebici",
 "ZMT<GEO>	s	Georgian State Museum, Zoological Section",
@@ -7129,6 +7559,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ZMUT	s	University of Tokyo, Department of Zoology",
 "ZMUU	s	Uppsala Universitet, Zoologiska Museet",
 "ZMUZ	s	Zoologisches Museum der Universitaet Zuerich",
+"ZNG	h	Bulent Ecevit University",
 "ZNM	s	Zhejiang Natural Museum",
 "ZNP	s	Zion National Park",
 "ZNPC	s	Springdale, Zion National Park",
@@ -7171,6 +7602,7 @@ static const char* const kInstitutionCollectionCodeList[] = {
 "ZVC	s	Depto. de Zoologia Vertebrados de la Facultad de Humanidades y Ciencias",
 "ZVCB<URY>	s	Vertebrate Collection, Facultad de Ciencias, Universidad de la Republica",
 "ZVS	s	Bundesamt fuer Naturschutz",
+"ZY	h	Zunyi Normal College",
 "ZYTC	s	Zhangye Teachers College, Chemistry-Biology Department",
 "ZZN	c	Zavod za naravoslovje",
 "ZZSZ	s	Zoology Department, Faculty of Natural Sciences, University of Zagreb"
diff --git a/c++/src/objects/seqfeat/institution_codes.txt b/c++/src/objects/seqfeat/institution_codes.txt
index f7fbdd8..39c6ba8 100644
--- a/c++/src/objects/seqfeat/institution_codes.txt
+++ b/c++/src/objects/seqfeat/institution_codes.txt
@@ -1,5 +1,6 @@
 A	s	Arnold Arboretum, Harvard University
 AA	s	Ministry of Science, Academy of Sciences
+AAC	c	Arignar Anna College
 AAH	s	Arnold Arboretum, Harvard University
 AAPI	s	Plant Industry Laboratory
 AAR	s	Reliquae Aaronsohnianae
@@ -114,6 +115,7 @@ AJBC	s	Atkins Jardin Botanico de Cienfuegos
 AJOU	s	Ajou University, Biological Sciences Department
 AK	s	Auckland War Memorial Museum
 AKPM	s	Akita Prefectural Museum
+AKSU	h	Aksaray University
 AKU<JPN>	c	Faculty of Agriculture
 AKU<NZ>	s	University of Auckland, School of Biological Sciences
 AL	s	Universite d'Alger
@@ -506,6 +508,7 @@ BIRM	s	University of Birmingham
 BISH	s	Bishop Museum, Department of Natural Sciences
 BITU	s	Department of Biology, Faculty of Science, Toyama University
 BIUB	s	Mongolian Academy of Sciences
+BJ	h	Bi Jie University
 BJA	s	University of Burundi, Biology Department
 BJFC	s	Beijing Forestry University
 BJM	s	Beijing Natural History Museum
@@ -522,7 +525,9 @@ BLFU	s	University of the Free State, Department of Botany and Genetics
 BLGA	s	Burgenlandisches Landesmuseum
 BLH	s	Cranbrook Institute of Science
 BLIH	s	Biological Laboratory Imperial Household of Japan
+BLMAR	h	Bureau of Land Management Arcata Field Office
 BLMLK	s	Bureau of Land Management
+BLMPR	h	Bureau of Land Management, Prineville Field Office
 BLT	s	Belfast Natural History and Philosophical Society
 BLUZ	s	Museo de Biologia
 BLWG	c	Bayerische Landesanstalt fur Weinbau und Gartenbau
@@ -553,6 +558,7 @@ BNA<ESP>	c	National Bank of Algae
 BNA<GBR>	s	British (Empire) Naturalists' Association
 BNBE	s	YMCA Hostel
 BNFF	s	Banff Museum
+BNFH	h	U.S. Forest Service, Bitterroot National Forest
 BNH	s	Nassau Botanical Gardens, Department of Agriculture
 BNHD	s	Bengal Natural History Museum
 BNHM<CHN>	s	Beijing Natural History Museum
@@ -637,6 +643,7 @@ BRS	s	Agriculture and Agri-Food Canada
 BRSL	s	Wroclaw University, Botany Department
 BRSMG	s	Department of Geology
 BRSN	s	University of Wales, Bangor Research Unit
+BRSU	h	Bryansk State University
 BRTN	s	Brighton Natural History Society
 BRU	s	Brown University
 BRUN	s	Brunei Forestry Centre
@@ -653,6 +660,7 @@ BSD	s	Botanical Survey of India, Northern Circle
 BSE	s	Moyse's Hall Museum
 BSHC	s	Botanical Survey of India, Sikkim Himalayan Circle
 BSI	s	Botanical Survey of India, Western Circle, Ministry of Environment and Forests
+BSID	h	Botanical Survey of India
 BSIP	s	Ministry of Natural Resources, Department of Forests, Environment, and Conservation
 BSIS	s	Botanical Survey of India, Industrial Section
 BSJO	s	Botanical Survey of India, Arid Zone Circle
@@ -679,6 +687,7 @@ BTJW	s	Bridger Teton National Forest
 BTN	s	Booth Museum of Natural History
 BTT	s	Burton-upon-Trent Natural History and Archaeological Society
 BTU	s	Technische Universitaet Berlin
+BU	h	Brock University
 BUA	s	University of Baghdad, Plant Protection Department
 BUAG	s	University of Agronomical Sciences and Veterinary Medicine, Botany and Plant Physiology Department
 BUC	s	Universitatea din Bucuresti
@@ -699,15 +708,18 @@ BUNH	s	University of Baghdad
 BUNS	s	University of Novi Sad, Department of Biology and Ecology
 BUPL	s	Bucknell University, Biology Department
 BURD	s	University of Burdwan, Botany Department
+BURI	h	Banasthali University
 BURP	s	Burpee Museum of Natural History
 BUS	s	University of Miami, Biology Department
 BUT	s	Butler University
 BUTC	s	Boston University
 BVC	s	Buena Vista College
+BVS	h	Transylvania University of Brasov
 BYBS	s	Bungay Botanical Society
 BYDG	s	Technical-Agriculture Academy, Department of Botany and Ecology
 BYU	s	Monte L. Bean Life Science Museum
 BZ	s	Herbarium Bogoriense
+BZCM	h	Bozhou Vocational and Technical College
 BZF	s	Forest Research and Development Center and Nature Conservation
 BZM	s	Museum fur Naturkunde, Berlin
 BZT	s	Biological Institute Titograd
@@ -737,6 +749,7 @@ CAL	s	Botanical Survey of India
 CALI	s	University of Calicut, Botany Department
 CALP	s	University of the Philippines at Los Banos
 CALU	c	Collection of Algae in Leningrad, St. Petersburg, State University
+CALVIN	h	Calvin College
 CAM<AUST>	s	Central Australian Museum
 CAM<UK>	s	St. John's College
 CAME	s	Universita di Camerino, Dipartimento de Botanica ed Ecologia
@@ -753,6 +766,7 @@ CANTY	s	Canterbury Museum
 CANU	s	University of Canterbury, Department of Plant and Microbial Sciences
 CAPM	c	Collection of Animal Pathogenic Microorganisms
 CAR	s	Museo de Historia Natural La Salle, Departamento de Botanica
+CARAN	h	Herbarium Carautanum
 CARD	s	Caribbean Agricultural Research Institute
 CARE	s	Caribbean Epidemiology Centre
 CARI	s	Cukurova Agricultural Research Institute
@@ -783,6 +797,8 @@ CASM	s	Chicago Academy of Sciences, Museum of Natural History
 CASMB	s	Centre of Advanced Study in Marine Biology
 CASS	s	Chinese Academy of Sciences, Shenyang
 CAT	s	Universita di Catania, Dipartimento di Botanica e Orto Botanico
+CATA	h	Catalina Island Conservancy
+CATH	h	Catholicate College
 CATIE	s	Tropical Agricultural Research and Training Center (CATIE), Plant Production Department
 CAU	s	China Agricultural University
 CAUP<COL>	s	Universidad del Cauca
@@ -803,6 +819,8 @@ CBM	s	Natural History Museum and Institute
 CBM:ZC	s	Natural History Museum and Institute, Zoological Collection
 CBMAI	c	Brazilian Collection of Microorganisms from the Environment and Industry (Colecao Brasileira de Microrganismos de Ambiente e Industria)
 CBNM	s	Cedar Breaks National Monument
+CBNSA	h	Conservatoire botanique national Sud-Atlantique
+CBPF	h	Conservatoire Botanique Pierre Fabre
 CBS	sc	Centraalbureau voor Schimmelcultures, Fungal and Yeast Collection
 CBSIZA	s	Caspian Biological Station Institute of Zoology
 CBTCCCAS	c	The Cell Bank of Type Culture Collection of Chinese Academy of Sciences
@@ -826,6 +844,7 @@ CCC<IND>	c	Cyanobacterial Culture Collection, National Centre for Conservation a
 CCCC	s	Carthage College
 CCCIEB	c	Culture Collections of Microorgansisms of Center of Genetic Engineering and Biotechnology
 CCCM	c	Canadian Center for the Culture of Microorganisms
+CCCR	h	Federal University of Tocantins
 CCCryo<DEU>	c	Culture Collection of Cryophilic Algae
 CCCS	c	Culture Collection of Ciliates and their Symbionts
 CCCZ	s	University of Malawi
@@ -846,6 +865,7 @@ CCG<CHN>	s	Chengdu College of Geology
 CCG<GHN>	s	University of Cape Coast, Botany Department
 CCGB	c	Cole(e7)o de Culturas do G(ea)ero Bacillus e G(ea)eros Correlatos
 CCGVCC	c	China Centre for General Viruses Culture Collection
+CCH	h	University of Arizona South, Agricultural Extension Service
 CCIAL	c	Cultures Cells for Institute Adolfo Lutz
 CCIBSO	c	Culture Collection IBSO
 CCIM	c	Culture Collection of Industrial Microorganisms
@@ -857,6 +877,7 @@ CCMAC	c	Culture Collection of Macromycetes (Basidiomycotina and Ascomycotina)
 CCMCU	c	Culture Collection of Microorganisms
 CCMF	c	University of Portsmouth
 CCMGE	s	Chernyshev Central Museum of Geological Explorations,Collections of the Department of Herpetology, Zoological Institute of the Russian Academy of Sciences
+CCMH	h	Concordia College
 CCMI	c	Culture Collection of Industrial Microorganisms
 CCML	s	Coleccion Ictiologica del Departamento de Ciencias Marinas de la Universidad de la Laguna
 CCMM	c	Moroccan Coordinated Collections of Microorganisms
@@ -879,6 +900,8 @@ CCT	c	Colecao de Culturas Tropical
 CCTCC	c	China Center for Type Culture Collection
 CCTM	c	Centre de Collection de Type Microbien, Institut de Microbiologie, Universite de Lausanne
 CCTR	c	Culture Collection Trutnov
+CCTS	h	Universidade Federal de Sao Carlos
+CCTU	c	Culture Collection of Tabriz University
 CCUF	s	Universidade Federal de Alagoas, Centro de Ciencias Biologicas
 CCUG	c	Culture Collection, University of Goteborg, Department of Clinical Bacteriology
 CCVC	s	Centenary College, Vertebrate Collection
@@ -931,8 +954,11 @@ CET	s	Centro de Estudios Tropicales
 CETESB	c	Setor de Pesquisa Tecnologica de Sistemas de Tratamento de Efluentes Domesticos
 CEU	s	Collage of Eastern Utah
 CFB	s	Northern Forestry Centre, Canadian Forest Service
+CFBH	s	Celio F.B. Haddad Herpetological Collection, Departamento de  Zoologia, Universidade Estadual Paulista
 CFBP	c	Collection Francaise des Bacteries Phytopathogenes
+CFCC	cb	China Forestry Culture Collection Center
 CFI	s	Genetic Resources and Biotechnology (CENARGEN), EMBRAPA
+CFIA	h	Canadian Food Inspection Agency
 CFMR	sc	Center for Forest Mycology Research
 CFN	s	Clifton College, Biology Department
 CFNL	s	Universidad Autonoma de Nuevo Leon
@@ -1051,6 +1077,7 @@ CIZ	s	Centro de Investigaciones Zoologicas
 CKE	s	Calke Abbey
 CL	s	Babes-Bolyai University
 CLA	s	Universitatea de Stiinte Agricole si Medicina Veterinara
+CLARK	h	Dr. Charles F. and Wilhelmina Husser Clark Herbarium
 CLCB	s	Laboratorul de Ecologie
 CLCC	s	Augustana University College
 CLD	s	Cleveland Literary and Philosophical Society
@@ -1099,6 +1126,7 @@ CMM<BRA>	c	Culture Collection of Phytopathogenic Fungi  (Colecao de Culturas de
 CMMC	c	China Marine Microbe Collection
 CMMED<USA-HI>	c	Center for Marine Microbial Ecology & Diversity Collection
 CMMEX	s	Universidad Autonoma de Baja California
+CMMF	h	Jardin botanique de Montreal
 CMMI	s	Chinese Academy of Traditional Medicine
 CMML	s	Colorado State University Herbarium
 CMN	s	Canadian Museum of Nature
@@ -1118,9 +1146,14 @@ CMNFI	s	Canadian Museum of Nature, Fish Collection
 CMNH	s	The Cleveland Museum of Natural History
 CMNS	s	Museum of Natural History, Shanghai
 CMNZ	s	Canterbury Museum
+CMPH	h	Colegio de Postgraduados
+CMPR	h	Centre for Medicinal Plants Research
+CMS	h	Christian Missionary Society College
 CMSK	s	City Museum, Sheffield
 CMSU	s	Central Missouri State University
 CMU	s	Chiang Mai University
+CMUB	h	Chiang Mai University
+CMUH	h	Central Mindanao University
 CMUT	s	Chiang Mai University
 CMV	s	Centre Marie-Victorin
 CMW	c	Forestry and Agricultural Biotechnology Institute, University of Pretoria, Pretoria
@@ -1142,6 +1175,7 @@ CNCTC	c	Czech National Collection of Type Cultures
 CNE	s	Victoria Jubilee Museum
 CNEN-LABPC	c	Laboratorio de Pocos de Caldas
 CNF	s	Croatian Mycological Society
+CNH	h	Canakkale Onsekiz Mart University
 CNHM<CRO>	s	Croatian Natural History Museum, Botany Department
 CNHM<USA-OH>	s	Cincinnati Museum of Natural History
 CNHP	s	Beijing Natural History Museum
@@ -1151,15 +1185,20 @@ CNM-CM	c	Filamentous fungus collection of the Spanish National Center for Microb
 CNM<ESP>	s	Centro Nacional de Microbiologia
 CNMC	s	Colorado National Monument
 CNMS	s	Colombo National Museum
+CNMT	h	Universidade Federal de Mato Grosso
+CNPO	h	Embrapa Pecuaria Sul
 CNPS	s	Centro Nacional de Pesquisas da Soja
 CNPSo	c	Culture Collection of Diazotrophic and Plant Growth Promoting Bacteria of Embrapa Soja
+CNR	h	Crimean Natural Reserve
 CNRO	s	Centre National de Recherches Oceanographiques
 CNRS	s	Centre National de la Recherche Scientifique
 CNRZ	c	Centre National de Recherches Zootechniques
 CNS<AUS>	s	Australian Tropical Herbarium
+CNSF	h	Centre National de Semences Forestieres
 CNU<CHN>	s	Capital Normal University, College of Life Sciences
 CNU<KOR-TJ>	s	Chungnam National University
 CNU<KOR>	s	Chonbuk National University
+CNUK	h	Chungnam National University
 CNWGRGL	b	Chinese National Waterfowl Germplasm Resources Gene Library
 CO	s	Museum National d'Histoire Naturelle, Department of Marine Biology
 COA	s	Herbario, Universidad de Cordoba - Jardin Botanico de Cordoba
@@ -1167,6 +1206,7 @@ COA<USA-ME>	s	College of the Atlantic, Museum
 COAD	c	Colecao Octavio de Almeida Drumond
 COAH	s	Herbario Amazonico Colombiano (Instituto Amazonico de Investigaciones Cientificas SINCHI)
 COCA	s	Comision Tecnico Consultiva de Coeficientes de Agostadero (COTECOCA)
+COCAZ	h	Coconino National Forest Herbarium
 COCH	s	Universidad Mayor de San Simon, Departamento de Botanica
 COCO	s	Colorado College, Biology Department
 CODAGEM	s	Universidad Autonoma del Estado de Mexico
@@ -1287,13 +1327,18 @@ CSTIU	s	Faculty of Science, University of Tokyo
 CSU<USA-CO>	s	Colorado State University
 CSU<USA-OK>	s	University of Central Oklahoma, Biology Department
 CSUC	s	California State University, Chico, Vertebrate Museum
+CSUCI	h	California State University Channel Islands
 CSUF	s	California State University, Fresno
+CSUH	h	Chelyabinsk State University
 CSULB	s	California State University, Long Beach
 CSUN	s	California State University, Northridge
+CSUNIV	h	Charleston Southern University
 CSUR	c	Collection de Souches de l'Unite des Rickettsies
+CSUSB	h	California State University, San Bernardino
 CSUTC	s	Colorado State University, Mammalogy Teaching Collection
 CSVFC	s	Caradoc and Severn Valley Field Club
 CT	s	University of Cape Town, Botany Department
+CTC	h	Chongqing Normal University
 CTES	s	Instituto de Botanica del Nordeste
 CTESN	s	Universidad Nacional del Nordeste
 CTM<TUN>	c	Centre de Biotechnologie de Sfax culture collection
@@ -1328,6 +1373,7 @@ CUNRC	s	Universidad Nacional de Rio Cuarto, Coleccion de Mamiferos (Argentina)
 CUP	s	Cornell University, Plant Pathology Herbarium
 CUP<CHN>	s	Catholic University of Peking
 CUP<CZE>	s	Charles University
+CURLA	h	Centro Universitario Regional del Litoral Atlantico
 CUS	s	Cusino Wildlife Research Station, Natural Resources Department
 CUSC	s	Clemson University, Vertebrate Collections
 CUVC<COL>	s	Universidad del Valle, Departamento de Biologia
@@ -1352,6 +1398,7 @@ CYN	s	Chipstead Valley Primary School
 CYP	s	Ministry of Agriculture, Natural Resources and Environment, Forestry Department
 CZAA	s	Catedra de Zoologia Agricola
 CZACC	s	Coleccion Zoologia, Academia de Ciencias de Cuba
+CZH	h	Hanshan Normal University
 CZIP	s	Universidad de Magallanes, Instituto de la Patagonia (Chile)
 CZL	s	Centro de Zoologia
 CZRMA	s	Coleccion Zoologica Regional (Mammalia) del Instituto de Historia Natural y Ecologia
@@ -1363,6 +1410,7 @@ DACB	s	Bangladesh National Herbarium
 DACL	s	London Research Centre
 DACT	c	Dept. Agricult. Chem. Technol.
 DAFH	s	Department of Agriculture and Fisheries
+DAG	h	Mountain Botanical Garden of the  Dagestan Scientific Centre
 DAKAR	s	Universite Cheikh Anta Diop, Departement de Biologie Vegetale
 DAL	s	Dalhousie University, Biology Department
 DANV	s	Umweltamt Darmstadt
@@ -1372,9 +1420,11 @@ DAR	c	Plant Pathology Herbarium
 DARI	s	Insect Collection, New South Wales Department of Agriculture
 DAS	s	Agriculture and Agri-Food Canada
 DASF	s	Department of Agriculture, Stock and Fisheries
+DAU	h	University of Daugavpils
 DAV	s	University of California, Plant Biology
 DAVFP	s	Pacific Forestry Centre, Canadian Forest Service
 DAVH	s	University of California, Environmental Horticulture Department
+DAWES	h	The Dawes Arboretum
 DBAI	s	Instituto de Ciencias Biologicas
 DBAU	s	Universidade Santa Ursula
 DBC	s	University College, Botany Department
@@ -1409,6 +1459,7 @@ DCPC	s	DominicusCirillus[deceased]
 DCR	s	Doncaster Museum and Art Gallery
 DD	s	Forest Research Institute, Indian Council of Forestry Research and Education, Systematic Botany Discipline
 DDFF	s	Departamento de Defensa Fitossanitarista
+DDMS	h	Fundacao Universidade Federal da Grande Dourados
 DE	s	Debrecen University, Botany Department
 DE-CSIRO	c	CSIRO Insect Pathogen Culture Collection
 DEBU	s	Ontario Insect Collection, University of Guelph
@@ -1417,7 +1468,7 @@ DECV	s	Douglas Ecological Consultants
 DEE	s	McManus Galleries, Natural History Department
 DEES	s	Universidade de Sao Paulo, Piracicaba
 DEFS	s	Universidade de Sao Paulo
-DEI	s	Deutsches Entomologisches Institut im ZALF
+DEI	s	Senckenberg Deutsches Entomologisches Institut
 DEIB	s	Deutsches Entomologisches Institut
 DEK	s	Northern Illinois University, Biological Sciences Department
 DELS	s	University of Delaware, Plant Science Department
@@ -1428,6 +1479,7 @@ DENF	s	Grand Mesa-Uncompahgre-Gunnison Natonal Forests
 DENH	s	University of New Hampshire
 DERM	s	Intermountain Experiment Station
 DES	sb	Desert Botanical Garden, Research Department
+DEV	h	St. Joseph's College
 DEVA	s	Death Valley National Park
 DEWV	s	Davis and Elkins College, Biology and Environmental Science Department
 DEZA	s	Dipartimento di Entomologia e Zoologia Agraria dell'Universita
@@ -1452,6 +1504,7 @@ DGR:Fish	s	Division of Genomic Resources, University of New Mexico, fish tissue
 DGR:Herp	s	Division of Genomic Resources, University of New Mexico, herpetology tissue collection
 DGR:Mamm	s	Division of Genomic Resources, University of New Mexico, mammal tissue collection
 DGS	s	The Manx Museum
+DGU	h	Daegu University
 DGUB	c	Department of Genetics, University of Bratislava
 DH	s	Hobart and William Smith Colleges, Biology Department
 DHISUB	s	Department of Hydrobiology and Ichthyology, Sofia Univiversity
@@ -1461,6 +1514,7 @@ DHMB	s	Department of Harbours and Marine
 DHNS	s	Dunbartonshire Natural History Society
 DI	s	Universite de Bourgogne, Laboratoire de Phytobiologie Cellulaire
 DIA	s	Museu do Dundo
+DIAM	h	Universidade Federal dos Vales do Jequitinhonha e Mucuri
 DIN	s	Museum National d'Histoire Naturelle
 DINH	s	Delta Institute of Natural History
 DINO	s	Dinosaur National Monument
@@ -1471,6 +1525,7 @@ DiSTA<ITA>	s	Phytoplasma Collection University of Bologn
 DIX	s	Dixie College, Natural History Museum
 DKG	s	Juniper Hall Field Centre
 DLF	s	Stetson University, Biology Department
+DLU	h	Da Lat University
 DLY	s	Dudley and Midland Geological and Scientific Society and Field Club
 DM<NZ>	s	Dominion Museum
 DM<USA-UT>	s	The Dinosaur Museum
@@ -1482,6 +1537,7 @@ DMCMU2	c	Department of Microbiology, Faculty of Medicine
 DMCU	c	Microbiology Department, Faculty of Science
 DMDC	s	Douala Museum
 DMFS	s	Crichton Royal Institution Museum
+DMHN	h	The University of Newcastle
 DMIV	c	Department of Microbiology and Immunology
 DMKKU1	c	Department of Microbiology, Faculty of Medicine
 DMKKU2	c	Department of Microbiology, Faculty of Medical Science
@@ -1507,11 +1563,13 @@ DMUP	c	Microbiology and Biophysics Charles University
 DMUR	c	Department of Mycology
 DMVB	c	Department of Microbiology, Veterinary Branch of National Strain Collection
 DNA	s	Department of Natural Resources, Environment and the Arts
+DNAP	h	Department of Primary Industry and Fisheries
 DNATAX	b	DNA-TAX
 DNHM<CHN>	s	Dalian Museum of Natural History
 DNHM<USA-UT>	s	Dinosaur Natural History Museum
 DNPM	s	Setor de Paleontologia do Departamento Nacional de Producao Mineral
 DNS	s	Dundee Naturalists' Society
+DNZ	h	Donetsk Botanical Garden of the National Academy of Sciences of Ukraine
 DO	s	Societe d'Agriculture Sciences et Arts
 DOA	c	Department Of Agriculture, Thailand
 DOMO	s	Collegio Mellerio Rosmini
@@ -1541,10 +1599,12 @@ DSEC	s	Universidade Federal da Paraiba
 DSIR	s	Department of Scientific and Industrial Research
 DSM	c	Deutsche Sammlung von Mikroorganismen und Zellkulturen GmbH
 DSM<TZA>	s	University of Dar es Salaam, Botany Department
+DSMZ	c	Deutsche Sammlung von Mikroorganismen und Zellkulture
 DSP	s	Fitzsimon's Snake Park
 DSSC<USA-CA>	b	Drosophila Species Stock Center
 DSU	s	Dnipropetrovsk National University, Department of Geobotany, Soil, and Ecology
 DSY	s	Dewsbury Museum
+DTE	h	Centro de Investigaciones Cientificas y Transferencia de Tecnologia a la Produccion (CICyTTP-CONICET)
 DTIC	s	Departamento Parasitologia
 DTN	s	Darlington and Teesdale Naturalists' Field Club
 DU	s	Duke University Vertebrate Collection
@@ -1552,12 +1612,15 @@ DUB	s	National Botanic Gardens
 DUBN	s	Dublin Naturalists' Field Club
 DUE	s	University of Dundee
 DUF	s	University of Dicle, Biological Department, Botany
+DUGAND	h	Universidad del Atlantico
 DUH	s	University of Delhi, Botany Department
 DUIS	s	Universitaet Duisburg, Fachbereich 6, Botanik
 DUKE	s	Duke University, Biology Department
 DUL	s	University of Minnesota, Biology Department
 DUM<IND>	c	Delhi University Mycological Herbarium
 DUM<TUR>	s	Zooligical Museum of Science and Art Faculty
+DUOF	h	Duzce University
+DUP	h	Dumlupinar University
 DUR	s	Southeastern Oklahoma State University, Biological Sciences Department
 DUSS	s	Universitaet Duesseldorf
 DVBID	c	Division Vector-Borne Infectious Diseases
@@ -1569,6 +1632,7 @@ DVR	s	Dover Corporation Museum
 DVZUT	s	Department of Vertebrate Zoology
 DWC	s	West Chester University, Biology Department
 DWN	s	Darwen Library
+DWP	h	Disney Wilderness Preserve/The Nature Conservancy
 DWT	c	Wood Technology and Forest Research Division
 DWU	s	Dakota Wesleyan University, Biology Department
 DZCU	s	Calcutta University
@@ -1588,6 +1652,8 @@ E	sb	Royal Botanic Garden Edinburgh
 EA	s	National Museums of Kenya
 EAA	s	Estonian Agricultural University
 EAC	s	Universidade Federal do Ceara, Departamento de Biologia
+EAFM	h	Instituto Federal de Educacao, Ciencia e Tecnologia do Amazonas
+EALA	h	Jardin Botanique d'Eala
 EAN	s	Universidade Federal da Paraiba, Campus III - CCA, Departamento de Fitotecnia
 EAP	s	Escuela Agricola Panamericana
 EAPZ	s	Escuela Agricola Panamericana
@@ -1600,6 +1666,7 @@ EBDS	s	Estacion Biologica de Donana
 EBE	s	Eastbourne Museum
 EBF	s	Hubei Forestry Institute
 EBH	s	Botanical Society of Edinburgh
+EBL	h	Ecosystem Research and Development Bureau
 EBMC	s	Universidad de Chile
 EBMTV	s	Estacion de Biologia Marina del Instituto Tecnologico de Veracruz
 EBNHS	s	Edinburgh Natural History Society
@@ -1610,6 +1677,7 @@ EBV	s	Laboratoire de Biologie Generale et de Botanique
 ECACC	c	European Collection of Authenticated Cell Cultures
 ECENT	s	East Central University
 ECH	s	Elmira College
+ECK	h	Buffalo State College
 ECM	s	Hubei College of Traditional Chinese Medicine, Department of Chinese Materia Medica
 ECNB	s	Escuela Nacional Ciencias
 ECO-SC-M	s	Coleccion Mastozoologica de El Colegio de la Frontera Sur Unidad San Cristobal de las Casas, Chiapas
@@ -1621,9 +1689,14 @@ ECOSCM	s	Coleccion Mastozoologica de El Colegio de la Frontera Sur, Unidad San
 ECOSUR	s	El Colegio de la Frontera Sur (Mexico)
 ECSC	s	East Central University, Biology Department
 ECSFI	s	East China Sea Fisheries Institute
+ECU	h	Edith Cowan University
+ECUAMZ	h	Universidad Estatal Amazonica
+ECUH	h	East Carolina University
+ECWP	h	Emirates Centre for Wildlife Propagation
 EDC	s	Hubei Institute for Drug Control
 EDH	s	Plinian Society
 EDNC	s	Raleigh, North Carolina Department of Agriculture
+EDTU	h	Trakya Universitesi
 EEBP	s	Estacao Experimental de Biologia e Piscicultura de Pirassununga
 EELM	s	Estacion Experimental Agricola de la Molina
 EERU	s	Economic Entomology  Research Unit
@@ -1651,6 +1724,7 @@ EJ	s	?Ein Yabrud collection catalogue entries at The Hebrew University
 EKU	s	Eastern Kentucky University
 EKY	s	Eastern Kentucky University, Biological Sciences Department
 ELCAK	s	Entomological Laboratory, College of Agriculture
+ELH	h	Bureau of Land Management, Eagle Lake Field Office
 ELM	s	East London Museum
 ELMF	s	Augusta, Maine Forest Service
 ELN	s	Elgin Museum
@@ -1667,6 +1741,7 @@ EMCC	c	Egypt Microbial Culture Collection
 EMEC	s	Essig Museum of Entomology
 EMET	s	Faculty of Agriculture, Entomology Museum
 EMMA	s	Universidad Politecnica de Madrid, Unidad Docente Botanica, Departamento Silvopascicultura
+EMNH	h	The Everhart Museum of Natural History, Science & Art
 EMPARN	c	Empresa de Pesquisa Agropecuaria do Rio Grande do Norte
 EMU	s	Eastern Michigan University, T. L. Hankinson Vertebrate Museum
 EMUS	s	Utah State University
@@ -1676,6 +1751,7 @@ ENCB<MEX-Ensenada>	s	Universidad de Autonoma de Baja California
 ENCB<MEX-Mexico City>	s	Instituto Politecnico Nacional
 ENG	s	Royal Holloway College, University of London, Botany Department
 ENIH	s	National Institute of Health
+ENLC	h	Eastern Nevada Landscape Coalition
 ENMU	s	Eastern New Mexico University, Natural History Museum
 ENMUNHM	s	Eastern New Mexico University, Natural History Museum
 ENP	s	Everglades National Park
@@ -1692,10 +1768,12 @@ EPHR	s	Snow College, Biology Department
 EPM	s	Epsom College Museum
 EPN	s	Escuela Polytecnica Nacional
 EPRL	s	University of Puerto Rico
+EPU	h	Centre de Formation et de Recherche en Conservation Forestiere
 ER	s	Universitaet Erlangen-Nuernberg, Geobotanik
 ERA	s	Universidad Nacional de Entre Rios, Botanica Sistematica
 ERAEP	c	Radiation Ecology Section, Biological Science Division, Office of Atomic Energy for Peace
 ERCB	s	Yerevan State University, Botany Department
+ERCH	h	Erciyes University
 ERCULE	c	European Rumen Ciliate Culture Collection, Rowett Research Institute
 ERE	s	Institute of Botany of the National Academy of Sciences of Armenia, Department of Plant Taxonomy and Geography
 EREM	s	Institute of Botany of the National Academy of Sciences of Armenia, Mycology Department
@@ -1721,7 +1799,10 @@ ETE	s	El Colegio de la Frontera Sur, Coleccion de insectos Asociados a Plantas C
 ETH<CHE>	c	Kultursammlungen der Eidgenosische Technische Hochschule
 ETH<ETH>	s	Addis Ababa University, Biology Department
 ETHZ	s	Eidgenoessische Technische Hochschule-Zentrum
+ETL	h	Lake Forest College
 ETN	s	Eton College Museum
+ETNH	h	Jarvis Christian College
+ETON	h	Eton College Museum
 ETST	s	Texas A&M University, Biology Department
 ETSU	s	East Tennessee State University, Biological Sciences Department
 EU	s	Hubei University, Biology Department
@@ -1731,13 +1812,16 @@ EUQ	s	Department of Entomology, Queensland University
 EUSL	c	Eastern University
 EVA	c	European Virus Archive
 EVCV	s	Erster Vorarlberger Coleopterische Verein
+EVE	h	The Evergreen State College
 EVMU	s	Everhart Museum, Natural History Department
 EWH	s	Ewha Womans University
+EWM	h	Elizabeth Winston Mize Herbarium
 EWNHM	s	Ewha Womens University, Natural History Museum
 EX	c	The Culture Collection of Extremophilic Fungi
 EXN	s	Exton Hall
 EXR	s	University of Exeter, Biological Sciences Department
 F	s	Field Museum of Natural History, Botany Department
+FAA	h	Universidad Nacional del Centro de la Provincia de Buenos Aires
 FABR	s	Harmas de J. H. Fabre
 FACHB	c	Freshwater Algae Culture Collection
 FACS	s	Fujian Agricultural College
@@ -1785,10 +1869,12 @@ FDLW	s	University of Wisconsin Center, Biology Department
 FDNR	s	Florida Department of Natural Resources
 FDUC	s	Fairleigh Dickinson University [collection transferred to FSCA].
 FDVC	s	De La Villa, Francisco
+FEN	h	Lycee Felix Esclangon, Region PACA
 FER	s	Universita de Ferrara, Dipartimento di Biologia - Sezione di Botanica
 FERM	c	Patent and Bio-Resource Center, National Institute of Advanced Industrial Science and Technology (AIST)
 FEZA	s	Universidad Nacional Autonoma de Mexico, Carrera de Biologia
 FFB	s	Atlantic Forestry Centre, Canadian Forest Service
+FFBNM	h	Florissant Fossil Beds National Monument
 FFCL	s	Nossa Senhora do Patrocinia
 FFR	s	Forfar Museum and Art Gallery, Meffan Institute
 FFS	s	University of Stellenbosch
@@ -1851,6 +1937,7 @@ FMPC	s	Fairbanks Museum and Planetarium Collection
 FMR	c	Facultad de Medicina
 FMRI	s	Central Marine Fisheries Marine Research Institute
 FMSS	s	Parque Zoological Nacional "Finca Modelo", Natural History Museum
+FMUH	h	Francis Marion University
 FNCC	c	Food and Nutrition Culture Collection
 FNFR	s	Fishlake National Forest
 FNLO	s	Fremont National Forest
@@ -1860,6 +1947,7 @@ FNP	s	Fundy National Park
 FNPS	s	South Florida Collections Management Center, Everglades National Park
 FNU<CHN>	s	Fujian Normal University
 FNU<JPN>	s	Nagasaki University - Fisheries
+FOF	h	National University of Laos
 FOR	s	Forssa Museum of Natural History
 FOSJ	s	Fisheries and Oceans Biological Station
 FPDB	s	Universidad de Puerto Rico, Departamento de Ciencias Marinas
@@ -1909,6 +1997,7 @@ FTCC	c	Food Technology Culture Collection
 FTCMU	c	Department of Food Science and Technology, Faculty of Agriculture
 FTG	sb	Fairchild Tropical Botanic Garden
 FTI	c	Centro de Biotecnologia e Quimica-CEBIQ
+FTOH	h	Forestry Training Institute, Olmotonyi
 FTS	s	Fuzhou Teachers College, Biology Department
 FTU	s	University of Central Florida, Biology Department
 FU<CHN>	s	Fudan University, Department of Biology
@@ -1918,9 +2007,11 @@ FUE	s	Fukuoka University of Education
 FUEL	s	Universidade Estadual de Londrina, Departamento de Biologia Animal e Vegetal
 FUGR	s	Furman University, Biology Department
 FUH	s	Firat Ueniversitesi
+FUK	h	Fukui Botanical Garden
 FULD	s	Verein fuer Naturkunde in Osthessen
 FUMH	s	Ferdowsi University
 FUMT	s	University of Tokyo
+FURB	h	Universidade Regional de Blumenau
 FUS	s	Fudan University, Biology Department
 FUSC	c	Flinders University Smut Collection
 FVCC	s	Flathead Valley Community College, Biology Department
@@ -1938,12 +2029,14 @@ GAB	s	National Museum, Monuments, and Art Gallery
 GABAS	s	Centre d'Etude et de Conservation des Resources Vegetales
 GAC	s	Guangxi Agricultural University, Forestry Department
 GACP	s	Guizhou Agricultural College, Department of Plant Protection
+GADI	h	Grootfontein Agricultural Development Institute
 GAES	s	Georgia Agricultural Experiment Station
 GAFS	s	Ganzhou Forestry School
 GAI	s	Folk Museum
 GALW	s	National University of Ireland, Galway, Botany Department
 GAM<USA-GA>	s	University of Georgia
 GAM<VEN>	c	Grupo Actinomicetales Merida Facultad de Medicina
+GAP	h	Conservatoire Botanique National Alpin
 GAS	s	Georgia Southern University, Department of Biology
 GAT	s	Institute of Plant Genetics and Crop Plant Research
 GAUA	s	Guangxi University
@@ -1954,6 +2047,7 @@ GAZI	s	Gazi Ueniversitesi, Biyoloji Boeluemue
 GB	s	Goeteborg University, Department of Plant and Environmental Sciences
 GBFM	s	Universidad de Panama
 GBG<SWE>	b	Goteburg Botanical Garden
+GBH	h	Herbarium of Geo. B. Hinton
 GBNM	s	Glacier Bay National Park and Preserve Museum
 GBY	s	Grimsby Arts and Natural History
 GC<GHN>	s	University of Ghana, Botany Department
@@ -1964,8 +2058,10 @@ GCM<PAK>	s	Government College, Department of Zoology
 GCNP	s	Grand Canyon National Park
 GCRL	s	Gulf Coast Research Laboratory
 GCTP	s	Global Colosseum
+GCU	h	Gachon University
 GDA	s	Universidad de Granada
 GDAC	s	Universidad de Granada, Departamento de Biologia Vegetal, Botanica
+GDB	h	Herbarium de Gerard de Belair
 GDGM	s	Guangdong Institute of Microbiology
 GDMA	s	Medical University of Gdansk, Department of Biology and Pharmaceutical Botany
 GDMCC	c	Guangdong Microbial Culture Collection Center
@@ -1986,6 +2082,7 @@ GFJP	s	Universidade do Estado de Minas Gerais
 GFND	s	University of North Dakota, Biology Department
 GFRC	s	Golestan Fisheries Research Centre
 GFS	s	Guizhou Forestry School
+GFT	h	Grumeti Fund Tanzania
 GFW	s	Ernst-Moritz-Arndt-Universitaet, Botanisches Institut und Botanischer Garten
 GGB	s	Gesneriad Gardens
 GGM	s	Gosudarstvennyi Geologicheskii Musei - State Geological Museum
@@ -2000,10 +2097,12 @@ GHS	s	George Heriot's School, Biology Department
 GI	s	Justus-Liebig-Universitat Giessen
 GI-SPS	s	Geological Institute, Section of Palaeontology and Stratigraphy
 GIFU<JPN>	s	Herbarium of Gifu Pharmaceutical University
+GINCO	h	Agriculture and Agri-Food Canada
 GIUV	s	Geological Institute, University of Vienna
 GJO	s	Steiermaerkisches Landesmuseum Joanneum, Botany Department
 GKAR	s	Karoo National Botanical Garden
 GL	s	University of Glasgow, Botany Department
+GLA	h	George Landis Arboretum
 GLAC	s	Glacier National Park, Glacier Collection
 GLAHM	s	University of Glasgow, Hunterian Museum
 GLAM	s	Art Gallery and Museum, Natural History Department
@@ -2025,6 +2124,7 @@ GMAU	s	Geological Museum of Amsterdam University
 GMBL	s	College of Charleston
 GMC	s	Guangxi Medical College
 GMCE	s	Grosvenor Museum
+GMDRC	h	Granite Mountains Desert Research Center
 GMH	s	Sammlung Jacobi des Geiseltalmuseum Halle
 GMHH	s	Geological Museum of Heilongjang Province
 GML<USA-IL>	s	Gorgas Memorial Laboratory
@@ -2033,6 +2133,7 @@ GMNGZ	s	Glasgow Museum and Art Galleries
 GMNH-PV	s	Paleo-Vertebrate Collection
 GMNH<SWTZ>	s	Museum d'Histoire Naturelle
 GMNH<USA-GA>	s	Georgia Museum of Natural History
+GMNHJ	h	Gunma Museum of Natural History
 GMNP	s	Gros Morne National Park
 GMS	s	Hopkins Marine Station, Stanford University, Biological Sciences Department
 GMU	s	N. P. Ogariov Mordovia State University, Department of Botany and Plant Physiology
@@ -2041,6 +2142,7 @@ GMUG	s	Universitat Gottingen, Geologisches-Palaatologisches Museum
 GMUM	s	Institut fuer Palaeontologie und Geologisches Museum der Universitat
 GMUV	s	Geological Museum, University of Vienna
 GNA	s	Gannan Arboretum of Jiangxi
+GNDUH	h	Guru Nanak Dev University
 GNE	c	Genentech
 GNHM	s	Goulandris Natural History Museum
 GNHNA	s	Gallery of Natural History and Native Art
@@ -2056,6 +2158,7 @@ GOE<DEU>	s	Institut und Museum fuer Geologie und Palaeontologie
 GOE<GBR>	s	Goole Scientific Society
 GOET	s	Herbarium Universitat Gottingen
 GOFS	s	Free State National Botanical Garden
+GOPU	h	Gaziosmanpasa University
 GOW	s	Clydebank High School
 GP	s	Instituto de Geociencias, Universidade de Sao Paulo
 GPA	s	Grande Prairie Regional College, Science Department
@@ -2085,6 +2188,7 @@ GRS	s	Gezira Research Station
 GRSM	s	Great Smoky Mountains National Park
 GRSU	s	Yanka Kupala Grodno State University, Department of Botany
 GRSW	s	Desert Ecological Research Unit
+GRTE	h	Grand Teton National Park
 GSAT	s	The Geological Survey of Alabama
 GSC	s	Geological Survey of Canada
 GSDNM	s	Great Sand Dunes National Monument
@@ -2103,14 +2207,18 @@ GTM	s	Grantham Museum
 GTNP	s	Grand Teton National Park
 GTV	s	Gregorio T. Velasquez Phycological Herbarium
 GU	s	Gotland University, Department of Biology
+GU-IITG	s	for Gauhati University- Indian Institute of Technology Guwahati
 GUA	s	DIVEA, DEP, FEEMA, FEEMA
 GUAD	s	Institut National de la Recherche Agronomique and Parc National de Guadeloupe
 GUADA	s	Universidad Autonoma de Guadalajara
 GUAM	s	University of Guam, Biology Department
 GUAT	s	Herbario Ulises Roja
 GUAY	s	Universidad de Guayaquil
+GUBH	h	Gauhati University
 GUBIOTJT	c	Freshwater microalgae collection and culture laboratory
+GUCM	h	Guangzhou University of Chinese Medicine
 GUH	s	HNB Garhwal University, Botany Department
+GUL	h	Suleyman Demirel University
 GUM	s	Glasgow University Museum (Hunter Museum)
 GUM<IRN>	s	Mycological herbarium of University of Guilan
 GUMACC	c	Gotheburg University Marine Algal Culture Collection
@@ -2142,25 +2250,32 @@ HAC	s	Instituto de Ecologia y Sistematica
 HACC	s	Academia de Ciencias Camagueey
 HACW	s	Department of Fishery, Huazhong Agriculture Collection
 HAF	s	Hainan Forestry Institute
+HAH	h	Hoyt Arboretum
+HAI	h	University of Haifa
 HAJB	s	Jardin Botanico Nacional
+HAJU	h	Herbario Dr. Armando Jesus Urquiola
 HAK	s	Hokkaido University, Faculty of Fisheries
 HAKS	s	Hakgala Botanic Gardens
 HAL	s	Martin-Luther-Universitaet
 HALA	s	University of Alabama, Biological Sciences Department
+HALE	h	Haleakala National Park
 HALLE	s	Zoologisches Institut der Martin-Luther Universitaet
 HALLST	s	Botanische Station
+HALN	h	State Agency for Environmental Protection Saxony-Anhalt
 HALX	s	Halifax Literary and Philosophical Society
 HAM	s	Royal Botanical Gardens
 HAMAB	s	Instituto de Pesquisas Cientificas e Tecnologicas do Estado do Amapa
 HAMBI	c	HAMBI Culture Collection
 HAMU	s	University of Newcastle upon Tyne
 HAN	s	Universitaet Hannover
+HANC	h	National Aquarium of Cuba
 HANU	s	Harbin Normal University, Biology Department
 HAO	s	Universidad Privada Antenor Orrego
 HAQ	s	Institut der Technische Hochschule (RWTH), Institut fuer Biologie I
 HAS	s	Fundacao Zoobotanica do Rio Grande do Sul
 HAST	s	Research Center for Biodiversity, Academia Sinica
 HASU	s	Universidade do Vale do Rio dos Sinos - CCS/ Centro 2
+HAU	h	Alzahra University
 HAUH	s	Haryana Agricultural University
 HAVI	s	Eastern Mennonite University, Biology Department
 HAVO	s	Hawaii Volcanoes National Park
@@ -2168,6 +2283,8 @@ HAW	s	University of Hawaii, Botany Department
 HAX	s	Belle Vue Museum
 HAY	s	California State University, Biological Sciences Department
 HB	s	Herbarium Bradeanum
+HBA	h	National Botanic Garden of Latvia
+HBARC	h	Bhabha Atomic Research Centre
 HBAU	s	Hebei Agricultural University
 HBAUD	s	Hebei Agricultural University, Handan Branch, Agriculture Department
 HBBS	s	Museo Civico di Scienze Naturali
@@ -2182,13 +2299,17 @@ HBIL	s	Institut d'Estudis Ilerdencs
 HBNU	s	Hebei Normal University, Biology Department
 HBOM	s	Harbor Branch Oceanographic Museum
 HBR	s	Universidade Federal de Santa Catarina
+HBRA	h	Universidade Federal do Para, Campus Braganca
 HBUM	s	College of Life Sciences Hebei Univesity, Baoding
 HC	s	Hangchow Christian College
 HCAT	s	University of Tabriz, Landscape Department
 HCB	s	Universidade de Santa Cruz do Sul, Departamento de Biologia
 HCCA	s	Hastings College
+HCCN	h	National Institute of Agricultural Science and Technology
 HCCV	s	Hastings College, Collection of Vertebrates
+HCDAL	h	Universidade Regional do Cariri
 HCEN	s	Universidad Nacional del Centro del Peru
+HCF	h	Universidade Tecnologica Federal do Parana
 HCH	s	Lewis-Clark State College, Natural Sciences Department
 HCHM	s	Hope College, Biology Department
 HCIB	s	Centro de Investigaciones Biologicas del Noroeste, S. C.
@@ -2197,9 +2318,12 @@ HCMS	s	Hampshire County Council Museums Service
 HCMZ	s	Hope College
 HCNHSC	s	Ohio Historical Society, Natural History Synoptic Collection
 HCOA	s	College of the Atlantic, Herbarium
+HCOM	h	Centre d'Oceanologie de Marseille - University of Aix-Marseille II
 HCT	s	Taiwan Forestry Research Institute
 HCTR	s	Hoogstraal Center for Tick Research
+HDCF	h	Department of Forestry Science
 HDD	s	Tolson Museum, Natural History Department
+HDJF	h	Universidade Federal dos Vales do Jequitinhonha e Mucuri
 HDOA	s	Hawaii Department of Agriculture
 HDSM	s	University of Massachusetts Dartmouth
 HDTC	s	Huddersfield Technical College
@@ -2211,6 +2335,7 @@ HEFG	s	l'Ecole de Faune de Garoua
 HEH	s	Escuela Nacional de Ciencias Forestales, Departamento de Investigacion Forestal Aplicada
 HEID	s	Universitaet Heidelberg, Heidelberger Institut fuer Pflanzenwissenschaften
 HEL	s	University of Helsinki, Section of Botany
+HEM	h	Universidad de Ciencias y Artes de Chiapas
 HEMS	s	Haslemere Educational Museum
 HENA	s	Escuela Nacional de Agricultura
 HEND	s	Henderson State University, Biology Department
@@ -2219,16 +2344,22 @@ HENU	s	Henan Normal University, Biology Department
 HEPH	s	Jardim Botanico de Brasilia
 HER<CAN>	c	Felix d'Herelle Reference Center for Bacterial Viruses
 HER<ZAF>	s	Hermanus Botanical Society
+HERBAM	h	Universidade do Estado de Mato Grosso
+HERT	h	Fundacao Universidade Estadual do Ceara
 HERZ	s	Herzen State Pedagogical University of Russia, Department of Botany
 HERZU	s	Universidad del Zulia
+HEUS	h	Universidad de Sucre
 HF	s	Universidade Federal do Para
 HFB	s	Hainan Forestry Bureau
 HFBG	s	Forestry Botanical Garden of Heilongjiang
 HFCC	c	Flagellate Culture Collection, University of Cologne
 HFD	s	Hereford Museum
+HFLA	h	Sapienza University of Rome - Scuola di Specializzazione in Beni Naturali e Territoriali
+HFN	h	Herbarium Frisicum
 HFP	c	Hokkaido Forest Products Research Institute
 HFR	s	Finnish Forest Research Institute
 HFRI	s	Hunan Forestry Research Institute
+HFSL	h	Centro de Ensino, Faculdade Sao Lucas Ltda.
 HFU	s	Herbarium of Fayoum University
 HFV	s	Universidad Austral de Chile, Instituto de Produccion y Sanidad Vegetal
 HFX	s	Bankfield Museum and Art Gallery
@@ -2236,8 +2367,11 @@ HGAS	s	Guizhou Academy of Sciences, Plant Taxonomy Group
 HGCRL	s	Gulf Coast Research Laboratory
 HGI	s	Universitat de Girona, Unitat de Biologia Vegetal
 HGM	s	Hunan Geological Museum
+HGOM	h	Universidad Autonoma del Estado de Hidalgo
 HGS	s	Public Museum and Art Gallery, St. John's Place
 HGTC	s	Huanggang Teachers College, Biology Department
+HGU	h	Khakass State University
+HH	h	Instituto de Investigaciones de la Amazonia Peruana
 HHBG	s	Hangzhou Botanical Garden
 HHC	s	University of Helsinki, Horticulture Department
 HHH	s	Hartwick College
@@ -2246,6 +2380,7 @@ HHU	s	Hallym University
 HHUA	s	Universidad Nacional de Huanuco Hermilio Valdizan
 HHUF	s	Hirosaki University, Laboratory of Plant Pathology
 HIB	s	Wuhan Institute of Botany
+HIBG	h	Hiroshima Botanical Garden
 HIC	s	University of Kentucky, Department of Entomology, Hymenoptera Institute Collection
 HIFP	s	French Institute
 HILL	s	Sir Harold Hillier Gardens
@@ -2255,9 +2390,11 @@ HIP	s	Universidad de Magallanes
 HIPC	s	Instituto Superior Pedagogico Jose Marti, Departamento de Biologia
 HIRO	s	Hiroshima University, Biological Science Department
 HIRU	s	Okayama University of Science
+HISA	h	Universidade Estadual Paulista
 HITBC	s	Xishuangbanna Tropical Botanical Garden, Chinese Academy of Sciences
 HIUW	s	Hygiene-Institut der Universitaet
 HIWNT	s	Hampshire and Isle of Wight Naturalists' Trust Ltd.
+HJBC	h	Jardin Botanico Culiacan
 HJBL	s	Escuela Nacional de Ciencias Forestales
 HJBS	s	Fundacio Jardi Botanic de Soller
 HK	s	Agriculture, Fisheries, and Conservation Department
@@ -2266,32 +2403,41 @@ HKBU	s	Hong Kong Baptist University, Biology Department
 HKFRS	s	Hong Kong Fisheries Research Station
 HKGL	s	Naturwissenschaftliche Sammlungen des Kantons Glarus
 HKI	c	Hans-Knoll Institute
+HKM	h	University of Comoros
+HKS	h	Research Center of Agricultural and Natural Resources Kurdistan Province
 HKU	s	University of Hong Kong, Ecology and Biodiversity Department
 HKUCC	c	The University of Hong Kong Culture Collection
 HL	s	Houghton Lake Wildlife Research Station, Natural Resources Department
 HLA	s	Harold L. Lyon Arboretum
 HLCM	s	Heilongjiang College of Traditional Chinese Medicine, Department of Chinese Materia Medica
 HLD	s	Hessisches Landesmuseum
+HLDG	h	Las Cruces Biological Station, Organization for Tropical Studies
 HLL	s	Queen's Gardens, College of Higher Education, Natural Science Department
 HLMA	s	Town Docks Museum, Hull City Corporation
 HLMD	s	Hessisches Landesmuseum Darmstadt
 HLNM	s	Heilongjiang Provincial Museum
 HLO	s	Vlastivedne Muzeum v Hlohovci
+HLSD	h	Hillsdale College
 HLU	s	University of Hull, Botany Department
 HLUC	s	Universita degli Studi della Basilicata, Dipartimento di Biologia Difesa e Biotecnologie Agroforestali
 HLUL	s	University of Hull
 HLX	s	Ovenden Naturalists' Society
 HM<DEU>	s	Humbolt Museum
 HM<USA-NE>	s	Hastings Museum
+HMAR	h	Universidade Federal do Ceara
 HMAS	sc	Institute of Microbiology, Academia Sinica
 HMC	s	Jardin Botanico de Las Tunas
 HME	s	Haslemere Educational Museum
+HMGBH	h	Giardini Botanici Hanbury / Hanbury Botanic Gardens
 HMH	s	Hoebarth Museum Horn
+HMIM	h	Jardi Botanic Marimurtra
 HMJAU	sc	Herbarium of Mycology of Jilin Agricultural University
 HMLN	s	District Museum
 HMM	s	Horsham Museum
+HMMNH	h	Macedonian Museum of Natural History
 HMN	s	Humbolt Museum fur Naturkunde, East Berlin
 HMNH	s	Hayashibara Museum of Natural History
+HMNR	h	Mordovian State Nature Reserve
 HMNS	s	Houston Museum of Natural Science
 HMNT	s	Hancock Museum, Newcastle University
 HMP	s	Hornonitrianske muzeum, Department of Natural History
@@ -2300,22 +2446,28 @@ HMUG	s	Hunterian Museum
 HN	s	National Center for Natural Sciences and Technology, Botany Department
 HNBU	s	Institut de l'Environnement et de Recherche Agricola (INERA)
 HNCMB	c	Hungarian National Collection of Medical Bacteria
+HNG	h	Universite. Gamal Abdel Nasser de Conakry
 HNH	s	Dartmouth College, Biological Sciences Department
 HNHH	s	Heilongjiang Natural History Museum
 HNHM<HUN>	s	Hungarian Natural History Museum (Termeszettudomanyi Muzeum)
 HNHM<HUN>:Moll	c	Hungarian Natural History Museum (Termeszettudomanyi Muzeum), Mollusca Collection
 HNHM<KOR>	s	Hannam University, Department of Biology
+HNHPS	h	Hunan Hupingshan National Nature Reserve
 HNHR	s	University of California, Hastings Natural History Reservation
 HNIP	s	Hanoi College of Pharmacy
+HNL	h	Conseil National des Sciences
+HNM	h	Ecole Normale Superieure de Nouakchott
 HNMN	s	Universidad Centroamericana
 HNN	s	Horniman Museum of Natural History
 HNNU	s	Hunan Normal University, Botany Department
+HNPGBI	h	Seed and Plant Improvement Institute
 HNR	s	Heilongjiang Academy of Sciences
 HNT	s	Huntington Botanical Gardens
 HNTS	s	Vlastivedne muzeum
 HNU<CHN>	s	Hunan Normal University
 HNU<VNM>	s	Vietnam National University, Department of Botany
 HNUB	s	Northeastern University, Biology Department
+HNUL	h	Northwestern University Inc.
 HNWP	s	Northwest Plateau Institute of Biology, Chinese Academy of Sciences
 HNWU	s	Nebraska Wesleyan University, Biology Department
 HO	s	Tasmanian Museum & Art Gallery
@@ -2324,11 +2476,16 @@ HOLZ	s	Paleontological Collection
 HOMP	s	Okresni muzeum Pribram Brezove Hory
 HON	s	Sichuan Grassland Research Institute
 HOU	s	University of Houston
+HOXA	h	Estacion biologica del Jardin Botanico de Missouri
+HPAN	h	University of the State of Mato Grosso, UNEMAT
+HPBR	h	Universidade Regional Integrada do Alto Uruguai e das Missoes
 HPC	s	Howard Payne University, Biology Department
 HPD	s	Hampstead Scientific Society
 HPDL	s	Hampstead Public Library
 HPH	s	Monroe County Department of Parks
+HPL	h	Jardim Botanico Plantarum
 HPM	s	Houston Museum of Natural Science
+HPNP	h	Pumat National Park
 HPP	s	University of Helsinki, Plant Biology Department
 HPPR	s	Instituto Superior Pedagogico de Pinar del Rio, Departamento de Biologia
 HPSU	s	Portland State University, Biology Department
@@ -2339,20 +2496,26 @@ HPVC	s	Universidad Pedagogico Felix Varela,, Departamento de Biologia
 HR	s	Muzeum Vychodnich Cech
 HRB	s	IBGE
 HRCB	s	Universidade Estadual Paulista
+HREC	h	Hopland Research & Extension Center
 HRJ	s	Universidade do Estado do Rio de Janeiro, Departamento de Biologia Animal e Vegetal
 HRP	s	Universidad Nacional de La Patagonia, Departamento Biologia General
 HSB	s	Universidad Mayor Real y Pontificia de San Francisco Xavier de Chuquisaca
+HSBU	h	Shahid Beheshti University
 HSC	s	Humboldt State University, Biological Sciences Department
 HSCC	c	Culture Collection of the Research and Development Department
 HSI	s	University of Helsinki, Silviculture Department
 HSIB	s	Shanxi Institute of Biology, Botany Department
 HSIC	s	Ministry of Natural Resources, Solomon Islands
 HSM	s	Christ's Hospital, Biology Department
+HSMC	h	Whyte Thorne Botanic Garden
 HSNU	s	East China Normal University, Biology Department
+HSP	h	Instituto Cientifico Michael Owen Dillon
 HSS	s	Development, Technological and Investigacion Service, Forest Production Department
+HSTM	h	Universidade Federal do Oeste do Para
 HSU<USA-CA>	s	Humboldt State University
 HSU<USA-TX>	s	Hardin-Simmons University, Biology Department
 HSUCV	s	Hardin-Simmons University, Collection of Vertebrates
+HSUD	h	Station of Nature Research and Environmental Education
 HSUE	s	Natural History Museum, Addis Ababa
 HSUMZ	s	Henderson State University, Museum of Zoology
 HSUVM	s	Humboldt State University Vertebrate Museum
@@ -2365,23 +2528,31 @@ HTN	s	Hitchin Museum
 HTO	s	Universidade Federal do Tocantins, Nucleo de Estudos Ambientais
 HTTU	s	Tennessee Technological University, Biology Department
 HTU	s	University of Taiz, Biology Department
+HTW	h	Universidad Nacional de la Patagonia San Juan Bosco
 HU	s	University of Zhejiang
 HUA	s	Universidad de Antioquia, Centro de Investigaciones
 HUAA	s	Universidad Autonoma de Aquascalientes, Departamento de Biologia
 HUAL	s	Universidad de Almeria, Departamento de Biologia Vegetal y Ecologia
 HUAP	s	Herbario, Universidad Autonoma de Puebla
+HUAZ	h	Universidad de la Amazonia
 HUB	s	Hacettepe University, Botany Department
 HUBE	s	Golden West College, Biology/Life Sciences Department
 HUBO	s	Universita degli Studi di Bologna
 HUC	s	Universidad de Cordoba, Departamento de Biologia
 HUCM	s	Hunan College of Traditional Chinese Medicine, Department of Chinese Materia Medica
 HUCP	s	Pontifica Universidade Catolica do Parana, Departamento de Ciencias Biologicas
+HUCS	h	University of  Caxias do Sul
 HUDC	s	Howard University, Biology Department
 HUE	s	Hunan Education College, Biology Department
 HUEF	s	Hacettepe Ueniversitesi
 HUEFS	s	Universidade Estadual de Feira de Santana, Departamento de Ciencias Biologicas
+HUEG	h	Universidade Estadual de Goias
 HUEM	s	Universidade Estadual de Maringa, Departamento de Biologia
+HUESB	h	Universidade Estadual do Sudoeste da Bahia-Campus de Jequie
+HUESBVC	h	Universidade Estadual do Sudoeste da Bahia-Vitoria  da Conquista
 HUF	s	Hunan Forestry School
+HUFABC	h	Universidade Federal do ABC
+HUFSJ	h	Universidade Federal de Sao Joao del-Rei
 HUFU	s	Universidade Federal de Uberlandia, Instituto de Biologia
 HUIC	s	Hacettepe University Ichthyological Collection
 HUIF	s	Hunan Forestry Institute
@@ -2391,20 +2562,31 @@ HUKUK	c	Culture Collection of Animal Cells
 HUL	s	Fine Arts Museum
 HULE	s	Universidad Nacional Autonoma de Nicaragua, Departamento de Biologia
 HUM	s	Humbolt University Zoologischen Museum
+HUMC	h	Universidade de Mogi das Cruzes
 HUMO	s	Universidad Autonoma del Estado de Morelos, Centro de Educacion Ambiental e Investigacion Sierra de Huautla
 HUMP	s	Muzeum v Humpolci
 HUMZ	s	Hokkaido University, Laboratory of Marine Zoology
+HUNEB	h	Universidade do Estado da Bahia
+HUNT	h	Huntington University
+HUP	h	Hazara University
 HUPG	s	State University of Ponta Grossa, Departamento de Biologia
 HUQ	s	Universidad del Quindio
+HURB	h	Universidade Federal do Reconcavo da Bahia
 HURG	s	Universidade do Rio Grande, Departamento de Ciencias Morfo-Biologicas
+HUS	h	Siauliai University
 HUSA	s	Universidad Nacional de San Agustin de Arequipa, Facultad de Ciencias Biologicas y Agropecuarias, Area de Biomedicas
+HUSC	h	Universidade Santa Cecilia - UNISANTA
 HUSEC<DEU>	c	Konsiliarlabor fur Hamolytisch-Uramisches Syndrom
 HUST	s	Hunan University of Science and Technology, School of Life Sciences
 HUT<JPN>	c	HUT Culture Collection
 HUT<PER>	s	Herbarium Truxillense, Universidad Nacional de La Libertad-Trujillo
 HUTB	s	Hainan University
+HUTI	h	Universidad Tecnologica Indoamerica
 HUTM	s	Hunan Academy of Traditional Chinese Medicine and Pharmacy
+HUTO	s	Fundacao Universidade do Tocantins , UNITINS
 HUTPL	s	Universidad Tecnica Particular De Loja
+HUVA	h	Universidade Estadual Vale do Acarau
+HVASF	h	Universidade Federal do Vale do Sao Francisco
 HVR	s	Universidade de Tras-os-Montes e Alto Douro
 HWA	s	Southwest Agricultural University, Department of Biological Basic Courses
 HWB	s	Harrow School, Biology Department
@@ -2443,11 +2625,16 @@ IAN	s	Embrapa Amazonia Oriental
 IAPG	s	Institute of Animal Physiology and Genetics, Academy of Sciences of the Czech Republic
 IARI	sb	Indian Agricultural Research Institute
 IASI	s	Universitatea Agronomica, Disciplina de Botanica
+IAUGH	h	Islamic Azad University Garmsar
+IAUH	h	Islamic Azad University
+IAUM	h	Islamic Azad University of Mashhad
+IAUNT	h	Islamica Azad University, North Tehran Branch
 IAV	sb	Institut Agronomique et Veterinaire Hassan II, Departement d'Ecologie Vegetale
 IAVH	s	Instituto de Ivestigacion de los Recursos Biologicos Alexander von Humboldt
 IB	s	Universitaet Innsbruck
 IBA<ESP>	s	Instituto Asturiano de Taxonomia y Ecologia Vegetal
 IBA<POL>	c	Collection of Microorganisms Producing Antibiotics
+IBAR	h	Ibaraki University
 IBAUNC	s	Universidad Nacional de Cuyo, Instituto de Biologia Animal
 IBE	s	Institute for Botanical Exploration
 IBE<ESP>	s	Institut de Biologia Evolutiva, (CSIC-UPF)
@@ -2550,6 +2737,7 @@ IEME	s	Institute for Evolution, Morphology, and Ecology of Animals
 IEMM	s	Instituto de Ecologia
 IENU	s	Istituto di Entomologia, Universita degli Studi
 IEPA	s	Istituto di Entomologia Agraria dell'Universita
+IER	h	Institut d'Economie Rurale
 IEUC	s	Istituto di Entomologia Agraria dell'Universita Cattolica
 IEUP	s	Istituto di Entomologia, Universita degli Studi
 IEVB	s	Institut de Zoologie [Institut Ed. Van Beneden]
@@ -2567,6 +2755,7 @@ IFM<AUS>	c	IFM Quality Services Pty Ltd
 IFM<JPN>	c	Research Center for Pathogenic Fungi and Microbial Toxicoses, Chiba University
 IFO	c	Institute for Fermentation
 IFP	s	Institute of Applied Ecology, Academia Sinica
+IFRD	h	Research Institute of Resource Insects
 IFRDCC	c	International Fungal Research and Development Culture Collection
 IFREMER	s	Institut Francais pour l'Etude de la Mer
 IFRI	s	Indian Forest Research Institute
@@ -2579,6 +2768,7 @@ IGCAGS	s	Institute of geology, Chinese Academy of Geological Science
 IGCU	s	Instituto de Geologia, Ciudad Universitaria
 IGESALQ	c	Colecao Microorganismos
 IGF	s	Instituto di Geologia e Paleontologia
+IGGDC	h	Institute of Geology and Geophysics, Chinese Academy of Sciences
 IGL	s	Institute fuer Geowissenschaften Leoben
 IGM<MEX>	s	Instituto de Geologia
 IGM<MNG>	s	Geological Institute, Mongolian Academy of Sciences
@@ -2617,6 +2807,7 @@ IMAS	c	Institute for Marine and Antarctic Studies
 IMAU	c	Inner Mongolia Agricultural University, Key Laboratory of Dairy Biotechnology and Engineering
 IMC	s	Sichuan Academy of Traditional Chinese Medicine and Pharmacy
 IMCC	c	Inha Microbe Culture Collection, Inha University
+IMCN	s	Instituto Vallecaucano de Investigaciones Cientificas
 IMD	c	Industrial Microbiology Dublin
 IMD<CHN>	s	Institute of Medicinal Plant Development, Chinese Academy of Medical Sciences
 IMDC	s	Inner Mongolia Institute for Drug Control
@@ -2656,8 +2847,10 @@ IND-AN	s	Amphibian Collection
 IND-M	s	La Unidad de Investigacion "Federico Medem"-Inderena (Colombia)
 INDRE	c	Pathogen Fungi and Actinomycetes Collection
 INEGI	s	Instituto Nacional de Estadistica Geografia e Informatica, Departamento de Botanica
+INEP	h	Institute of the Industrial Ecology Problems of the North of Kola Science Center of the Russian Academy of Sciences.
 INER	s	Istituto Nazionale di Entomologia
 INFYB	s	Instituto Nacional de Farmacologia y Bromatologia, Farmacobotanica
+INGU	h	Ingush State University
 INH	s	Institut National d'Horticulture, Departement de Sciences Biologiques
 INHM	s	Iraq Natural History Museum
 INHS	s	Illinois Natural History Survey
@@ -2682,6 +2875,7 @@ INPC	s	National Pusa Collections
 INRA	b	Institut National de la Recherche Agronomique
 INRA:CGAB	cb	Institut National de la Recherche Agronomique, Collection of Germplasms of Agaricus bisporus
 Insitute of Biology and Soil Science, Russian Academy of Sciences	s	Insitute of Biology and Soil Science, Russian Academy of Sciences
+INU	h	Inonu University
 INV	s	Inverness Museum and Art Gallery
 INVA	s	Invergordon Academy
 INVAM	c	International Culture Collection of (Vesicular) Arbuscular Mycorrhizal Fungi
@@ -2730,7 +2924,9 @@ IPT	c	Agrupamento de Biotecnologia, Culture Collection of Microorganisms
 IPTB	s	Instituto de Pesquisas Tecnologicas
 IPUW	s	Institut fuer Palaeontologie der Universitaet Wien
 IPW	s	Instutut fuer Palaeontologie der Uinversitaet Wurzburg
+IQW	h	Senckenberg Forschungsinstitut und Naturmuseen
 IRAG	s	Institut National de la Recherche Agronomique de Antilles et Guyane
+IRAI	h	Parque da Ciencia Newton Freire Maia
 IRAN	sc	Iranian Research Institute of Plant Protection, Department of Botany
 IRBR	s	Universidad de Oriente, Departamento de Biologia
 IRCW	s	Madison, University of Wisconsin
@@ -2759,6 +2955,7 @@ ISBC:CMF	cb	Institute of Soil Biology, Academy of Science of the Czech Republic,
 ISC<FRA>	c	International Salmonella Centre (W.H.O.)
 ISC<USA-IA>	s	Iowa State University, Botany Department
 ISCM	s	Institut Scientifique Cheripen
+ISE	h	Universidade Federal de Sergipe, Campus Professor Alberto Carvalho
 ISEA	s	Institute of Systematics and Evolution of Animals
 ISEAK	s	Instytut Systematyki i Ewolucji Zwierz
 ISEM	s	Institut des Sciences de l'Evolution Montpellier 	
@@ -2766,8 +2963,10 @@ ISER	s	Institutul Speologie Emil G. Racovita
 ISH	s	Institut fuer Seefischerei
 ISI	s	Geological Museum, Indian Statistical Institute
 ISIS	s	Naturforschende Gesellschaft Isis
+ISKW	h	Ishikawa Museum of Natural History
 ISL	s	Quaid-I-Azam University, Biological Sciences Department
 ISM	s	Illinois State Museum
+ISMAR	h	Consiglio Nazionale delle Ricerche, Istituto di Scienze  Marine
 ISMC	s	Indiana Department of Natural Resources
 ISNHC	s	State Historical Society of Iowa
 ISNP	s	Istituto Sperimentale per la Nutrizione delle Piante
@@ -2793,6 +2992,7 @@ ITAL	c	Banco de Fermentos Lacticos
 ITALSL	c	Secao de Leite e Derivados
 ITALSM	c	Secao de Microbiologia
 ITBCC	c	Institute of Technology Bandung Culture Collection
+ITBZC	s	Institute of Tropical Biology, Zoology Collection
 ITC	b	International Transit Centre
 ITCC<IND>	c	Indian Type Culture Collection
 ITCC<ITA>	s	Istituto Tecnico Stattale "Camillo Cavour"
@@ -2806,6 +3006,7 @@ ITH	c	W.H.O./F.A.O. Collaborating Centre for Reference and Research on Leptospir
 ITHA	s	Instituut voor Tropische Hygiene
 ITIC	s	Universidad de El Salvador, Escuela de Biologia
 ITLJ	s	National Institute of Agro-environmental Sciences
+ITMH	h	Muhimbili University of Health and Allied Sciences
 ITMM	s	Instituto Tecnologico de Monterrey
 IU	s	Indiana University
 IUI	s	Inha University, Biology Department
@@ -2817,6 +3018,7 @@ IUQ	s	Laboratorio de Ictiologia
 IVAU	s	Instituut Voor Aardwetenschappen
 IVB	s	Institute of  Vertebrate Biology, Academy of Sciences of the Czech Republic
 IVF	s	Chinese Academy of Agricultural Sciences
+IVGU	h	Ivanovo State University
 IVIC	s	Instituto Venezolano de Investigaciones Cientificas
 IVPP	s	Institute of Vertebrate Paleontology and Paleoanthropology
 IZ<BRA>	c	Departamento de Tecnologia Rural
@@ -2861,7 +3063,9 @@ JATH	s	University of Szeged
 JAUM	s	Jardin Botanico Joaquin Antonio Uribe
 JAY	s	Fondation Cognacq-Jay
 JBAG	s	Jardin Botanico Atlantico, Ayuntamiento de Gijon
+JBB	h	Jardin Botanico Jose Celestino Mutis
 JBC<MEX>	b	Francisco Javier Clavijero Botanic Garden
+JBCC	h	Alaska State Museum
 JBG	s	Johannesburg Botanic Garden
 JBGP	s	Jardin Botanico Guillermo Pineres
 JBL	s	Jardin Botanico Lankester, Universidad de Costa Rica
@@ -2880,11 +3084,13 @@ JEF	s	Indiana University Southeast, Biology Department
 JEL	c	Joyce E. Longcore Chytrid Collection at the University of Maine
 JEL<LVA>	s	Latvian Agricultural Academy, Plant Protection Department
 JEPS	s	University of California, Jepson Herbarium
+JES	h	Universidad Autonoma Chapingo
 JESW	s	John Evelyn Society's Museum
 JEY	s	Boys' Grammar School, Victoria College
 JF	s	Jonkershoek Forestry Research Centre, Environment Affairs Department
 JFBM	s	James Ford Bell Museum of Natural History
 JHH	s	New York State Herbarium
+JHS	h	Regional Research Institute
 JHWU	s	Wittenberg University, Biology Department
 JIC	b	John Innes Centre
 JII	s	John Innes Institute
@@ -2895,6 +3101,7 @@ JJU	s	Jeonju University
 JLFC	s	Forestry College of Beihua University, Forestry Department
 JLMP	s	Jilin Academy of Traditional Chinese Medicine and Materia Medica
 JM	s	Jura Museum, Eichstatt
+JME	h	Jura-Museum Eichstatt
 JMM	s	Earlham College, Joseph Moore Museum
 JMRC	c	Jena Microbial Resource Collection
 JMRC:SF	c	Jena Microbial Resource Collection, Subcollection Fungi
@@ -2904,13 +3111,18 @@ JN	s	Jinggang Mountain Nature Reserve
 JNR	s	Jiulian Mountain Nature Reserve, Administration Department
 JNU<CHN>	s	Ji Nan University
 JNU<KOR>	s	Chonbuk National University, Faculty of Biological Sciences
+JNUB	h	Jeju National University
 JOE	s	University of Joensuu, Biology Department
+JOI	h	Universidade da Regiao de Joinville
+JOMU	h	John Muir National Historic Site
 JONK	s	Jonkershoek Herbarium
+JOTR	h	Joshua Tree National Park
 JP	s	Phyletisches Museum Jena
 JPB	s	Universidade Federal da Paraiba, Cidade Universitaria, Departamento de Sistematica e Ecologia
 JPMP	s	Janus Pannonius Museum
 JPU	s	Janus Pannonius University, Botany Department
 JRAU	s	University of Johannesburg, Department of Botany and Plant Biotechnology
+JROH	h	Jasper Ridge Biological Preserve, Stanford University
 JRY	s	Jersey College for Girls
 JSHC	s	Jay S. Haft Collection
 JSMPE	s	Joint Soviet Mongolian Paleontolgical Expedition
@@ -2943,6 +3155,7 @@ KAGS	s	Kagoshima University, Biology Department
 KAI	s	Henan University, Biology Department
 KAMA	s	Yokohama University
 KANA	s	Kanazawa University
+KAND	h	Kandalaksha State Nature Reserve
 KANU	s	University of Kansas
 KAR	s	University of Tehran, Horticulture Department
 KARI	s	Kenya Agricultural Research Institute
@@ -2984,12 +3197,15 @@ KEND	s	Kendal Natural History Society
 KEP	s	Forest Research Institute Malaysia
 KESC	s	Keene State College, Department of Biology
 KEVO	s	University of Turku
+KF	h	Kerman University of Medical Sciences
+KFBG	h	Kadoorie Farm and Botanic Garden
 KFCC	c	Korean Federation of Culture Collection
 KFI	s	Hongnung Arboretum, Silviculture Department
 KFRI	s	Kerala Forest Research Institute
 KFRS	s	Kanudi Fisheries Research Station
 KFTA	s	Saint Petersburg State S. M. Kirov Forest Technology Academy, Botany and Dendrology Department
 KFUH	s	King Faisal University, Chemistry and Botany Department
+KG	h	International Phytochemistry Research and Production Institute
 KGU	s	Geology and Mineralogy Museum
 KGY	s	Cliffe Castle Art Gallery and Museum
 KH	s	Korea National Arboretum
@@ -3005,7 +3221,11 @@ KHUG	s	Aussenstelle der Universitaet
 KHUS	s	Kyung Hee University, Biology Department
 KIEL	s	Christian-Albrechts-Universitaet Kiel
 KIFB	s	Korean Institute of Freshwater Biology
+KIOM	h	Korea Institute of Oriental Medicine
+KIP	h	Institut National pour l'Etude et la Recherche Agronomique
 KIRI	s	University of Rhode Island, Department of Biological Sciences
+KIS	h	Universite de Kisangani
+KISA	h	Institut Congolais  pour la Conservation de la Nature
 KIT	c	Laboratorium voor Tropische Hygiene
 KIUJ	s	Kyusu University
 KIZ	s	Kunming Institute of Zoology, Chinese Academy of Sciences
@@ -3038,6 +3258,7 @@ KMU	s	Karl-Marx-Universitat Leipzeg
 KMV	s	Kunming Municipal Museum
 KMVC	s	Krajske Muzeum Vychodnich Cech
 KNFY	s	Klamath National Forest, Resources Department
+KNH	h	Kongju National University
 KNHM	s	The Educational Science Museum [=Kuwait Natural History Museum?]
 KNK	s	Northern Kentucky University, Department of Biological Sciences
 KNL	s	Kinneil Museum
@@ -3069,6 +3290,7 @@ KR	s	Staatliches Museum fuer Naturkunde Karlsruhe
 KRA	s	Jagiellonian University
 KRAM	s	Polish Academy of Sciences, Department of Plant Systematics
 KRAS	s	Krasnoyarsk State Pedagogical University, Department of Botany
+KRB	h	Kebun Raya Bogor
 KRDY	s	Kirkcaldy Museum and Art Gallery
 KRF	s	V. N. Sukachev Institute of Forest and Wood
 KRG	s	Westfield Museum
@@ -3085,6 +3307,7 @@ KSHS	s	Kochi Senior High School
 KSK	s	Fitz Part Museum and Art Gallery
 KSO	s	Tweedside Physical and Antiquarian Society Museum
 KSP	s	Pittsburg State University, Biology Department
+KSPI	h	Kostanay State Pedagogical Institute
 KSRV	s	Khosrov State Reserve
 KSTC	s	Emporia State University
 KSU	s	King Saud University, Botany and Microbiology Department
@@ -3094,22 +3317,23 @@ KTC	s	Pedagogical University, Botany Department
 KTG	s	Kettering and District Naturalists' Society and Field Club
 KTU	s	University of Silesia, Department of Plant Systematics
 KTUH	s	Kuwait University, Botany and Microbiology Department
-KU	s	University of Kansas, Museum of Natural History
+KU	s	University of Kansas Natural History Museum
 KU-MACC	c	Kobe University Macroalgal Culture Collection
-KU:H	s	University of Kansas, Museum of Natural History, Herpetology Collection
-KU:I	s	University of Kansas, Museum of Natural History, Ichthyology collection
-KU:IP	s	University of Kansas, Museum of Natural History, Invertebrate Paleontology Collection
-KU:IT	sb	University of Kansas, Museum of Natural History, Ichthyology tissue collection
-KU:IZ	s	University of Kansas, Museum of Natural History, Invertebrate Zoology Collection
-KU:M	s	University of Kansas, Museum of Natural History, Mammology Collection
-KU:O	s	University of Kansas, Museum of Natural History, Ornithology Collection
-KU:PB	s	University of Kansas, Museum of Natural History, Paleobotany Collection
-KU:VP	s	University of Kansas, Museum of Natural History, Vertebrate Paleontology Collection
+KU:H	s	University of Kansas Natural History Museum, Herpetology Collection
+KU:I	s	University of Kansas Natural History Museum, Ichthyology collection
+KU:IP	s	University of Kansas Natural History Museum, Invertebrate Paleontology Collection
+KU:IT	sb	University of Kansas Natural History Museum, Ichthyology tissue collection
+KU:IZ	s	University of Kansas Natural History Museum, Invertebrate Zoology Collection
+KU:M	s	University of Kansas Natural History Museum, Mammology Collection
+KU:O	s	University of Kansas Natural History Museum, Ornithology Collection
+KU:PB	s	University of Kansas Natural History Museum, Paleobotany Collection
+KU:VP	s	University of Kansas Natural History Museum, Vertebrate Paleontology Collection
 KU<CHN>	s	Kwangsi University
 KUBL	s	Yoshida College, Biological Laboratory
 KUEC	s	Kyushu University Entomology Collection
 KUEL	s	Kyushu University, Entomology Laboratory
 KUFC	c	Kasetsart University Fungus Collection
+KUFS	h	Kabul University
 KUH	s	University of Karachi, Botany Department
 KUHE	s	Kyoto University, Graduate School of Human and Environmental Studies
 KUIC	s	Kagoshima University
@@ -3124,11 +3348,13 @@ KUO	s	Kuopio Natural History Museum
 KURS	s	Kursk State University, Department of Botany
 KUS	s	Korea University, Biology Department
 KUU	s	University of Science and Technology
+KUW	h	Kakatiya University
 KUZ<JPN>	s	Zoological Collection of the Kyoto University
 KUZC	s	Kyushu University, Zoological Collection
 KVCH	s	Kivach Nature Reserve
 KW	s	National Academy of Sciences of Ukraine
 KWHA	s	Ukrainian National Academy of Sciences
+KWHU	h	O. V. Fomin Botanical Garden of National Taras Schevchenko University of Kiev
 KWNU	s	Kangwon National University, Biology Department
 KWP	s	Kenelm W. Philip Collection, University of Alaska Museum of the North
 KWP:Ento	s	Kenelm W. Philip Collection, University of Alaska Museum of the North, Lepidoptera collection
@@ -3183,6 +3409,7 @@ LBN	s	Lembaga Biologi Nasional
 LBRP	s	Laboratorio de Biodiversidade de Recursos Pesqueiros
 LBUCH	s	Laboratorio de Biologia
 LBV	s	CENAREST
+LC	h	Lewis & Clark College
 LCC<CAN>	c	Labatt Culture Collection, Technology Development
 LCC<POL>	c	University of Warmia and Mazury in Olsztyn
 LCDI	s	Luther College, Biology Department
@@ -3214,7 +3441,9 @@ LEB<ESP>	s	Universidad de Leon, Departamento de Biologia, Botanica
 LEB<LVA>	s	Entomological Society of Latvia
 LEC	s	Universita degli Studi di Lecce, Dipartimento di Biologia
 LECB	s	Saint Petersburg State University, Botany Department
+LEDLIE	h	Patricia Ledlie Herbarium
 LEF	s	Economic Forestry Institute of Liaoning Province
+LEH	h	Lehigh University
 LEI	s	Leicester Literary and Philosophical Society
 LeishCryoBank	c	International Cryobank of Leishmania
 LEIUG	s	Department of Geology Leicester University
@@ -3260,8 +3489,10 @@ LILLE	s	Institut Catholique de Lille, Laboratoire de Biologie Vegetale
 LIM	s	Severoceske muzeum
 LIMFC	s	Limerick Field Club
 LIMK	s	Limerick Museum
+LIMO	h	Universite de Limoges
 LIN-SB	c	Limnological Institute, Siberian Branch, Russian Academy of Sciences
 LINC	s	Lincoln University, Plant Sciences Group
+LINCO	h	Linfield College
 LINF	s	Shanxi Normal University, Biology Department
 LINHM	s	Long Island Natural History Museum
 LINN	s	Linnean Society of London
@@ -3285,10 +3516,13 @@ LIVCM	s	Liverpool County Museum
 LIVNFC	s	Liverpool Naturalists' Field Club
 LIVU	s	Hartley Botanical Laboratories
 LJC	c	Coleccion de fitopatogenos de cultivos horticolas
+LJF	h	Slovenian Forestry Institute
 LJM	s	Prirodoslovni Muzej Slovenije
+LJS	h	Scientific Research Centre
 LJU	s	University of Ljubljana, Botany Department
 LKHD	s	Lakehead University, Biology Department
 LL	s	University of Texas at Austin, Plant Resources Center
+LLANOS	h	Universidad de los Llanos
 LLC	s	Our Lady of the Lake University, Biology Department
 LLN	s	Lincolnshire Naturalists' Union
 LLO	s	Lloyd Library and Museum
@@ -3304,13 +3538,16 @@ LMJ<MOZ>	s	Centro de Investigacao Cientifica Algodoeira, Botanical Department
 LMKG	s	Landesmuseum fur Karnten
 LMND	s	Landessammlungen fuer Naturkunde
 LMNH	s	Museum d'Histoire naturelle
+LMO	h	Landesmuseum Natur und Mensch
 LMRZ	s	Livingstone Museum
 LMS	c	Carolina Biological Supply Company
 LMSZ	s	Latvian University, Museum of Systemic Zoology
 LMU	s	Eduardo Mondlane University, Department of Biological Sciences
 LMZG	s	Local Museum
 LNAF	s	Liaoning Academy of Forestry
+LNAU	h	Luhansk National Agrarian University
 LNCM	s	Liaoning College of Traditional Chinese Medicine
+LNCN	h	Lincoln Memorial University
 LNHS	s	London Natural History Society
 LNK	s	Landessammlungen fuer Naturkunde
 LNKD	s	Landessammlung fuer Naturkunde
@@ -3332,6 +3569,7 @@ LP<RUS>	s	Laboratory of Palaeontology
 LPA	s	Jardin Botanico Canario Viera y Clavijo
 LPAG	s	Universidad Nacional de La Plata, Area de Botanica
 LPB	s	Herbario Nacional de Bolivia
+LPC	h	Museo de La Plata
 LPD	s	Laboratorio de Botanica de la Direccion de Agricultura
 LPFU	s	Lehrstuhl fur Palaontologie
 LPL	s	The University
@@ -3398,9 +3636,11 @@ LUG	s	Museo cantonale di storia naturale
 LUGO	s	Universidad de Satniago de Compostela, Departamento de Produccion Vegetal
 LUH	s	University of Lagos, Biological Sciences Department, Botany Unit
 LUH<NLD>	c	Leiden University Medical Center
+LUKI	h	Institut National pour l'Etude et la Recherche Agronomiques
 LUNZ	s	Lincoln University Entomology Research Museum
 LUQ	s	Laval University
 LUS	s	Lushan Botanical Garden
+LUSC	h	Universidade do Estado de Santa Catarina
 LUW	s	Landbouwuniversiteit Wageningen, Department of Entomology
 LUX	s	Musee national d'histoire naturelle
 LV	s	Catholic University of Leuven, Laboratory of Plant Systematics
@@ -3410,6 +3650,7 @@ LW	s	Ivan Franko National University of Lviv, Botany Department
 LWA	s	Agricultural Experiment Station
 LWD	s	Museum Dzieduszyckich
 LWG	s	National Botanical Research Institute
+LWI	h	Centre de Recherche en Sciences Naturelles (CRSN/Lwiro)
 LWKS	s	Institute of Ecology of the Carpathians
 LWL<DEU>	s	LWL-Museum fuer Naturkunde
 LWL<DEU>:DNA	b	LWL-Museum fuer Naturkunde, LWL-DNA- und Gewebearchiv
@@ -3503,7 +3744,10 @@ MAO	c	Mircen Afrique Ouest
 MAPA	s	Museu Anchieta Porto Alegra
 MAPR	s	University of Puerto Rico, Mayagueez Campus, Biology Department
 MAR	c	Grasslands Rhizobium Collection
+MARDI	h	Malaysian Agricultural Research and Development Institute
 MARE	s	Marmara University, Department of Pharmaceutical Botany
+MARI	h	Mari State University
+MARK	h	Cadi Ayyad University
 MARO	s	Marylhurst College
 MARS	s	Universite de Provence Centre St-Charles, case 4
 MARSSJ	s	Universite Paul Cezanne
@@ -3512,6 +3756,7 @@ MASE	s	Maseru Experiment Station
 MASS	s	University of Massachusetts, Biology Department
 MATSU	s	Ehime University, Forestry Department
 MAU	s	Mauritius Sugar Industry Research Institute
+MAUAM	h	Universidad Autonoma de Madrid
 MAY	s	Adygean State University, Department of Botany
 MB<DEU-Berlin>	s	Museum of Natural History of Humboldt-University
 MB<DEU-Marburg>	s	Philipps-Universitaet, Spezielle Botanik
@@ -3553,7 +3798,9 @@ MCCI	s	Museo Civico di Storia Natural de Carmognola
 MCCM<DEU>	c	Medical Culture Collection Marburg
 MCCM<IND>	s	Madras Christian College
 MCD	s	Muzeul Civilizatiei Dacice si Romane Deva
+MCDNL	h	McDaniel College
 MCES	s	Museum of the Center for Entomological Studies
+MCF	h	Sts. Cyril and Methodius University
 MCF-PVPH	s	Museo Carmen Funes
 MCFB	s	Museo de la Cienica Fundacion
 MCFM	s	Museo Civico "Francesco Mina Palumbo"
@@ -3623,6 +3870,7 @@ MDE	s	Musee des Dinosaures in Esperaza
 MDFW	s	Massachusetts Division of Fisheries and Wildlife
 MDH<GBR>	s	Dorman Museum
 MDH<USA-MI>	c	Michigan Department of Health
+MDI	h	Malaysian Agricultural Research and Development Institute
 MDKY	s	Morehead State University, Biological and Environmental Sciences Department
 MDLA	s	Museu do Dundo
 MDM	s	Mifune Dinosaur Museum
@@ -3639,6 +3887,7 @@ MEDEL	s	Universidad Nacional de Colombia - Sede de Medellin, Departamento de Bio
 MEFLG	s	Museo Entomologico Francisco Luis Gallego
 MEL	s	Royal Botanic Gardens Melbourne
 MELG	s	Geology Department, University of Melbourne
+MELIT	h	Bogdan Khmel'nysckyi State Pedagogical University of Melitopol'
 MELU	s	University of Melbourne
 MEM	s	University of Memphis, Biology Department
 MEMO	s	Instituto Tecnologico y de Estudios Superiores de Monterrey, Departamento de Recursos Naturales
@@ -3646,6 +3895,7 @@ MEN	s	UNCuyo, Catedra de Botanica Agricola, Departamento de Ciencias Biologicas
 MEPAN	s	Museum of Evolution, Polish Academy of Sciences
 MER	s	Universidad de Los Andes
 MERC	s	Universidad de Los Andes, Centro Jardin Botanico
+MERCA	h	Mercer Arboretum and Botanic Gardens
 MERF	s	Universidad de Los Andes
 MERL	s	Instituto Argentino de Investigaciones de las Zonas Aridas (CRICYTME)
 MESA	s	Mesa State College, Biology Department
@@ -3700,6 +3950,7 @@ MGUWR	s	Institute of Geological Sciences, University of Wroclaw
 MH<CHE>	s	Naturhistorisches Museum, Basel
 MH<IND>	s	Tamil Nadu Agricultural University
 MHA	s	Main Botanical Garden of the Russian Academy of Sciences
+MHES	h	Museo de Historia Natural de El Salvador
 MHH	c	Institute of Virology
 MHL	s	Mildenhall and District Museum
 MHM	s	Malham Tarn Field Centre
@@ -3737,6 +3988,7 @@ MI	s	Universita degli Studi di Milano, Dipartimento di Biologia
 MIB	s	University of Milano - Bicocca, Department of Biotechnology and Biosciences
 MIB:ZPL	s	University of Milano - Bicocca, Department of Biotechnology and Biosciences, ZooPlantLab
 MIC	s	Mar Ivanios College (Zoology museum)
+MICG	h	Universidad de San Carlos de Guatemala
 MICH	s	University of Michigan
 MICKKU	c	MICKKU Culture Collection
 MID	s	Middlebury College, Biology Department
@@ -3750,9 +4002,11 @@ MIN	s	University of Minnesota
 MINC	s	Universidad Politecnica
 MINI	s	Muzeul de Istoria Naturala
 MIPV	s	Universita degli Studi di Milano, Laboratorio di Micologia e Batteriologia Fitopathologica
+MIRR	h	Museu Integrado de Roraima
 MISR	s	Macaulay Land Use Research Institute
 MISS	s	University of Mississippi, Department of Biology
 MISSA	s	Mississippi State University, Department of Biological Sciences
+MISU	h	Minot State University
 MIT	c	Massachusetts Institute of Technology
 MIWG	s	Museum of he Isle of Wight Geology
 MIZA	s	Museuo del Instituto de Zoologia Agricola
@@ -3768,8 +4022,12 @@ MJMO	s	Universidad Centro Occidental, Decanato de Agronomia
 MJS	s	Xiaolongshan Forestry Experiment Bureau
 MJSD	s	Museum-Jardin des Sciences
 MK	s	National Museum of Kenya
+MKMEL	h	Herbarium Melovskiorum
+MKNDC	h	Institute of Biology
+MKNH	h	Institute of Biology
 ML	s	Musee de Lectoure
 MLAV	s	Musees de Laval
+MLGU	h	Institut National pour l'Etude et la Recherche  Agronomiques
 MLLD	c	Microbiological Research Laboratory, Soil and Water Section, Department of Land Development
 MLMJI	c	Department of Plant Protection, Faculty of Agricultural Production
 MLP	s	Museo de La Plata
@@ -3777,7 +4035,7 @@ MLRU	c	Microbiology Laboratory, Department of Biology, Faculty of Science
 MLS<AUS>	s	Marine Laboratory Sydney
 MLS<COL>	s	Museo del Instituto de La Salle
 MLS<GBR>	s	Lathallan Preparatory School
-MLUH	s	Martin Luther Universitaet
+MLUH	s	Martin Luther Universitat
 MLY	s	Arboretum Mlynany
 MLZ	s	Moore Laboratory of Zoology, Occidental College
 MLZ:Bird	s	Moore Laboratory of Zoology, Occidental College, Bird Collection
@@ -3870,10 +4128,12 @@ MNRJ	s	Museu Nacional/Universidade Federal de Rio de Janeiro
 MNSB	s	Museum of Natural Sciences
 MNSL	s	Museum of Natural Sciences
 MNUFR	s	Mongolian National University
+MNVD	h	Museum fur Naturkunde und Vorgeschichte Dessau
 MNVL	s	Museum d'Histoire Naturelle de Ville de Lille
 MNZ	s	Museum of New Zealand Te Papa Tongarewa
 MO	s	Missouri Botanical Garden
 MOAR	s	Morris Arboretum, University of Pennsylvania, Botany Department
+MOBR	h	Estacion de Investigaciones Marinas de Margarita, Fundacion La Salle de Ciencias Naturales
 MOC	s	Western Oregon University, Biology Department
 MOD	s	Universita degli Studi di Modena e Reggio Emilia, Dipartimento de Biologia Animale
 MODNR	s	Division of State Parks, Department of Natural Resources
@@ -3894,6 +4154,7 @@ MOSI	s	Museum of Science and Industry
 MOSM	s	All-Russian Research Institute of Medicinal and Aromatic Plants
 MOSN	s	Museo Ornitologico e di Scienze Naturali
 MOSP	s	Moscow State Pedagogical University, Botany Department
+MOSS	h	Universidade Federal Rural do Semi-Arido
 MOT	s	Mote Marine Laboratory
 MOTH	s	Museum of the Hemispheres
 MOUFPE	s	Oceanographic Museum of the Federal University of Pernambuco
@@ -3912,6 +4173,7 @@ MPEF-PV	s	Muso Paleontologico Egidio Fergulio
 MPEG	s	Museu Paraense Emilio Goeldi
 MPEP	s	Musee de Paleontologie et de l'evolution
 MPGB	s	Museum of Portuguese Guinea
+MPH	h	Shahid Behershti University
 MPKV	c	Biological Nitrogen Fixation Project College of Agriculture
 MPL	s	Musee de Port Louis
 MPLN	s	Museo Provinciale di Storia Naturale
@@ -3976,6 +4238,7 @@ MSEM	s	Museu Geologic del Seminari de Barcelona
 MSEN	s	Montrose Natural History and Antiquarian Society
 MSF	s	Sauriermuseum Frick
 MSGP	s	Nusee des Services Geologiques du Portugal
+MSI	h	Marine Science Institute, University of the Philippines
 MSIE	s	Museum of Shanghai
 MSINR	s	Museum Sichuan Institute of Natural Resources
 MSIR	s	Mauritius Sugar Industry
@@ -4019,9 +4282,11 @@ MT<CAN>	s	Universite de Montreal
 MT<RUS>	s	Mus. Tinro, Vladyvostok
 MTA	s	Maden Tetkik ve Arama Enstituesue
 MTCC	c	Microbial Type Culture Collection & Gene Bank
+MTCHT	h	Mar Thoma College
 MTD	s	Museum of Zoology Senckenberg Dresden
 MTD:T	s	Museum of Zoology Senckenberg Dresden, Tissue collection
 MTD:TD	s	Museum of Zoology Senckenberg Dresden, Herpetological Tissue Collection
+MTDO	h	Chiba University
 MTEC	s	Montana State University
 MTJB	s	Jardin botanique de Montreal
 MTKD	s	Staatliches Museum fuer Tierkunde
@@ -4050,6 +4315,7 @@ MUFM	s	Manipur University Fish Museum
 MUFS	s	Department of Animal Science, Miyazaki  University
 MUGM	s	Museo de Ciencias Naturales, Coleccion "Gustavo Orces" (Ecuador)
 MUGT	s	Museo de Ciencias Naturales de la Universidad de Guayaquil
+MUH	h	Mirpur University of Science & Technology
 MUHW	s	Marshall University, Biological Sciences Department
 MUJ	s	Museo Javeriano de Historia Natural, Laboratoriao de Entomologia
 MUL	c	Department of Microbiology MUL-B 250
@@ -4070,7 +4336,9 @@ MUSA	s	Universidad Nacional de San Agustin, Museo de Historia Natural (Peru)
 MUSK	s	Muskegon Community College, Life Science Department
 MUSM	s	Museo de Historia Natural de la Universidad Nacional Mayor de San Marcos en Lima
 MUSN	s	Museo Universitario di Storia Naturale e della Strumentazione Scientifica
+MUST	h	Al-Mustansiriya University
 MUT<ITA>	c	Mycotheca Universitatis Taurinensis
+MUZ	h	King Abdulaziz City for Science and Technology
 MV	s	University of Montana Museum
 MVC	s	University of Charleston, Natural Sciences Department
 MVDA	s	Ministerio de Ganaderia y Agricultura
@@ -4142,14 +4410,15 @@ MZUB	s	Museo di Zoologia
 MZUC<CHL>	s	Museo de Zoologia, Universidad de Concepcion
 MZUC<ITA>	s	Universita di Cagliari
 MZUCR	s	Universidad de Costa Rica, Museo de Zoologia
+MZUEL	s	Museu de Zoologia da Universidade Estadual de Londrina
 MZUESC<BRA>	s	Museu de Zoologia da Universidade Estadual de Santa Cruz
 MZUF	s	Museo Zoologico La Specola, Universita di Firenze
 MZUN	s	Museo Zoologico di Universita degli Studi
 MZUNAP	s	Museo de Zoologia de la Universidad Nacional de la Amazonia Peruana
 MZUP<ITA-Padova>	s	Museo Zoologia
 MZUP<ITA-Parma>	s	Museo Zoologico di Universita degli Studi
-MZUR	s	Museo di Zoologia dell'Universita "La Sapienza"
-MZUR:BAU	s	Museo di Zoologia dell'Universita "La Sapienza", Zoological collection of the Department of Biology and Biotechnology
+MZUR	s	Museo di Zoologia dell'Universita di Roma "La Sapienza"
+MZUR:BAU	s	Museo di Zoologia dell'Universita di Roma "La Sapienza", Zoological collection of the Department of Biology and Biotechnology
 MZUS	s	Musee de Zoologie de l'Universite de Strasbourg
 MZUSP	s	Museu de Zoologia da Universidade de Sao Paulo
 MZUT<ITA-Torino>	s	Museo di Zoologia, Instituto di Zoologia e Anatomia Comparata Universita di Torino
@@ -4165,6 +4434,7 @@ NABG	s	Botanical Garden
 NAC	s	Nagano Nature Conservation Research Institute
 NAI	s	University of Nairobi, Botany Department
 NAIC	s	National Agricultural Insect Collection
+NAKU	h	Namik Kemal University
 NAM	s	Facultes Universitaires Notre-Dame de la Paix
 NAN	s	Nantong Teachers College, Biology Department
 NAP<CHN>	s	Institute of Zoology, Academia Sinica (formerly National Academy of Peiping)
@@ -4234,12 +4504,14 @@ NCLN	s	New College
 NCMA	s	Raleigh, North Carolina Department of Environmental Health and Natural Resources
 NCMH	c	The North Carolina Memorial Hostital
 NCMK	s	Norwich Castle Museum
+NCP	h	National  Collection of Passiflora
 NCPF	c	National Collection of Pathogenic Fungi
 NCPPB	c	National Collection of Plant Pathogenic Bacteria
 NCPV	c	National Collection of Pathogenic Viruses
 NCS	s	North Carolina State University
 NCSC<THA>	c	National Center of Streptococcus Collection, Department of Microbiology, Faculty of Medical Science
 NCSC<USA-NC>	s	North Carolina State University, Botany Department
+NCSLG	h	North Carolina State University
 NCSM	s	North Carolina Museum of Natural Sciences
 NCSU	s	North Carolina State University Collections
 NCTC	c	National Collection of Type Cultures
@@ -4261,6 +4533,7 @@ NDTC	s	Ningde Teachers College, Biology Department
 NE	s	University of New England
 NEB	s	University of Nebraska State Museum
 NEBC	s	Harvard University
+NEBK	h	University of Nebraska at Kearney
 NEFI	s	Northeastern Forestry University, Forestry Department
 NEM	c	Faculte de Medecine Necker-Enfants Malades
 NEMO	s	Truman State University
@@ -4270,6 +4543,7 @@ NENU	s	Northeast Normal University, Biology Department
 NEPCC	c	North East Pacific Culture Collection
 NESH	s	University of Nevada
 NEU	s	Universite de Neuchatel, Laboratoire de botanique evolutive
+NEUN	h	Near East University
 NEW	s	University of Newcastle
 NEWHM	s	Hancock Museum
 NEZ	s	Museum, Zoology Department, University of New England
@@ -4283,14 +4557,18 @@ NFRC	s	Northern Forest Research Centre
 NFRDI	c	National Fisheries Research & Development Institute
 NFRI	c	Norwegian Forest Research Institute
 NFRN	s	Canadian Forest Service, NRCan
+NGBB	h	Nezahat Gokyigit Botanik Bahcesi
+NGCPR	h	Naoroji Godrej Centre for Plant Research
 NGI	s	Nanjing Geographical Institute
 NGM	s	Bromley House Library
 NGMC	s	National Geological Museum of China
 NGR	c	Plant Pathology
 NH	s	South African National Biodiversity Institute
 NHA	s	University of New Hampshire, Plant Biology Department
+NHCP	h	National Bureau of Plant Genetic Resources
 NHES	s	Connecticut Agricultural Experiment Station, Entomology Department
 NHG	s	Naturhistorische Gesellschaft e. V., Abteilung Botanik
+NHI	h	Natural History Institute
 NHIC	s	Ontario Ministry of Natural Resources
 NHL	c	National Institute of Hygienic Sciences
 NHM<CHE>	s	Naturhistorisches Museum, Bern
@@ -4302,6 +4580,7 @@ NHMBe	s	Naturhistorisches Museum Bern
 NHMC<GRC>	s	Natural History Museum of Crete, University of Crete, Department of Botany
 NHMC<MMR>	s	Natural History Museum, Rangoon
 NHME	s	Natuurhistorisch Museum
+NHMF	h	Natural History Museum Fribourg
 NHMG<CHN>	s	Natural History Museum of Guangxi
 NHMG<SWE>	s	Goteborgs Naturhistoriska Museet
 NHMK	s	Landesmuseum fuer Karnten
@@ -4312,11 +4591,14 @@ NHMN	s	Nottingham Natural History Museum (Wollaton Hall)
 NHMR<HRV>	s	Natural History Museum Rijeka
 NHMR<ISL>	s	Natural History Museum, Reykjavik
 NHMR<NLD>	s	Natuurhistorisch Museum
-NHMUK	s	Natural History Museum, London
+NHMS	h	Natural History Museum Split
+NHMTU	s	Natural History Museum, Tribhuvan University
+NHMUK	sb	Natural History Museum, London
 NHMUK<PAK>	s	Natural History Museum, Karachi
 NHMW	s	Naturhistorisches Museum, Wien
 NHNC	s	La Chaux-de-Fons
 NHNE	s	New England College, Biology Department
+NHR	h	Institute of Scientific and Technological Research (IRST)
 NHRI	s	Islandic Museum of Natural History
 NHRM	s	Naturhistoriska Rijkmuseet
 NHRS	s	Swedish Museum of Natural History, Entomology Collections
@@ -4344,6 +4626,9 @@ NIFRS	s	National Research Institute of Fisheries Science
 NIG	s	Nanjing Geographical Institute
 NIGL	s	Nanjing Institute of Geography and Limnology
 NIGP	s	Naking Institute of Geology and Palaeontology
+NIHHS	h	National Institute of Horticultural and Herbal Science, RDA
+NIM	h	Museum d'histoire naturelle de Nimes
+NIMM	h	National Institute of Medicinal Materials
 NINF	s	Newfoundland Insectarium
 NIO	s	National Institute of Oceanography
 NIOCC	c	National Institute of Oceanography Culture Collection
@@ -4381,6 +4666,7 @@ NMBA<AUT>	s	Naturhistorisches Museum der Benediktiner-Abtei
 NMBA<CHE>	s	Naturhistorisches Museum, Basel
 NMBE	s	Naturhistorisches Museum der Burgergemeinde Bern
 NMBO	s	National Museum, Bloemfontein
+NMBT	h	Natuurmuseum Brabant
 NMBZ	s	Natural History Museum of Zimbabwe
 NMC	s	New Mexico State University, Department of Biology
 NMC<CAN>	s	Canadian Museum of Nature
@@ -4421,6 +4707,7 @@ NMND	s	National Museum of Natural History, New Delhi
 NMNH<IND>	s	National Museum of Natural History, New Delhi
 NMNHI	s	National Museum of Natural History, New Delhi
 NMNK	s	National Museum of Nepal
+NMNL	h	Natuurmuseum Nijmegen e.o.
 NMNS	s	National Museum of Natural Science
 NMNW	s	National Museum of Namibia
 NMNZ	s	National Museum of New Zealand
@@ -4444,6 +4731,7 @@ NMPG<CHN>	s	Zhejiang Institute of Traditional Chinese Medicine
 NMPG<DEU>	s	Museum der Natur-Gotha
 NMPI	s	Division of Plant Industry
 NMQR	s	National Museum, Bloemfontein
+NMR	h	Semyung University
 NMRC<USA-MD>	c	Naval Medical Research Center
 NMRC<USA-MD>:RDD	c	Naval Medical Research Center, Rickettsial Diseases Division
 NMS	s	National Museums of Scotland
@@ -4523,6 +4811,7 @@ NPS	s	United States National Park Service
 NPSC	s	Northern Prairie Science Center
 NPT	s	Newport Museum and Art Gallery
 NPWRC	s	Northern Prairie Research Center
+NR	h	Institute of Forest Ecology Slovak Academy of Sciences
 NRC	c	Division of Biological Sciences, National Research Council of Canada
 NRC<EGY>	s	National Research Centre
 NRCC	s	National Research Council of Canada
@@ -4535,6 +4824,9 @@ NRN	s	Nairn Literary Society Library, Public Library
 NRNZ	s	Northland Regional Museum
 NRPSU	c	Department of Agro-industry, Faculty of Natural Resources
 NRRL	c	Agricultural Research Service Culture Collection
+NRRL:MOLD	sc	Agricultural Research Service Culture Collection, 
+NRRL:PROK	sc	Agricultural Research Service Culture Collection, 
+NRRL:YEAST	sc	Agricultural Research Service Culture Collection, 
 NRS	s	Naturhistoriska Riksmuseet
 NRWC	s	N. R. Whitney Collection
 NRZM	c	German Reference Center for Meningococci
@@ -4633,6 +4925,7 @@ OAKL	s	Oakland Museum of California, Natural Sciences Department
 OAMB	s	Open Air Museum of Ethnography and Natural Sciences
 OAX	s	Instituto Politecnico Nacional (CIIDIR-Oax., I.P.N.)
 OAXM	s	Centro Interdisciplinario de Estudios, Coleccion Mastozoologica (Mexico)
+OB	h	Station Umwelt- und Natur Oberhausen
 OBG<OMN>	s	The Oman Botanic Garden
 OBI	s	California Polytechnic State University, Biological Sciences Department
 OBPF	s	Planting Fields Arboretum State Historic Park
@@ -4642,6 +4935,7 @@ OCLA	s	University of Science and Arts of Oklahoma
 OCM	c	Oregon Collection of Methanogens
 OCNF	s	Ochoco National Forest
 OCSA	s	Veterinary Research Institute
+OCU	h	Oklahoma City University
 ODAC	s	Oregon Department of Agriculture
 ODU	s	Old Dominion University, Department of Biological Sciences
 OFC	s	Orielton Field Centre
@@ -4651,6 +4945,7 @@ OGL:OGR	b	Ocean Genome Legacy, Ocean Genome Resource
 OGU	s	Odesskij Gosudarstvennij Universitet
 OH	s	Agricultural Museum of Praha
 OHBR	s	Ontario Hydro
+OHHI	h	Orel State University
 OHM	s	Oldham Microscopical and Natural History Society
 OHN	s	Regionherbariet i Oskarshamn
 OHSC	s	Ohio Historical Society
@@ -4667,8 +4962,10 @@ OLE	s	Oundle School, Biology Department
 OLM	s	Vlastivedne muzeum v Olomouci
 OLML	s	Oberoesterreichisches Landesmuseum
 OLP	s	Univerzity Palackeho, Katedra biologie
+OLS	h	University of Warmia and Mazury
 OLTC	s	Teachers Training College, Botany Department
 OLV	s	Olivet College, Biology Department
+OLYM	h	Olympic National Park
 OM	s	Otago Museum
 OMA	s	University of Nebraska Omaha, Biology Department
 OMC<NZL>	s	Catalogues in Otago Museum
@@ -4685,6 +4982,7 @@ OMP	s	Polabske muzeum v Podebradech
 OMPB	s	Osservatorio per le Malattie delle Piante per la Regione Emilia-Romagna
 OMPG	s	Osservatorio per le Malattie delle Piante per le Province di Genova e La Spezia
 OMPS	s	Osservatorio per le Malattie delle Piante per la Sardegna
+OMSK	h	Omsk Pedagogical Univeristy
 OMSKM	s	Omsk State Agrarian University, Department of Forestry and Plant Conservation
 OMUB	s	Ondokuz Mayis University, Biology Department
 ON	s	Oman Natural History Museum
@@ -4724,6 +5022,7 @@ OSM<CZE>	s	Ostravske muzeum
 OSM<USA-OH>	s	Ohio State University Museum
 OSMC	s	St. Martin's College, Biology Department
 OSN	s	Museum am Schoelerberg, Natur und Umwelt
+OSTR	h	University of Ostrava
 OSU<USA-OH>	s	Ohio State University
 OSU<USA-OK>	s	Oklahoma State University, Collection of Vertebrates
 OSUC	s	Oregon State University
@@ -4732,6 +5031,7 @@ OSUFW	s	Oregon State University, Department of Fisheries and Wildlife Mammal Col
 OSUMZ	s	Ohio State University, Museum of Biological Diversity
 OSUO	s	Oregon State University, School of Oceanography
 OSUS	s	Oklahoma State University
+OSW	h	State University of New York at Oswego
 OSWY	s	Oswestry Museum
 OTA	s	University of Otago, Botany Department
 OTF	s	Canadian Forest Service
@@ -4753,6 +5053,7 @@ OXD	s	Wadham College
 OXF	s	University of Oxford, Department of Plant Sciences
 OXM	s	Magdalen College Library
 P	s	Herbier National de Paris
+PA	h	Universidade Federal do Oeste do Para
 PAC	s	Pennsylvania State University, Biology Department
 PACA	s	Instituto Anchietano de Pesquisas/UNISINOS
 PACMA	s	Pennsylvania State University, Biology Department
@@ -4765,6 +5066,7 @@ PAM	s	Pennsylvania Department of Agriculture
 PAMC	c	Polar and Alpine Microbial Collection
 PAMG	s	Empresa de Pesquisa Agropecuaria de Minas Gerais (EPAMIG), Departamento de Pesquisa
 PAMP	s	Universidad de Navarra, Departamento de Botanica
+PAMUH	h	Pamukkale University
 PAN	s	Panjab University, Botany Department
 PAP	s	Musee de Tahiti et des Iles
 PAR	s	Museo de Ciencias Naturales y Antropologicas Prof. Antonio Serrano, Departamento de Botanica
@@ -4780,6 +5082,7 @@ PAUMC	s	Pan American University, Mammal Collection
 PAUP	s	Punjab Agricultural University
 PAV	s	Universita di Pavia, Dipartimento de Ecologia del Territorio
 PAY	s	Paisley Philosophical Institute
+PBB	h	Research Center for the Conservation of Natural Resources University and Phu An Botanic Gardens
 PBC<USA-HI>	c	Pacific Bacterial Collection
 PBF	c	Perum Bio Farma
 PBH	s	Peterborough City Museum
@@ -4790,6 +5093,7 @@ PBS	s	Chambers Institute, Tweeddale Museum
 PBZT	s	Parc Botanique et Zoologique de Tsimbazaza
 PC	s	Museum National d'Histoire Naturelle
 PCC	c	Pasteur Culture Collection of Cyanobacteria
+PCE	h	Hugh Nicholson and Tony Abbott Herbarium
 PCH	s	Prestwich and Pilkington Botanical Society
 PCM<IND>	s	Presidency College, Botany Department
 PCM<POL>	c	Polish Collection of Microorganisms
@@ -4814,6 +5118,7 @@ PEM<CHN>	s	Beijing Medical University, Botany Department
 PEM<ZAF>	s	Port Elizabeth Museum
 PEN	s	Penrith Museum
 PENN	s	University of Pennsylvania Herbarium
+PER	h	City Museum
 PERM	s	University of Perm, Botany Department
 PERTH	s	Western Australian Herbarium
 PERU	s	Universita di Perugia, Dipartimento di Biologia Vegetale
@@ -4830,6 +5135,7 @@ PFI	s	Percy FitzPatrick Institute of African Ornithology
 PFRA	s	Tree Nursery
 PFRS	s	Pacific Southwest Forest and Range Experiment Station
 PFSS	s	Petrified Forest National Park
+PG	h	Plant Gateway
 PGC	c	Peterhof Genetic Collection of Microalgae
 PGFA	s	Pyatigorsk State Pharmaceutical Academy, Botany Department
 PGL	s	Preussiche Geologische Landesanstalt
@@ -4841,13 +5147,18 @@ PGRC<CAN>:CN	b	Plant Gene Resources of Canada, Canadian National Plant Germplasm
 PGSC<USA-NC>	c	Pseudomonas Genetic Stock Center
 PH	s	Academy of Natural Sciences, Botany Department
 PHA	s	Pharmaceutical Society of Great Britain
+PHARM	h	Southern Cross University
 PHBL	c	Philip Harris Biological Ltd.
 PHEL	s	Plant Health and Environment Laboratory
+PHEO	h	Karadag Natural Reserve
 PHG	s	Peper Harow
+PHH	h	University of Science,Ho Chi Minh City Vietnam National University
 PHIL	s	University of the Sciences in Philadelphia, Biological Sciences Department
 PI<DEU>	s	Institut und Museum fuer Geologie und Palaeontologie
 PI<ITA>	s	Universita di Pisa, Dipartimento di Scienze Botaniche
 PI<RUS>	s	Paleontological Institute
+PIAGR	h	University of Pisa
+PICRC	h	Palau International Coral Reef Center
 PIHG	s	Florida Department of Agriculture and Consumer Services
 PIHU	s	Paleontological Institut of Helsingfors
 PIKN	s	Koronivia Research Station
@@ -4862,8 +5173,12 @@ PIUU	s	Paleontological Institut, University of Uppsala
 PKDC	s	Divisao de Museu de Historia Natural
 PKM	s	V. G. Belinsk Pedagogical Institute of Penza
 PL	s	Zapadoceske muzeum
+PLAT	h	State University of New York, College at Plattsburgh
+PLES	h	Plyos State Museum
 PLFV	s	Principality of Liechtenstein
 PLH	s	Plymouth City Museum and Art Gallery
+PLP	h	Institute of Himalayan Bioresource Technology
+PLU	h	Pacific Lutheran University
 PLY	sc	Plymouth Institution and Athenaeum
 PLYMOUTH	c	Plymouth Culture Collection
 PLYP	s	University of Plymouth, Department of Biological Sciences
@@ -4905,6 +5220,7 @@ PMU<SWE>	s	Paleontological Museum of Uppsala
 PMV	s	Provincial Museum
 PNBG	s	University of the Philippines
 PNCM-BIOTECH	c	Philippine National Collection of Microorganisms
+PND	h	Dr. Shivaram Karantha  Pilikula Nisarga Dhama
 PNG	s	Division of Primary Industry
 PNGM	s	National Museum and Art Gallery, Port Moresby
 PNH	s	Philippine National Herbarium
@@ -4931,6 +5247,7 @@ POZG	s	Adam Mickiewicz University, Department of Geobotany
 POZM	s	Adam Mickiewicz University, Department of Plant Ecology and Environment Protection
 POZNB	s	Agricultural Academy, Botany Department
 POZW	s	Adam Mickiewicz University
+PPC	h	Palawan State University
 PPCC<AUS>	c	Plant Pathology Culture Collection
 PPCC<NZL>	s	Plant Protection Centre Collection
 PPCD	s	West Virginia Department of Agriculture
@@ -4950,10 +5267,12 @@ PPKU6	c	Department of Plant Pathology, Faculty of Agriculture, Thailand
 PPL	s	Agricultural Development and Advisory Service, Harpenden Laboratory
 PPNP	s	Point Pelee National Park
 PPPO	s	Pusat Penelitian dan Pengembangan Oseanologi
-PPPPB	c	South African Plant Pathogenic and Plant Protecting Bacteria
+PPPPB	c	ARC-Plant Protection Research Institute, Plant Pathogenic and Plant Protecting Bacteria
 PPRI	c	ARC-Plant Protection Research Institute, National Collection of Fungi: Culture Collection
+PPRL	h	USDA-ARS Poisonous Plant Research Lab
 PPRZ	s	Plant Protection Research Institute
 PPSIO	s	P. P. Shirshov Institute of Oceanology
+PPU	h	Perm State Teacher Training University
 PQFC	b	Phu Qui's Fruit Tree Center-Vietnam
 PR	s	National Museum in Prague, Department of Botany
 PRA	s	Institute of Botany, Academy of Sciences
@@ -4973,6 +5292,7 @@ PRU	s	University of Pretoria, Botany Department
 PRV	s	Porvoo Museum of Natural History
 PSAE	s	Alberta Environmental Centre
 PSGB	s	University of Bradford, Pharmacy Department
+PSK	h	Pskov State University
 PSM	s	University of Puget Sound, James R. Slater Museum of Natural History
 PSO	s	Universidad de Narino
 PSP	s	Parasitic Seed Plants
@@ -5012,6 +5332,7 @@ PUR	s	Purdue University, Department of Botany and Plant Pathology
 PURC	s	Purdue University
 PUS	s	Puslinch House
 PUSC	s	University of Southern Colorado, Life Sciences Department
+PVB	h	Institute of Ecology of the Volga River Basin, Russian Academy of Science
 PVF	c	Pusat Veterinaria Farma
 PVGB	c	Plant Virus GenBank
 PVHR	s	Universite Paris VI
@@ -5021,6 +5342,7 @@ PVPH	s	Paleontolga de Vertebrados
 PVSJ	s	Museo do Ciencias Naturles
 PW	s	Paleontological Collections
 PWRC	s	Patuxent Wildlife Research Center
+PWU	h	V.G.Korolenko Poltava National Pedagogical University
 PY	s	Centro de Estudios y Colecciones Biologicas para la Conservacion
 PYCC	c	Portuguese Yeast Culture Collection
 PYU	s	Yunnan University, Laboratory of Pteridophyta
@@ -5085,6 +5407,7 @@ RAME	s	Royal Albert Memorial Museum
 RAMK	s	Ramkhamhaeng University, Biology Department
 RAMM	s	Royal Albert Memorial Museum, Leisure and Tourism Department
 RANG	s	Yangon University
+RANK	h	Research Center of Agriculture and Natural Resources of Kermanshah province
 RARS	s	Regina Research Station
 RAS	s	Union of Burma Applied Research Institute, Pharmaceutical Department
 RAU	s	Laboratoire de Biologie Vegetale
@@ -5110,13 +5433,16 @@ RCN	s	Richmond Naturalists' Field Club
 RCR	s	Rochester Public Museum
 RCS	s	Royal College of Surgeons
 RCSL	s	Royal College of Surgeons
+RCVC	h	Universidad Nacional de Rio Cuarto
 RDAF	s	Research Department South East Asian Fisheries Development Centre
 RDG	s	Reading Museum and Archive Service
 RDS	s	Royal Dublin Society
 RE	s	Liaoning Reed Science Institute
 RED	s	University of Redlands, Biology Department
 REDM	s	Reading Museum and Archive Service
+REED	h	Reed College
 REG	s	Universitaet Regensburg, Regensburgische Botanische Gesellschaft
+REGGIO	h	Universita Mediterranea di Reggio Calabria
 RELC	s	INIFAP-SAGAR
 REN	s	Campus Scientifique de Beaulieu, Laboratoire de Botanique
 RENO	s	University of Nevada, Environmental and Resource Sciences Department
@@ -5126,11 +5452,13 @@ RESC	s	Shasta College
 REU	s	Universite de la Reunion
 RFA	s	Universidade Federal do Rio de Janeiro, Departamento de Botanica
 RFE	s	Radcliffe Literary and Scientific Society Museum
+RFFP	h	Universidade do Estado do Rio de Janeiro
 RFNS	s	Rochdale Field Naturalists' Society
 RGM	s	Nationaal Natuurhistorisch Museum Leiden
 RGMC	s	Musee Royal de l'Afrique Centrale
 RGY	s	Rugby School Natural History Society Museum
 Rh-EF	s	Museum of Grannat
+RHK	h	St. Berchmans College
 RHLCY	s	Reservoir of Heilongtan
 RHM	s	Public Reference Library
 RHMC	s	Red House Museum
@@ -5160,6 +5488,7 @@ RIVE<SVK>	c	Research Institute for Viticulture and Enology
 RIVE<USA-WI>	s	University of Wisconsin, Biology Department
 RIY	s	National Agriculture and Water Research Center
 RIZ	s	Instituto de Zootecnia
+RKT	h	Regional Research Institute (Ayurveda)
 RLS	s	Royal Latin School
 RM<CAN>	s	McGill University, Redpath Museum
 RM<NZL>	c	Rumen Microorganisms
@@ -5172,25 +5501,26 @@ RMCA	s	Royal Museum for Central Africa
 RMDRC	s	Rocky Mountain Dinosaur Resource Center
 RMF	c	Rocky Mountain Herbarium, Fungi
 RMFM	s	Richmond Marine Fossils Museum
-RMNH	s	Nationaal Natuurhistorisch Museum
-RMNH:ACA	s	Nationaal Natuurhistorisch Museum, Acari collection
-RMNH:AVES	s	Nationaal Natuurhistorisch Museum, bird collection
-RMNH:BRA	s	Nationaal Natuurhistorisch Museum, brachiopod collection
-RMNH:BRY	s	Nationaal Natuurhistorisch Museum, bryozoan collection
-RMNH:COEL	s	Nationaal Natuurhistorisch Museum, Coelomate collection
-RMNH:CRUS	s	Nationaal Natuurhistorisch Museum, crustacean collection
-RMNH:CRUS.D	s	Nationaal Natuurhistorisch Museum, decapod collection
-RMNH:INS	s	Nationaal Natuurhistorisch Museum, Insect collection
-RMNH:MAM	s	Nationaal Natuurhistorisch Museum, Mammal collection
-RMNH:MOL	s	Nationaal Natuurhistorisch Museum, mollusc collection
-RMNH:PISC	s	Nationaal Natuurhistorisch Museum, fish collection
-RMNH:POR	s	Nationaal Natuurhistorisch Museum, poriferan collection
+RMNH	s	Naturalis Biodiversity Center
+RMNH:ACA	s	Naturalis Biodiversity Center, Acari collection
+RMNH:AVES	s	Naturalis Biodiversity Center, bird collection
+RMNH:BRA	s	Naturalis Biodiversity Center, brachiopod collection
+RMNH:BRY	s	Naturalis Biodiversity Center, bryozoan collection
+RMNH:COEL	s	Naturalis Biodiversity Center, Coelomate collection
+RMNH:CRUS	s	Naturalis Biodiversity Center, crustacean collection
+RMNH:CRUS.D	s	Naturalis Biodiversity Center, decapod collection
+RMNH:INS	s	Naturalis Biodiversity Center, Insect collection
+RMNH:MAM	s	Naturalis Biodiversity Center, Mammal collection
+RMNH:MOL	s	Naturalis Biodiversity Center, mollusc collection
+RMNH:PISC	s	Naturalis Biodiversity Center, fish collection
+RMNH:POR	s	Naturalis Biodiversity Center, poriferan collection
 RMNHD	s	Naturalis Biodiversity Center
 RMNP	s	Riding Mountain National Park
 RMRC	b	Regional Medical Research Centre
 RMS	s	University of Wyoming Herbarium
 RMSC	s	Rocky Mountain Forest and Range Experiment Station
 RMSCC	c	Roche Molecular Systems Culture Collection
+RMTV	h	University of Rome Tor Vergata
 RMWC	s	Randolph-Macon Woman's College, Biology Department
 RNG	s	University of Reading
 RNMUT	s	Republic Nature Museum of Uzbekistan
@@ -5209,6 +5539,7 @@ ROM:ORN	s	Royal Ontario Museum, Ornithology Collection
 ROME	s	Royal Ontario Museum, Entomology Collection
 ROML	s	National University of Lesotho, Biology Department
 ROMO	s	Rocky Mountain National Park
+RON	h	Universidade Federal de Rondonia
 ROO	s	Agricultural Research Council-Range and Forage Institute
 ROPA	s	Sonoma State University, Biology Department
 ROPV	s	Istituto Sperimentale per la Patologia Vegetale
@@ -5234,6 +5565,7 @@ RSDR	s	Desert Institute, Turkmenistan Academy of Sciences
 RSKK	c	Refik Saydam National Type Culture Collection-RSKK
 RSM<CAN>	s	Royal Saskatchewan Museum
 RSM<GBR>	s	Royal Scottish Museum
+RSU	h	Ryazan State University
 RSY	s	Buteshire Natural History Society, The Museum
 RTE	s	Holmesdale Natural History Club Museum
 RTHM	s	Munidipal Museum and Art Gallery
@@ -5247,6 +5579,7 @@ RUHV	s	Radford University, Biology Department
 RUIC	s	Rutgers University
 RUMF	s	University Museum, University of the Ryukyus
 RUNYON	s	Robert Runyon Herbarium
+RUPP	h	Royal University of Phnom Penh
 RUSI	s	J.L.B. Smith Institute of Ichthyology (formerly of Rhodes University)
 RUSU	s	Universidade Santa Ursula
 RUT	s	Douglass College, Rutgers University, Biological Sciences Department
@@ -5273,9 +5606,11 @@ SACL	s	Santa Clara University, Biology Department
 SACON	s	Salim Ali Centre for Ornithology and Natural History
 SACS	s	Shenyang Agricultural College
 SACT	s	California State University, Biological Sciences Department
+SAF	h	Department of Agricultural and Forest Sciences
 SAFB	s	University of Saskatchewan, Forestry Department
 SAFU	s	University of San Francisco
 SAG	c	Sammlung von Algenkulturen at Universitat Gottingen
+SAG<CHL>	c	Coleccion de Micoligica Laboratorio Regional, Servicio Agricola y Ganadero
 SAIAB	sb	South African Institute of Aquatic Biodiversity
 SAIM	s	South African Institute for Medical Research
 SAIMR	s	South African Institute for Medical Research
@@ -5291,6 +5626,7 @@ SALLE	s	Instituto Geobiologico La Salle
 SAM<ZAF>	s	South African Museum
 SAMA	sb	South Australian Museum
 SAMC	s	Iziko Museum of Capetown
+SAMF	h	Samford University
 SAMU	s	Savaria Museum, Department of Natural History
 SAN	s	Forest Research Centre, Forest Department
 SANBI	s	South African National Biodiversity Institute
@@ -5305,9 +5641,11 @@ SAP	s	Herbarium of Graduate School of Science, Hokkaido University
 SAPA	s	Hokkaido University Museum (Fungal collection)
 SAPCL	s	St. Andrews Presbyterian College, Biology Department
 SAPS	s	Hokkaido University Museum (Plant collection)
+SAPT	h	Hokkaido University Botanic Garden
 SAR	s	Department of Forestry
 SARA	s	Zemaljski Muzej Bosne I. Herzegovine
 SARAT	s	Department of Morphology and Systematic Botany
+SARBG	h	Saratov State University Botanical Garden
 SARC	s	Roanoke College, Biology Department
 SARI	s	Sakarya Agricultural Research Institute
 SAS	s	Sammlung Arnhardt des Museums Schloss Wilhelmsburg Schmalkalden
@@ -5351,9 +5689,11 @@ SCARB	s	Boys' High School
 SCB	s	Station Centrale de Boukoko
 SCCAP	c	Scandinavian Culture Collection of Algae and Protozoa
 SCCBC	s	Selkirk College, Environmental Sciences and Technologies Department
+SCCN	h	Scott Christian College
 SCDH	s	South Carolina Department of Health and Environmental Control
 SCFI	s	Sichuan Academy of Forestry
 SCFQ	s	Service canadien de la faune
+SCFS	h	University of California-Berkeley, Sagehen Creek Field Station
 SCH	s	Museum zu Allerheiligen
 SCHG	s	George Museum
 SCHN	s	Smith College, Biological Sciences Department
@@ -5363,17 +5703,21 @@ SCM	s	Sheffield City Museums
 SCN	s	Sociedad de Ciencias Naturales "La Salle"
 SCNHM	s	Southwestern College, Natural History Museum
 SCNU	s	Sichuan Normal University, Biology Department
+SCP	h	Sociedad Cientifica del Paraguay
 SCPS	s	Scarborough Philosophical and Archaeological Society Museum
 SCR	s	Scripps Institution of Oceanography, Herbarium
 SCS	s	Agriculture and Agri-Food Canada, Semiarid Prairie
 SCSC	s	Saint Cloud State University
 SCSFRI	s	South China Sea Fisheries Research Institute
+SCSG	h	South China Sea Institute of Oceanology, Academia Sinica
 SCSIO	s	South China Sea Institute of Oceanology, Academia Sinica
 SCSM	s	South Carolina State Museum
 SCT	s	Friend's School
 SCTCC	c	Sichuan Type Culture Collection
 SCU	s	Shandong Christian University
 SCUF	s	Universidade Federal de Santa Catarina
+SCUI	h	Suez Canal University
+SCV	b	State Collection of Viruses
 SCZ	s	Smithsonian Tropical Research Institute
 SD	s	Herbarium, San Diego Natural History Museum
 SDAKS	s	South Dakota State University
@@ -5423,6 +5767,7 @@ SEMO	s	Southeast Missouri State University, Department of Biology
 SERC<USA-MD>	s	Smithsonian Environmental Research Center
 SERG	s	Institut de Recherche Agronomique de Guinee
 SERO	s	Sociedad para el Estudio de los Recursos Bioticos de Oaxaca
+SERTC	s	Southeastern Regional Taxonomic Center
 SES	s	Southeastern Shanxi Teachers School, Biochemistry Department
 SETON	s	Philmont Scout Ranch, Seton Memorial Library
 SEV	s	Universidad de Sevilla, Departamento de Biologia Vegetal y Ecologia
@@ -5456,6 +5801,7 @@ SGEL	s	Stalybridge Library
 SGGS	s	The Museum
 SGGW	s	Warsaw University of Life Sciences
 SGMA	s	Universidade Nova de Lisboa
+SGN	h	Southern Institute of Ecology
 SGO	s	Herbario, Museo Nacional de Historia Natural, Santiago
 SGSC	c	Salmonella Genetic Stock Centre
 SGWG	s	Sammlung der Sektion Geologische Wissenschaften der Ernst-Moritz-Arndt University
@@ -5493,6 +5839,7 @@ SIAC<CHN>	s	Sichuan Institute of Agriculture
 SIAC<ITA>	s	Accademia dei Fisiocritici Onlus
 SIB	s	Sibiu Natural History Museum
 SIBAC	s	Southwest Institute of Biology
+SIBS	h	Institute of Biology of the Southern Seas
 SICH	s	Simpson College, Biology and Environmental Sciences Department
 SIEMEA	s	Severtsov Insitute for Evolutionary Morphology and Animal Ecology
 SIENA	s	Universita di Siena, Dipartimento di Scienze Ambientali "G. Sarfatti"
@@ -5551,6 +5898,7 @@ SLTC	s	Teachers College, Botany Department
 SLU<CAN>	s	Laurentian University, Biology Department
 SLU<USA-LA>	s	Southeastern Louisiana University, Vertebrate Museum
 SLUB	s	St. Louis University Museum
+SLUBGH	h	Shah Abdul Latif University
 SLUM	s	Saint Louis University Museum Ichthylogy Collection
 SM<CHN>	s	Chongqing Municipal Academy of Chinese Materia Medica
 SM<DEU-Frankfurt>	s	Senckenberg Museum
@@ -5598,6 +5946,7 @@ SMRG	c	Soil Microbiology Research Group, Division of Soil Science, Department of
 SMRS	s	Stavropol Museum of Regional Studies
 SMS	s	Missouri State University, Department of Biology
 SMSM	s	Sarawak Museum
+SMTP	s	Swedish Malaise Trap Project
 SMTWA	c	School of Medical Technology Western Australia
 SMU	s	St. Mary's University
 SMU<KOR>	s	Sangmiung University
@@ -5619,6 +5968,7 @@ SNMB	s	Staatliches Naturhistorisches Museum
 SNMBR	s	Staatliches Naturhistorisches Museum in Braunschweig
 SNMC	s	Slovenske Narodne Muzeum
 SNMG	s	Staatliches Museum fuer Naturkunde
+SNMH	h	Sree Narayana Mangalam College
 SNMNH	s	Saudi Arabian National Museum of Natural History
 SNOMNH	s	Sam Nobel Oklahoma Museum of Natural History
 SNP<MYS>	s	Sabah Parks, Botany Section
@@ -5632,6 +5982,7 @@ SO	s	Sofia University "St. Kliment Ohridski", Botany Department
 SOA	s	Agricultural University of Plovdiv, Botany Department
 SOB	s	Husite Museum Tabor
 SOC	s	Southern Oregon University, Biology Department
+SOF	h	Sofyivka National Dendrological Park
 SOFM	s	National Museum of Natural History, Sofia
 SOFRI	b	Southern Fruit Research Institute  Vietnam
 SOGS	s	Pal. Coll, Sokoto State Government Palaeontological Collection
@@ -5639,6 +5990,7 @@ SOIC	s	Natural History Museum, National Insect Collection
 SOKO	s	Okresni muzeum Sokolov (Regional Muzeum), Botany Department
 SOM	s	Bulgarian Academy of Sciences
 SOMF	s	Bulgarian Academy of Sciences
+SORO	h	Universidade Federal de Sao Carlos, campus Sorocaba
 SOSCMVNH	s	Southern Oregon State College, Museum of Vertebrate Natural History
 SOSN	s	Silesian Medical School in Katowice, Department of Pharmaceutical Botany
 SOSSRC	s	Save Our Seas Shark Research Center, Nova Southeastern University
@@ -5665,10 +6017,13 @@ SPNRI	s	Sichuan Province, Natural Resources Institute
 SPR	s	Springfield Science Museum, Natural Science Department
 SPRY	s	Burton Constable Foundation
 SPSF	s	Instituto Florestal
+SPSU	h	St. Petersburg State University
 SPT	s	Botanic Gardens Museum
 SPTS	s	Southport Scientific Society
 SPWH	s	Marine Biological Laboratory
+SQB	h	Societe quebecoise de bryologie
 SQF	s	Universidad de Chile, Laboratorio de Botanica, Escuela de Quimica y Farmacia
+SQUH	h	Sultan Qaboos University
 SR	s	Sichuan Institute of Natural Resources
 SRAICC	c	SRAI's culture collection
 SRCG	s	Baylor University
@@ -5681,6 +6036,7 @@ SRNP	s	Insects of the Area Conservacion Guanacaste, northwestern Costa Rica
 SRP	s	Boise State University, Biology Department
 SRR	s	Koninklijke Shell (Shell Research N.V.)
 SRRC	c	Southern Regional Research Center, Agricultural Research Service, United States Department of Agriculture
+SRS	h	Universidade do Sul de Santa Catarina
 SRSC	s	Sul Ross State University, Department of Biology
 SRSU	s	Sul Ross State University
 SS	s	Universita di Sassari, Dipartimento di Botanica ed Ecologia Vegetale
@@ -5729,10 +6085,12 @@ STM<DEU>	s	Stettinger Museum
 STM<FRA>	c	Laboratoire des Symbioses Tropicales et Mediterraneennes
 STM<GBR>	s	Streatham Antiquarian and Natural History Society
 STMC	s	School of Tropical Medicine
+STNF	h	Shasta-Trinity National Forest
 STO	s	The Potteries Museum & Art Gallery
 STP	s	La Societe Guernesiaise, Priaulx Library
 STPCM	s	Island Museum, Candie Gardens
 STPE	s	Florida Marine Research Institute, Florida Department of Environmental Protection
+STPH	h	Direccao Geral do Ambiente, Cabinet of Environment, Ministry of Natural Resources and Environment
 STPS	s	St. Paul's School
 STR	s	Institut de Botanique
 STRI	sc	Smithsonian Tropical Research Institute
@@ -5753,6 +6111,8 @@ SUCO	s	State University of New York, College at Oneonta, Biology Department
 SUD	s	Stroud and District Museum
 SUEL	s	Natural History Museum of Bakony Mountains
 SUF	s	Shimonoseki University of Fisheries
+SUFA	h	Sulaimania University
+SUFAF	h	Siirt University Flora and Fauna Center
 SUHC	s	Salisbury University, Department of Biology
 SUK	s	Shivaji University Kolhapur
 SUM<CZE>	s	Okresni vlastivedne muzeum v Sumperku
@@ -5762,6 +6122,8 @@ SUND	s	Sunderland Natural History and Antiquarian Society
 SUNIV	s	University of Stockholm
 SUNY	s	State University of New York
 SUNYO	s	State University of New York at Oneonta
+SURCO	h	Universidad Surcolombiana
+SUU	h	Southern Utah University
 SUVA	s	University of the South Pacific
 SUVM	s	Shippensburg University, Vertebrate Museum
 SUWS	s	University of Wisconsin-Superior, Department of Biology and Earth Science
@@ -5770,8 +6132,10 @@ SVCK	c	Sammlung von Conjugaten Kulturen
 SVER	s	Institute of Plant and Animal Ecology, Laboratory of Plant Ecology and Geobotany
 SVG	s	Arkeologisk museum i Stavanger
 SVIEC	c	Secao de Virus
+SVUTY	h	Sri Venkateswara University
 SVVC	s	Seminario Vescovile
 SWA	s	Swansea Museum
+SWAT	h	University of Swat Pakistan
 SWAU	s	Southwest Agricultural University, Horticulture Department
 SWBR	s	Sweet Briar College, Biology Department
 SWC<GBR>	s	Sammlung des Cambridge, University of Zoology
@@ -5781,6 +6145,7 @@ SWE	s	Chandos House, Stowe School
 SWF	s	Florida Gulf Coast University
 SWFC	s	Southwest Forestry College
 SWFSC	s	Southwest Fisheries Science Center
+SWGC	h	Grenfell Campus, Memorial University of Newfoundland
 SWIBASC	s	Academia Sinica
 SWMT	s	Rhodes College, Biology Department
 SWN	s	Saffron Walden Museum
@@ -5789,9 +6154,11 @@ SWRS	s	Southwestern Research Station
 SWSL	s	USDA/ARS, Southern Weed Science Research Unit
 SWT	s	Southwest Texas State University, Department of Biology
 SWTN	s	Swinton and Pendlebury Botanical Society
+SWU	h	Sungshin Women's University
 SWU2	c	Department of Biology, Faculty of Science
 SXAU	s	Shanxi Agricultural University, Forestry Department
 SXDC	s	Shaanxi Institute for Drug Control
+SXIM	h	Shaanxi Institute of Microbiology
 SXMP	s	Shaanxi Academy of Traditional Chinese Medicine and Pharmacology
 SXU	s	Shanxi University, Biology Department
 SY	s	Shenyang Municipal Academy of Landscape Gardening
@@ -5805,11 +6172,13 @@ SYR	s	Syracuse University, Plant Sciences Department
 SYRF	s	State University of New York
 SYS	s	Sun Yatsen University, Biology Department
 SYS:Z	s	Sun Yatsen University, Biology Department, Zoology Collection
+SYSBM	s	The Museum of Biology Sun Yat-sen University
 SYSU	s	National Sun Yat-Sen University, Department of Biological Sciences
 SYT	s	Stonyhurst College
 SZ	s	Sichuan University, Biological Department
 SZB	s	Haus der Natur
 SZCU	s	Department of Systematic Zoology
+SZCZ	h	University of Szczecin
 SZE<HUN>	s	Mora Ferenc Museum, Natural Science Department
 SZE<TUR>	s	Zoology Department, Aegean University, Science Faculty
 SZG	s	Shenzhen Fairy Lake Botanical Garden
@@ -5820,6 +6189,7 @@ SZMN	s	Siberian Zoological Museum
 SZPT	s	Shenzhen Polytechnic
 SZPT:ENT	s	Shenzhen Polytechnic, Entomology Collection
 SZU	s	University of Salzburg, Department of Organismic Biology
+SZUB	h	University of Szczecin
 T	s	Tavera, Department of Geology and Geophysics
 TA	s	Timescale Adventures Research and Interpretive Center
 TAA	s	Estonian Agricultural University, Institute of Agricultural and Environmental Sciences
@@ -5830,10 +6200,12 @@ TAES	s	Texas A&M University, Department of Rangeland Ecology and Management
 TAFIRI	s	Tanzania Fisheries Research Institute
 TAI	s	National Taiwan University, Institute of Ecology and Evolutionary Biology
 TAIC	s	Texas A&M University-Kingsville, Department of Biology
+TAIE	h	Endemic Species Research Institute
 TAIF	s	Taiwan Forestry Research Institute
 TAIM	s	Taiwan Museum
 TAIU	s	Texas A&M University - Kingsville, Texas A&I Collections
 TAK	s	Lenin State University
+TAL	h	Jardin botanique de Talence
 TALE	s	Laboratoire Geologique
 TALL	s	Tallinn Botanic Garden, Department of Environmental Education
 TAM	s	Estonian Museum of Natural History, Botany Department
@@ -5850,11 +6222,13 @@ TASM	s	Uzbek Academy of Sciences, Laboratory of Mycology
 TAU<GRC>	s	Aristotle University of Thessaloniki, Biology Department
 TAU<ISR>	s	Tel-Aviv University
 TAUF	s	Aristotle University of Thessaloniki, Department of Forestry and Natural Environment
+TAWES	h	Maryland Department of Natural Resources
 TB	s	Tbilisi State University, Botany Department
 TBG<JPN>	b	Tsukuba Botanical Garden
 TBGT	s	Tropical Botanic Garden and Research Institute
 TBI	s	Georgian Academy of Sciences
 TBIP	s	Research Institute of Plant Protection
+TBPH	h	Iovel Kutateladze Institute of Pharmacochemistry
 TBY	s	Tenby Museum
 TCB	s	National Chung Hsing University, Botany Department
 TCC/USP	c	Trypanosomatid Culture Collection, University of Sao Paulo
@@ -5894,6 +6268,7 @@ TER	s	Indiana State University, Life Science Department
 TESC	s	The Evergreen State College
 TESRI	s	Taiwan Endemic Species Research Institute
 TEU	s	Teikyo University, Education Department
+TEUI	h	U.S. Forest Service Southwest Region, Terrestrial Ecological Unit Inventory
 TEX	s	University of Texas at Austin, Plant Resources Center
 TEXA	s	Blackland Experiment Station
 TF<JPN>	s	Forestry and Forest Products Research Institute
@@ -5911,6 +6286,7 @@ TFRI	s	Taiwan Fisheries Research Institute
 TGM	s	Janashia State Museum of Georgia
 TGPI	s	Tiraspolskij Gosudarstvennij Pedagogiceskij Institut
 TGRC	b	C.M. Rick Tomato Genetics Resource Center
+TGU	h	University of Montenegro
 TH	s	University of Tokyo
 THBC	s	Technische Hochschule
 THIB	s	Nicholls State University, Department of Biological Sciences
@@ -5968,6 +6344,7 @@ TMMC	s	Texas Memorial Museum
 TMNH	s	Tianjin Museum of Natural History
 TMP<FIN>	s	Tampere Museums
 TMP<ZAF>	s	Transvaal Museum
+TMRC	h	Shahid Beheshti University of Medical Sciences
 TMS	s	Toleco Museum of Health and Natural History
 TMSA	s	Transvaal Museum
 TMTC	s	Taiwan Provincial Museum
@@ -5994,8 +6371,10 @@ TOKE	s	Tokyo University of Education
 TOLI	s	Universidad del Tolima, Departamento de Biologia
 TOM	s	Istituto Missioni Consolata
 TOM<CAN>	c	Tomicus collection Canadian Forest Service
+TON	h	Ministry of Agriculture and Food, Forestry and Fisheries
 TONG	s	Tonghua Teachers College, Biology Department
 TOR	s	Torquay Museum
+TOU	h	University of Tours
 TOYA	s	Toyama Science Museum, Botany Department
 TPI	s	The Pirbright Institute
 TPI:ENT	s	The Pirbright Institute, Entomology collection
@@ -6014,6 +6393,7 @@ TRN	s	N. Copernicus University
 TRO	s	Royal Horticultural Society of Cornwall
 TROM	s	University of Tromsoe, Botanical Department
 TROY	s	Troy State University, Department of Biological and Environmental Sciences
+TRPM	h	Tottori Prefectural Museum
 TRT	s	Royal Ontario Museum, Department of Natural History
 TRTC	s	Royal Ontario Museum, Center for Biodiversity and Conservation Biology
 TRTE	s	Erindale College, University of Toronto, Department of Biology
@@ -6024,6 +6404,7 @@ TS	s	National University of Shandong, Biology Department
 TSB	s	Universita degli Studi di Trieste, Dipartimento di Biologia
 TSC	s	Tarleton State University, Tarleton State Collection
 TsGM	s	Central Geological Museum
+TSH	h	University of Tsukuba
 TSM	s	Erbario, Museo Civico di Storia Naturale, Trieste
 TSMHN	s	Teylers Strichtina Museum
 TsNIGRI	s	Tsentralny Nauchno-Issledovatelskii Geolgo-Razvedochni Muzei (Chernyshev's Central Museum of Geological Exploration)
@@ -6051,12 +6432,16 @@ TUB	s	Eberhard-Karls-Universitaet Tuebingen, Institut fuer Biologie I
 TUBSB	b	Tohoku University Brassica Seed Bank
 TUC	s	University of Arizona, Ecology and Evolutionary Biology Department
 TUCH	s	Tribhuvan University, Central Department of Botany
+TUCIM	c	TU Wien collection of industrial microorganisms
+TUCIM:	c	TU Wien collection of industrial microorganisms, 
+TUFC	s	Tottori University Fungal Culture Collection
 TUFIL	s	Tokyo University of Fisheries, Ichthyological Laboratory
 TUFT	s	Tufts University, Biology Department
 TUH	s	Tehran University, Department of Biology
 TULE	s	Tokyo University of Agriculture & Technology
 TULS	s	University of Tulsa
 TULV	s	Jardin Botanico Juan Maria Cespedes
+TUM	h	Technische Universitat Munchen
 TUMH	s	Tottori Fungus/Mushroom Resource and Research Center
 TUN	s	Universite de Tunis, Laboratoire de Biologie Vegetale
 TUNG	s	Tunghai University, Biology Department
@@ -6076,6 +6461,7 @@ TVY	s	Turvey Abbey
 TWC	s	Texas Wesleyan College, Museum of Zoology
 TWRA	s	Tennessee Wildlife Resources Agency
 TYF	s	Shangxi Forestry Institute
+TYM	h	Botanic Gardens of Toyama
 TZM	s	National Science Museum
 U	s	Nationaal Herbarium Nederland, Utrecht University branch
 UA<GRC>	s	Department of Historical Geology and Paleontology
@@ -6123,6 +6509,7 @@ UAMM	s	Universidad de los Andes
 UAMZ	s	University of Alberta Museum of Zoology
 UAMZC	s	University of Arkansas, Museum Zoological Collections
 UANL	s	Universidad Autonoma de Nuevo Leon
+UAPC	h	University of Alberta
 UARK	s	University of Arkansas
 UAS	s	Universidad Autonoma de Sinaloa
 UAS-B	s	University of Agricultural Sciences Bangalore
@@ -6143,6 +6530,7 @@ UBC:CTC	s	Beaty Biodiversity Museum, University of British Columbia, Cowan Tetra
 UBC:Fish	s	Beaty Biodiversity Museum, University of British Columbia, Fish Collection
 UBCC	c	University of Barcelona Culture Collection
 UBCZ	s	University of British Columbia, Spencer Entomological Museum
+UBDH	h	Universiti Brunei Darussalam
 UBJTL	s	Universidad Bogota Jorge Tadeo Lozano
 UBL	s	Universite du Benin
 UBOCC	c	Universite de Bretagne Occidentale
@@ -6166,6 +6554,7 @@ UCDBA	s	University of Chicago
 UCFC	s	University of Central Florida
 UCGC	s	University of Colorado, Geological Museum
 UCGE	c	Unit Cell of Genetic Engineering, Department of Biochemistry
+UCH	h	Universidad Autonoma de Chiriqui
 UCHT	s	University of Tennessee, Chattanooga, Department of Biological and Environmental Sciences
 UCI	s	University of Ibadan, Botany and Microbiology Department
 UCJ	s	Universite d'Abidjan, Departemente de Botanique
@@ -6178,6 +6567,10 @@ UCLZ	s	University College London
 UCM<ESP>	s	Universidad Complutense Madrid
 UCM<UKR>	c	Ukrainian Collection of Microorganisms, Zabolotny Institute of Microbiology and Virology
 UCM<USA-CO>	s	University of Colorado Museum
+UCM<USA-CO>:Bird	s	University of Colorado Museum, University of Colorado Museum Bird Collection
+UCM<USA-CO>:Fish	s	University of Colorado Museum, University of Colorado Museum Fish collection
+UCM<USA-CO>:Herp	s	University of Colorado Museum, University of Colorado Museum Amplibian and Reptile collection
+UCM<USA-CO>:Mamm	s	University of Colorado Museum, University of Colorado Museum Mammal Collection
 UCMC	s	University of Colorado Museum
 UCME	s	Faculdad de Biologia, Departamento de Zoologia
 UCMM	s	Pontificia Universidad Catolica Madre y Maestra
@@ -6214,6 +6607,7 @@ UEA	s	University of East Anglia
 UEC	s	Universidade Estadual de Campinas, Departamento de Botanica
 UEFS	s	Laboratorio de Ictiologia
 UENF	s	Universidade Estadual do Norte Fluminense
+UESC	h	Universidade Estadual de Santa Cruz
 UESS	s	Universidad de El Salvador
 UEVH	s	Universidade de Evora, Departamento de Biologia
 UF	sb	University of Florida Museum of Natural History
@@ -6225,6 +6619,7 @@ UF:Mammalogy	s	University of Florida Museum of Natural History, Mammalogy Collec
 UF:Ornithology	s	University of Florida Museum of Natural History, Ornithology Skins and Skeletons Collection
 UF:Porifera	s	University of Florida Museum of Natural History, 
 UFA	s	Ufa Scientific Centre, Russian Academy of Sciences
+UFACPZ	h	Universidade Federal do Acre/Parque Zoobotanico
 UFC	s	Universidade Federal do Ceara, Departamento de Biologia
 UFES	s	Universidade Federal do Espirito Santo
 UFG	s	Universidade Federal de Goias, Unidade de Conservacao
@@ -6246,9 +6641,11 @@ UFRJ<herbarium>	sc	Herbario e Colecao Fitopathologica "Verlande Duarte Silveira"
 UFRJ<museum>	s	Departramento de Zoologia, Universidade Federal do Rio de Janeiro
 UFRJIM	c	Departamento de Microbiologia Medica
 UFRN	s	Universidade Federal do Rio Grande do Norte
+UFRR	h	Universidade Federal de Roraima
 UFS	s	Nyabyeya Forestry College, Department of Environmental Forestry
 UFSC	s	Universidade Federal de Santa Catarina
 UFScarCC	c	Freshwater Microalgae Collection Cultures
+UFU	h	Ural Federal University
 UFVB	s	Vicosa, Universidade Federal de Vicosa, Museum of Entomology
 UG<ESP>	s	Museo del Departamento de Estratigrafia y Paleontologia
 UG<GHA>	s	University of Ghana
@@ -6273,6 +6670,7 @@ UIM	s	University of Idaho
 UIMNH	s	University of Illinois, Museum of Natural History
 UIS	s	Universidad Industrial de Santander, Departamento de Biologia
 UIS:H	s	Universidad Industrial de Santander, Departamento de Biologia, Collecion Herpetologica
+UISMHN	s	Universidad Industrial de Santander, Museo de Historia Natural
 UJAT	s	Universidad Juarez Autonoma de Tabasco
 UJB	c	University of Jaffna Botany
 UJIM	s	University of Jordan Insect Museum
@@ -6293,7 +6691,7 @@ ULABG	s	Universidad de los Andes, Laboratorio de Biogeografia
 ULCI	s	Universidad de la Laguna
 ULF	s	Universite Laval, Departement des Sciences forestieres
 ULKY	s	University of Louisville
-ULLZ	s	University of Louisiana at Layafette, Zoological Collection
+ULLZ	s	University of Louisiana at Layafette Zoological Collection
 ULM	s	Universitaet Ulm, Abteilung Systematische Botanik und Oekologie
 ULMG	s	University of Leipzig
 ULN	s	University of Lagos
@@ -6329,6 +6727,7 @@ UMIP	c	Collection de Champignons et Actinomycetes Pathogenes
 UMKC	s	University of Missouri
 UMKL	s	University of Malaysia
 UMKU	s	Uganda Museum
+UMM	h	University of Maine at Machias
 UMML	s	University of Miami Marine Laboratory
 UMMP	s	University of Michigan
 UMMZ	s	University of Michigan, Museum of Zoology
@@ -6344,6 +6743,7 @@ UMRM	s	W.R. Enns Entomology Museum
 UMS	s	Universiti Malaysia Sabah
 UMSA	s	Instituto de Ecologia
 UMSP	s	University of Minnesota
+UMSS	s	Universidad Mayor de San Simon, Facultad de Ciencias y Tecnologia, Centro de Biodiversidad, Zoologia,Laboratorio de Ictiologia
 UMT	s	Mutare Museum
 UMUT	s	University Museum, University of Tokyo
 UMUTZ	s	Department of Zoology, University Museum
@@ -6372,6 +6772,7 @@ UNAM:CNPGG	s	Universidad Nacional Autonoma de Mexico, Coleccion Nacional del Phy
 UNAN	s	Universidad Nacional Autonoma de Nicaragua
 UNB	s	Connell Memorial Herbarium
 UNC-B	s	University of Northern Colorado
+UNCA	h	University of North Carolina at Asheville
 UNCB	s	Universidad Nacional de Colombia, Insituto de Ciencias Naturales de la Universidad Nacional
 UNCC<COL>	s	Universidad Nacional de Caldas, Museo de Historia Natural
 UNCC<USA-NC>	s	University of North Carolina, Biology Department
@@ -6391,6 +6792,7 @@ UNIMAS<MYS>	s	Universiti Malaysia Sarawak
 UNIN	s	University of the North, Botany Department
 UNIP	s	Universidade Paulista, Laboratorio de Botanica
 UNIQEM	c	Institute of Microbiology, Russian Academy of Sciences
+UNITEC	h	Unitec Institute of Technology
 UNL<MEX>	s	Universidad Autonoma de Nuevo Leon
 UNL<PRT>	s	Centro de Estratigrafia e Paleobiologia da Universidade Nova de Lisboa
 UNL<USA-NE>	s	University of Nebraska State Museum
@@ -6434,6 +6836,7 @@ UP	s	University of Papua and New Guinea
 UPA	s	University of Patras, Department of Plant Biology
 UPCB	s	Universidade Federal do Parana, Departamento de Botanica
 UPCC	c	Natural Sciences Research Institute Culture Collection
+UPCT	h	Universidad Politecnica De Cartagena
 UPEI	s	University of Prince Edward Island, Biology Department
 UPF	s	Universite de Polynesie Francaise Herbarium
 UPIE	b	Unidad de Patologia Infecciosa y Epidemiologia
@@ -6445,7 +6848,7 @@ UPMR	c	Rhizobium Collection
 UPMSI	s	Marine Science Institute
 UPNA	s	Universidad Publica de Navarra, Departamento de Ciencias del Medio Natural
 UPNG	s	University of Papua New Guinea, Division of Biological Sciences
-UPOL<CZE>	s	University Palacky Olomouc
+UPOL	s	University Palacky Olomouc
 UPOS	s	Universidad Pablo de Olavide, Ciencias Ambientales (Botanica)
 UPP	s	Uppingham School Museum
 UPPC	s	University of the Philippines
@@ -6517,6 +6920,8 @@ USLH	s	University of Louisiana Lafayette, Department of Renewable Resources
 USM<MYS>	s	Universiti Sains Malaysia
 USM<MYS>:VCRU	s	Universiti Sains Malaysia, Vector Control Research Unit
 USM<PER>	s	Universidad Nacional Mayor de San Marcos, Museo de Historia Natural, Herbario
+USMMC	s	Universiti Sains Malaysia Mollusc Collection
+USMP	h	Universiti Sains Malaysia
 USMS	s	University of Southern Mississippi, Department of Biological Sciences
 USNC	s	Smithsonian Institution, Paleobiology Department
 USNM	sb	National Museum of Natural History, Smithsonian Institution
@@ -6539,6 +6944,7 @@ USSC	s	U.S. Soil Conservation Service
 USTF	s	Technologische Faculteit
 USTK	s	University of Science and Technology, Museum of Natural History
 USU	s	United States Department of Agriculture
+USUUB	h	Utah State University Uintah Basin
 USZ	s	Universidad Autonoma Gabriel Rene Moreno
 UT<USA-TN>	s	University of Tennessee
 UT<USA-UT>	s	University of Utah Herbarium
@@ -6551,6 +6957,7 @@ UTCI	s	University of Tennessee at Chattanooga Insect Collection
 UTD	s	University of Texas, Plant Resources Center
 UTE	s	University of Tartu
 UTEP	s	University of Texas at El Paso, Centennial Museum
+UTEP:Herp	s	University of Texas at El Paso, Centennial Museum, Herpetology Collection
 UTEX	c	The Culture Collection of Algae at the University of Texas Austin
 UTG	s	University of Tuebingen
 UTGD	s	Geology Department, The University of Tasmania
@@ -6567,6 +6974,7 @@ UU<SWE>	s	University of Uppsala
 UU<UKR>	s	Uzhgorod State University, Botany Department
 UU<USA-UT>	s	University of Utah, Department of Biology
 UUC	c	Janet A. Robertson Collection of Ureaplasma urealyticum Cultures
+UUDE	h	Buryat State University
 UUH	s	Institute of General and Experimental Biology, Department of Floristics and Geobotany
 UUVP	s	University of Utah, Vertebrate Paleontology
 UUZM	s	Uppsala University, Zoological Museum
@@ -6588,6 +6996,7 @@ UVST	s	Southwest Texas Junior College, Biology Department
 UVV	s	Universita di Venezia, Dipartimento de Scienze Ambientali
 UW	s	University of Washington Fish Collection
 UWA	s	University of Western Australia, Botany Department
+UWAL	h	University of West Alabama
 UWBM	s	University of Washington, Burke Museum
 UWBM:Mamm	s	University of Washington, Burke Museum, Burke Museum's mammal collection
 UWBM:ORN	s	University of Washington, Burke Museum, Ornithology Collection
@@ -6652,8 +7061,11 @@ VENDA	s	Thohoyandou Botanical Gardens, Department of Agriculture, Land & Environ
 VER	s	Herbario, Museo Civico di Storia Naturale, Verona
 VETMED	s	University of Veterinary Medicine
 VF	s	Universidad de Valencia, Departamento de Biologia Vegetal, Botanica
+VFM	h	Forest Inventory and Planning Institute
 VFWD	s	Vermont Fish and Wildlife Department
+VFWO	h	U.S. Fish and Wildlife Service, Ventura Fish and Wildlife Office
 VGZ	s	Voronezh State Biosphere Reserve, Research Department
+VH	h	Vivekanand Arts Sardar Dalipsingh Commerce and Science College
 VHS<AUS>	c	Vegetation Health Service  ( Phytophthora cultures )
 VI<NOR>	c	Mykotektet, National Veterinary Institute
 VI<SWE>	s	Gotlands Fornsal
@@ -6664,6 +7076,7 @@ VIC	s	Universidade Federal de Vicosa, Departamento de Biologia Vegetal
 VICA	s	Agriculture Department
 VICF	s	Forestry Department
 VICH	s	Plant Protection Department
+VIES	h	Federal University of Espirito Santo
 VIL	s	Universite de Paris-Sud
 VIMS	s	Virginia Institute of Marine Science
 VIST	s	University of the Virgin Islands, Natural Resources Program
@@ -6673,17 +7086,21 @@ VKM	c	All-Russian Collection of Microorganisms
 VKPM	c	Russian National Collection of Industrial Microorganisms
 VLA	s	Far Eastern Branch, Russian Academy of Sciences, Botany Department
 VM	s	Okresni vlastivedne muzeum
+VMI	h	Virginia Military Institute
 VMIL	s	Virginia Military Institute, Biology Department
 VMKSC	s	Kearney State University, Vertebrate Museum
 VMM	s	Vanderbilt Marine Museum
 VMNH	s	Virginia Museum of Natural History
 VMSL	s	I.N.T.A., E.E.A. San Luis, Pastizales Naturales
 VNC	s	Los Angeles Valley College, Life Sciences Department
+VNF	h	Vietnam Forestry Herbarium
 VNGA	s	Vorarlberger Naturschau
 VNIRO	s	Institute of Oceanography
+VNM	h	Institute of Tropical Biology
 VNMN	s	Vietnam National Museum of Nature
 VOA	s	Ostrobothnian Museum
 VOR	s	Voronezh State University, Biology and Plant Ecology Department
+VORB	h	Botanical Garden Dr. B.M. Kozo-Polyansky, Voronezh State University
 VORG	s	Voronezh State University, Faculty of Geography and Geoecology
 VPB	c	Veterinary Pathology and Bacteriology Collection
 VPCI	c	Fungal Culture Collection
@@ -6700,7 +7117,8 @@ VSM<NOR>	s	Det Kgl. Norske Videnskabers Selskab Museet
 VSM<SVK>	s	Eastern Slovakian (Vychodoslovenske) Museum, Natural History Department
 VSRI	s	N.I. Vavilov All-Russian Scientific Research Instiutte of Plant Industry
 VSUH	s	Virginia State University, Life Sciences Department
-VT	s	University of Vermont, Botany Department
+VT	s	Pringle Herbarium, University of Vermont
+VTA	h	Jardin Botanique de la Villa Thuret
 VTB	c	Banco de Celulas Humanas e Animais Laboratorio de Patologia Celular e Molecular
 VTCC	c	Vietnam Type Culture Collection, Center of Biotechnology
 VTT	c	VTT Biotechnology, Culture Collection
@@ -6711,8 +7129,9 @@ VUWE	s	Victoria University
 VYH	c	Finnish Environment Institute (SYKE)
 VYM	s	Muzeum Vyakovska
 W	s	Naturhistorisches Museum Wien, Department of Botany
-WA	s	Warsaw University, Department of Plant Systematics and Geography
+WA	s	Herbarium, Faculty of Biology, University of Warsaw
 WAB	s	Wabash College, Biological Sciences Department
+WABG	h	University of Warsaw Botanic Garden
 WAC	c	Department of Agriculture Western Australia Plant Pathogen Collection
 WACA<USA-AZ>	s	Walnut Canyon National Monument
 WACA<USA-OR>	s	Work Amber Collection
@@ -6720,6 +7139,7 @@ WACC	c	Western Australian Culture Collection
 WADA	s	Western Australia Department of Agriculture
 WAG	s	Wageningen University
 WAHO	s	Institute of Horticultural Plant Breeding, Department of Biosystematics
+WAI	h	Waimea Valley
 WAIK	s	University of Waikato, Biological Sciences Department
 WAITE	c	Insect Pathology Pathogen Collection
 WAL	c	Wadsworth Anaerobe Laboratory, Wadsworth Hospital Center
@@ -6727,6 +7147,7 @@ WAM	s	Western Australian Museum
 WAMP	s	Western Australian Museum
 WAN	s	Forest Research Station
 WANF	s	Wasatch-Cache National Forest
+WAPA	h	War in the Pacific National Historical Park
 WAR	s	Warwickshire Museum, Natural History Department
 WARC	c	New Zealand Reference Culture Collection
 WARK	s	Western Illinois University, Biology Department
@@ -6751,6 +7172,7 @@ WCL	s	Willesden Borough Council
 WCP	s	Walla Walla College, Biological Sciences Department
 WCR	s	Winchester City Museum
 WCRP	s	Winchester Public Library
+WCSBG	h	West China Subalpine Botanical Garden
 WCSU	s	Western Connecticut State University, Department of Biological and Environmental Sciences
 WCU	s	West China University of Medical Sciences
 WCUH	s	Western Carolina University, Department of Biology
@@ -6772,6 +7194,7 @@ WFIS	s	Wagner Free Institute of Science
 WFU	s	Wake Forest University, Biology Department
 WFUVC	s	Wake Forest University, Vertebrate Collection
 WGC	s	State University of West Georgia, Biology Department
+WGCH	h	Wilton Garden Club
 WGD	s	Washington Game Department
 WGMM	s	Woodspring Museum
 WGRC	b	Wheat Genetics Resource Center
@@ -6790,6 +7213,7 @@ WIB	s	Ministry of Environment and Parks, Resource Quality Section
 WIBF	s	West Indian Beetle Fauna Project Collection
 WIBG	s	Windward Islands Banana Grower's Association
 WICA	s	Wind Cave National Park
+WICH	h	Wichita State University
 WIES	s	Museum Wiesbaden
 WII	s	Wildlife Institute of India, Department of Habitat Ecology
 WILLI	s	The College of William and Mary, Department of Biology
@@ -6801,6 +7225,7 @@ WINDM	s	Delta Marsh Field Station (University of Manitoba)
 WINF	s	Forestry and Rural Developmen Department
 WINFM	s	Forestry and Rural Developmen Department
 WINO	s	Saint Mary's College, Biology Department
+WINU	h	Winthrop University
 WIR	sb	N. I. Vavilov Institute of Plant Industry, Department of Introduction and Systematics
 WIS	s	University of Wisconsin, Botany Department
 WIU	s	Western Illinois University, Museum of Natural History
@@ -6881,6 +7306,7 @@ WUH	s	Wuhu School of Traditional Chinese Medicine
 WUK	s	Northwestern Institute of Botany
 WUM	s	University of Witwatersrand
 WUME	s	Willamette University
+WUP	h	Department of Pharmacognosy, Universitat Wien
 WVA	s	West Virginia University, Biology Department
 WVBS	s	West Virginia Biological Survey
 WVDH	c	West Virginia Hygienic Laboratory
@@ -6890,6 +7316,7 @@ WVN	s	Whitehaven Scientific Association
 WVUC	s	West Virginia University
 WVW	s	West Virginia Wesleyan College, Biology Department
 WWB	s	Western Washington University, Biology Department
+WWC	h	Warren Wilson College
 WWF	s	Welder Wildlife Foundation
 WWM	s	Werner Wildlife Museum
 WWSP	s	Weymouth Woods Sandhills Nature Preserve
@@ -6914,6 +7341,7 @@ XJNU	s	Xinjiang Normal University, Biology Department
 XJU	s	Xinjiang University, Biology Department
 XJUG	s	Xinjiang University, Geography Department
 XM	s	Xinjiang Medical College, Pharmacy Department
+XMU	s	Xiamen University
 XNC	s	Department of Biology, Xinxiang Normal College
 XOLO	s	Universidad Autonoma Chapingo, Departamento de Fitotecnia
 XTNM	s	Xinjiang Institute of Traditional Chinese and Minorities Medicine
@@ -6929,6 +7357,7 @@ YAI	s	Armenian Agricultural Academy, Botany Department
 YAK	s	Forest Survey and Design Institute
 YALT	s	The State Nikita Botanical Gardens, Flora and Vegetation
 YAM	s	Yamaguchi University, Plant Pathology Department
+YAMA	h	Yamagata Prefectural Museum
 YAR	s	Yaroslavl State University, Department of Biology and Ecology
 YBDC	s	Yibin Institute for Drug Control
 YBI	s	Institut National pour l'Etude et la Recherche Agronomique, Departement de Botanique
@@ -7051,7 +7480,7 @@ ZMH	s	Zoologisches Museum Hamburg
 ZMHB	s	Museum fuer Naturkunde der Humboldt-Universitat
 ZMHU	s	Zoologisches Museum der Humboldt Universitaet
 ZMJU	s	Zoological Museum, Jagiellonian University
-ZMK<DEU>	s	Zoologisches Museum der Universitaet Kiel
+ZMK<DEU>	s	Zoologisches Museum der Universitat Kiel
 ZMK<DNK>	s	Zoological Museum, Copenhagen
 ZMK<NOR>	s	Zoological Musem, Kristiania
 ZMKR	s	Koenigsberg Zoologisches Museum
@@ -7070,6 +7499,7 @@ ZMMU:Invertebrates	s	Zoological Museum, Moscow Lomonosov State University, Inver
 ZMMU:Mamm	s	Zoological Museum, Moscow Lomonosov State University, Mammal Collection
 ZMNH	s	Zhejiang Museum of Natural History
 ZMO	s	Zoology Museum, Oxford University
+ZMS	s	Zentralmuseum Senckenberg (SENCKENBERG world of biodiversity)
 ZMSZ	s	Zemaljski Mujski
 ZMT<CZE>	s	Zapadomoravske muzeum v Trebici
 ZMT<GEO>	s	Georgian State Museum, Zoological Section
@@ -7096,6 +7526,7 @@ ZMUP	s	Zoological Museum of the University of Patras
 ZMUT	s	University of Tokyo, Department of Zoology
 ZMUU	s	Uppsala Universitet, Zoologiska Museet
 ZMUZ	s	Zoologisches Museum der Universitaet Zuerich
+ZNG	h	Bulent Ecevit University
 ZNM	s	Zhejiang Natural Museum
 ZNP	s	Zion National Park
 ZNPC	s	Springdale, Zion National Park
@@ -7138,6 +7569,7 @@ ZV	s	Technical University, Department of Phytology
 ZVC	s	Depto. de Zoologia Vertebrados de la Facultad de Humanidades y Ciencias
 ZVCB<URY>	s	Vertebrate Collection, Facultad de Ciencias, Universidad de la Republica
 ZVS	s	Bundesamt fuer Naturschutz
+ZY	h	Zunyi Normal College
 ZYTC	s	Zhangye Teachers College, Chemistry-Biology Department
 ZZN	c	Zavod za naravoslovje
 ZZSZ	s	Zoology Department, Faculty of Natural Sciences, University of Zagreb
diff --git a/c++/src/objects/seqfeat/lat_lon_country.inc b/c++/src/objects/seqfeat/lat_lon_country.inc
index 81531ed..106600b 100644
--- a/c++/src/objects/seqfeat/lat_lon_country.inc
+++ b/c++/src/objects/seqfeat/lat_lon_country.inc
@@ -1,4 +1,4 @@
-/*  $Id: lat_lon_country.inc 434988 2014-05-13 14:45:17Z bollin $
+/*  $Id: lat_lon_country.inc 513850 2016-09-15 17:37:05Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1194,11 +1194,6 @@ static const char* const s_DefaultLatLonCountryText[] = {
     "	18	-73	-67",
     "	17	-73	-67",
     "	16	-72	-70",
-    "East Timor",
-    "	-7	123	128",
-    "	-8	123	128",
-    "	-9	123	128",
-    "	-10	123	127",
     "Ecuador",
     "	2	-80	-77",
     "	1	-81	-74",
@@ -2958,6 +2953,11 @@ static const char* const s_DefaultLatLonCountryText[] = {
     "	6	97	103",
     "	5	98	103",
     "	4	99	102",
+    "Timor-Leste",
+    "	-7	123	128",
+    "	-8	123	128",
+    "	-9	123	128",
+    "	-10	123	127",
     "Togo",
     "	12	-1	1",
     "	11	-1	2",
diff --git a/c++/src/objects/seqfeat/lat_lon_country.txt b/c++/src/objects/seqfeat/lat_lon_country.txt
index 1f952ef..4ae7289 100644
--- a/c++/src/objects/seqfeat/lat_lon_country.txt
+++ b/c++/src/objects/seqfeat/lat_lon_country.txt
@@ -74542,147 +74542,6 @@ Dominican Republic
 	17.55	-71.55	-71.48
 	17.54	-71.55	-71.49
 	17.53	-71.53	-71.50
-East Timor
-	-8.12	125.62	125.65
-	-8.13	125.60	125.66
-	-8.14	125.59	125.66
-	-8.15	125.58	125.66
-	-8.16	125.57	125.66
-	-8.17	125.56	125.65
-	-8.18	125.55	125.65
-	-8.19	125.55	125.65
-	-8.20	125.54	125.64
-	-8.21	125.52	125.64
-	-8.22	125.51	125.63
-	-8.23	125.50	125.63
-	-8.24	125.50	125.62
-	-8.25	125.49	125.62
-	-8.26	125.49	125.61
-	-8.27	125.49	125.61
-	-8.28	125.49	125.61
-	-8.29	125.49	125.60	126.95	126.98
-	-8.30	125.50	125.60	126.93	126.99
-	-8.31	125.54	125.60	126.92	127.01	127.18	127.20
-	-8.32	125.55	125.59	126.90	127.03	127.17	127.22
-	-8.33	126.89	127.05	127.15	127.22
-	-8.34	126.88	127.08	127.14	127.23
-	-8.35	126.87	127.24
-	-8.36	126.85	127.27
-	-8.37	126.84	127.30
-	-8.38	126.82	127.31
-	-8.39	126.80	127.31
-	-8.40	126.40	126.42	126.70	127.32
-	-8.41	126.36	126.42	126.67	127.32
-	-8.42	126.34	126.44	126.65	127.32
-	-8.43	126.31	126.51	126.63	127.32
-	-8.44	126.29	126.52	126.61	127.31
-	-8.45	126.28	126.53	126.59	127.30
-	-8.46	126.26	126.54	126.56	127.28
-	-8.47	125.83	125.95	126.25	127.27
-	-8.48	125.80	126.02	126.22	127.26
-	-8.49	125.77	126.04	126.11	127.24
-	-8.50	125.74	127.23
-	-8.51	125.62	125.66	125.70	127.22
-	-8.52	125.60	127.21
-	-8.53	125.52	127.20
-	-8.54	125.49	127.19
-	-8.55	125.39	125.44	125.47	127.18
-	-8.56	125.36	127.17
-	-8.57	125.32	127.15
-	-8.58	125.29	127.14
-	-8.59	125.21	127.13
-	-8.60	125.18	127.11
-	-8.61	125.15	127.10
-	-8.62	125.13	127.09
-	-8.63	125.11	127.08
-	-8.64	125.11	127.07
-	-8.65	125.10	127.05
-	-8.66	125.10	127.04
-	-8.67	125.09	127.03
-	-8.68	125.09	127.03
-	-8.69	125.09	126.99
-	-8.70	125.09	126.95
-	-8.71	125.09	126.93
-	-8.72	125.09	126.91
-	-8.73	125.09	126.90
-	-8.74	125.09	126.88
-	-8.75	125.09	126.87
-	-8.76	125.09	126.85
-	-8.77	125.09	126.77
-	-8.78	125.08	126.67
-	-8.79	125.06	126.66
-	-8.80	125.04	126.64
-	-8.81	125.02	126.62
-	-8.82	125.01	126.58
-	-8.83	125.01	126.57
-	-8.84	125.00	126.57
-	-8.85	125.00	126.56
-	-8.86	124.99	126.55
-	-8.87	124.99	126.54
-	-8.88	124.98	126.54
-	-8.89	124.97	126.53
-	-8.90	124.97	126.52
-	-8.91	124.96	126.52
-	-8.92	124.95	126.51
-	-8.93	124.94	126.50
-	-8.94	124.92	126.49
-	-8.95	124.90	126.48
-	-8.96	124.90	126.46
-	-8.97	124.90	126.39
-	-8.98	124.90	126.30
-	-8.99	124.90	126.21
-	-9.00	124.90	126.15
-	-9.01	124.89	126.13
-	-9.02	124.89	125.07	125.11	126.12
-	-9.03	124.89	125.07	125.12	126.10
-	-9.04	124.89	125.06	125.13	126.09
-	-9.05	124.89	125.04	125.14	126.07
-	-9.06	124.90	125.02	125.14	126.05
-	-9.07	124.91	125.00	125.15	126.04
-	-9.08	124.92	124.98	125.15	126.02
-	-9.09	125.14	126.01
-	-9.10	125.14	126.00
-	-9.11	125.14	125.98
-	-9.12	125.13	125.97
-	-9.13	125.13	125.95
-	-9.14	125.13	125.84	125.89	125.94
-	-9.15	125.13	125.83
-	-9.16	125.13	125.81
-	-9.17	124.39	124.46	124.98	125.04	125.09	125.74
-	-9.18	124.38	124.46	124.96	125.05	125.08	125.72
-	-9.19	124.35	124.46	124.95	125.70
-	-9.20	124.30	124.46	124.94	125.59	125.63	125.68
-	-9.21	124.26	124.46	124.94	125.58
-	-9.22	124.23	124.46	124.94	125.57
-	-9.23	124.20	124.45	124.94	125.54
-	-9.24	124.18	124.45	124.94	125.52
-	-9.25	124.17	124.44	124.94	125.50
-	-9.26	124.16	124.44	124.94	125.47
-	-9.27	124.15	124.44	124.95	125.44
-	-9.28	124.14	124.44	124.95	125.42
-	-9.29	124.10	124.44	124.95	125.39
-	-9.30	124.08	124.44	124.95	125.37
-	-9.31	124.05	124.43	124.96	125.35
-	-9.32	124.03	124.42	124.97	125.34
-	-9.33	124.02	124.42	124.98	125.33
-	-9.34	124.02	124.41	125.00	125.31
-	-9.35	124.02	124.40	125.01	125.30
-	-9.36	124.03	124.38	125.01	125.28
-	-9.37	124.03	124.37	125.01	125.27
-	-9.38	124.04	124.35	125.01	125.26
-	-9.39	124.04	124.18	124.20	124.35	125.02	125.25
-	-9.40	124.05	124.16	124.21	124.35	125.02	125.24
-	-9.41	124.06	124.15	124.22	124.35	125.03	125.24
-	-9.42	124.07	124.14	124.22	124.35	125.03	125.23
-	-9.43	124.08	124.13	124.23	124.34	125.04	125.21
-	-9.44	124.24	124.34	125.04	125.14
-	-9.45	124.24	124.34	125.04	125.13
-	-9.46	124.24	124.34	125.04	125.11
-	-9.47	124.24	124.34	125.05	125.10
-	-9.48	124.24	124.34	125.05	125.09
-	-9.49	124.24	124.33	125.05	125.07
-	-9.50	124.24	124.31
-	-9.51	124.24	124.26
 Ecuador
 	1.44	-78.83	-78.81
 	1.43	-78.84	-78.79
@@ -165990,6 +165849,147 @@ Thailand
 	5.63	101.09	101.17
 	5.62	101.09	101.15
 	5.61	101.11	101.14
+Timor-Leste
+	-8.12	125.62	125.65
+	-8.13	125.60	125.66
+	-8.14	125.59	125.66
+	-8.15	125.58	125.66
+	-8.16	125.57	125.66
+	-8.17	125.56	125.65
+	-8.18	125.55	125.65
+	-8.19	125.55	125.65
+	-8.20	125.54	125.64
+	-8.21	125.52	125.64
+	-8.22	125.51	125.63
+	-8.23	125.50	125.63
+	-8.24	125.50	125.62
+	-8.25	125.49	125.62
+	-8.26	125.49	125.61
+	-8.27	125.49	125.61
+	-8.28	125.49	125.61
+	-8.29	125.49	125.60	126.95	126.98
+	-8.30	125.50	125.60	126.93	126.99
+	-8.31	125.54	125.60	126.92	127.01	127.18	127.20
+	-8.32	125.55	125.59	126.90	127.03	127.17	127.22
+	-8.33	126.89	127.05	127.15	127.22
+	-8.34	126.88	127.08	127.14	127.23
+	-8.35	126.87	127.24
+	-8.36	126.85	127.27
+	-8.37	126.84	127.30
+	-8.38	126.82	127.31
+	-8.39	126.80	127.31
+	-8.40	126.40	126.42	126.70	127.32
+	-8.41	126.36	126.42	126.67	127.32
+	-8.42	126.34	126.44	126.65	127.32
+	-8.43	126.31	126.51	126.63	127.32
+	-8.44	126.29	126.52	126.61	127.31
+	-8.45	126.28	126.53	126.59	127.30
+	-8.46	126.26	126.54	126.56	127.28
+	-8.47	125.83	125.95	126.25	127.27
+	-8.48	125.80	126.02	126.22	127.26
+	-8.49	125.77	126.04	126.11	127.24
+	-8.50	125.74	127.23
+	-8.51	125.62	125.66	125.70	127.22
+	-8.52	125.60	127.21
+	-8.53	125.52	127.20
+	-8.54	125.49	127.19
+	-8.55	125.39	125.44	125.47	127.18
+	-8.56	125.36	127.17
+	-8.57	125.32	127.15
+	-8.58	125.29	127.14
+	-8.59	125.21	127.13
+	-8.60	125.18	127.11
+	-8.61	125.15	127.10
+	-8.62	125.13	127.09
+	-8.63	125.11	127.08
+	-8.64	125.11	127.07
+	-8.65	125.10	127.05
+	-8.66	125.10	127.04
+	-8.67	125.09	127.03
+	-8.68	125.09	127.03
+	-8.69	125.09	126.99
+	-8.70	125.09	126.95
+	-8.71	125.09	126.93
+	-8.72	125.09	126.91
+	-8.73	125.09	126.90
+	-8.74	125.09	126.88
+	-8.75	125.09	126.87
+	-8.76	125.09	126.85
+	-8.77	125.09	126.77
+	-8.78	125.08	126.67
+	-8.79	125.06	126.66
+	-8.80	125.04	126.64
+	-8.81	125.02	126.62
+	-8.82	125.01	126.58
+	-8.83	125.01	126.57
+	-8.84	125.00	126.57
+	-8.85	125.00	126.56
+	-8.86	124.99	126.55
+	-8.87	124.99	126.54
+	-8.88	124.98	126.54
+	-8.89	124.97	126.53
+	-8.90	124.97	126.52
+	-8.91	124.96	126.52
+	-8.92	124.95	126.51
+	-8.93	124.94	126.50
+	-8.94	124.92	126.49
+	-8.95	124.90	126.48
+	-8.96	124.90	126.46
+	-8.97	124.90	126.39
+	-8.98	124.90	126.30
+	-8.99	124.90	126.21
+	-9.00	124.90	126.15
+	-9.01	124.89	126.13
+	-9.02	124.89	125.07	125.11	126.12
+	-9.03	124.89	125.07	125.12	126.10
+	-9.04	124.89	125.06	125.13	126.09
+	-9.05	124.89	125.04	125.14	126.07
+	-9.06	124.90	125.02	125.14	126.05
+	-9.07	124.91	125.00	125.15	126.04
+	-9.08	124.92	124.98	125.15	126.02
+	-9.09	125.14	126.01
+	-9.10	125.14	126.00
+	-9.11	125.14	125.98
+	-9.12	125.13	125.97
+	-9.13	125.13	125.95
+	-9.14	125.13	125.84	125.89	125.94
+	-9.15	125.13	125.83
+	-9.16	125.13	125.81
+	-9.17	124.39	124.46	124.98	125.04	125.09	125.74
+	-9.18	124.38	124.46	124.96	125.05	125.08	125.72
+	-9.19	124.35	124.46	124.95	125.70
+	-9.20	124.30	124.46	124.94	125.59	125.63	125.68
+	-9.21	124.26	124.46	124.94	125.58
+	-9.22	124.23	124.46	124.94	125.57
+	-9.23	124.20	124.45	124.94	125.54
+	-9.24	124.18	124.45	124.94	125.52
+	-9.25	124.17	124.44	124.94	125.50
+	-9.26	124.16	124.44	124.94	125.47
+	-9.27	124.15	124.44	124.95	125.44
+	-9.28	124.14	124.44	124.95	125.42
+	-9.29	124.10	124.44	124.95	125.39
+	-9.30	124.08	124.44	124.95	125.37
+	-9.31	124.05	124.43	124.96	125.35
+	-9.32	124.03	124.42	124.97	125.34
+	-9.33	124.02	124.42	124.98	125.33
+	-9.34	124.02	124.41	125.00	125.31
+	-9.35	124.02	124.40	125.01	125.30
+	-9.36	124.03	124.38	125.01	125.28
+	-9.37	124.03	124.37	125.01	125.27
+	-9.38	124.04	124.35	125.01	125.26
+	-9.39	124.04	124.18	124.20	124.35	125.02	125.25
+	-9.40	124.05	124.16	124.21	124.35	125.02	125.24
+	-9.41	124.06	124.15	124.22	124.35	125.03	125.24
+	-9.42	124.07	124.14	124.22	124.35	125.03	125.23
+	-9.43	124.08	124.13	124.23	124.34	125.04	125.21
+	-9.44	124.24	124.34	125.04	125.14
+	-9.45	124.24	124.34	125.04	125.13
+	-9.46	124.24	124.34	125.04	125.11
+	-9.47	124.24	124.34	125.05	125.10
+	-9.48	124.24	124.34	125.05	125.09
+	-9.49	124.24	124.33	125.05	125.07
+	-9.50	124.24	124.31
+	-9.51	124.24	124.26
 Togo
 	11.14	-0.17	-0.13
 	11.13	-0.17	-0.08
diff --git a/c++/src/objects/seqfeat/seqfeat.asn b/c++/src/objects/seqfeat/seqfeat.asn
index 303f779..b12e040 100644
--- a/c++/src/objects/seqfeat/seqfeat.asn
+++ b/c++/src/objects/seqfeat/seqfeat.asn
@@ -1,4 +1,4 @@
---$Revision: 488584 $
+--$Revision: 509630 $
 --**********************************************************************
 --
 --  NCBI Sequence Feature elements
@@ -1310,7 +1310,8 @@ Prot-ref ::= SEQUENCE {
        preprotein (1) ,
        mature (2) ,
        signal-peptide (3) ,
-       transit-peptide (4) } DEFAULT not-set }
+       transit-peptide (4) ,
+       propeptide (5) } DEFAULT not-set }
 
 END
 --********************************************************************
diff --git a/c++/src/objects/seqloc/Seq_id.cpp b/c++/src/objects/seqloc/Seq_id.cpp
index d96b37d..d700d33 100644
--- a/c++/src/objects/seqloc/Seq_id.cpp
+++ b/c++/src/objects/seqloc/Seq_id.cpp
@@ -1,4 +1,4 @@
-/* $Id: Seq_id.cpp 499418 2016-04-26 14:08:21Z ivanov $
+/* $Id: Seq_id.cpp 516491 2016-10-13 17:39:08Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objects/seqloc/Seq_loc.cpp b/c++/src/objects/seqloc/Seq_loc.cpp
index 904ce0f..15f06b2 100644
--- a/c++/src/objects/seqloc/Seq_loc.cpp
+++ b/c++/src/objects/seqloc/Seq_loc.cpp
@@ -1,4 +1,4 @@
-/* $Id: Seq_loc.cpp 494243 2016-03-04 15:40:06Z ivanov $
+/* $Id: Seq_loc.cpp 514371 2016-09-21 15:22:54Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -576,17 +576,18 @@ int CSeq_loc::x_CompareSingleId(const CSeq_loc& loc, const CSeq_id* id1,
 }
 
 
-int CSeq_loc::Compare(const CSeq_loc& loc) const
+int CSeq_loc::Compare(const CSeq_loc& loc_arg) const
 {
     // first try fast single-id comparison
     const CSeq_id* id1 = GetId();
-    const CSeq_id* id2 = id1 == NULL ? NULL : loc.GetId();
+    const CSeq_id* id2 = id1 == NULL ? NULL : loc_arg.GetId();
     if (id1 != NULL  &&  id2 != NULL) {
-        return x_CompareSingleId(loc, id1, id2);
+        return x_CompareSingleId(loc_arg, id1, id2);
     }
     // Slow comparison of ranges on each Seq-id separately.
-    CSeq_loc_CI iter1(*this, CSeq_loc_CI::eEmpty_Allow);
-    CSeq_loc_CI iter2(  loc, CSeq_loc_CI::eEmpty_Allow);
+    CSeq_loc_CI iter1(*this,   CSeq_loc_CI::eEmpty_Allow);
+    CSeq_loc_CI iter2(loc_arg, CSeq_loc_CI::eEmpty_Allow);
+    
     for ( ; iter1 && iter2; ) {
         CRef<CSeq_loc> loc1, loc2;
         for ( int k = 0; k < 2; ++k ) {
@@ -3038,9 +3039,10 @@ const CSeq_id* s_GetLabel
         *label += ":";
     }
     last_id = &itval.GetId();
-    if (itval.IsSetStrand() && itval.GetStrand() != eNa_strand_unknown) {
-        *label += GetTypeInfo_enum_ENa_strand()
-            ->FindName(itval.GetStrand(), true);
+    //if (itval.IsSetStrand() && itval.GetStrand() != eNa_strand_unknown) {
+    if (itval.IsSetStrand() && (itval.GetStrand() == eNa_strand_minus || itval.GetStrand() == eNa_strand_both_rev)) {
+        //*label += GetTypeInfo_enum_ENa_strand()->FindName(itval.GetStrand(), true);
+        *label += "c";
     }
     if (itval.IsSetStrand() &&
         (itval.GetStrand() == eNa_strand_minus ||
@@ -3994,8 +3996,8 @@ public:
 
     void ResetFuzzFrom(void) { m_Fuzz_from.Reset(); }
     void ResetFuzzTo(void) { m_Fuzz_to.Reset(); }
-    TFuzz IsSetFuzzFrom(void) const { return m_Fuzz_from; }
-    TFuzz IsSetFuzzTo(void) const { return m_Fuzz_to; }
+    bool IsSetFuzzFrom(void) const { return m_Fuzz_from; }
+    bool IsSetFuzzTo(void) const { return m_Fuzz_to; }
     const CInt_fuzz& GetFuzzFrom(void) const { return *m_Fuzz_from; }
     const CInt_fuzz& GetFuzzTo(void) const { return *m_Fuzz_to; }
 
@@ -4011,6 +4013,16 @@ public:
         x_AddFuzz(m_Fuzz_to, rg.m_Fuzz_to, rg.m_Strand);
     }
 
+    void AddFuzzFrom(const CInt_fuzz& fuzz, ENa_strand strand)
+    {
+        x_AddFuzz(m_Fuzz_from, ConstRef(&fuzz), strand);
+    }
+    
+    void AddFuzzTo(const CInt_fuzz& fuzz, ENa_strand strand)
+    {
+        x_AddFuzz(m_Fuzz_to, ConstRef(&fuzz), strand);
+    }
+
     void CopyFrom(const CRangeWithFuzz& rg)
     {
         SetFrom(rg.GetFrom());
@@ -4615,9 +4627,15 @@ void x_MergeAndSort(CSeq_loc& dst,
 }
 
 
+typedef map<TSeqPos, CConstRef<CInt_fuzz> > TFuzzMap;
+
 static
 void x_SingleRange(CSeq_loc& dst,
-                   const CSeq_loc& src,
+                   const CSeq_loc& minuend,
+                   const TFuzzMap& fuzz_from_plus,
+                   const TFuzzMap& fuzz_from_minus,
+                   const TFuzzMap& fuzz_to_plus,
+                   const TFuzzMap& fuzz_to_minus,
                    TIdToRangeColl& rg_coll_plus,
                    TIdToRangeColl& rg_coll_minus,
                    ISynonymMapper& syn_mapper,
@@ -4626,7 +4644,7 @@ void x_SingleRange(CSeq_loc& dst,
     TRangeWithFuzz total_rg(TRangeWithFuzz::GetEmpty());
     CSeq_id_Handle first_id;
     ENa_strand first_strand = eNa_strand_unknown;
-    for (CSeq_loc_CI it(src, CSeq_loc_CI::eEmpty_Allow); it; ++it) {
+    for (CSeq_loc_CI it(minuend, CSeq_loc_CI::eEmpty_Allow); it; ++it) {
         CSeq_id_Handle next_id = syn_mapper.GetBestSynonym(it.GetSeq_id());
         if ( !next_id ) {
             // Ignore NULLs
@@ -4665,9 +4683,22 @@ void x_SingleRange(CSeq_loc& dst,
         if (curr_rg.GetFrom() == it_range.GetFrom()) {
             curr_rg.AddFuzzFrom(it_range);
         }
-        else if (curr_rg.GetTo() == it_range.GetTo()) {
+        if (curr_rg.GetTo() == it_range.GetTo()) {
             curr_rg.AddFuzzTo(it_range);
         }
+        
+        // If range start/stop comes from subtrahend, copy fuzz.
+        const TFuzzMap& fm_from = IsReverse(it.GetStrand()) ? fuzz_from_minus : fuzz_from_plus;
+        TFuzzMap::const_iterator subtr_fuzz = fm_from.find(curr_rg.GetToOpen());
+        if (subtr_fuzz != fm_from.end()) {
+            curr_rg.AddFuzzTo(*subtr_fuzz->second, it.GetStrand());
+        }
+        const TFuzzMap& fm_to = IsReverse(it.GetStrand()) ? fuzz_to_minus : fuzz_to_plus;
+        subtr_fuzz = fm_to.find(curr_rg.GetFrom());
+        if (subtr_fuzz != fm_to.end()) {
+            curr_rg.AddFuzzFrom(*subtr_fuzz->second, it.GetStrand());
+        }
+            
         total_rg += curr_rg;
     }
 
@@ -4699,7 +4730,11 @@ void x_SingleRange(CSeq_loc& dst,
 
 static
 void x_SubNoSort(CSeq_loc& dst,
-                 const CSeq_loc& src,
+                 const CSeq_loc& minuend,
+                 const TFuzzMap& fuzz_from_plus,
+                 const TFuzzMap& fuzz_from_minus,
+                 const TFuzzMap& fuzz_to_plus,
+                 const TFuzzMap& fuzz_to_minus,
                  TIdToRangeColl& rg_coll_plus,
                  TIdToRangeColl& rg_coll_minus,
                  ISynonymMapper& syn_mapper,
@@ -4711,7 +4746,7 @@ void x_SubNoSort(CSeq_loc& dst,
     TRangeWithFuzz last_rg(TRangeWithFuzz::GetEmpty());
     ENa_strand last_strand = eNa_strand_unknown;
     bool have_range = false;
-    for (CSeq_loc_CI it(src, CSeq_loc_CI::eEmpty_Allow); it; ++it) {
+    for (CSeq_loc_CI it(minuend, CSeq_loc_CI::eEmpty_Allow); it; ++it) {
         CSeq_id_Handle idh = syn_mapper.GetBestSynonym(it.GetSeq_id());
         bool rev = IsReverse(it.GetStrand());
         TRangeWithFuzz it_range = TRangeWithFuzz(it);
@@ -4748,9 +4783,22 @@ void x_SubNoSort(CSeq_loc& dst,
                 if (curr_rg.GetFrom() == it_range.GetFrom()) {
                     curr_rg.AddFuzzFrom(it_range);
                 }
-                else if (curr_rg.GetTo() == it_range.GetTo()) {
+                if (curr_rg.GetTo() == it_range.GetTo()) {
                     curr_rg.AddFuzzTo(it_range);
                 }
+
+                // If range start/stop comes from subtrahend, copy fuzz.
+                const TFuzzMap& fm_from = IsReverse(it.GetStrand()) ? fuzz_from_minus : fuzz_from_plus;
+                TFuzzMap::const_iterator subtr_fuzz = fm_from.find(curr_rg.GetToOpen());
+                if (subtr_fuzz != fm_from.end()) {
+                    curr_rg.AddFuzzTo(*subtr_fuzz->second, it.GetStrand());
+                }
+                const TFuzzMap& fm_to = IsReverse(it.GetStrand()) ? fuzz_to_minus : fuzz_to_plus;
+                subtr_fuzz = fm_to.find(curr_rg.GetFrom());
+                if (subtr_fuzz != fm_to.end()) {
+                    curr_rg.AddFuzzFrom(*subtr_fuzz->second, it.GetStrand());
+                }
+
                 if ( have_range  &&  last_id == idh ) {
                     if (x_MergeRanges(last_rg,
                                     last_strand,
@@ -4802,7 +4850,11 @@ void x_SubNoSort(CSeq_loc& dst,
 
 static
 void x_SubAndSort(CSeq_loc& dst,
-                  const CSeq_loc& src,
+                  const CSeq_loc& minuend,
+                  const TFuzzMap& fuzz_from_plus,
+                  const TFuzzMap& fuzz_from_minus,
+                  const TFuzzMap& fuzz_to_plus,
+                  const TFuzzMap& fuzz_to_minus,
                   TIdToRangeColl& rg_coll_plus,
                   TIdToRangeColl& rg_coll_minus,
                   ISynonymMapper& syn_mapper,
@@ -4824,7 +4876,7 @@ void x_SubAndSort(CSeq_loc& dst,
     ENa_strand default_minus = use_strand ?
         eNa_strand_minus : eNa_strand_unknown;
 
-    for (CSeq_loc_CI it(src, CSeq_loc_CI::eEmpty_Allow); it; ++it) {
+    for (CSeq_loc_CI it(minuend, CSeq_loc_CI::eEmpty_Allow); it; ++it) {
         CSeq_id_Handle idh = syn_mapper.GetBestSynonym(it.GetSeq_id());
         TRangeWithFuzz it_range = TRangeWithFuzz(it);
         if ( it_range.IsWhole() ) {
@@ -4852,12 +4904,26 @@ void x_SubAndSort(CSeq_loc& dst,
         if ( modified ) {
             ITERATE(TRangeColl, rg_it, it_rg_coll) {
                 TRangeWithFuzz curr_rg(*rg_it);
+                // If range start/stop comes from the minuend, preserve strand.
                 if (curr_rg.GetFrom() == it_range.GetFrom()) {
                     curr_rg.AddFuzzFrom(it_range);
                 }
-                else if (curr_rg.GetTo() == it_range.GetTo()) {
+                if (curr_rg.GetTo() == it_range.GetTo()) {
                     curr_rg.AddFuzzTo(it_range);
                 }
+
+                // If range start/stop comes from subtrahend, copy fuzz.
+                const TFuzzMap& fm_from = IsReverse(it.GetStrand()) ? fuzz_from_minus : fuzz_from_plus;
+                TFuzzMap::const_iterator subtr_fuzz = fm_from.find(curr_rg.GetToOpen());
+                if (subtr_fuzz != fm_from.end()) {
+                    curr_rg.AddFuzzTo(*subtr_fuzz->second, it.GetStrand());
+                }
+                const TFuzzMap& fm_to = IsReverse(it.GetStrand()) ? fuzz_to_minus : fuzz_to_plus;
+                subtr_fuzz = fm_to.find(curr_rg.GetFrom());
+                if (subtr_fuzz != fm_to.end()) {
+                    curr_rg.AddFuzzFrom(*subtr_fuzz->second, it.GetStrand());
+                }
+
                 rg_map.push_back(curr_rg);
             }
         }
@@ -4895,7 +4961,7 @@ public:
     CDummyLengthGetter(void) {}
     virtual ~CDummyLengthGetter(void) {}
 
-    virtual TSeqPos GetLength(const CSeq_id& id)
+    virtual TSeqPos GetLength(const CSeq_id&)
         {
             return CSeq_loc::TRange::GetWholeToOpen();
         }
@@ -4979,6 +5045,11 @@ CRef<CSeq_loc> CSeq_loc::Subtract(const CSeq_loc& other,
     TIdToRangeColl& rg_coll_minus = use_strand ?
         *p_rg_coll_minus.get() : rg_coll_plus;
 
+    // Collect fuzzes so that they can be copied to the new ranges after subtracting.
+    // Note: if there are multiple ranges with the same boundaries only the last
+    // fuzz found will be used.
+    TFuzzMap fuzz_from_plus, fuzz_from_minus, fuzz_to_plus, fuzz_to_minus;
+
     // Create range collection(s) for loc2
     for (CSeq_loc_CI it(other); it; ++it) {
         if ( it.IsEmpty() ) {
@@ -4988,11 +5059,31 @@ CRef<CSeq_loc> CSeq_loc::Subtract(const CSeq_loc& other,
         TRangeColl& rmap = IsReverse(it.GetStrand()) ?
             rg_coll_minus[idh] : rg_coll_plus[idh];
         rmap += TRangeWithFuzz(it);
+
+        const CInt_fuzz* fuzz = it.GetFuzzFrom();
+        if ( fuzz ) {
+            if (it.IsSetStrand()  &&  IsReverse(it.GetStrand())) {
+                fuzz_from_minus[it.GetRange().GetFrom()].Reset(fuzz);
+            }
+            else {
+                fuzz_from_plus[it.GetRange().GetFrom()].Reset(fuzz);
+            }
+        }
+        fuzz = it.GetFuzzTo();
+        if ( fuzz ) {
+            if (it.IsSetStrand()  &&  IsReverse(it.GetStrand())) {
+                fuzz_to_minus[it.GetRange().GetToOpen()].Reset(fuzz);
+            }
+            else {
+                fuzz_to_plus[it.GetRange().GetToOpen()].Reset(fuzz);
+            }
+        }
     }
 
     if ( (flags & CSeq_loc::fMerge_SingleRange) != 0 ) {
         x_SingleRange(*ret,
                       *this,
+                      fuzz_from_plus, fuzz_from_minus, fuzz_to_plus, fuzz_to_minus,
                       rg_coll_plus,
                       rg_coll_minus,
                       *syn_mapper,
@@ -5001,6 +5092,7 @@ CRef<CSeq_loc> CSeq_loc::Subtract(const CSeq_loc& other,
     else if ( (flags & CSeq_loc::fSort) == 0 ) {
         x_SubNoSort(*ret,
                     *this,
+                    fuzz_from_plus, fuzz_from_minus, fuzz_to_plus, fuzz_to_minus,
                     rg_coll_plus,
                     rg_coll_minus,
                     *syn_mapper,
@@ -5010,6 +5102,7 @@ CRef<CSeq_loc> CSeq_loc::Subtract(const CSeq_loc& other,
     else {
         x_SubAndSort(*ret,
                      *this,
+                     fuzz_from_plus, fuzz_from_minus, fuzz_to_plus, fuzz_to_minus,
                      rg_coll_plus,
                      rg_coll_minus,
                      *syn_mapper,
diff --git a/c++/src/objects/seqloc/accguide.inc b/c++/src/objects/seqloc/accguide.inc
index 69eec7a..a5e8109 100644
--- a/c++/src/objects/seqloc/accguide.inc
+++ b/c++/src/objects/seqloc/accguide.inc
@@ -1,4 +1,4 @@
-/*  $Id: accguide.inc 497278 2016-04-05 17:43:39Z ucko $
+/*  $Id: accguide.inc 519343 2016-11-15 13:41:14Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,7 +31,7 @@
  */
 
 static const char* const kBuiltInGuide[] = {
-    "# $Id: accguide.inc 497278 2016-04-05 17:43:39Z ucko $",
+    "# $Id: accguide.inc 519343 2016-11-15 13:41:14Z ucko $",
     "version  1 # of file format",
     "",
     "# 8-character protein accessions",
@@ -44,7 +44,6 @@ static const char* const kBuiltInGuide[] = {
     "3+5  E??  gb_wgs_prot",
     "3+5  F??  ddbj_tpa_prot",
     "3+5  G??  ddbj_wgs_prot",
-    "3+5  H??  gb_tpa_wgs_prot",
     "3+5  I??  ddbj_tpa_prot # fallback to placate older clients",
     "3+5  I??  ddbj_tpa_wgs_prot",
     "3+5  J??  gb_tsa_prot",
@@ -99,12 +98,9 @@ static const char* const kBuiltInGuide[] = {
     "4+8   E???  ddbj_tpa_wgs_nuc",
     "4+9   E???  ddbj_tpa_wgs_nuc",
     "4+10  E???  ddbj_tpa_wgs_nuc",
-    "4+8   F???  embl_tpa_nuc # fallback to placate older clients",
-    "4+9   F???  embl_tpa_nuc # fallback to placate older clients",
-    "4+10  F???  embl_tpa_nuc # fallback to placate older clients",
-    "4+8   F???  embl_tpa_wgs_nuc",
-    "4+9   F???  embl_tpa_wgs_nuc",
-    "4+10  F???  embl_tpa_wgs_nuc",
+    "4+8   F???  embl_wgs_nuc",
+    "4+9   F???  embl_wgs_nuc",
+    "4+10  F???  embl_wgs_nuc",
     "4+8   G???  gb_tsa_nuc",
     "4+9   G???  gb_tsa_nuc",
     "4+10  G???  gb_tsa_nuc",
@@ -132,12 +128,9 @@ static const char* const kBuiltInGuide[] = {
     "4+8   N???  gb_wgs_nuc",
     "4+9   N???  gb_wgs_nuc",
     "4+10  N???  gb_wgs_nuc",
-    "4+8   O???  embl_tpa_nuc # fallback to placate older clients",
-    "4+9   O???  embl_tpa_nuc # fallback to placate older clients",
-    "4+10  O???  embl_tpa_nuc # fallback to placate older clients",
-    "4+8   O???  embl_tpa_wgs_nuc",
-    "4+9   O???  embl_tpa_wgs_nuc",
-    "4+10  O???  embl_tpa_wgs_nuc",
+    "4+8   O???  embl_wgs_nuc",
+    "4+9   O???  embl_wgs_nuc",
+    "4+10  O???  embl_wgs_nuc",
     "4+8   P???  gb_wgs_nuc",
     "4+9   P???  gb_wgs_nuc",
     "4+10  P???  gb_wgs_nuc",
@@ -147,6 +140,9 @@ static const char* const kBuiltInGuide[] = {
     "4+8   R???  gb_wgs_nuc",
     "4+9   R???  gb_wgs_nuc",
     "4+10  R???  gb_wgs_nuc",
+    "4+8   S???  gb_wgs_nuc # specifically, USPTO pre-grant patent data",
+    "4+9   S???  gb_wgs_nuc # specifically, USPTO pre-grant patent data",
+    "4+10  S???  gb_wgs_nuc # specifically, USPTO pre-grant patent data",
     "",
     "# Mass sequence Genome for Annotation",
     "5+7   A???? ddbj_other_nuc",
@@ -487,6 +483,7 @@ static const char* const kBuiltInGuide[] = {
     "2+6  KU  gb_dirsub",
     "2+6  KV  gb_con",
     "2+6  KX  gb_dirsub",
+    "2+6  KY  gb_dirsub",
     "2+6  K?  gb_other_nuc",
     "2+6  LA  ddbj_tsa_nuc",
     "2+6  LB  ddbj_gss",
@@ -509,8 +506,8 @@ static const char* const kBuiltInGuide[] = {
     "2+6  LS  embl_other_nuc",
     "2+6  LT  embl_other_nuc",
     "2+6  LU  ddbj_est",
-    "2+6  LV  ddbj_other_nuc",
-    "2+6  LX  ddbj_other_nuc",
+    "2+6  LV  ddbj_patent",
+    "2+6  LX  ddbj_patent",
     "2+6  LY  ddbj_other_nuc",
     "2+6  LZ  ddbj_other_nuc",
     "2+6  MA  ddbj_other_nuc",
@@ -9710,11 +9707,37 @@ static const char* const kBuiltInGuide[] = {
     "special  CEL77190-CEL78176  embl_tpa_prot",
     "special  CEL78178-CEL78353  embl_tpa_prot",
     "special  CEL78355-CEL78878  embl_tpa_prot",
+    "special  CEO43666-CEO43667  embl_tpa_prot",
+    "special  CRI06393-CRI06404  embl_tpa_prot",
     "special  CRK77046           embl_tpa_prot",
     "special  CTQ86077-CTQ86287  embl_tpa_prot",
     "special  CUS27851-CUS27862  embl_tpa_prot",
     "special  CUS58523-CUS58613  embl_tpa_prot",
+    "",
+    "special  SAI82130-SAI82138  embl_tpa_prot",
+    "special  SAI82141           embl_tpa_prot",
+    "special  SAI82144-SAI82145  embl_tpa_prot",
+    "special  SAI82147-SAI82149  embl_tpa_prot",
+    "special  SAI82151-SAI82165  embl_tpa_prot",
+    "special  SAI82168-SAI82180  embl_tpa_prot",
+    "special  SAI82182-SAI82186  embl_tpa_prot",
+    "special  SAI82188-SAI82198  embl_tpa_prot",
+    "special  SAI82201-SAI82210  embl_tpa_prot",
+    "special  SAI82212-SAI82222  embl_tpa_prot",
+    "special  SAI82224-SAI82225  embl_tpa_prot",
+    "special  SAI82227-SAI82235  embl_tpa_prot",
+    "special  SAI82237-SAI82242  embl_tpa_prot",
+    "special  SAI82244-SAI82255  embl_tpa_prot",
+    "special  SAI82257-SAI82282  embl_tpa_prot",
+    "special  SAI82284-SAI82285  embl_tpa_prot",
+    "special  SAI82287           embl_tpa_prot",
+    "special  SAI82289           embl_tpa_prot",
+    "special  SAI82292           embl_tpa_prot",
+    "special  SAI82294-SAI82296  embl_tpa_prot",
+    "special  SAI82298-SAI82303  embl_tpa_prot",
+    "special  SAQ69746-SAQ69766  embl_tpa_prot",
+    "special  SAQ71209           embl_tpa_prot",
     "## Err on the side of caution on as yet unassigned IDs, and hope that",
     "## there's not *too* much more backfilling.",
-    "#special CUT08921-CZZ99999  unreserved_prot"
+    "#special SEW57495-SZZ99999  unreserved_prot"
 };
diff --git a/c++/src/objects/seqloc/accguide.txt b/c++/src/objects/seqloc/accguide.txt
index 3e66bfa..996d315 100644
--- a/c++/src/objects/seqloc/accguide.txt
+++ b/c++/src/objects/seqloc/accguide.txt
@@ -1,4 +1,4 @@
-# $Id: accguide.txt 497278 2016-04-05 17:43:39Z ucko $
+# $Id: accguide.txt 519343 2016-11-15 13:41:14Z ucko $
 version  1 # of file format
 
 # 8-character protein accessions
@@ -11,7 +11,6 @@ version  1 # of file format
 3+5  E??  gb_wgs_prot
 3+5  F??  ddbj_tpa_prot
 3+5  G??  ddbj_wgs_prot
-3+5  H??  gb_tpa_wgs_prot
 3+5  I??  ddbj_tpa_prot # fallback to placate older clients
 3+5  I??  ddbj_tpa_wgs_prot
 3+5  J??  gb_tsa_prot
@@ -66,12 +65,9 @@ version  1 # of file format
 4+8   E???  ddbj_tpa_wgs_nuc
 4+9   E???  ddbj_tpa_wgs_nuc
 4+10  E???  ddbj_tpa_wgs_nuc
-4+8   F???  embl_tpa_nuc # fallback to placate older clients
-4+9   F???  embl_tpa_nuc # fallback to placate older clients
-4+10  F???  embl_tpa_nuc # fallback to placate older clients
-4+8   F???  embl_tpa_wgs_nuc
-4+9   F???  embl_tpa_wgs_nuc
-4+10  F???  embl_tpa_wgs_nuc
+4+8   F???  embl_wgs_nuc
+4+9   F???  embl_wgs_nuc
+4+10  F???  embl_wgs_nuc
 4+8   G???  gb_tsa_nuc
 4+9   G???  gb_tsa_nuc
 4+10  G???  gb_tsa_nuc
@@ -99,12 +95,9 @@ version  1 # of file format
 4+8   N???  gb_wgs_nuc
 4+9   N???  gb_wgs_nuc
 4+10  N???  gb_wgs_nuc
-4+8   O???  embl_tpa_nuc # fallback to placate older clients
-4+9   O???  embl_tpa_nuc # fallback to placate older clients
-4+10  O???  embl_tpa_nuc # fallback to placate older clients
-4+8   O???  embl_tpa_wgs_nuc
-4+9   O???  embl_tpa_wgs_nuc
-4+10  O???  embl_tpa_wgs_nuc
+4+8   O???  embl_wgs_nuc
+4+9   O???  embl_wgs_nuc
+4+10  O???  embl_wgs_nuc
 4+8   P???  gb_wgs_nuc
 4+9   P???  gb_wgs_nuc
 4+10  P???  gb_wgs_nuc
@@ -114,6 +107,9 @@ version  1 # of file format
 4+8   R???  gb_wgs_nuc
 4+9   R???  gb_wgs_nuc
 4+10  R???  gb_wgs_nuc
+4+8   S???  gb_wgs_nuc # specifically, USPTO pre-grant patent data
+4+9   S???  gb_wgs_nuc # specifically, USPTO pre-grant patent data
+4+10  S???  gb_wgs_nuc # specifically, USPTO pre-grant patent data
 
 # Mass sequence Genome for Annotation
 5+7   A???? ddbj_other_nuc
@@ -454,6 +450,7 @@ version  1 # of file format
 2+6  KU  gb_dirsub
 2+6  KV  gb_con
 2+6  KX  gb_dirsub
+2+6  KY  gb_dirsub
 2+6  K?  gb_other_nuc
 2+6  LA  ddbj_tsa_nuc
 2+6  LB  ddbj_gss
@@ -476,8 +473,8 @@ version  1 # of file format
 2+6  LS  embl_other_nuc
 2+6  LT  embl_other_nuc
 2+6  LU  ddbj_est
-2+6  LV  ddbj_other_nuc
-2+6  LX  ddbj_other_nuc
+2+6  LV  ddbj_patent
+2+6  LX  ddbj_patent
 2+6  LY  ddbj_other_nuc
 2+6  LZ  ddbj_other_nuc
 2+6  MA  ddbj_other_nuc
@@ -9677,10 +9674,36 @@ special  CEL76768-CEL77188  embl_tpa_prot
 special  CEL77190-CEL78176  embl_tpa_prot
 special  CEL78178-CEL78353  embl_tpa_prot
 special  CEL78355-CEL78878  embl_tpa_prot
+special  CEO43666-CEO43667  embl_tpa_prot
+special  CRI06393-CRI06404  embl_tpa_prot
 special  CRK77046           embl_tpa_prot
 special  CTQ86077-CTQ86287  embl_tpa_prot
 special  CUS27851-CUS27862  embl_tpa_prot
 special  CUS58523-CUS58613  embl_tpa_prot
+
+special  SAI82130-SAI82138  embl_tpa_prot
+special  SAI82141           embl_tpa_prot
+special  SAI82144-SAI82145  embl_tpa_prot
+special  SAI82147-SAI82149  embl_tpa_prot
+special  SAI82151-SAI82165  embl_tpa_prot
+special  SAI82168-SAI82180  embl_tpa_prot
+special  SAI82182-SAI82186  embl_tpa_prot
+special  SAI82188-SAI82198  embl_tpa_prot
+special  SAI82201-SAI82210  embl_tpa_prot
+special  SAI82212-SAI82222  embl_tpa_prot
+special  SAI82224-SAI82225  embl_tpa_prot
+special  SAI82227-SAI82235  embl_tpa_prot
+special  SAI82237-SAI82242  embl_tpa_prot
+special  SAI82244-SAI82255  embl_tpa_prot
+special  SAI82257-SAI82282  embl_tpa_prot
+special  SAI82284-SAI82285  embl_tpa_prot
+special  SAI82287           embl_tpa_prot
+special  SAI82289           embl_tpa_prot
+special  SAI82292           embl_tpa_prot
+special  SAI82294-SAI82296  embl_tpa_prot
+special  SAI82298-SAI82303  embl_tpa_prot
+special  SAQ69746-SAQ69766  embl_tpa_prot
+special  SAQ71209           embl_tpa_prot
 ## Err on the side of caution on as yet unassigned IDs, and hope that
 ## there's not *too* much more backfilling.
-#special CUT08921-CZZ99999  unreserved_prot
+#special SEW57495-SZZ99999  unreserved_prot
diff --git a/c++/src/objects/seqset/Bioseq_set.cpp b/c++/src/objects/seqset/Bioseq_set.cpp
index cf9e6f1..d683eff 100644
--- a/c++/src/objects/seqset/Bioseq_set.cpp
+++ b/c++/src/objects/seqset/Bioseq_set.cpp
@@ -1,4 +1,4 @@
-/* $Id: Bioseq_set.cpp 497874 2016-04-11 18:28:01Z ivanov $
+/* $Id: Bioseq_set.cpp 519216 2016-11-14 16:06:08Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -207,9 +207,10 @@ void CBioseq_set::GetLabel(string* label, ELabelType type) const
     if (!best_seq_id) {
         *label += "(No Bioseqs)";
     } else {
-        CNcbiOstrstream os;
-        os << best_seq_id->DumpAsFasta();
-        *label += CNcbiOstrstreamToString(os);
+        //CNcbiOstrstream os;
+        //os << best_seq_id->DumpAsFasta();
+        //*label += CNcbiOstrstreamToString(os);
+        *label += best_seq_id->GetSeqIdString();
         if (this->IsSetSeq_set()) {
             const TSeq_set& sset = this->GetSeq_set();
             size_t len = sset.size();
@@ -326,5 +327,29 @@ CConstRef<CBioseq_set> CBioseq::GetParentSet(void) const
 }
 
 
+bool CBioseq_set::NeedsDocsumTitle(EClass set_class)
+{
+    bool rval = false;
+    if (set_class == CBioseq_set::eClass_pop_set
+        || set_class == CBioseq_set::eClass_phy_set
+        || set_class == CBioseq_set::eClass_eco_set
+        || set_class == CBioseq_set::eClass_mut_set) {
+        rval = true;
+    }
+    return rval;
+}
+
+
+bool CBioseq_set::NeedsDocsumTitle() const
+{
+    bool rval = false;
+    if (IsSetClass()) {
+        rval = NeedsDocsumTitle(GetClass());
+    }
+    return rval;
+
+}
+
+
 END_objects_SCOPE // namespace ncbi::objects::
 END_NCBI_SCOPE
diff --git a/c++/src/objects/taxon1/Taxon2_data.cpp b/c++/src/objects/taxon1/Taxon2_data.cpp
index 63a3640..f32e3b7 100644
--- a/c++/src/objects/taxon1/Taxon2_data.cpp
+++ b/c++/src/objects/taxon1/Taxon2_data.cpp
@@ -1,4 +1,4 @@
-/* $Id: Taxon2_data.cpp 454841 2014-12-18 17:45:33Z domrach $
+/* $Id: Taxon2_data.cpp 494538 2016-03-08 14:31:04Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objects/taxon1/taxon1.cpp b/c++/src/objects/taxon1/taxon1.cpp
index be92151..e4cea54 100644
--- a/c++/src/objects/taxon1/taxon1.cpp
+++ b/c++/src/objects/taxon1/taxon1.cpp
@@ -1,4 +1,4 @@
-/* $Id: taxon1.cpp 488663 2016-01-04 18:15:48Z domrach $
+/* $Id: taxon1.cpp 504314 2016-06-14 14:34:17Z domrach $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1057,12 +1057,12 @@ CTaxon1::GetSpecies(TTaxId id_tax, ESpeciesMode mode)
     if( mode == eSpeciesMode_RankOnly ) {
         int species_rank(m_plCache->GetSpeciesRank());
         while( !pNode->IsRoot() ) {
-        int rank( pNode->GetRank() );
-        if( rank == species_rank )
-            return pNode->GetTaxId();
-        if( (rank > 0) && (rank < species_rank))
-            return 0;
-        pNode = pNode->GetParent();
+	    int rank( pNode->GetRank() );
+	    if( rank == species_rank )
+		return pNode->GetTaxId();
+	    if( (rank >= 0) && (rank < species_rank))
+		return 0;
+	    pNode = pNode->GetParent();
         }
         return 0;
     } else { // Based on flag
@@ -1114,10 +1114,11 @@ CTaxon1::GetGenus(TTaxId id_tax)
             int rank( pNode->GetRank() );
             if( rank == genus_rank )
                 return pNode->GetTaxId();
-            if( (rank > 0) && (rank < genus_rank))
-                return 0;
+            if( (rank >= 0) && (rank < genus_rank))
+                break;
             pNode = pNode->GetParent();
         }
+	return 0;
     }
     return -1;
 }
@@ -1145,10 +1146,9 @@ CTaxon1::GetSuperkingdom(TTaxId id_tax)
             int rank( pNode->GetRank() );
             if( rank == sk_rank )
                 return pNode->GetTaxId();
-            if( (rank > 0) && (rank < sk_rank))
-                return 0;
             pNode = pNode->GetParent();
         }
+	return 0;
     }
     return -1;
 }
@@ -1897,7 +1897,7 @@ CTaxon1::LoadSubtreeEx( TTaxId tax_id, int levels, const ITaxon1Node** ppNode )
                             pIt->GoNode( pNode );
                         } else { // Invalid parent specified
                             SetLastError( ("Invalid parent taxid "
-                                           + NStr::IntToString((*i)->GetTaxid())
+                                           + NStr::NumericToString((*i)->GetTaxid())
                                            ).c_str() );
                             return false;
                         }
diff --git a/c++/src/objects/taxon1/taxon1.def b/c++/src/objects/taxon1/taxon1.def
index 415b483..ec06b29 100644
--- a/c++/src/objects/taxon1/taxon1.def
+++ b/c++/src/objects/taxon1/taxon1.def
@@ -7,3 +7,15 @@ id4gi._storage_type = ncbi::TIntId
 
 [Taxon1-name]
 taxid._type = ncbi::TTaxId
+
+[Taxon1-info]
+ival1._type = ncbi::TEntrezId
+ival1._storage_type = ncbi::TIntId
+ival2._type = ncbi::TEntrezId
+ival2._storage_type = ncbi::TIntId
+
+[Taxon1-name]
+taxid._type = ncbi::TEntrezId
+taxid._storage_type = ncbi::TIntId
+cde._type = ncbi::TEntrezId
+cde._storage_type = ncbi::TIntId
diff --git a/c++/src/objects/trackmgr/TMgr_ClientInfo.cpp b/c++/src/objects/trackmgr/TMgr_ClientInfo.cpp
index 2a0dfac..90fa2cf 100644
--- a/c++/src/objects/trackmgr/TMgr_ClientInfo.cpp
+++ b/c++/src/objects/trackmgr/TMgr_ClientInfo.cpp
@@ -1,4 +1,4 @@
-/* $Id: TMgr_ClientInfo.cpp 441174 2014-07-21 20:51:07Z meric $
+/* $Id: TMgr_ClientInfo.cpp 498903 2016-04-20 15:50:10Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -66,7 +66,7 @@ void CTMgr_ClientInfo::SetContext(const CTMgr_ClientInfo::TContext& value)
     TContext context = value;
 
     TTokens major_tokens;
-    NStr::Tokenize(value, major_delim, major_tokens, NStr::fSplit_ByPattern);
+    NStr::Split(value, major_delim, major_tokens, NStr::fSplit_ByPattern);
     bool is_context = true;
 
     ITERATE (TTokens, it, major_tokens) {
diff --git a/c++/src/objects/trackmgr/displaytrack_client.cpp b/c++/src/objects/trackmgr/displaytrack_client.cpp
index 4676feb..c7ecbbc 100644
--- a/c++/src/objects/trackmgr/displaytrack_client.cpp
+++ b/c++/src/objects/trackmgr/displaytrack_client.cpp
@@ -1,4 +1,4 @@
-/* $Id: displaytrack_client.cpp 439067 2014-06-25 13:02:23Z meric $
+/* $Id: displaytrack_client.cpp 505996 2016-06-30 17:03:39Z meric $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -32,6 +32,7 @@
 #include <ncbi_pch.hpp>
 #include <objects/trackmgr/trackmgr__.hpp>
 #include <objects/trackmgr/displaytrack_client.hpp>
+#include <serial/rpcbase.hpp>
 
 
 BEGIN_NCBI_SCOPE
@@ -53,20 +54,90 @@ CTMS_DisplayTrack_Client::CTMS_DisplayTrack_Client(const string& NS_registry_sec
 {
 }
 
-CTMS_DisplayTrack_Client::~CTMS_DisplayTrack_Client()
+CTMS_DisplayTrack_Client::CTMS_DisplayTrack_Client(const HttpService&& http_svc)
+    : m_Http_svc(http_svc.service),
+      m_Http_session(new CHttpSession())
 {
 }
 
-CTMS_DisplayTrack_Client::TReplyRef
+CTMS_DisplayTrack_Client
+CTMS_DisplayTrack_Client::CreateServiceClient(const string& http_svc)
+{
+    return CTMS_DisplayTrack_Client{HttpService{http_svc}};
+}
+
+bool
+CTMS_DisplayTrack_Client::FetchRawStream(CNcbiIstream& requeststr, CNcbiOstream& replystr) const
+{
+    if (m_Http_session.NotNull()) {
+        NCBI_THROW(CException, eUnknown, "FetchRawStream() does not support HTTP-based client");
+    }
+    try {
+        const auto retval = TBaseClient::AskStream(requeststr, replystr);
+        return retval.second; // timed_out
+    }
+    catch (const CException& e) {
+        NCBI_REPORT_EXCEPTION("Exception communicating with TMS-DisplayTrack service ", e);
+        return false;
+    }
+    NCBI_THROW(CException, eUnknown, "FetchRawStream(): unexpected code path");
+}
+
+string
+RequestToString(const CTMS_DisplayTrack_Client::TRequest& request)
+{
+    CConn_MemoryStream mem_str;
+    // need the asnbincompressed stream to be destroyed in order for stream to be flushed
+    *CAsnBinCompressed::GetOStream(mem_str) << request;
+    string data;
+    mem_str.ToString(&data);
+    ERR_POST(Trace << "encoded request " << mem_str.tellp() << " bytes");
+    return data;
+}
+
+auto
+CTMS_DisplayTrack_Client::x_HttpFetch(const TRequest& request) const
+-> TReplyRef
+{
+    CPerfLogGuard pl("Fetch via HTTP");
+    const CTimeout timeout{ 20, 400000 }; // 20400ms
+    const auto& content_type = kEmptyStr;
+    // read data from stream
+    const auto reqdata = RequestToString(request);
+    ERR_POST(Trace << "encoded request " << reqdata.size() << " bytes");
+    // connect to http service
+    const auto response = m_Http_session->Post(m_Http_svc, reqdata, content_type, timeout);
+    if (!response.CanGetContentStream()) {
+        pl.Post(CRequestStatus::e200_Ok, "No response");
+        CConn_MemoryStream mem_str;
+        NcbiStreamCopy(mem_str, response.ErrorStream());
+        string err;
+        mem_str.ToString(&err);
+        ERR_POST(response.GetStatusText() << " -- " << err);
+        return TReplyRef{};
+    }
+    ERR_POST(Trace << "status_code: " << response.GetStatusCode());
+    auto objistr = CAsnBinCompressed::GetIStream(response.ContentStream());
+    auto reply = Ref(new TReply());
+    *objistr >> *reply;
+    pl.Post(CRequestStatus::e200_Ok, "Fetch");
+    return reply;
+}
+
+auto
 CTMS_DisplayTrack_Client::Fetch(const TRequest& request) const
+-> TReplyRef
 {
-    CRef<TReply> reply;
+    TReplyRef reply;
     try {
+        if (m_Http_session.NotNull()) {
+            return x_HttpFetch(request);
+        }
         reply.Reset(new TReply());
-        TBaseClient::Ask(request, *reply);
+        TBaseClient::Ask(request, reply.GetObject());
     }
     catch (const CException& e) {
-        NCBI_REPORT_EXCEPTION("Exception communicating with TMS-DisplayTrack service ", e);
+        NCBI_REPORT_EXCEPTION("Exception communicating with TMS-DisplayTracks service ", e);
         reply.Reset();
     }
     return reply;
diff --git a/c++/src/objects/trackmgr/trackmgr.asn b/c++/src/objects/trackmgr/trackmgr.asn
index e5860c7..e9c7640 100644
--- a/c++/src/objects/trackmgr/trackmgr.asn
+++ b/c++/src/objects/trackmgr/trackmgr.asn
@@ -1,4 +1,4 @@
---- $Id: trackmgr.asn 478159 2015-09-04 13:57:39Z meric $
+--- $Id: trackmgr.asn 498762 2016-04-19 15:46:52Z clausen $
 ---
 --- Definitions for the TrackManager service
 ---
@@ -79,7 +79,8 @@ TMgr-DisplayTrackRequest ::= SEQUENCE {
     authorization TMgr-TrackACL-Authorization OPTIONAL,
     flags SEQUENCE {
         include-stats BOOLEAN DEFAULT FALSE,
-        include-default-tracks BOOLEAN OPTIONAL
+        include-default-tracks BOOLEAN OPTIONAL,
+        include-track-items BOOLEAN DEFAULT FALSE
     } OPTIONAL
 }
 
@@ -183,7 +184,8 @@ TMgr-DisplayTrack ::= SEQUENCE {
     dtrack-id TMgr-DTrackId,
     name UTF8String,
     attrs SET OF TMgr-Attribute OPTIONAL,
-    seqs SET OF TMgr-DatasetItemSeq OPTIONAL
+    seqs SET OF TMgr-DatasetItemSeq OPTIONAL,
+    items SET OF TMgr-DatasetItem OPTIONAL
 }
 
 TMgr-DatasetItem ::= SEQUENCE {
@@ -380,7 +382,10 @@ TMgr-RetrieveTracksetRequest ::= SEQUENCE {
 
 TMgr-RetrieveTracksetReply ::= SEQUENCE {
     messages SEQUENCE OF TMgr-Message OPTIONAL,
-    tracksets SET OF TMgr-TrackSet OPTIONAL
+    tracksets SET OF TMgr-TrackSet OPTIONAL,
+    flags SEQUENCE {
+        include-track-items BOOLEAN DEFAULT FALSE
+    } OPTIONAL
 }
 
 TMgr-CreateTracksetRequest ::= SEQUENCE {
diff --git a/c++/src/objects/valerr/ValidErrItem.cpp b/c++/src/objects/valerr/ValidErrItem.cpp
index dc21742..2fce2fa 100644
--- a/c++/src/objects/valerr/ValidErrItem.cpp
+++ b/c++/src/objects/valerr/ValidErrItem.cpp
@@ -1,4 +1,4 @@
-/* $Id: ValidErrItem.cpp 493799 2016-03-02 13:50:42Z ivanov $
+/* $Id: ValidErrItem.cpp 519224 2016-11-14 16:08:42Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -51,696 +51,738 @@ BEGIN_objects_SCOPE // namespace ncbi::objects::
 typedef SStaticPair<const char*, const char*> TErrStrs;
 typedef SStaticPair<unsigned int, TErrStrs> TErrTypStrs;
 
-static const TErrTypStrs sc_ErrStrs [] = {
+static const TErrTypStrs sc_ErrStrs[] = {
     { eErr_ALL,
-    {  "ALL", "ALL" } },
+    { "ALL", "ALL" } },
     { eErr_UNKNOWN,
-    {  "UNKNOWN", "UNKNOWN" } },
-
-/* SEQ_INST */
-
-   { eErr_SEQ_INST_ExtNotAllowed,
-   { "ExtNotAllowed",
-"A Bioseq \"extension\" is used for special classes of Bioseq. This class of \
-Bioseq should not have one but it does. This is probably a software error." } },
-   { eErr_SEQ_INST_ExtBadOrMissing,
-   { "ExtBadOrMissing",
-"This class of Bioseq requires an \"extension\" but it is missing or of the \
-wrong type. This is probably a software error." } },
-   { eErr_SEQ_INST_SeqDataNotFound,
-   { "SeqDataNotFound",
-"No actual sequence data was found on this Bioseq. This is probably a \
-software problem." } },
-   { eErr_SEQ_INST_SeqDataNotAllowed,
-   { "SeqDataNotAllowed",
-"The wrong type of sequence data was found on this Bioseq. This is probably a \
-software problem." } },
-   { eErr_SEQ_INST_ReprInvalid,
-   { "ReprInvalid",
-"This Bioseq has an invalid representation class. This is probably a software \
-error." } },
-   { eErr_SEQ_INST_CircularProtein,
-   { "CircularProtein",
-"This protein Bioseq is represented as circular. Circular topology is \
-normally used only for certain DNA molecules, for example, plasmids." } },
-   { eErr_SEQ_INST_DSProtein,
-   { "DSProtein",
-"This protein Bioseq has strandedness indicated. Strandedness is normally a \
-property only of DNA sequences. Please unset the strandedness." } },
-   { eErr_SEQ_INST_MolNotSet,
-   { "MolNotSet",
-"It is not clear whether this sequence is nucleic acid or protein. Please set \
-the appropriate molecule type (Bioseq.mol)." } },
-   { eErr_SEQ_INST_MolOther,
-   { "MolOther",
-"Most sequences are either nucleic acid or protein. However, the molecule \
-type (Bioseq.mol) is set to \"other\". It should probably be set to nucleic \
-acid or a protein." } },
-   { eErr_SEQ_INST_FuzzyLen,
-   { "FuzzyLen",
-"This sequence is marked as having an uncertain length, but the length is \
-known exactly." } },
-   { eErr_SEQ_INST_InvalidLen,
-   { "InvalidLen",
-"The length indicated for this sequence is invalid. This is probably a \
-software error." } },
-   { eErr_SEQ_INST_InvalidAlphabet,
-   { "InvalidAlphabet",
-"This Bioseq has an invalid alphabet (e.g. protein codes on a nucleic acid or \
-vice versa). This is probably a software error." } },
-   { eErr_SEQ_INST_SeqDataLenWrong,
-   { "SeqDataLenWrong",
-"The length of this Bioseq does not agree with the length of the actual data. \
-This is probably a software error." } },
-   { eErr_SEQ_INST_SeqPortFail,
-   { "SeqPortFail",
-"Something is very wrong with this entry. The validator cannot open a SeqPort \
-on the Bioseq. Further testing cannot be done." } },
-   { eErr_SEQ_INST_InvalidResidue,
-   { "InvalidResidue",
-"Invalid residue codes were found in this Bioseq." } },
-   { eErr_SEQ_INST_StopInProtein,
-   { "StopInProtein",
-"Stop codon symbols were found in this protein Bioseq." } },
-   { eErr_SEQ_INST_PartialInconsistent,
-   { "PartialInconsistent",
-"This segmented sequence is described as complete or incomplete in several \
-places, but these settings are inconsistent." } },
-   { eErr_SEQ_INST_ShortSeq,
-   { "ShortSeq",
-"This Bioseq is unusually short (less than 4 amino acids or less than 11 \
-nucleic acids). GenBank does not usually accept such short sequences." } },
-   { eErr_SEQ_INST_NoIdOnBioseq,
-   { "NoIdOnBioseq",
-"No SeqIds were found on this Bioseq. This is probably a software error." } },
-   { eErr_SEQ_INST_BadDeltaSeq,
-   { "BadDeltaSeq",
-"Delta sequences should only be HTGS-1 or HTGS-2." } },
-   { eErr_SEQ_INST_LongHtgsSequence,
-   { "LongHtgsSequence",
-"HTGS-1 or HTGS-2 sequences must be < 350 KB in length." } },
-   { eErr_SEQ_INST_LongLiteralSequence,
-   { "LongLiteralSequence",
-"Delta literals must be < 350 KB in length." } },
-   { eErr_SEQ_INST_SequenceExceeds350kbp,
-   { "SequenceExceeds350kbp",
-"Individual sequences must be < 350 KB in length, unless they represent a single gene." } },
-   { eErr_SEQ_INST_ConflictingIdsOnBioseq,
-   { "ConflictingIdsOnBioseq",
-"Two SeqIds of the same class was found on this Bioseq. This is probably a software error." } },
-   { eErr_SEQ_INST_MolNuclAcid,
-   { "MolNuclAcid",
-"The specific type of this nucleic acid (DNA or RNA) is not set." } },
-   { eErr_SEQ_INST_ConflictingBiomolTech,
-   { "ConflictingBiomolTech",
-"HTGS/STS/GSS records should be genomic DNA. There is a conflict between the \
-technique and expected molecule type." } },
-   { eErr_SEQ_INST_SeqIdNameHasSpace,
-   { "SeqIdNameHasSpace",
-"The Seq-id.name field should be a single word without any whitespace. This should be \
-fixed by the database staff." } },
-   { eErr_SEQ_INST_IdOnMultipleBioseqs,
-   { "IdOnMultipleBioseqs",
-"There are multiple occurrences of the same Seq-id in this record. Sequence \
-identifiers must be unique within a record." } },
-   { eErr_SEQ_INST_DuplicateSegmentReferences,
-   { "DuplicateSegmentReferences",
-"The segmented sequence refers multiple times to the same Seq-id. This may be due \
-to a software error. Please consult with the database staff to fix this record." } },
-   { eErr_SEQ_INST_TrailingX,
-   { "TrailingX",
-"The protein sequence ends with one or more X (unknown) amino acids." } },
-   { eErr_SEQ_INST_BadSeqIdFormat,
-   { "BadSeqIdFormat",
-"A nucleotide sequence identifier should be 1 letter plus 5 digits or 2 letters \
-plus 6 digits, and a protein sequence identifer should be 3 letters plus 5 digits." } },
-   { eErr_SEQ_INST_PartsOutOfOrder,
-   { "PartsOutOfOrder",
-"The parts inside a segmented set should correspond to the seq_ext of the segmented \
-bioseq.  A difference will affect how the flatfile is displayed." } },
-   { eErr_SEQ_INST_BadSecondaryAccn,
-   { "BadSecondaryAccn",
-"A secondary accession usually indicates a record replaced or subsumed by the current \
-record.  In this case, the current accession and secondary are the same." } },
-   { eErr_SEQ_INST_ZeroGiNumber,
-   { "ZeroGiNumber",
-"GI numbers are assigned to sequences by NCBI's sequence tracking database.  0 is not \
-a legal value for a gi number." } },
-   { eErr_SEQ_INST_RnaDnaConflict,
-   { "RnaDnaConflict",
-"The MolInfo biomol field is inconsistent with the Bioseq molecule type field." } },
-   { eErr_SEQ_INST_HistoryGiCollision,
-   { "HistoryGiCollision",
-"The Bioseq history gi refers to this Bioseq, not to its predecessor or successor." } },
-   { eErr_SEQ_INST_GiWithoutAccession,
-   { "GiWithoutAccession",
-"The Bioseq has a gi identifier but no GenBank/EMBL/DDBJ accession identifier." } },
-   { eErr_SEQ_INST_MultipleAccessions,
-   { "MultipleAccessions",
-"The Bioseq has a gi identifier and more than one GenBank/EMBL/DDBJ accession identifier." } },
-   { eErr_SEQ_INST_HistAssemblyMissing,
-   { "HistAssemblyMissing",
-"The Bioseq has a TPA identifier but does not have a Seq-hist.assembly alignment.  This \
-should be annotated or calculated by the database, resulting in a PRIMARY block visible \
-in the flatfile." } },
-   { eErr_SEQ_INST_TerminalNs,
-   { "TerminalNs",
-"The Bioseq has one or more N bases at the end." } },
-   { eErr_SEQ_INST_UnexpectedIdentifierChange,
-   { "UnexpectedIdentifierChange",
-"The set of sequence identifiers on a Bioseq are not consistent with the previous version \
-of the record in the database." } },
-   { eErr_SEQ_INST_InternalNsInSeqLit,
-   { "InternalNsInSeqLit",
-"There are runs of many Ns inside the SeqLit component of a delta Bioseq." } },
-   { eErr_SEQ_INST_SeqLitGapLength0,
-   { "SeqLitGapLength0",
-"A SeqLit component of a delta Bioseq can specify a gap, but it should not be a gap \
-of 0 length." } },
-   { eErr_SEQ_INST_TpaAssmeblyProblem,
-   { "TpaAssmeblyProblem",
-"Third party annotation records should have a TpaAssembly user object and a \
-Seq-hist.assembly alignment for the PRIMARY block." } },
-   { eErr_SEQ_INST_SeqLocLength,
-   { "SeqLocLength",
-"A SeqLoc component of a delta Bioseq is suspiciously small." } },
-   { eErr_SEQ_INST_MissingGaps,
-   { "MissingGaps",
-"HTGS delta records should have gaps between each sequence segment." } },
-   { eErr_SEQ_INST_CompleteTitleProblem,
-   { "CompleteTitleProblem",
-"The sequence title has complete genome in it, but it is not marked as complete." } },
-   { eErr_SEQ_INST_CompleteCircleProblem,
-   { "CompleteCircleProblem",
-"This sequence has a circular topology, but it is not marked as complete." } },
-   { eErr_SEQ_INST_BadHTGSeq,
-   { "BadHTGSeq",
-"High throughput genomic sequences without gaps should have quality score graphs." } },
-   { eErr_SEQ_INST_GapInProtein,
-   { "GapInProtein",
-"Gap symbols found in this protein Bioseq." } },
-   { eErr_SEQ_INST_BadProteinStart,
-   { "BadProteinStart",
-"A gap symbols was found at the start of this protein Bioseq." } },
-   { eErr_SEQ_INST_TerminalGap,
-   { "TerminalGap",
-"The Bioseq has a gap at the end." } },
-   { eErr_SEQ_INST_OverlappingDeltaRange,
-   { "OverlappingDeltaRange",
-"The Bioseq has a gap at the end." } },
-   { eErr_SEQ_INST_LeadingX,
-   { "LeadingX",
-"The protein sequence starts with one or more X (unknown) amino acids." } },
-   { eErr_SEQ_INST_InternalNsInSeqRaw,
-   { "InternalNsInSeqRaw",
-"There are runs of greater than 100 Ns within sequence.  Please describe \
-what these Ns represent with your sequence submission." } },
-   { eErr_SEQ_INST_InternalNsAdjacentToGap,
-   { "InternalNsAdjacentToGap",
-"There are Ns directly adjacent to a SeqLit gap in a delta Bioseq." } },
-   { eErr_SEQ_INST_CaseDifferenceInSeqID,
-   { "CaseDifferenceInSeqID",
-"Multiple Bioseqs have the same Seq-id except for capitalization. Sequence \
-identifiers must be unique in a case-insensitive manner within a record." } },
-   { eErr_SEQ_INST_DeltaComponentIsGi0,
-   { "DeltaComponentIsGi0",
-"Delta component refers to gi 0. This indicates an error in database processing of this record." } },
-   { eErr_SEQ_INST_FarFetchFailure,
-   { "FarFetchFailure",
-"Fetching of a far feature location or component bioseq was needed, but no fetch \
-function is registered in the program." } },
-   { eErr_SEQ_INST_InternalGapsInSeqRaw,
-   { "InternalGapsInSeqRaw",
-"Raw sequences should not have gap characters." } },
-   { eErr_SEQ_INST_SelfReferentialSequence,
-   { "SelfReferentialSequence",
-"A delta sequence must refer to other components, not to itself." } },
-   { eErr_SEQ_INST_WholeComponent,
-   { "WholeComponent",
-"A delta sequence component should be described as a specific interval, not as \
-the whole of a sequence." } },
-   { eErr_SEQ_INST_TSAHistAssemblyMissing,
-   { "TSAHistAssemblyMissing",
-"The Bioseq has a TSA MolInfo tech but does not have a Seq-hist.assembly alignment." } },
-   { eErr_SEQ_INST_ProteinsHaveGeneralID,
-   { "ProteinsHaveGeneralID",
-"One or more protein Bioseqs have a general Seq-id." } },
-   { eErr_SEQ_INST_HighNContent,
-   { "HighNContent",
-"This sequence contains too many Ns." } },
-   { eErr_SEQ_INST_SeqLitDataLength0,
-   { "SeqLitDataLength0",
-"A SeqLit component of a delta Bioseq must not have 0 length." } },
-   { eErr_SEQ_INST_DSmRNA,
-   { "DSmRNA",
-"This mRNA Bioseq is not single stranded." } },
-   { eErr_SEQ_INST_HighNContentStretch,
-   { "HighNContentStretch",
-"This sequence contains long stretches of Ns." } },
-   { eErr_SEQ_INST_HighNContentPercent,
-   { "HighNContentPercent",
-"This sequence contains a high percentage of Ns." } },
-   { eErr_SEQ_INST_SeqLitGapFuzzNot100,
-   { "SeqLitGapFuzzNot100",
-"Gap of unknown length should have standard length of 100." } },
-   { eErr_SEQ_INST_SeqGapProblem,
-   { "SeqGapProblem",
-"Inconsistent data in Seq-gap fields." } },
-   { eErr_SEQ_INST_WGSMasterLacksStrucComm,
-   { "WGSMasterLacksStrucComm",
-"WGS Master records require a Genome Assembly Data structured comment user object." } },
-   { eErr_SEQ_INST_TSAMasterLacksStrucComm,
-   { "TSAMasterLacksStrucComm",
-"TSA Master records require an Assembly Data structured comment user object." } },
-   { eErr_SEQ_INST_AllNs,
-   { "AllNs",
-"Sequence has only Ns." } },
-
-
-/* SEQ_DESCR */
-
-   { eErr_SEQ_DESCR_BioSourceMissing,
-   { "BioSourceMissing",
-"The biological source of this sequence has not been described correctly.  A \
-Bioseq must have a BioSource descriptor that covers the entire molecule. \
-Additional BioSource features may also be added to recombinant molecules, \
-natural or otherwise, to designate the parts of the molecule. Please add the \
-source information." } },
-   { eErr_SEQ_DESCR_InvalidForType,
-   { "InvalidForType",
-"This descriptor cannot be used with this Bioseq. A descriptor placed at the \
-BioseqSet level applies to all of the Bioseqs in the set. Please make sure \
-the descriptor is consistent with every sequence to which it applies." } },
-   { eErr_SEQ_DESCR_FileOpenCollision,
-   { "FileOpenCollision",
-"FileOpen is unable to find a local file.  This is normal, and can be ignored." } },
-   { eErr_SEQ_DESCR_Unknown,
-   { "Unknown",
-"An unknown or \"other\" modifier was used." } },
-   { eErr_SEQ_DESCR_NoPubFound,
-   { "NoPubFound",
-"No publications were found in this entry which refer to this Bioseq. If a \
-publication descriptor is added to a BioseqSet, it will apply to all of the \
-Bioseqs in the set. A publication feature should be used if the publication \
-applies only to a subregion of a sequence." } },
-   { eErr_SEQ_DESCR_NoOrgFound,
-   { "NoOrgFound",
-"This entry does not specify the organism that was the source of the sequence. \
-Please name the organism." } },
-   { eErr_SEQ_DESCR_MultipleBioSources,
-   { "MultipleBioSources",
-"There are multiple BioSource or OrgRef descriptors in the same chain with \
-the same taxonomic name. Their information should be combined into a single \
-BioSource descriptor." } },
-   { eErr_SEQ_DESCR_NoMolInfoFound,
-   { "NoMolInfoFound",
-"This sequence does not have a Mol-info descriptor applying to it.  This indicates \
-genomic vs. message, sequencing technique, and whether the sequence is incomplete." } },
-   { eErr_SEQ_DESCR_BadCountryCode,
-   { "BadCountryCode",
-"The country code (up to the first colon) is not on the approved list of countries." } },
-   { eErr_SEQ_DESCR_NoTaxonID,
-   { "NoTaxonID",
-"The BioSource is missing a taxonID database identifier.  This will be inserted by \
-the automated taxonomy lookup called by Clean Up Record." } },
-   { eErr_SEQ_DESCR_InconsistentBioSources,
-   { "InconsistentBioSources",
-"This population study has BioSource descriptors with different taxonomic names. \
-All members of a population study should be from the same organism." } },
-   { eErr_SEQ_DESCR_MissingLineage,
-   { "MissingLineage",
-"A BioSource should have a taxonomic lineage, which can be obtained from the \
-taxonomy network server." } },
-   { eErr_SEQ_DESCR_SerialInComment,
-   { "SerialInComment",
-"Comments that refer to the conclusions of a specific reference should not be \
-cited by a serial number inside brackets (e.g., [3]), but should instead be \
-attached as a REMARK on the reference itself." } },
-   { eErr_SEQ_DESCR_BioSourceNeedsFocus,
-   { "BioSourceNeedsFocus",
-"Focus must be set on a BioSource descriptor in records where there is a \
-BioSource feature with a different organism name." } },
-   { eErr_SEQ_DESCR_BadOrganelle,
-   { "BadOrganelle",
-"Note that only Kinetoplastida have kinetoplasts, and that only Chlorarchniophyta \
-and Cryptophyta have nucleomorphs." } },
-   { eErr_SEQ_DESCR_MultipleChromosomes,
-   { "MultipleChromosomes",
-"There are multiple chromosome qualifiers on this Bioseq.  With the exception of \
-some pseudoautosomal genes, this is likely to be a biological annotation error." } },
-   { eErr_SEQ_DESCR_BadSubSource,
-   { "BadSubSource",
-"Unassigned SubSource subtype." } },
-   { eErr_SEQ_DESCR_BadOrgMod,
-   { "BadOrgMod",
-"Unassigned OrgMod subtype." } },
-   { eErr_SEQ_DESCR_InconsistentProteinTitle,
-   { "InconsistentProteinTitle",
-"An instantiated protein title descriptor should normally be the same as the \
-automatically generated title.  This may be a curated exception, or it may \
-be out of synch with the current annotation." } },
-   { eErr_SEQ_DESCR_Inconsistent,
-   { "Inconsistent",
-"There are two descriptors of the same type which are inconsistent with each \
-other. Please make them consistent." } },
-   { eErr_SEQ_DESCR_ObsoleteSourceLocation,
-   { "ObsoleteSourceLocation",
-"There is a source location that is no longer legal for use in GenBank records." } },
-   { eErr_SEQ_DESCR_ObsoleteSourceQual,
-   { "ObsoleteSourceQual",
-"There is a source qualifier that is no longer legal for use in GenBank records." } },
-   { eErr_SEQ_DESCR_StructuredSourceNote,
-   { "StructuredSourceNote",
-"The name of a structured source field is present as text in a note.  The data \
-should probably be put into the appropriate field instead." } },
-   { eErr_SEQ_DESCR_UnnecessaryBioSourceFocus,
-   { "UnnecessaryBioSourceFocus",
-"Focus should not be set on a BioSource descriptor in records where there is no \
-BioSource feature." } },
-   { eErr_SEQ_DESCR_RefGeneTrackingWithoutStatus,
-   { "RefGeneTrackingWithoutStatus",
-"The RefGeneTracking user object does not have the required Status field set." } },
-   { eErr_SEQ_DESCR_UnwantedCompleteFlag,
-   { "UnwantedCompleteFlag",
-"The Mol-info.completeness flag should not be set on a genomic sequence, unless \
-the title also says it is a complete sequence or complete genome, nor should it \
-be set on a plasmid, chromosome, or organelle." } },
-   { eErr_SEQ_DESCR_CollidingPublications,
-   { "CollidingPublications",
-"Multiple publication descriptors with the same PMID or MUID apply to a Bioseq. \
-The lower-level ones are redundant, and should be removed." } },
-   { eErr_SEQ_DESCR_TransgenicProblem,
-   { "TransgenicProblem",
-"A BioSource descriptor with /transgenic set must be accompanied by a BioSource \
-feature on the nucleotide record." } },
-   { eErr_SEQ_DESCR_TaxonomyLookupProblem,
-   { "TaxonomyLookupProblem",
-"A BioSource descriptor or feature has flags returned by taxonomy lookup that \
-are either inconsistent with the data or require a taxonomy consult." } },
-   { eErr_SEQ_DESCR_MultipleTitles,
-   { "MultipleTitles",
-"There are multiple title descriptors in the same Bioseq or BioseqSet chain." } },
-   { eErr_SEQ_DESCR_RefGeneTrackingOnNonRefSeq,
-   { "RefGeneTrackingOnNonRefSeq",
-"The RefGeneTracking user object should only be in RefSeq records." } },
-   { eErr_SEQ_DESCR_BioSourceInconsistency,
-   { "BioSourceInconsistency",
-"There is an internal inconsistency with specific fields in the BioSource." } },
-   { eErr_SEQ_DESCR_FastaBracketTitle,
-   { "FastaBracketTitle",
-"Bracketed [...=...] information remains in the title.  This should have been parsed \
-out during sequence record generation to obtain qualifier values." } },
-   { eErr_SEQ_DESCR_MissingText,
-   { "MissingText",
-"Comments, regions, and other text descriptors need a descriptive text string. \
-The string provided with this descriptor is empty. If no text is desired, then \
-the descriptor should be removed." } },
-   { eErr_SEQ_DESCR_BadCollectionDate,
-   { "BadCollectionDate",
-"The collection date is not in the required format." } },
-   { eErr_SEQ_DESCR_BadPCRPrimerSequence,
-   { "BadPCRPrimerSequence",
-"The PCR primer sequence has illegal characters or non-IUPAC nucleotides." } },
-   { eErr_SEQ_DESCR_BadPunctuation,
-   { "BadPunctuation",
-"The title ends with incorrect punctuation marks." } },
-   { eErr_SEQ_DESCR_BadPCRPrimerName,
-   { "BadPCRPrimerName",
-"The PCR primer name appears to be a sequence instead of an identifying label." } },
-   { eErr_SEQ_DESCR_BioSourceOnProtein,
-   { "BioSourceOnProtein",
-"A BioSource descriptor should not be placed on a protein that is in a nuc-prot set." } },
-   { eErr_SEQ_DESCR_BioSourceDbTagConflict,
-   { "BioSourceDbTagConflict",
-"Multiple db_xrefs with the same database should not appear on a single BioSource." } },
-   { eErr_SEQ_DESCR_DuplicatePCRPrimerSequence,
-   { "DuplicatePCRPrimerSequence",
-"The PCR primer sequence has duplicate subsequences." } },
-   { eErr_SEQ_DESCR_MultipleNames,
-   { "MultipleNames",
-"There are multiple name descriptors in the same Bioseq or BioseqSet chain." } },
-   { eErr_SEQ_DESCR_MultipleComments,
-   { "MultipleComments",
-"There are multiple identical comment descriptors in the same Bioseq or BioseqSet chain." } },
-   { eErr_SEQ_DESCR_LatLonProblem,
-   { "LatLonProblem",
-"There is a problem with the lat_lon qualifier in the BioSource." } },
-   { eErr_SEQ_DESCR_LatLonFormat,
-   { "LatLonFormat",
-"The format of lat_lon should be dd.dd N|S ddd.dd E|W." } },
-   { eErr_SEQ_DESCR_LatLonRange,
-   { "LatLonRange",
-"Latitude or longitude is out of range." } },
-   { eErr_SEQ_DESCR_LatLonValue,
-   { "LatLonValue",
-"Latitude or longitude values appear to be in the wrong hemisphere or swapped." } },
-   { eErr_SEQ_DESCR_LatLonCountry,
-   { "LatLonCountry",
-"The lat_lon coordinate does not map to the indicated country." } },
-   { eErr_SEQ_DESCR_LatLonState,
-   { "LatLonState",
-"The lat_lon coordinate does not map to the indicated state or province." } },
-   { eErr_SEQ_DESCR_BadSpecificHost,
-   { "BadSpecificHost",
-"A BioSource descriptor or feature has a specific host value that may \
-require a taxonomy consult." } },
-   { eErr_SEQ_DESCR_RefGeneTrackingIllegalStatus,
-   { "RefGeneTrackingIllegalStatus",
-"The RefGeneTracking user object has an illegal Status value." } },
-   { eErr_SEQ_DESCR_ReplacedCountryCode,
-   { "ReplacedCountryCode",
-"The country code (up to the first colon) is no longer on the approved list of countries." } },
-   { eErr_SEQ_DESCR_BadInstitutionCode,
-   { "BadInstitutionCode",
-"The institution (or institution: collection) code is not on the approved list." } },
-   { eErr_SEQ_DESCR_BadCollectionCode,
-   { "BadCollectionCode",
-"The institution code is recognized, but the collection is not on the approved list." } },
-   { eErr_SEQ_DESCR_BadVoucherID,
-   { "BadVoucherID",
-"The voucher is missing a specific identifier." } },
-   { eErr_SEQ_DESCR_UnstructuredVoucher,
-   { "UnstructuredVoucher",
-"The voucher needs to be structured as \"<institution-code>:[<collection-code>:]<culture_id>\"." } },
-   { eErr_SEQ_DESCR_ChromosomeLocation,
-   { "ChromosomeLocation",
-"BioSource location is not usually chromosome." } },
-   { eErr_SEQ_DESCR_MultipleSourceQualifiers,
-   { "MultipleSourceQualifiers",
-"BioSource has unexpected multiple qualifiers of the same type." } },
-   { eErr_SEQ_DESCR_UnbalancedParentheses,
-   { "UnbalancedParentheses",
-"Qualifier should have matching ( and ) parentheses or [ and ] brackets." } },
-   { eErr_SEQ_DESCR_MultipleSourceVouchers,
-   { "MultipleSourceVouchers",
-"BioSource has unexpected multiple bio_material/culture_collection/specimen_voucher \
-from the same institution." } },
-   { eErr_SEQ_DESCR_BadCountryCapitalization,
-   { "BadCountryCapitalization",
-"The country code does not use the correct capitalization." } },
-   { eErr_SEQ_DESCR_WrongVoucherType,
-   { "WrongVoucherType",
-"The institution (or institution: collection) code normally uses a different \
-bio_material/culture_collection/specimen_voucher type." } },
-   { eErr_SEQ_DESCR_UserObjectProblem,
-   { "UserObjectProblem",
-"The user object is missing required fields or has invalid data." } },
-   { eErr_SEQ_DESCR_TitleHasPMID,
-   { "TitleHasPMID",
-"The title has (PMID #####) embedded in it." } },
-   { eErr_SEQ_DESCR_BadKeyword,
-   { "BadKeyword",
-"The keyword is not appropriate in this record." } },
-   { eErr_SEQ_DESCR_NoOrganismInTitle,
-   { "NoOrganismInTitle",
-"A RefSeq record should have the organism name at the beginning of a nucleotide title and bracketed at the end of a protein title." } },
-   { eErr_SEQ_DESCR_MissingChromosome,
-   { "MissingChromosome",
-"An NC or AC RefSeq record should have a chromosome annotated." } },
-   { eErr_SEQ_DESCR_LatLonAdjacent,
-   { "LatLonAdjacent",
-"The lat_lon coordinate may be in an adjacent country or in surrounding waters." } },
-   { eErr_SEQ_DESCR_BadStrucCommInvalidFieldName,
-   { "BadStrucCommInvalidFieldName",
-"Structured comment is missing required fields or field values do not conform to correct format." } },
-   { eErr_SEQ_DESCR_BadStrucCommInvalidFieldValue,
-   { "BadStrucCommInvalidFieldValue",
-"Structured comment is missing required fields or field values do not conform to correct format." } },
-   { eErr_SEQ_DESCR_BadStrucCommMissingField,
-   { "BadStrucCommMissingField",
-"Structured comment is missing required fields or field values do not conform to correct format." } },
-   { eErr_SEQ_DESCR_BadStrucCommFieldOutOfOrder,
-   { "BadStrucCommFieldOutOfOrder",
-"Structured comment is missing required fields or field values do not conform to correct format." } },
-   { eErr_SEQ_DESCR_BadStrucCommMultipleFields,
-   { "BadStrucCommMultipleFields",
-"Structured comment is missing required fields or field values do not conform to correct format." } },
-   { eErr_SEQ_DESCR_BioSourceNeedsChromosome,
-   { "BioSourceNeedsChromosome",
-"Chromosome should be set on a BioSource descriptor in non-viral complete genomes." } },
-   { eErr_SEQ_DESCR_MolInfoConflictsWithBioSource,
-   { "MolInfoConflictsWithBioSource",
-"Viral lineage information conflicts with MolInfo." } },
-   { eErr_SEQ_DESCR_MissingKeyword,
-   { "MissingKeyword",
-"Expected keyword was not found." } },
-   { eErr_SEQ_DESCR_FakeStructuredComment,
-   { "FakeStructuredComment",
-"Comment descriptor may have been formatted to look like structured comment." } },
-   { eErr_SEQ_DESCR_StructuredCommentPrefixOrSuffixMissing,
-   { "StructuredCommentPrefixOrSuffixMissing",
-"Structured comments should have a prefix or suffix." } },
-   { eErr_SEQ_DESCR_LatLonWater,
-   { "LatLonWater",
-"The lat_lon coordinate map in a body of water." } },
-   { eErr_SEQ_DESCR_LatLonOffshore,
-   { "LatLonOffshore",
-"The lat_lon coordinate is probably in a minor or unnamed body of water." } },
-   { eErr_SEQ_DESCR_MissingPersonalCollectionName,
-   { "MissingPersonalCollectionName",
-"The personal collection does not indicate the name of the collector." } },
-   { eErr_SEQ_DESCR_LatLonPrecision,
-   { "LatLonPrecision",
-"The precision of lat_lon should be dd.dd N|S ddd.dd E|W." } },
-   { eErr_SEQ_DESCR_DBLinkProblem,
-   { "DBLinkProblem",
-"Only one DBLink user object with approved databases should apply to each Bioseq." } },
-   { eErr_SEQ_DESCR_FinishedStatusForWGS,
-   { "FinishedStatusForWGS",
-"WGS projects should not have the Genome-Assembly-Data structured comment current \
-finishing status set to Finished." } },
-   { eErr_SEQ_DESCR_BadTentativeName,
-   { "BadTentativeName",
-"A structured comment descriptor or feature has a tentative name value that may \
-require a taxonomy consult." } },
-   { eErr_SEQ_DESCR_OrganismNotFound,
-   { "OrganismNotFound",
-"The indicated organism is not in the taxonomy database." } },
-   { eErr_SEQ_DESCR_TaxonomyIsSpeciesProblem,
-   { "TaxonomyIsSpeciesProblem",
-"Taxonomy lookup of the indicated organism reports an is_species_level problem." } },
-   { eErr_SEQ_DESCR_TaxonomyConsultRequired,
-   { "TaxonomyConsultRequired",
-"A taxonomy consult is required for the indicated organism." } },
-   { eErr_SEQ_DESCR_TaxonomyNucleomorphProblem,
-   { "TaxonomyNucleomorphProblem",
-"Taxonomy lookup indicates that the nucleomorph flag should be set for this organism." } },
-   { eErr_SEQ_DESCR_InconsistentMolTypeBiomol,
-   { "InconsistentMolTypeBiomol",
-"The Bioseq instance molecule field is inconsistent with the Mol-info biomol field." } },
-   { eErr_SEQ_DESCR_BadInstitutionCountry,
-   { "BadInstitutionCountry",
-"The institution (or institution: collection) code should not have a <country> modifier." } },
-   { eErr_SEQ_DESCR_AmbiguousSpecificHost,
-   { "AmbiguousSpecificHost",
-"A BioSource descriptor or feature has an ambiguous specific host value that may \
-require a taxonomy consult." } },
-   { eErr_SEQ_DESCR_BadAltitude,
-   { "BadAltitude",
-"The altitude must be reported as a number followed by a space and the letter m (for meters)." } },
-   { eErr_SEQ_DESCR_RefGeneTrackingOnNucProtSet,
-   { "RefGeneTrackingOnNucProtSet",
-"The RefGeneTracking user object should not be on a nuc-prot set." } },
-   { eErr_SEQ_DESCR_InconsistentDates,
-   { "InconsistentDates",
-"There are two date descriptors that are inconsistent with each \
-other. Please make them consistent." } },
-   { eErr_SEQ_DESCR_MultipleTaxonIDs,
-   { "MultipleTaxonIDs",
-"There are multiple BioSources with multiple taxonIDs in this RefSeq record." } },
-   { eErr_SEQ_DESCR_ScaffoldLacksBioProject,
-   { "ScaffoldLacksBioProject",
-"There is no BioProject database link for this scaffold record." } },
-   { eErr_SEQ_DESCR_CompleteGenomeLacksBioProject,
-   { "CompleteGenomeLacksBioProject",
-"There is no BioProject database link for this complete genome record." } },
-   { eErr_SEQ_DESCR_TaxonomyPlastidsProblem,
-   { "TaxonomyPlastidsProblem",
-"Taxonomy lookup indicates that the plastids flag should be set for this organism." } },
-   { eErr_SEQ_DESCR_OrganismIsUndefinedSpecies,
-   { "OrganismIsUndefinedSpecies",
-"Organism is an undefined species and does not have a specific identifier." } },
-   { eErr_SEQ_DESCR_SuspectedContaminatedCellLine,
-   { "SuspectedContaminatedCellLine",
-"Suspected contaminated cell line." } },
-   { eErr_SEQ_DESCR_WrongBiomolForTechnique,
-   { "WrongBiomolForTechnique",
-"TSA records are expected to make use of a very limited set of MolInfo.biomol values: transcribed-RNA, mRNA, rRNA, ncRNA." } },
-   { eErr_SEQ_DESCR_WrongOrganismFor16SrRNA,
-   { "WrongOrganismFor16SrRNA",
-"16S ribosomal RNA is not present in eukaryotic ribosomes." } },
-   { eErr_SEQ_DESCR_InconsistentWGSFlags,
-   { "InconsistentWGSFlags",
-"WGS indicators are used inconsistently in this record." } },
-
-/* SEQ_GENERIC */
-
-   { eErr_GENERIC_NonAsciiAsn,
-   { "NonAsciiAsn",
-"There is a non-ASCII type character in this entry." } },
-   { eErr_GENERIC_Spell,
-   { "Spell",
-"There is a potentially misspelled word in this entry." } },
-   { eErr_GENERIC_AuthorListHasEtAl,
-   { "AuthorListHasEtAl",
-"The author list contains et al, which should be replaced with the \
-remaining author names." } },
-   { eErr_GENERIC_MissingPubInfo,
-   { "MissingPubInfo",
-"The publication is missing essential information, such as title or authors." } },
-   { eErr_GENERIC_UnnecessaryPubEquiv,
-   { "UnnecessaryPubEquiv",
-"A nested Pub-equiv is not normally expected in a publication.  This may prevent \
-proper display of all publication information." } },
-   { eErr_GENERIC_BadPageNumbering,
-   { "BadPageNumbering",
-"The publication page numbering is suspect." } },
-   { eErr_GENERIC_MedlineEntryPub,
-   { "MedlineEntryPub",
-"Publications should not be of type medline-entry.  This has abstract and MeSH \
-term information that does not appear in the GenBank flatfile.  Type cit-art \
-should be used instead." } },
-   { eErr_GENERIC_BadDate,
-   { "BadDate",
-"There are bad values for month, day, or year in a date." } },
-   { eErr_GENERIC_StructuredCitGenCit,
-   { "StructuredCitGenCit",
-"The publication has title or journal embedded in the unstructured citgen.cit \
-field." } },
-   { eErr_GENERIC_CollidingSerialNumbers,
-   { "CollidingSerialNumbers",
-"Multiple publications have the same serial number explicitly recorded in the \
-data." } },
-   { eErr_GENERIC_EmbeddedScript,
-   { "EmbeddedScript",
-"Script or other markup tags should not be used in sequence record fields." } },
-   { eErr_GENERIC_PublicationInconsistency,
-   { "PublicationInconsistency",
-"Some fields in the publication should not be present with other fields." } },
-   { eErr_GENERIC_SgmlPresentInText,
-   { "SgmlPresentInText",
-"SGML markup is embedded in text." } },
-   { eErr_GENERIC_UnexpectedPubStatusComment,
-   { "UnexpectedPubStatusComment",
-"An unexpected publication status exists for a print, online-only, or ahead-of-print article : Content-Of-Pubdesc.comment-String." } },
-   { eErr_GENERIC_PastReleaseDate,
-   { "PastReleaseDate",
-"The record has is marked as hold-until-published, but the release anyway date has already passed." } },
-   { eErr_GENERIC_MissingISOJTA,
-   { "MissingISOJTA",
-"The publication journal is missing an ISO journal title abbreviation." } },
-   { eErr_GENERIC_MissingVolume,
-   { "MissingVolume",
-"The publication volume is missing." } },
-   { eErr_GENERIC_MissingVolumeEpub,
-   { "MissingVolumeEpub",
-"The electronic publication volume is missing." } },
-   { eErr_GENERIC_MissingPages,
-   { "MissingPages",
-"The publication pages are missing." } },
-   { eErr_GENERIC_MissingPagesEpub,
-   { "MissingPagesEpub",
-"The electronic publication pages are missing." } },
+    { "UNKNOWN", "UNKNOWN" } },
+
+    /* SEQ_INST */
+
+    { eErr_SEQ_INST_ExtNotAllowed,
+    { "ExtNotAllowed",
+    "A Bioseq \"extension\" is used for special classes of Bioseq. This class of \
+    Bioseq should not have one but it does. This is probably a software error." } },
+    { eErr_SEQ_INST_ExtBadOrMissing,
+    { "ExtBadOrMissing",
+    "This class of Bioseq requires an \"extension\" but it is missing or of the \
+    wrong type. This is probably a software error." } },
+    { eErr_SEQ_INST_SeqDataNotFound,
+    { "SeqDataNotFound",
+    "No actual sequence data was found on this Bioseq. This is probably a \
+    software problem." } },
+    { eErr_SEQ_INST_SeqDataNotAllowed,
+    { "SeqDataNotAllowed",
+    "The wrong type of sequence data was found on this Bioseq. This is probably a \
+    software problem." } },
+    { eErr_SEQ_INST_ReprInvalid,
+    { "ReprInvalid",
+    "This Bioseq has an invalid representation class. This is probably a software \
+    error." } },
+    { eErr_SEQ_INST_CircularProtein,
+    { "CircularProtein",
+    "This protein Bioseq is represented as circular. Circular topology is \
+    normally used only for certain DNA molecules, for example, plasmids." } },
+    { eErr_SEQ_INST_DSProtein,
+    { "DSProtein",
+    "This protein Bioseq has strandedness indicated. Strandedness is normally a \
+    property only of DNA sequences. Please unset the strandedness." } },
+    { eErr_SEQ_INST_MolNotSet,
+    { "MolNotSet",
+    "It is not clear whether this sequence is nucleic acid or protein. Please set \
+    the appropriate molecule type (Bioseq.mol)." } },
+    { eErr_SEQ_INST_MolOther,
+    { "MolOther",
+    "Most sequences are either nucleic acid or protein. However, the molecule \
+    type (Bioseq.mol) is set to \"other\". It should probably be set to nucleic \
+    acid or a protein." } },
+    { eErr_SEQ_INST_FuzzyLen,
+    { "FuzzyLen",
+    "This sequence is marked as having an uncertain length, but the length is \
+    known exactly." } },
+    { eErr_SEQ_INST_InvalidLen,
+    { "InvalidLen",
+    "The length indicated for this sequence is invalid. This is probably a \
+    software error." } },
+    { eErr_SEQ_INST_InvalidAlphabet,
+    { "InvalidAlphabet",
+    "This Bioseq has an invalid alphabet (e.g. protein codes on a nucleic acid or \
+    vice versa). This is probably a software error." } },
+    { eErr_SEQ_INST_SeqDataLenWrong,
+    { "SeqDataLenWrong",
+    "The length of this Bioseq does not agree with the length of the actual data. \
+    This is probably a software error." } },
+    { eErr_SEQ_INST_SeqPortFail,
+    { "SeqPortFail",
+    "Something is very wrong with this entry. The validator cannot open a SeqPort \
+    on the Bioseq. Further testing cannot be done." } },
+    { eErr_SEQ_INST_InvalidResidue,
+    { "InvalidResidue",
+    "Invalid residue codes were found in this Bioseq." } },
+    { eErr_SEQ_INST_StopInProtein,
+    { "StopInProtein",
+    "Stop codon symbols were found in this protein Bioseq." } },
+    { eErr_SEQ_INST_PartialInconsistent,
+    { "PartialInconsistent",
+    "This segmented sequence is described as complete or incomplete in several \
+    places, but these settings are inconsistent." } },
+    { eErr_SEQ_INST_ShortSeq,
+    { "ShortSeq",
+    "This Bioseq is unusually short (less than 4 amino acids or less than 11 \
+    nucleic acids). GenBank does not usually accept such short sequences." } },
+    { eErr_SEQ_INST_NoIdOnBioseq,
+    { "NoIdOnBioseq",
+    "No SeqIds were found on this Bioseq. This is probably a software error." } },
+    { eErr_SEQ_INST_BadDeltaSeq,
+    { "BadDeltaSeq",
+    "Delta sequences should only be HTGS-1 or HTGS-2." } },
+    { eErr_SEQ_INST_LongHtgsSequence,
+    { "LongHtgsSequence",
+    "HTGS-1 or HTGS-2 sequences must be < 350 KB in length." } },
+    { eErr_SEQ_INST_LongLiteralSequence,
+    { "LongLiteralSequence",
+    "Delta literals must be < 350 KB in length." } },
+    { eErr_SEQ_INST_SequenceExceeds350kbp,
+    { "SequenceExceeds350kbp",
+    "Individual sequences must be < 350 KB in length, unless they represent a single gene." } },
+    { eErr_SEQ_INST_ConflictingIdsOnBioseq,
+    { "ConflictingIdsOnBioseq",
+    "Two SeqIds of the same class was found on this Bioseq. This is probably a software error." } },
+    { eErr_SEQ_INST_MolNuclAcid,
+    { "MolNuclAcid",
+    "The specific type of this nucleic acid (DNA or RNA) is not set." } },
+    { eErr_SEQ_INST_ConflictingBiomolTech,
+    { "ConflictingBiomolTech",
+    "HTGS/STS/GSS records should be genomic DNA. There is a conflict between the \
+    technique and expected molecule type." } },
+    { eErr_SEQ_INST_SeqIdNameHasSpace,
+    { "SeqIdNameHasSpace",
+    "The Seq-id.name field should be a single word without any whitespace. This should be \
+    fixed by the database staff." } },
+    { eErr_SEQ_INST_IdOnMultipleBioseqs,
+    { "IdOnMultipleBioseqs",
+    "There are multiple occurrences of the same Seq-id in this record. Sequence \
+    identifiers must be unique within a record." } },
+    { eErr_SEQ_INST_DuplicateSegmentReferences,
+    { "DuplicateSegmentReferences",
+    "The segmented sequence refers multiple times to the same Seq-id. This may be due \
+    to a software error. Please consult with the database staff to fix this record." } },
+    { eErr_SEQ_INST_TrailingX,
+    { "TrailingX",
+    "The protein sequence ends with one or more X (unknown) amino acids." } },
+    { eErr_SEQ_INST_BadSeqIdFormat,
+    { "BadSeqIdFormat",
+    "A nucleotide sequence identifier should be 1 letter plus 5 digits or 2 letters \
+    plus 6 digits, and a protein sequence identifer should be 3 letters plus 5 digits." } },
+    { eErr_SEQ_INST_PartsOutOfOrder,
+    { "PartsOutOfOrder",
+    "The parts inside a segmented set should correspond to the seq_ext of the segmented \
+    bioseq.  A difference will affect how the flatfile is displayed." } },
+    { eErr_SEQ_INST_BadSecondaryAccn,
+    { "BadSecondaryAccn",
+    "A secondary accession usually indicates a record replaced or subsumed by the current \
+    record.  In this case, the current accession and secondary are the same." } },
+    { eErr_SEQ_INST_ZeroGiNumber,
+    { "ZeroGiNumber",
+    "GI numbers are assigned to sequences by NCBI's sequence tracking database.  0 is not \
+    a legal value for a gi number." } },
+    { eErr_SEQ_INST_RnaDnaConflict,
+    { "RnaDnaConflict",
+    "The MolInfo biomol field is inconsistent with the Bioseq molecule type field." } },
+    { eErr_SEQ_INST_HistoryGiCollision,
+    { "HistoryGiCollision",
+    "The Bioseq history gi refers to this Bioseq, not to its predecessor or successor." } },
+    { eErr_SEQ_INST_GiWithoutAccession,
+    { "GiWithoutAccession",
+    "The Bioseq has a gi identifier but no GenBank/EMBL/DDBJ accession identifier." } },
+    { eErr_SEQ_INST_MultipleAccessions,
+    { "MultipleAccessions",
+    "The Bioseq has a gi identifier and more than one GenBank/EMBL/DDBJ accession identifier." } },
+    { eErr_SEQ_INST_HistAssemblyMissing,
+    { "HistAssemblyMissing",
+    "The Bioseq has a TPA identifier but does not have a Seq-hist.assembly alignment.  This \
+    should be annotated or calculated by the database, resulting in a PRIMARY block visible \
+    in the flatfile." } },
+    { eErr_SEQ_INST_TerminalNs,
+    { "TerminalNs",
+    "The Bioseq has one or more N bases at the end." } },
+    { eErr_SEQ_INST_UnexpectedIdentifierChange,
+    { "UnexpectedIdentifierChange",
+    "The set of sequence identifiers on a Bioseq are not consistent with the previous version \
+    of the record in the database." } },
+    { eErr_SEQ_INST_InternalNsInSeqLit,
+    { "InternalNsInSeqLit",
+    "There are runs of many Ns inside the SeqLit component of a delta Bioseq." } },
+    { eErr_SEQ_INST_SeqLitGapLength0,
+    { "SeqLitGapLength0",
+    "A SeqLit component of a delta Bioseq can specify a gap, but it should not be a gap \
+    of 0 length." } },
+    { eErr_SEQ_INST_TpaAssmeblyProblem,
+    { "TpaAssmeblyProblem",
+    "Third party annotation records should have a TpaAssembly user object and a \
+    Seq-hist.assembly alignment for the PRIMARY block." } },
+    { eErr_SEQ_INST_SeqLocLength,
+    { "SeqLocLength",
+    "A SeqLoc component of a delta Bioseq is suspiciously small." } },
+    { eErr_SEQ_INST_MissingGaps,
+    { "MissingGaps",
+    "HTGS delta records should have gaps between each sequence segment." } },
+    { eErr_SEQ_INST_CompleteTitleProblem,
+    { "CompleteTitleProblem",
+    "The sequence title has complete genome in it, but it is not marked as complete." } },
+    { eErr_SEQ_INST_CompleteCircleProblem,
+    { "CompleteCircleProblem",
+    "This sequence has a circular topology, but it is not marked as complete." } },
+    { eErr_SEQ_INST_BadHTGSeq,
+    { "BadHTGSeq",
+    "High throughput genomic sequences without gaps should have quality score graphs." } },
+    { eErr_SEQ_INST_GapInProtein,
+    { "GapInProtein",
+    "Gap symbols found in this protein Bioseq." } },
+    { eErr_SEQ_INST_BadProteinStart,
+    { "BadProteinStart",
+    "A gap symbols was found at the start of this protein Bioseq." } },
+    { eErr_SEQ_INST_TerminalGap,
+    { "TerminalGap",
+    "The Bioseq has a gap at the end." } },
+    { eErr_SEQ_INST_OverlappingDeltaRange,
+    { "OverlappingDeltaRange",
+    "The Bioseq has a gap at the end." } },
+    { eErr_SEQ_INST_LeadingX,
+    { "LeadingX",
+    "The protein sequence starts with one or more X (unknown) amino acids." } },
+    { eErr_SEQ_INST_InternalNsInSeqRaw,
+    { "InternalNsInSeqRaw",
+    "There are runs of greater than 100 Ns within sequence.  Please describe \
+    what these Ns represent with your sequence submission." } },
+    { eErr_SEQ_INST_InternalNsAdjacentToGap,
+    { "InternalNsAdjacentToGap",
+    "There are Ns directly adjacent to a SeqLit gap in a delta Bioseq." } },
+    { eErr_SEQ_INST_CaseDifferenceInSeqID,
+    { "CaseDifferenceInSeqID",
+    "Multiple Bioseqs have the same Seq-id except for capitalization. Sequence \
+    identifiers must be unique in a case-insensitive manner within a record." } },
+    { eErr_SEQ_INST_DeltaComponentIsGi0,
+    { "DeltaComponentIsGi0",
+    "Delta component refers to gi 0. This indicates an error in database processing of this record." } },
+    { eErr_SEQ_INST_FarFetchFailure,
+    { "FarFetchFailure",
+    "Fetching of a far feature location or component bioseq was needed, but no fetch \
+    function is registered in the program." } },
+    { eErr_SEQ_INST_InternalGapsInSeqRaw,
+    { "InternalGapsInSeqRaw",
+    "Raw sequences should not have gap characters." } },
+    { eErr_SEQ_INST_SelfReferentialSequence,
+    { "SelfReferentialSequence",
+    "A delta sequence must refer to other components, not to itself." } },
+    { eErr_SEQ_INST_WholeComponent,
+    { "WholeComponent",
+    "A delta sequence component should be described as a specific interval, not as \
+    the whole of a sequence." } },
+    { eErr_SEQ_INST_TSAHistAssemblyMissing,
+    { "TSAHistAssemblyMissing",
+    "The Bioseq has a TSA MolInfo tech but does not have a Seq-hist.assembly alignment." } },
+    { eErr_SEQ_INST_ProteinsHaveGeneralID,
+    { "ProteinsHaveGeneralID",
+    "One or more protein Bioseqs have a general Seq-id." } },
+    { eErr_SEQ_INST_HighNContent,
+    { "HighNContent",
+    "This sequence contains too many Ns." } },
+    { eErr_SEQ_INST_SeqLitDataLength0,
+    { "SeqLitDataLength0",
+    "A SeqLit component of a delta Bioseq must not have 0 length." } },
+    { eErr_SEQ_INST_DSmRNA,
+    { "DSmRNA",
+    "This mRNA Bioseq is not single stranded." } },
+    { eErr_SEQ_INST_HighNContentStretch,
+    { "HighNContentStretch",
+    "This sequence contains long stretches of Ns." } },
+    { eErr_SEQ_INST_HighNContentPercent,
+    { "HighNContentPercent",
+    "This sequence contains a high percentage of Ns." } },
+    { eErr_SEQ_INST_SeqLitGapFuzzNot100,
+    { "SeqLitGapFuzzNot100",
+    "Gap of unknown length should have standard length of 100." } },
+    { eErr_SEQ_INST_SeqGapProblem,
+    { "SeqGapProblem",
+    "Inconsistent data in Seq-gap fields." } },
+    { eErr_SEQ_INST_WGSMasterLacksStrucComm,
+    { "WGSMasterLacksStrucComm",
+    "WGS Master records require a Genome Assembly Data structured comment user object." } },
+    { eErr_SEQ_INST_TSAMasterLacksStrucComm,
+    { "TSAMasterLacksStrucComm",
+    "TSA Master records require an Assembly Data structured comment user object." } },
+    { eErr_SEQ_INST_AllNs,
+    { "AllNs",
+    "Sequence has only Ns." } },
+
+
+    /* SEQ_DESCR */
+
+    { eErr_SEQ_DESCR_BioSourceMissing,
+    { "BioSourceMissing",
+    "The biological source of this sequence has not been described correctly.  A \
+    Bioseq must have a BioSource descriptor that covers the entire molecule. \
+    Additional BioSource features may also be added to recombinant molecules, \
+    natural or otherwise, to designate the parts of the molecule. Please add the \
+    source information." } },
+    { eErr_SEQ_DESCR_InvalidForType,
+    { "InvalidForType",
+    "This descriptor cannot be used with this Bioseq. A descriptor placed at the \
+    BioseqSet level applies to all of the Bioseqs in the set. Please make sure \
+    the descriptor is consistent with every sequence to which it applies." } },
+    { eErr_SEQ_DESCR_FileOpenCollision,
+    { "FileOpenCollision",
+    "FileOpen is unable to find a local file.  This is normal, and can be ignored." } },
+    { eErr_SEQ_DESCR_Unknown,
+    { "Unknown",
+    "An unknown or \"other\" modifier was used." } },
+    { eErr_SEQ_DESCR_NoPubFound,
+    { "NoPubFound",
+    "No publications were found in this entry which refer to this Bioseq. If a \
+    publication descriptor is added to a BioseqSet, it will apply to all of the \
+    Bioseqs in the set. A publication feature should be used if the publication \
+    applies only to a subregion of a sequence." } },
+    { eErr_SEQ_DESCR_NoOrgFound,
+    { "NoOrgFound",
+    "This entry does not specify the organism that was the source of the sequence. \
+    Please name the organism." } },
+    { eErr_SEQ_DESCR_MultipleBioSources,
+    { "MultipleBioSources",
+    "There are multiple BioSource or OrgRef descriptors in the same chain with \
+    the same taxonomic name. Their information should be combined into a single \
+    BioSource descriptor." } },
+    { eErr_SEQ_DESCR_NoMolInfoFound,
+    { "NoMolInfoFound",
+    "This sequence does not have a Mol-info descriptor applying to it.  This indicates \
+    genomic vs. message, sequencing technique, and whether the sequence is incomplete." } },
+    { eErr_SEQ_DESCR_BadCountryCode,
+    { "BadCountryCode",
+    "The country code (up to the first colon) is not on the approved list of countries." } },
+    { eErr_SEQ_DESCR_NoTaxonID,
+    { "NoTaxonID",
+    "The BioSource is missing a taxonID database identifier.  This will be inserted by \
+    the automated taxonomy lookup called by Clean Up Record." } },
+    { eErr_SEQ_DESCR_InconsistentBioSources,
+    { "InconsistentBioSources",
+    "This population study has BioSource descriptors with different taxonomic names. \
+    All members of a population study should be from the same organism." } },
+    { eErr_SEQ_DESCR_MissingLineage,
+    { "MissingLineage",
+    "A BioSource should have a taxonomic lineage, which can be obtained from the \
+    taxonomy network server." } },
+    { eErr_SEQ_DESCR_SerialInComment,
+    { "SerialInComment",
+    "Comments that refer to the conclusions of a specific reference should not be \
+    cited by a serial number inside brackets (e.g., [3]), but should instead be \
+    attached as a REMARK on the reference itself." } },
+    { eErr_SEQ_DESCR_BioSourceNeedsFocus,
+    { "BioSourceNeedsFocus",
+    "Focus must be set on a BioSource descriptor in records where there is a \
+    BioSource feature with a different organism name." } },
+    { eErr_SEQ_DESCR_BadOrganelle,
+    { "BadOrganelle",
+    "Note that only Kinetoplastida have kinetoplasts, and that only Chlorarchniophyta \
+    and Cryptophyta have nucleomorphs." } },
+    { eErr_SEQ_DESCR_MultipleChromosomes,
+    { "MultipleChromosomes",
+    "There are multiple chromosome qualifiers on this Bioseq.  With the exception of \
+    some pseudoautosomal genes, this is likely to be a biological annotation error." } },
+    { eErr_SEQ_DESCR_BadSubSource,
+    { "BadSubSource",
+    "Unassigned SubSource subtype." } },
+    { eErr_SEQ_DESCR_BadOrgMod,
+    { "BadOrgMod",
+    "Unassigned OrgMod subtype." } },
+    { eErr_SEQ_DESCR_InconsistentProteinTitle,
+    { "InconsistentProteinTitle",
+    "An instantiated protein title descriptor should normally be the same as the \
+    automatically generated title.  This may be a curated exception, or it may \
+    be out of synch with the current annotation." } },
+    { eErr_SEQ_DESCR_Inconsistent,
+    { "Inconsistent",
+    "There are two descriptors of the same type which are inconsistent with each \
+    other. Please make them consistent." } },
+    { eErr_SEQ_DESCR_ObsoleteSourceLocation,
+    { "ObsoleteSourceLocation",
+    "There is a source location that is no longer legal for use in GenBank records." } },
+    { eErr_SEQ_DESCR_ObsoleteSourceQual,
+    { "ObsoleteSourceQual",
+    "There is a source qualifier that is no longer legal for use in GenBank records." } },
+    { eErr_SEQ_DESCR_StructuredSourceNote,
+    { "StructuredSourceNote",
+    "The name of a structured source field is present as text in a note.  The data \
+    should probably be put into the appropriate field instead." } },
+    { eErr_SEQ_DESCR_UnnecessaryBioSourceFocus,
+    { "UnnecessaryBioSourceFocus",
+    "Focus should not be set on a BioSource descriptor in records where there is no \
+    BioSource feature." } },
+    { eErr_SEQ_DESCR_RefGeneTrackingWithoutStatus,
+    { "RefGeneTrackingWithoutStatus",
+    "The RefGeneTracking user object does not have the required Status field set." } },
+    { eErr_SEQ_DESCR_UnwantedCompleteFlag,
+    { "UnwantedCompleteFlag",
+    "The Mol-info.completeness flag should not be set on a genomic sequence, unless \
+    the title also says it is a complete sequence or complete genome, nor should it \
+    be set on a plasmid, chromosome, or organelle." } },
+    { eErr_SEQ_DESCR_CollidingPublications,
+    { "CollidingPublications",
+    "Multiple publication descriptors with the same PMID or MUID apply to a Bioseq. \
+    The lower-level ones are redundant, and should be removed." } },
+    { eErr_SEQ_DESCR_TransgenicProblem,
+    { "TransgenicProblem",
+    "A BioSource descriptor with /transgenic set must be accompanied by a BioSource \
+    feature on the nucleotide record." } },
+    { eErr_SEQ_DESCR_TaxonomyLookupProblem,
+    { "TaxonomyLookupProblem",
+    "A BioSource descriptor or feature has flags returned by taxonomy lookup that \
+    are either inconsistent with the data or require a taxonomy consult." } },
+    { eErr_SEQ_DESCR_MultipleTitles,
+    { "MultipleTitles",
+    "There are multiple title descriptors in the same Bioseq or BioseqSet chain." } },
+    { eErr_SEQ_DESCR_RefGeneTrackingOnNonRefSeq,
+    { "RefGeneTrackingOnNonRefSeq",
+    "The RefGeneTracking user object should only be in RefSeq records." } },
+    { eErr_SEQ_DESCR_BioSourceInconsistency,
+    { "BioSourceInconsistency",
+    "There is an internal inconsistency with specific fields in the BioSource." } },
+    { eErr_SEQ_DESCR_FastaBracketTitle,
+    { "FastaBracketTitle",
+    "Bracketed [...=...] information remains in the title.  This should have been parsed \
+    out during sequence record generation to obtain qualifier values." } },
+    { eErr_SEQ_DESCR_MissingText,
+    { "MissingText",
+    "Comments, regions, and other text descriptors need a descriptive text string. \
+    The string provided with this descriptor is empty. If no text is desired, then \
+    the descriptor should be removed." } },
+    { eErr_SEQ_DESCR_BadCollectionDate,
+    { "BadCollectionDate",
+    "The collection date is not in the required format." } },
+    { eErr_SEQ_DESCR_BadPCRPrimerSequence,
+    { "BadPCRPrimerSequence",
+    "The PCR primer sequence has illegal characters or non-IUPAC nucleotides." } },
+    { eErr_SEQ_DESCR_BadPunctuation,
+    { "BadPunctuation",
+    "The title ends with incorrect punctuation marks." } },
+    { eErr_SEQ_DESCR_BadPCRPrimerName,
+    { "BadPCRPrimerName",
+    "The PCR primer name appears to be a sequence instead of an identifying label." } },
+    { eErr_SEQ_DESCR_BioSourceOnProtein,
+    { "BioSourceOnProtein",
+    "A BioSource descriptor should not be placed on a protein that is in a nuc-prot set." } },
+    { eErr_SEQ_DESCR_BioSourceDbTagConflict,
+    { "BioSourceDbTagConflict",
+    "Multiple db_xrefs with the same database should not appear on a single BioSource." } },
+    { eErr_SEQ_DESCR_DuplicatePCRPrimerSequence,
+    { "DuplicatePCRPrimerSequence",
+    "The PCR primer sequence has duplicate subsequences." } },
+    { eErr_SEQ_DESCR_MultipleNames,
+    { "MultipleNames",
+    "There are multiple name descriptors in the same Bioseq or BioseqSet chain." } },
+    { eErr_SEQ_DESCR_MultipleComments,
+    { "MultipleComments",
+    "There are multiple identical comment descriptors in the same Bioseq or BioseqSet chain." } },
+    { eErr_SEQ_DESCR_LatLonProblem,
+    { "LatLonProblem",
+    "There is a problem with the lat_lon qualifier in the BioSource." } },
+    { eErr_SEQ_DESCR_LatLonFormat,
+    { "LatLonFormat",
+    "The format of lat_lon should be dd.dd N|S ddd.dd E|W." } },
+    { eErr_SEQ_DESCR_LatLonRange,
+    { "LatLonRange",
+    "Latitude or longitude is out of range." } },
+    { eErr_SEQ_DESCR_LatLonValue,
+    { "LatLonValue",
+    "Latitude or longitude values appear to be in the wrong hemisphere or swapped." } },
+    { eErr_SEQ_DESCR_LatLonCountry,
+    { "LatLonCountry",
+    "The lat_lon coordinate does not map to the indicated country." } },
+    { eErr_SEQ_DESCR_LatLonState,
+    { "LatLonState",
+    "The lat_lon coordinate does not map to the indicated state or province." } },
+    { eErr_SEQ_DESCR_BadSpecificHost,
+    { "BadSpecificHost",
+    "A BioSource descriptor or feature has a specific host value that may \
+    require a taxonomy consult." } },
+    { eErr_SEQ_DESCR_RefGeneTrackingIllegalStatus,
+    { "RefGeneTrackingIllegalStatus",
+    "The RefGeneTracking user object has an illegal Status value." } },
+    { eErr_SEQ_DESCR_ReplacedCountryCode,
+    { "ReplacedCountryCode",
+    "The country code (up to the first colon) is no longer on the approved list of countries." } },
+    { eErr_SEQ_DESCR_BadInstitutionCode,
+    { "BadInstitutionCode",
+    "The institution (or institution: collection) code is not on the approved list." } },
+    { eErr_SEQ_DESCR_BadCollectionCode,
+    { "BadCollectionCode",
+    "The institution code is recognized, but the collection is not on the approved list." } },
+    { eErr_SEQ_DESCR_BadVoucherID,
+    { "BadVoucherID",
+    "The voucher is missing a specific identifier." } },
+    { eErr_SEQ_DESCR_UnstructuredVoucher,
+    { "UnstructuredVoucher",
+    "The voucher needs to be structured as \"<institution-code>:[<collection-code>:]<culture_id>\"." } },
+    { eErr_SEQ_DESCR_ChromosomeLocation,
+    { "ChromosomeLocation",
+    "BioSource location is not usually chromosome." } },
+    { eErr_SEQ_DESCR_MultipleSourceQualifiers,
+    { "MultipleSourceQualifiers",
+    "BioSource has unexpected multiple qualifiers of the same type." } },
+    { eErr_SEQ_DESCR_UnbalancedParentheses,
+    { "UnbalancedParentheses",
+    "Qualifier should have matching ( and ) parentheses or [ and ] brackets." } },
+    { eErr_SEQ_DESCR_MultipleSourceVouchers,
+    { "MultipleSourceVouchers",
+    "BioSource has unexpected multiple bio_material/culture_collection/specimen_voucher \
+    from the same institution." } },
+    { eErr_SEQ_DESCR_BadCountryCapitalization,
+    { "BadCountryCapitalization",
+    "The country code does not use the correct capitalization." } },
+    { eErr_SEQ_DESCR_WrongVoucherType,
+    { "WrongVoucherType",
+    "The institution (or institution: collection) code normally uses a different \
+    bio_material/culture_collection/specimen_voucher type." } },
+    { eErr_SEQ_DESCR_UserObjectProblem,
+    { "UserObjectProblem",
+    "The user object is missing required fields or has invalid data." } },
+    { eErr_SEQ_DESCR_TitleHasPMID,
+    { "TitleHasPMID",
+    "The title has (PMID #####) embedded in it." } },
+    { eErr_SEQ_DESCR_BadKeyword,
+    { "BadKeyword",
+    "The keyword is not appropriate in this record." } },
+    { eErr_SEQ_DESCR_NoOrganismInTitle,
+    { "NoOrganismInTitle",
+    "A RefSeq record should have the organism name at the beginning of a nucleotide title and bracketed at the end of a protein title." } },
+    { eErr_SEQ_DESCR_MissingChromosome,
+    { "MissingChromosome",
+    "An NC or AC RefSeq record should have a chromosome annotated." } },
+    { eErr_SEQ_DESCR_LatLonAdjacent,
+    { "LatLonAdjacent",
+    "The lat_lon coordinate may be in an adjacent country or in surrounding waters." } },
+    { eErr_SEQ_DESCR_BadStrucCommInvalidFieldName,
+    { "BadStrucCommInvalidFieldName",
+    "Structured comment is missing required fields or field values do not conform to correct format." } },
+    { eErr_SEQ_DESCR_BadStrucCommInvalidFieldValue,
+    { "BadStrucCommInvalidFieldValue",
+    "Structured comment is missing required fields or field values do not conform to correct format." } },
+    { eErr_SEQ_DESCR_BadStrucCommMissingField,
+    { "BadStrucCommMissingField",
+    "Structured comment is missing required fields or field values do not conform to correct format." } },
+    { eErr_SEQ_DESCR_BadStrucCommFieldOutOfOrder,
+    { "BadStrucCommFieldOutOfOrder",
+    "Structured comment is missing required fields or field values do not conform to correct format." } },
+    { eErr_SEQ_DESCR_BadStrucCommMultipleFields,
+    { "BadStrucCommMultipleFields",
+    "Structured comment is missing required fields or field values do not conform to correct format." } },
+    { eErr_SEQ_DESCR_BioSourceNeedsChromosome,
+    { "BioSourceNeedsChromosome",
+    "Chromosome should be set on a BioSource descriptor in non-viral complete genomes." } },
+    { eErr_SEQ_DESCR_MolInfoConflictsWithBioSource,
+    { "MolInfoConflictsWithBioSource",
+    "Viral lineage information conflicts with MolInfo." } },
+    { eErr_SEQ_DESCR_MissingKeyword,
+    { "MissingKeyword",
+    "Expected keyword was not found." } },
+    { eErr_SEQ_DESCR_FakeStructuredComment,
+    { "FakeStructuredComment",
+    "Comment descriptor may have been formatted to look like structured comment." } },
+    { eErr_SEQ_DESCR_StructuredCommentPrefixOrSuffixMissing,
+    { "StructuredCommentPrefixOrSuffixMissing",
+    "Structured comments should have a prefix or suffix." } },
+    { eErr_SEQ_DESCR_LatLonWater,
+    { "LatLonWater",
+    "The lat_lon coordinate map in a body of water." } },
+    { eErr_SEQ_DESCR_LatLonOffshore,
+    { "LatLonOffshore",
+    "The lat_lon coordinate is probably in a minor or unnamed body of water." } },
+    { eErr_SEQ_DESCR_MissingPersonalCollectionName,
+    { "MissingPersonalCollectionName",
+    "The personal collection does not indicate the name of the collector." } },
+    { eErr_SEQ_DESCR_LatLonPrecision,
+    { "LatLonPrecision",
+    "The precision of lat_lon should be dd.dd N|S ddd.dd E|W." } },
+    { eErr_SEQ_DESCR_DBLinkProblem,
+    { "DBLinkProblem",
+    "Only one DBLink user object with approved databases should apply to each Bioseq." } },
+    { eErr_SEQ_DESCR_FinishedStatusForWGS,
+    { "FinishedStatusForWGS",
+    "WGS projects should not have the Genome-Assembly-Data structured comment current \
+    finishing status set to Finished." } },
+    { eErr_SEQ_DESCR_BadTentativeName,
+    { "BadTentativeName",
+    "A structured comment descriptor or feature has a tentative name value that may \
+    require a taxonomy consult." } },
+    { eErr_SEQ_DESCR_OrganismNotFound,
+    { "OrganismNotFound",
+    "The indicated organism is not in the taxonomy database." } },
+    { eErr_SEQ_DESCR_TaxonomyIsSpeciesProblem,
+    { "TaxonomyIsSpeciesProblem",
+    "Taxonomy lookup of the indicated organism reports an is_species_level problem." } },
+    { eErr_SEQ_DESCR_TaxonomyConsultRequired,
+    { "TaxonomyConsultRequired",
+    "A taxonomy consult is required for the indicated organism." } },
+    { eErr_SEQ_DESCR_TaxonomyNucleomorphProblem,
+    { "TaxonomyNucleomorphProblem",
+    "Taxonomy lookup indicates that the nucleomorph flag should be set for this organism." } },
+    { eErr_SEQ_DESCR_InconsistentMolTypeBiomol,
+    { "InconsistentMolTypeBiomol",
+    "The Bioseq instance molecule field is inconsistent with the Mol-info biomol field." } },
+    { eErr_SEQ_DESCR_BadInstitutionCountry,
+    { "BadInstitutionCountry",
+    "The institution (or institution: collection) code should not have a <country> modifier." } },
+    { eErr_SEQ_DESCR_AmbiguousSpecificHost,
+    { "AmbiguousSpecificHost",
+    "A BioSource descriptor or feature has an ambiguous specific host value that may \
+    require a taxonomy consult." } },
+    { eErr_SEQ_DESCR_BadAltitude,
+    { "BadAltitude",
+    "The altitude must be reported as a number followed by a space and the letter m (for meters)." } },
+    { eErr_SEQ_DESCR_RefGeneTrackingOnNucProtSet,
+    { "RefGeneTrackingOnNucProtSet",
+    "The RefGeneTracking user object should not be on a nuc-prot set." } },
+    { eErr_SEQ_DESCR_InconsistentDates,
+    { "InconsistentDates",
+    "There are two date descriptors that are inconsistent with each \
+    other. Please make them consistent." } },
+    { eErr_SEQ_DESCR_MultipleTaxonIDs,
+    { "MultipleTaxonIDs",
+    "There are multiple BioSources with multiple taxonIDs in this RefSeq record." } },
+    { eErr_SEQ_DESCR_ScaffoldLacksBioProject,
+    { "ScaffoldLacksBioProject",
+    "There is no BioProject database link for this scaffold record." } },
+    { eErr_SEQ_DESCR_CompleteGenomeLacksBioProject,
+    { "CompleteGenomeLacksBioProject",
+    "There is no BioProject database link for this complete genome record." } },
+    { eErr_SEQ_DESCR_TaxonomyPlastidsProblem,
+    { "TaxonomyPlastidsProblem",
+    "Taxonomy lookup indicates that the plastids flag should be set for this organism." } },
+    { eErr_SEQ_DESCR_OrganismIsUndefinedSpecies,
+    { "OrganismIsUndefinedSpecies",
+    "Organism is an undefined species and does not have a specific identifier." } },
+    { eErr_SEQ_DESCR_SuspectedContaminatedCellLine,
+    { "SuspectedContaminatedCellLine",
+    "Suspected contaminated cell line." } },
+    { eErr_SEQ_DESCR_WrongBiomolForTechnique,
+    { "WrongBiomolForTechnique",
+    "TSA records are expected to make use of a very limited set of MolInfo.biomol values: transcribed-RNA, mRNA, rRNA, ncRNA." } },
+    { eErr_SEQ_DESCR_WrongOrganismFor16SrRNA,
+    { "WrongOrganismFor16SrRNA",
+    "16S ribosomal RNA is not present in eukaryotic ribosomes." } },
+    { eErr_SEQ_DESCR_InconsistentWGSFlags,
+    { "InconsistentWGSFlags",
+    "WGS indicators are used inconsistently in this record." } },
+    { eErr_SEQ_DESCR_TitleNotAppropriateForSet,
+    { "TitleNotAppropriateForSet",
+    "Only population study, phylogenetic study, ecological sample study, and mutation sets should have title descriptors." } },
+
+    /* SEQ_GENERIC */
+
+    { eErr_GENERIC_NonAsciiAsn,
+    { "NonAsciiAsn",
+    "There is a non-ASCII type character in this entry." } },
+    { eErr_GENERIC_Spell,
+    { "Spell",
+    "There is a potentially misspelled word in this entry." } },
+    { eErr_GENERIC_AuthorListHasEtAl,
+    { "AuthorListHasEtAl",
+    "The author list contains et al, which should be replaced with the \
+    remaining author names." } },
+    { eErr_GENERIC_MissingPubInfo,
+    { "MissingPubInfo",
+    "The publication is missing essential information, such as title or authors." } },
+    { eErr_GENERIC_UnnecessaryPubEquiv,
+    { "UnnecessaryPubEquiv",
+    "A nested Pub-equiv is not normally expected in a publication.  This may prevent \
+    proper display of all publication information." } },
+    { eErr_GENERIC_BadPageNumbering,
+    { "BadPageNumbering",
+    "The publication page numbering is suspect." } },
+    { eErr_GENERIC_MedlineEntryPub,
+    { "MedlineEntryPub",
+    "Publications should not be of type medline-entry.  This has abstract and MeSH \
+    term information that does not appear in the GenBank flatfile.  Type cit-art \
+    should be used instead." } },
+    { eErr_GENERIC_BadDate,
+    { "BadDate",
+    "There are bad values for month, day, or year in a date." } },
+    { eErr_GENERIC_StructuredCitGenCit,
+    { "StructuredCitGenCit",
+    "The publication has title or journal embedded in the unstructured citgen.cit \
+    field." } },
+    { eErr_GENERIC_CollidingSerialNumbers,
+    { "CollidingSerialNumbers",
+    "Multiple publications have the same serial number explicitly recorded in the \
+    data." } },
+    { eErr_GENERIC_EmbeddedScript,
+    { "EmbeddedScript",
+    "Script or other markup tags should not be used in sequence record fields." } },
+    { eErr_GENERIC_PublicationInconsistency,
+    { "PublicationInconsistency",
+    "Some fields in the publication should not be present with other fields." } },
+    { eErr_GENERIC_SgmlPresentInText,
+    { "SgmlPresentInText",
+    "SGML markup is embedded in text." } },
+    { eErr_GENERIC_UnexpectedPubStatusComment,
+    { "UnexpectedPubStatusComment",
+    "An unexpected publication status exists for a print, online-only, or ahead-of-print article : Content-Of-Pubdesc.comment-String." } },
+    { eErr_GENERIC_PastReleaseDate,
+    { "PastReleaseDate",
+    "The record has is marked as hold-until-published, but the release anyway date has already passed." } },
+    { eErr_GENERIC_MissingISOJTA,
+    { "MissingISOJTA",
+    "The publication journal is missing an ISO journal title abbreviation." } },
+    { eErr_GENERIC_MissingVolume,
+    { "MissingVolume",
+    "The publication volume is missing." } },
+    { eErr_GENERIC_MissingVolumeEpub,
+    { "MissingVolumeEpub",
+    "The electronic publication volume is missing." } },
+    { eErr_GENERIC_MissingPages,
+    { "MissingPages",
+    "The publication pages are missing." } },
+    { eErr_GENERIC_MissingPagesEpub,
+    { "MissingPagesEpub",
+    "The electronic publication pages are missing." } },
+    { eErr_GENERIC_BarcodeTooShort,
+    { "BarcodeTooShort",
+    "Barcode sequence is too short." } },
+    { eErr_GENERIC_BarcodeMissingPrimers,
+    { "BarcodeMissingPrimers",
+    "Barcode sequence is missing primers." } },
+    { eErr_GENERIC_BarcodeMissingCountry,
+    { "BarcodeMissingCountry",
+    "Barcode sequence is missing country." } },
+    { eErr_GENERIC_BarcodeMissingVoucher,
+    { "BarcodeMissingVoucher",
+    "Barcode sequence is missing voucher." } },
+    { eErr_GENERIC_BarcodeTooManyNs,
+    { "BarcodeTooManyNs",
+    "Barcode sequence contains too many Ns" } },
+    { eErr_GENERIC_BarcodeBadCollectionDate,
+    { "BarcodeBadCollectionDate",
+"Barcode sequence has bad collection date" } } ,
+    { eErr_GENERIC_BarcodeMissingOrderAssignment,
+    { "BarcodeMissingOrderAssignment",
+"Barcode sequence is missing order assignment." } },
+    { eErr_GENERIC_BarcodeLowTrace,
+    { "BarcodeLowTrace",
+"Barcode sequence has low trace." } },
+    { eErr_GENERIC_BarcodeFrameShift,
+    { "BarcodeFrameShift",
+"Barcode sequence has frame shift." } },
+    { eErr_GENERIC_BarcodeStructuredVoucher,
+    { "BarcodeStructuredVoucher",
+"Barcode sequence has structured voucher problem." } },
+    { eErr_GENERIC_BarcodeTestFails,
+    { "BarcodeTestFails",
+"Barcode test fails." } },
+    { eErr_GENERIC_BarcodeTestPasses,
+    { "BarcodeTestPasses",
+"Barcode test passes." } },
+    { eErr_GENERIC_InvalidAsn,
+    { "InvalidAsn",
+    "Invalid ASN.1" } },
 
 /* SEQ_PKG */
 
@@ -1243,8 +1285,11 @@ converted to a publication or biosource descriptor." } },
 field on a feature." } },
    { eErr_SEQ_FEAT_CDSwithNoMRNAOverlap,
    { "CDSwithNoMRNAOverlap",
-"The CDS feature has more than one overlapping mRNA with the proper intervals and \
-no other identification assigning it to a different coding region." } },
+"The CDS feature has no overlapping mRNA with the proper intervals." } },
+   { eErr_SEQ_FEAT_CDSwithNoMRNA,
+   {"CDSwithNoMRNA",
+"The CDS feature has no matching mRNA. Matches are identified via xref \
+ or overlap." } },
    { eErr_SEQ_FEAT_FeatureProductInconsistency,
    { "FeatureProductInconsistency",
 "The CDS feature has more than one overlapping mRNA with the proper intervals and \
@@ -1619,6 +1664,15 @@ same id type" } },
    { eErr_SEQ_FEAT_SeqLocTypeProblem,
    { "SeqLocTypeProblem",
 "A sequence location component is not the expected type." } },
+   { eErr_SEQ_FEAT_RefSeqInText,
+   { "RefSeqInText",
+"The term RefSeq should not appear in a product name or a definition line." } },
+   { eErr_SEQ_FEAT_ColdShockProteinProblem,
+   { "ColdShockProteinProblem",
+"A misc_feature containing cspA should not overlap a cold-shock protein CDS." } },
+   { eErr_SEQ_FEAT_BadLocation,
+   { "BadLocation",
+"There is a problem with this feature location." } },
 
 /* SEQ_ALIGN */
 
diff --git a/c++/src/objects/valerr/ValidError.cpp b/c++/src/objects/valerr/ValidError.cpp
index 99b5fd5..596b97d 100644
--- a/c++/src/objects/valerr/ValidError.cpp
+++ b/c++/src/objects/valerr/ValidError.cpp
@@ -1,4 +1,4 @@
-/* $Id: ValidError.cpp 447658 2014-09-29 18:29:18Z bollin $
+/* $Id: ValidError.cpp 513779 2016-09-15 11:23:57Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -114,6 +114,23 @@ void CValidError::AddValidErrItem
 }
 
 
+void CValidError::AddValidErrItem(EDiagSev sev, unsigned int ec, const string& msg)
+{
+    if (ShouldSuppress(ec)) {
+        return;
+    }
+    CRef<CValidErrItem> item(new CValidErrItem());
+    item->SetSev(sev);
+    item->SetErrIndex(ec);
+    item->SetMsg(msg);
+    item->SetErrorName(CValidErrItem::ConvertErrCode(ec));
+    item->SetErrorGroup(CValidErrItem::ConvertErrGroup(ec));
+
+    SetErrs().push_back(item);
+    m_Stats[item->GetSeverity()]++;
+}
+
+
 void CValidError::SuppressError(unsigned int ec)
 {
     m_SuppressionList.push_back(ec);
diff --git a/c++/src/objects/valid/Comment_rule.cpp b/c++/src/objects/valid/Comment_rule.cpp
index fb97824..685b323 100644
--- a/c++/src/objects/valid/Comment_rule.cpp
+++ b/c++/src/objects/valid/Comment_rule.cpp
@@ -1,4 +1,4 @@
-/* $Id: Comment_rule.cpp 493827 2016-03-02 13:59:27Z ivanov $
+/* $Id: Comment_rule.cpp 491404 2016-02-04 17:37:54Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objects/valid/Comment_set.cpp b/c++/src/objects/valid/Comment_set.cpp
index 15edbef..9786564 100644
--- a/c++/src/objects/valid/Comment_set.cpp
+++ b/c++/src/objects/valid/Comment_set.cpp
@@ -1,4 +1,4 @@
-/* $Id: Comment_set.cpp 425372 2014-01-28 19:01:52Z kans $
+/* $Id: Comment_set.cpp 498903 2016-04-20 15:50:10Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -178,7 +178,7 @@ list<string> CComment_set::GetKeywords(const CUser_object& user)
             CComment_rule::TErrorList errors = rule.IsValid(user);
             if (errors.size() == 0) {
                 string kywd = CComment_rule::KeywordForPrefix( prefix );
-                NStr::Split(kywd, ";", keywords);
+                NStr::Split(kywd, ";", keywords, NStr::fSplit_Tokenize);
             }
         } catch (CException& ) {
             // no rule for this prefix, can't list fields
diff --git a/c++/src/objects/valid/validrules.inc b/c++/src/objects/valid/validrules.inc
index dd36001..06aa1fc 100644
--- a/c++/src/objects/valid/validrules.inc
+++ b/c++/src/objects/valid/validrules.inc
@@ -1,4 +1,4 @@
-/*  $Id: validrules.inc 493824 2016-03-02 13:58:25Z ivanov $
+/*  $Id: validrules.inc 520820 2016-12-01 18:51:57Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -822,7 +822,10 @@ static const char* const s_Defaultvalidrules[] = {
     "        match-expression \".+ v\\. .+\",",
     "        required TRUE } ,",
     "      {",
-    "        field-name \"Assembly Name\" } ,",
+    "        field-name \"Polishing Method\" } ,",
+    "      {",
+    "        field-name \"Assembly Name\",",
+    "        match-expression \"^[A-Za-z0-9 _#\\-\\.]*$\" } ,",
     "      {",
     "        field-name \"Long Assembly Name\" } ,",
     "      {",
@@ -926,7 +929,7 @@ static const char* const s_Defaultvalidrules[] = {
     "    dependent-rules {",
     "      {",
     "        match-name \"Sequencing Technology\" ,",
-    "        value-constraint \"\\(Sanger dideoxy sequencing\\|ABI PRISM\\|Sanger\\|Sanger sequencing\\)\",",
+    "        value-constraint \"\\(Sanger dideoxy sequencing\\|ABI\\|ABI 3730\\|ABI3730XL\\|ABI 3730XL Genetic Analyzer\\|ABI 3500\\|ABI 3500 Dx Genetic Analyzer CS2\\|ABI PRISM\\|Sanger\\|Sanger sequencing\\)\",",
     "        invert-match TRUE ,",
     "        other-fields {",
     "          {",
diff --git a/c++/src/objects/valid/validrules.prt b/c++/src/objects/valid/validrules.prt
index 4e49165..8444508 100644
--- a/c++/src/objects/valid/validrules.prt
+++ b/c++/src/objects/valid/validrules.prt
@@ -789,7 +789,10 @@ AR\|APR\|MAY\|JUN\|JUL\|AUG\|SEP\|OCT\|NOV\|DEC\)-\(19\|20\)\(0\|1\|2\|3\|4\|5
         match-expression ".+ v\. .+",
         required TRUE } ,
       {
-        field-name "Assembly Name" } ,
+        field-name "Polishing Method" } ,
+      {
+        field-name "Assembly Name",
+        match-expression "^[A-Za-z0-9 _#\-\.]*$" } ,
       {
         field-name "Long Assembly Name" } ,
       {
@@ -893,7 +896,7 @@ AR\|APR\|MAY\|JUN\|JUL\|AUG\|SEP\|OCT\|NOV\|DEC\)-\(19\|20\)\(0\|1\|2\|3\|4\|5
     dependent-rules {
       {
         match-name "Sequencing Technology" ,
-        value-constraint "\(Sanger dideoxy sequencing\|ABI PRISM\|Sanger\|Sanger sequencing\)",
+        value-constraint "\(Sanger dideoxy sequencing\|ABI\|ABI 3730\|ABI3730XL\|ABI 3730XL Genetic Analyzer\|ABI 3500\|ABI 3500 Dx Genetic Analyzer CS2\|ABI PRISM\|Sanger\|Sanger sequencing\)",
         invert-match TRUE ,
         other-fields {
           {
diff --git a/c++/src/objects/varrep/AaInterval.cpp b/c++/src/objects/varrep/AaInterval.cpp
new file mode 100644
index 0000000..9a0c0c3
--- /dev/null
+++ b/c++/src/objects/varrep/AaInterval.cpp
@@ -0,0 +1,82 @@
+/* $Id: AaInterval.cpp 497242 2016-04-05 14:40:38Z foleyjp $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  .......
+ *
+ * File Description:
+ *   .......
+ *
+ * Remark:
+ *   This code was originally generated by application DATATOOL
+ *   using the following specifications:
+ *   'variation_irep.asn'.
+ */
+
+// standard includes
+#include <ncbi_pch.hpp>
+#include <objects/varrep/AaSite.hpp>
+#include <corelib/ncbiexpt.hpp>
+
+// generated includes
+#include <objects/varrep/AaInterval.hpp>
+
+
+// generated classes
+
+BEGIN_NCBI_SCOPE
+
+BEGIN_objects_SCOPE // namespace ncbi::objects::
+
+// destructor
+CAaInterval::~CAaInterval(void)
+{
+}
+
+
+size_t CAaInterval::size(void) const
+{
+    const auto start_index = GetStart().GetIndex();
+    const auto stop_index = GetStop().GetIndex();
+    if ( stop_index <= start_index ) {
+        NCBI_THROW(CException, eUnknown, "Invalid interval limits");
+    }
+    const size_t length = stop_index-start_index+1;
+    return length;
+}
+
+
+string CAaInterval::GetString(void) const
+{
+    const auto start_residue = GetStart().GetAa();
+    const auto stop_residue = GetStop().GetAa();
+    return start_residue + ".." + stop_residue;
+}
+
+
+END_objects_SCOPE // namespace ncbi::objects::
+
+END_NCBI_SCOPE
+
+/* Original file checksum: lines: 57, chars: 1766, CRC32: dbe74b6e */
diff --git a/c++/src/objects/varrep/AaLocation.cpp b/c++/src/objects/varrep/AaLocation.cpp
new file mode 100644
index 0000000..6bef52a
--- /dev/null
+++ b/c++/src/objects/varrep/AaLocation.cpp
@@ -0,0 +1,77 @@
+/* $Id: AaLocation.cpp 497242 2016-04-05 14:40:38Z foleyjp $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  .......
+ *
+ * File Description:
+ *   .......
+ *
+ * Remark:
+ *   This code was originally generated by application DATATOOL
+ *   using the following specifications:
+ *   'variation_irep.asn'.
+ */
+
+// standard includes
+#include <ncbi_pch.hpp>
+
+// generated includes
+#include <objects/varrep/AaLocation.hpp>
+
+// generated classes
+
+BEGIN_NCBI_SCOPE
+
+BEGIN_objects_SCOPE // namespace ncbi::objects::
+
+// destructor
+CAaLocation::~CAaLocation(void)
+{
+}
+
+
+size_t CAaLocation::size(void) const 
+{
+    if (IsSite()) {
+        return 1;
+    }
+    return GetInt().size();
+}
+
+
+string CAaLocation::GetString(void) const
+{
+    if (IsSite()) {
+        return GetSite().GetAa();
+    }
+    return GetInt().GetString();
+}
+
+
+END_objects_SCOPE // namespace ncbi::objects::
+
+END_NCBI_SCOPE
+
+/* Original file checksum: lines: 57, chars: 1766, CRC32: 56b39eaa */
diff --git a/c++/src/objects/varrep/Makefile.in b/c++/src/objects/varrep/Makefile.in
new file mode 100644
index 0000000..f3e14f8
--- /dev/null
+++ b/c++/src/objects/varrep/Makefile.in
@@ -0,0 +1,3 @@
+ASN_PROJ = varrep
+srcdir = @srcdir@
+include @builddir@/Makefile.meta
diff --git a/c++/src/objects/varrep/Makefile.varrep.lib b/c++/src/objects/varrep/Makefile.varrep.lib
new file mode 100644
index 0000000..08047bd
--- /dev/null
+++ b/c++/src/objects/varrep/Makefile.varrep.lib
@@ -0,0 +1,3 @@
+ASN = varrep
+SRC = $(ASN:%=%__) $(ASN:%=%___)
+LIB = varrep
diff --git a/c++/src/objects/varrep/varrep.asn b/c++/src/objects/varrep/varrep.asn
new file mode 100644
index 0000000..43f3e40
--- /dev/null
+++ b/c++/src/objects/varrep/varrep.asn
@@ -0,0 +1,296 @@
+NCBI-VariationIRep DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN 
+
+
+--EXPORTS VariantExpression, SimpleVariant;
+
+VariantExpression ::= SEQUENCE {
+    input-expr VisibleString, -- contains the input expression to be parsed
+    reference-id VisibleString, -- contains the accession id or other identifier for the reference sequence
+    sequence-variant SequenceVariant
+}
+
+
+SequenceVariant ::= SEQUENCE {
+    seqtype VariantSeqType,
+    subvariants SEQUENCE OF Variant,
+    complex INTEGER {
+        mosaic  (1), 
+        chimera (2)
+    } OPTIONAL
+}
+
+
+Variant ::= CHOICE {
+    simple SimpleVariant, 
+    special SpecialVariant
+}
+
+
+VariantSeqType ::= INTEGER {
+    g (0), --genomic
+    m (1), --mitochondrial
+    c (2), --coding
+    r (3), --rna
+    n (4), --non-coding rna
+    p (5), --protein
+    u (6)  --unknown
+}
+
+
+SpecialVariant ::= INTEGER { 
+    unknown            (0), -- ?
+    not-analyzed       (1), -- (?) Not sure about this
+    nochange           (2), -- =
+    nochange-expected  (3), -- (=)
+    noseq              (4), -- 0
+    noseq-expected     (5), -- 0?
+    splice-expected    (6), -- spl?
+    splice-possible    (7)  -- (spl?) 
+}
+
+
+-- SimpleVarSeq is deprecated and should go
+SimpleVariantSeq ::= SEQUENCE { 
+    variants SEQUENCE OF SimpleVariant,  
+    sisters BOOLEAN DEFAULT FALSE,
+    fuzzy BOOLEAN DEFAULT FALSE
+}
+
+
+SimpleVariant ::= SEQUENCE {
+    type  CHOICE {
+        na-identity NaIdentity,
+        na-sub NaSub,
+        prot-sub ProteinSub,
+        del Deletion,
+        dup Duplication,
+        inv Inversion,
+        ins Insertion,
+        conv Conversion,
+        delins Delins,
+        repeat Repeat, --short-sequence repeat (ssr)
+        prot-ext ProteinExtension,
+        frameshift Frameshift
+    },
+    fuzzy BOOLEAN DEFAULT FALSE
+}
+
+
+Delins ::= SEQUENCE {
+    loc SeqLocation,
+    deleted-raw-seq VisibleString OPTIONAL, -- can optionally specify the deleted sequence
+    inserted-seq-info CHOICE {
+        identifier VisibleString, -- A sequence identifier (e.g. an accession id)
+        raw-seq VisibleString, -- The actual nucleotide / amino-acid sequence
+        count Count, -- The number of elements inserted
+        subseq Subsequence -- A subsequence specified by an id, type descriptor, and a range
+    }
+}
+
+
+NaSub ::= SEQUENCE {
+    loc NtLocation,
+    initial VisibleString,
+    final VisibleString
+}
+
+NaIdentity ::= SEQUENCE {
+    loc NtLocation,
+    nucleotide VisibleString OPTIONAL
+}
+
+
+ProteinSub ::= SEQUENCE {
+    type INTEGER {
+        missense(0),
+        nonsense(1),
+        unknown(2)
+    },
+    initial AaSite,
+    final VisibleString OPTIONAL
+}
+
+
+ProteinExtension ::= CHOICE {
+    nterm-ext NtermExtension,
+    cterm-ext CtermExtension
+}
+
+
+NtermExtension ::= SEQUENCE {
+    newStart Count,
+    newAa VisibleString OPTIONAL
+}
+
+
+CtermExtension ::= SEQUENCE {
+    refStop INTEGER, 
+    newAa VisibleString,
+    length Count 
+}
+
+
+Frameshift ::= CHOICE {
+    aasite AaSite,
+    stopcodon NULL
+}
+
+
+Deletion ::= SEQUENCE { 
+    loc SeqLocation,
+    raw-seq VisibleString OPTIONAL -- can optionally specify the deleted sequence
+}
+
+
+Duplication ::= SEQUENCE {
+    loc SeqLocation,
+    raw-seq VisibleString OPTIONAL -- can optionally specify the sequence duplicated sequence
+}
+
+
+Inversion ::= SEQUENCE {
+    ntint NtInterval,
+    raw-seq VisibleString OPTIONAL,
+    size  INTEGER OPTIONAL -- optionall specify the size of the inverted sequence
+}
+
+
+Insertion ::= SEQUENCE {
+    int SeqInterval,
+
+    seqinfo CHOICE {
+        identifier VisibleString, -- A sequence identifier (e.g. an accession id)
+        raw-seq VisibleString, -- The actual nucleotide / amino-acid sequence
+        count Count, -- The number of elements inserted
+        subseq Subsequence -- A subsequence specified by an id, type descriptor, and a range
+    }
+}
+
+
+Conversion ::= SEQUENCE {
+    loc NtLocation,
+    origin NtLocation
+}
+
+
+Subsequence ::= SEQUENCE {
+    identifier VisibleString, -- For example, an accession id
+    type VariantSeqType,
+    int SeqInterval
+}
+
+
+Repeat ::= SEQUENCE {
+    loc SeqLocation,
+    count Count,
+    raw-seq VisibleString OPTIONAL --Used if ntloc is a site, not an interval
+}
+
+
+SeqLocation ::= CHOICE {
+    aaloc AaLocation,
+    ntloc NtLocation
+}
+
+SeqInterval ::= CHOICE {
+    aaint AaInterval,
+    ntint NtInterval
+}
+
+
+AaLocation ::= CHOICE {
+    site AaSite,
+    range AaSiteRange,
+    int AaInterval
+}
+
+
+AaInterval ::= SEQUENCE {
+    start AaSite,
+    stop AaSite
+}
+
+
+AaSiteRange ::= SEQUENCE {
+    start AaSite,
+    stop  AaSite
+}
+
+
+    AaSite ::= SEQUENCE {
+        index INTEGER,
+        aa VisibleString
+    }
+
+
+    NtLocation ::= CHOICE {
+        site NtSite,
+        range NtSiteRange,
+        int NtInterval
+    }
+
+
+    NtIntLimit ::= CHOICE {
+        site NtSite,
+        range NtSiteRange
+    }
+
+    NtInterval ::= SEQUENCE {
+        start NtIntLimit,
+        stop NtIntLimit
+    }
+
+
+    NtSiteRange ::= SEQUENCE {
+        start NtSite,
+        stop  NtSite
+    }
+
+
+    NtSite ::= SEQUENCE {
+        seqid VisibleString OPTIONAL,
+        seqtype VariantSeqType OPTIONAL,
+
+        base CHOICE {
+            val INTEGER,
+            unknown NULL 
+        },
+
+        offset CHOICE {
+            val INTEGER,
+            plus-unknown NULL,
+            minus-unknown NULL
+        } OPTIONAL,
+
+        utr CHOICE {
+            five-prime NULL,
+            three-prime NULL
+        } OPTIONAL,
+
+
+        strand-minus BOOLEAN DEFAULT FALSE, -- TRUE implies opposite transcriptional orientation to 
+                                                -- to the reference sequence
+        fuzzy BOOLEAN DEFAULT FALSE, -- TRUE implies HGVS subexpression of the form (base + offset),
+        fuzzy-offset BOOLEAN DEFAULT FALSE -- TRUE implies HGVS subexpression of the form base+(offset)
+    }
+
+
+    Count ::= CHOICE {
+        unknown NULL,
+        val INTEGER,
+        fuzzy-val INTEGER,
+        range SEQUENCE { 
+            start CHOICE {
+                val INTEGER,
+                unknown NULL   
+            },
+            stop CHOICE {
+                val INTEGER,
+                unknown NULL
+            }
+        }
+    }
+
+    END
+
diff --git a/c++/src/objects/varrep/varrep.def b/c++/src/objects/varrep/varrep.def
new file mode 100644
index 0000000..92e707b
--- /dev/null
+++ b/c++/src/objects/varrep/varrep.def
@@ -0,0 +1,17 @@
+[AaSite]
+index._type = TSeqPos
+
+[NtSite]
+base.val._type = TSeqPos
+offset.val._type = TSignedSeqPos
+
+[Count]
+val._type = TSeqPos
+fuzzy-val._type = TSeqPos
+range.start.val._type = TSeqPos
+range.stop.val._type = TSeqPos
+
+
+
+
+
diff --git a/c++/src/objects/varrep/varrep.module b/c++/src/objects/varrep/varrep.module
new file mode 100644
index 0000000..dc51717
--- /dev/null
+++ b/c++/src/objects/varrep/varrep.module
@@ -0,0 +1 @@
+MODULE_PATH   = objects/varrep
diff --git a/c++/src/objmgr/Makefile.objmgr.lib b/c++/src/objmgr/Makefile.objmgr.lib
index 5b7f8f5..f7c7597 100644
--- a/c++/src/objmgr/Makefile.objmgr.lib
+++ b/c++/src/objmgr/Makefile.objmgr.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.objmgr.lib 496835 2016-03-31 15:49:15Z ivanov $
+# $Id: Makefile.objmgr.lib 501626 2016-05-17 17:32:10Z kornbluh $
 
 # Build library "xobjmgr"
 #################################
@@ -31,7 +31,7 @@ LIB    = xobjmgr
 # Dependencies for shared library
 DLL_LIB = $(SOBJMGR_LDEP)
 
-WATCHERS = vasilche kornbluh
+WATCHERS = vasilche
 
 
 USES_LIBRARIES =  \
diff --git a/c++/src/objmgr/annot_collector.cpp b/c++/src/objmgr/annot_collector.cpp
index 966f31e..0dcc622 100644
--- a/c++/src/objmgr/annot_collector.cpp
+++ b/c++/src/objmgr/annot_collector.cpp
@@ -1,4 +1,4 @@
-/*  $Id: annot_collector.cpp 499042 2016-04-21 17:39:04Z ivanov $
+/*  $Id: annot_collector.cpp 519943 2016-11-21 15:34:20Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -76,6 +76,7 @@
 #include <serial/serial.hpp>
 #include <serial/serialutil.hpp>
 
+#include <util/timsort.hpp>
 #include <algorithm>
 #include <typeinfo>
 
@@ -84,7 +85,7 @@
 
 BEGIN_NCBI_SCOPE
 
-NCBI_DEFINE_ERR_SUBCODE_X(1);
+NCBI_DEFINE_ERR_SUBCODE_X(2);
 
 BEGIN_SCOPE(objects)
 
@@ -414,7 +415,8 @@ const CSeq_id* CAnnotMapping_Info::GetProductId(void) const
 CAnnotObject_Ref::CAnnotObject_Ref(const CAnnotObject_Info& object,
                                    const CSeq_annot_Handle& annot_handle)
     : m_Seq_annot(annot_handle),
-      m_AnnotIndex(object.GetAnnotIndex())
+      m_AnnotIndex(object.GetAnnotIndex()),
+      m_AnnotType(eAnnot_Regular)
 {
     if ( object.IsFeat() ) {
         if ( object.IsRegular() ) {
@@ -424,6 +426,7 @@ CAnnotObject_Ref::CAnnotObject_Ref(const CAnnotObject_Info& object,
             }
         }
         else {
+            m_AnnotType = eAnnot_SeqTable;
             m_MappingInfo.SetPartial(GetSeq_annot_Info().IsTableFeatPartial(object));
         }
     }
@@ -447,9 +450,10 @@ CAnnotObject_Ref::CAnnotObject_Ref(const CSeq_annot_SNP_Info& snp_annot,
                                    const SSNP_Info& snp,
                                    CSeq_loc_Conversion* cvt)
     : m_Seq_annot(annot_handle),
-      m_AnnotIndex(TAnnotIndex(snp_annot.GetIndex(snp)) | kSNPTableBit)
+      m_AnnotIndex(TAnnotIndex(snp_annot.GetIndex(snp))),
+      m_AnnotType(eAnnot_SNPTable)
 {
-    _ASSERT(IsSNPFeat());
+    _ASSERT(IsSNPTableFeat());
     TSeqPos src_from = snp.GetFrom(), src_to = snp.GetTo();
     ENa_strand src_strand = eNa_strand_unknown;
     if ( snp.MinusStrand() ) {
@@ -461,8 +465,7 @@ CAnnotObject_Ref::CAnnotObject_Ref(const CSeq_annot_SNP_Info& snp_annot,
     if ( !cvt ) {
         m_MappingInfo.SetTotalRange(TRange(src_from, src_to));
         m_MappingInfo.SetMappedSeq_id(
-            const_cast<CSeq_id&>(GetSeq_annot_SNP_Info().
-            GetSeq_id()),
+            const_cast<CSeq_id&>(snp_annot.GetSeq_id()),
             src_from == src_to);
         m_MappingInfo.SetMappedStrand(src_strand);
         return;
@@ -481,10 +484,46 @@ CAnnotObject_Ref::CAnnotObject_Ref(const CSeq_annot_SNP_Info& snp_annot,
 }
 
 
+CAnnotObject_Ref::CAnnotObject_Ref(const CSeq_annot_Handle& annot_handle,
+                                   const CSeq_annot_SortedIter& iter,
+                                   CSeq_loc_Conversion* cvt)
+    : m_Seq_annot(annot_handle),
+      m_AnnotIndex(TAnnotIndex(iter.GetRow())),
+      m_AnnotType(eAnnot_SortedSeqTable)
+{
+    _ASSERT(IsSortedSeqTableFeat());
+    const CSeqTableInfo& annot_table = GetSeqTableInfo();
+    TRange src_range = iter.GetRange();
+    ENa_strand src_strand = annot_table.GetLocationStrand(m_AnnotIndex);
+    if ( !cvt ) {
+        m_MappingInfo.SetTotalRange(src_range);
+        m_MappingInfo.SetMappedSeq_id(
+            const_cast<CSeq_id&>(*annot_table.GetLocationId(m_AnnotIndex)),
+            src_range.GetLength() == 1);
+        m_MappingInfo.SetMappedStrand(src_strand);
+        return;
+    }
+
+    cvt->Reset();
+    if ( src_range.GetLength() == 1 ) {
+        // point
+        _VERIFY(cvt->ConvertPoint(src_range.GetFrom(),
+                                  src_strand));
+    }
+    else {
+        // interval
+        _VERIFY(cvt->ConvertInterval(src_range.GetFrom(),
+                                     src_range.GetTo(),
+                                     src_strand));
+    }
+    cvt->SetMappedLocation(*this, CSeq_loc_Conversion::eLocation);
+}
+
+
 void CAnnotObject_Ref::ResetLocation(void)
 {
     m_MappingInfo.Reset();
-    if ( !IsSNPFeat() ) {
+    if ( HasAnnotObject_Info() ) {
         const CAnnotObject_Info& object = GetAnnotObject_Info();
         if ( object.IsFeat() ) {
             const CSeq_feat& feat = *object.GetFeatFast();
@@ -498,11 +537,18 @@ void CAnnotObject_Ref::ResetLocation(void)
 
 const CSeq_annot_SNP_Info& CAnnotObject_Ref::GetSeq_annot_SNP_Info(void) const
 {
-    _ASSERT(IsSNPFeat());
+    _ASSERT(IsSNPTableFeat());
     return GetSeq_annot_Info().x_GetSNP_annot_Info();
 }
 
 
+const CSeqTableInfo& CAnnotObject_Ref::GetSeqTableInfo(void) const
+{
+    _ASSERT(IsAnySeqTableFeat());
+    return GetSeq_annot_Info().GetTableInfo();
+}
+
+
 const CAnnotObject_Info& CAnnotObject_Ref::GetAnnotObject_Info(void) const
 {
     _ASSERT(HasAnnotObject_Info());
@@ -512,14 +558,14 @@ const CAnnotObject_Info& CAnnotObject_Ref::GetAnnotObject_Info(void) const
 
 const SSNP_Info& CAnnotObject_Ref::GetSNP_Info(void) const
 {
-    _ASSERT(IsSNPFeat());
+    _ASSERT(IsSNPTableFeat());
     return GetSeq_annot_SNP_Info().GetInfo(GetAnnotIndex());
 }
 
 
 bool CAnnotObject_Ref::IsFeat(void) const
 {
-    return IsSNPFeat() || GetAnnotObject_Info().IsFeat();
+    return !HasAnnotObject_Info() || GetAnnotObject_Info().IsFeat();
 }
 
 
@@ -630,7 +676,10 @@ public:
 
     ENa_strand GetStrand(bool by_product);
 
-    const CSeq_loc* GetLoc(bool by_product);
+    const CSeq_loc* GetComplexLoc(bool by_product);
+
+    bool IsSetProduct(void);
+    CConstRef<CSeq_id> GetProductId(void);
 
     bool HasFeatLabel(void);
     string GetFeatLabel(void);
@@ -653,19 +702,23 @@ const CSeq_feat& CCreateFeat::GetOriginalFeat(void)
         if ( !m_CreatedOriginalFeat ) {
             CRef<CSeq_point> seq_pnt;
             CRef<CSeq_interval> seq_int;
-            if ( !m_Info ) {
+            if ( m_Ref.IsSNPTableFeat() ) {
                 // SNP table feature
-                const CSeq_annot_SNP_Info& annot_snp_info =
+                const CSeq_annot_SNP_Info& snp_info =
                     m_Ref.GetSeq_annot_SNP_Info();
-                m_Ref.GetSNP_Info().UpdateSeq_feat(m_CreatedOriginalFeat,
-                                                   seq_pnt, seq_int,
-                                                   annot_snp_info);
+                snp_info.GetInfo(m_Ref.GetAnnotIndex())
+                    .UpdateSeq_feat(m_CreatedOriginalFeat,
+                                    seq_pnt, seq_int,
+                                    snp_info);
             }
             else {
-                _ASSERT(m_Ref.IsTableFeat());
-                m_Ref.GetSeq_annot_Info().GetTableInfo().
-                    UpdateSeq_feat(m_Ref.GetAnnotIndex(),
-                                   m_CreatedOriginalFeat, seq_pnt, seq_int);
+                _ASSERT(m_Ref.IsAnySeqTableFeat());
+                const CSeqTableInfo& table_info =
+                    m_Ref.GetSeqTableInfo();
+                table_info
+                    .UpdateSeq_feat(m_Ref.GetAnnotIndex(),
+                                    m_CreatedOriginalFeat,
+                                    seq_pnt, seq_int);
             }
             _ASSERT(m_CreatedOriginalFeat);
         }
@@ -735,7 +788,7 @@ ENa_strand CCreateFeat::GetStrand(bool by_product)
         else {
             // location is not mapped - use original
             if ( !m_Info ) {
-                // table SNP without mapping
+                // table SNP or sorted table features have strand in mapping
                 return map.GetMappedStrand();
             }
             else {
@@ -751,10 +804,10 @@ ENa_strand CCreateFeat::GetStrand(bool by_product)
 }
 
 
-const CSeq_loc* CCreateFeat::GetLoc(bool by_product)
+const CSeq_loc* CCreateFeat::GetComplexLoc(bool by_product)
 {
     if ( !m_Info ) {
-        // table SNP -> no mix
+        // table SNP, or sorted feature table -> no mix
         return 0;
     }
     CAnnotMapping_Info& map = m_Ref.GetMappingInfo();
@@ -781,8 +834,29 @@ const CSeq_loc* CCreateFeat::GetLoc(bool by_product)
 }
 
 
+bool CCreateFeat::IsSetProduct(void)
+{
+    if ( !m_Info ) {
+        // table SNP or sorted table features -> no product
+        return false;
+    }
+    return GetOriginalFeat().IsSetProduct();
+}
+
+
+CConstRef<CSeq_id> CCreateFeat::GetProductId(void)
+{
+    _ASSERT(IsSetProduct());
+    return ConstRef(GetOriginalFeat().GetProduct().GetId());
+}
+
+
 bool CCreateFeat::HasFeatLabel(void)
 {
+    if ( !m_Info ) {
+        return m_Ref.GetSeq_annot_Info()
+            .TableFeat_HasLabel(m_Ref.GetAnnotIndex());
+    }
     const CSeq_feat& feat = GetOriginalFeat();
     return (feat.IsSetQual() && !feat.GetQual().empty()) ||
         (feat.IsSetComment() && !feat.GetComment().empty());
@@ -791,6 +865,11 @@ bool CCreateFeat::HasFeatLabel(void)
 
 string CCreateFeat::GetFeatLabel(void)
 {
+    if ( !m_Info ) {
+        return m_Ref.GetSeq_annot_Info()
+            .TableFeat_GetLabel(m_Ref.GetAnnotIndex());
+    }
+
     string label;
 
     const CSeq_feat& feat = GetOriginalFeat();
@@ -825,7 +904,7 @@ bool CAnnotObjectType_Less::operator()(const CAnnotObject_Ref& x,
     // gather x annotation type
     const CAnnotObject_Info* x_info;
     CSeq_annot::C_Data::E_Choice x_annot_type;
-    if ( !x.IsSNPFeat() ) {
+    if ( x.HasAnnotObject_Info() ) {
         x_info = &x.GetAnnotObject_Info();
         x_annot_type = x_info->GetAnnotType();
     }
@@ -837,7 +916,7 @@ bool CAnnotObjectType_Less::operator()(const CAnnotObject_Ref& x,
     // gather y annotation type
     const CAnnotObject_Info* y_info;
     CSeq_annot::C_Data::E_Choice y_annot_type;
-    if ( !y.IsSNPFeat() ) {
+    if ( y.HasAnnotObject_Info() ) {
         y_info = &y.GetAnnotObject_Info();
         y_annot_type = y_info->GetAnnotType();
     }
@@ -861,10 +940,15 @@ bool CAnnotObjectType_Less::operator()(const CAnnotObject_Ref& x,
             x_feat_type = x_info->GetFeatType();
             x_feat_subtype = x_info->GetFeatSubtype();
         }
-        else {
+        else if ( x.IsSNPTableFeat() ) {
             x_feat_type = CSeqFeatData::e_Imp;
             x_feat_subtype = CSeqFeatData::eSubtype_variation;
         }
+        else {
+            SAnnotTypeSelector type = x.GetSeqTableInfo().GetType();
+            x_feat_type = type.GetFeatType();
+            x_feat_subtype = type.GetFeatSubtype();
+        }
 
         // get y feature type
         CSeqFeatData::E_Choice y_feat_type;
@@ -873,10 +957,15 @@ bool CAnnotObjectType_Less::operator()(const CAnnotObject_Ref& x,
             y_feat_type = y_info->GetFeatType();
             y_feat_subtype = y_info->GetFeatSubtype();
         }
-        else {
+        else if ( y.IsSNPTableFeat() ) {
             y_feat_type = CSeqFeatData::e_Imp;
             y_feat_subtype = CSeqFeatData::eSubtype_variation;
         }
+        else {
+            SAnnotTypeSelector type = y.GetSeqTableInfo().GetType();
+            y_feat_type = type.GetFeatType();
+            y_feat_subtype = type.GetFeatSubtype();
+        }
 
         // order by feature type
         if ( x_feat_subtype != y_feat_subtype ) {
@@ -901,8 +990,8 @@ bool CAnnotObjectType_Less::operator()(const CAnnotObject_Ref& x,
         }
         
         // compare complex locations (mix or packed intervals)
-        const CSeq_loc* x_loc = x_create.GetLoc(m_ByProduct);
-        const CSeq_loc* y_loc = y_create.GetLoc(m_ByProduct);
+        const CSeq_loc* x_loc = x_create.GetComplexLoc(m_ByProduct);
+        const CSeq_loc* y_loc = y_create.GetComplexLoc(m_ByProduct);
         
         bool x_complex = x_loc && (x_loc->IsMix() || x_loc->IsPacked_int());
         bool y_complex = y_loc && (y_loc->IsMix() || y_loc->IsPacked_int());
@@ -954,18 +1043,16 @@ bool CAnnotObjectType_Less::operator()(const CAnnotObject_Ref& x,
         
         if ( !m_ByProduct ) {
             // order by product id
-            const CSeq_feat& x_feat = x_create.GetOriginalFeat();
-            const CSeq_feat& y_feat = y_create.GetOriginalFeat();
-            bool x_has_product = x_feat.IsSetProduct();
-            bool y_has_product = y_feat.IsSetProduct();
+            bool x_has_product = x_create.IsSetProduct();
+            bool y_has_product = y_create.IsSetProduct();
             if ( x_has_product != y_has_product ) {
                 return !x_has_product; // without product first
             }
             if ( x_has_product ) {
-                const CSeq_id* x_id = x_feat.GetProduct().GetId();
-                const CSeq_id* y_id = y_feat.GetProduct().GetId();
-                if ( (x_id == NULL) != (y_id == NULL) ) {
-                    return x_id == NULL; // no product id first
+                CConstRef<CSeq_id> x_id = x_create.GetProductId();
+                CConstRef<CSeq_id> y_id = y_create.GetProductId();
+                if ( x_id.IsNull() != y_id.IsNull() ) {
+                    return x_id.IsNull(); // no product id first
                 }
                 if ( x_id ) {
                     string x_id_str = x_id->AsFastaString();
@@ -1110,7 +1197,7 @@ struct CAnnotObject_Less
         }
     }
 
-    static
+    static inline
     void GetRangeOpen(TSeqPos &out_from, TSeqPos &out_to, 
                       const CAnnotObject_Ref& obj_ref)
     {
@@ -1135,10 +1222,6 @@ struct CAnnotObject_Less
     bool operator()(const CAnnotObject_Ref& x,
                     const CAnnotObject_Ref& y) const
         {
-            if ( x == y ) { // small speedup
-                return false;
-            }
-
             TSeqPos x_from = kInvalidSeqPos;
             TSeqPos y_from = kInvalidSeqPos;
             TSeqPos x_to = kInvalidSeqPos;
@@ -1168,6 +1251,11 @@ struct CAnnotObject_Less
             if ( x_to != y_to ) {
                 return x_to > y_to;
             }
+
+            if ( x == y ) { // small speedup
+                return false;
+            }
+
             return type_less(x, y);
         }
     CAnnotObjectType_Less type_less;
@@ -1315,10 +1403,10 @@ CCreatedFeat_Ref::GetOriginalFeature(const CSeq_feat_Handle& feat_h)
             CRef<CSeq_point> created_point;
             CRef<CSeq_interval> created_interval;
             //ReleaseRefsTo(&orig_feat, 0, &created_point, &created_interval);
-            annot.UpdateTableFeat(orig_feat,
-                                  created_point,
-                                  created_interval,
-                                  feat_h.x_GetAnnotObject_Info());
+            annot.GetTableInfo().UpdateSeq_feat(feat_h.x_GetFeatIndex(),
+                                                orig_feat,
+                                                created_point,
+                                                created_interval);
             ret = orig_feat;
             //ResetRefsFrom(&orig_feat, 0, &created_point, &created_interval);
             feat_h.m_CreatedOriginalFeat = ret;
@@ -1493,6 +1581,10 @@ CAnnot_Collector::~CAnnot_Collector(void)
 inline
 bool CAnnot_Collector::x_NoMoreObjects(void) const
 {
+    if ( x_MaxSearchSegmentsLimitIsReached() ) {
+        // search segment limit reached
+        return true;
+    }
     typedef SAnnotSelector::TMaxSize TMaxSize;
     TMaxSize limit = m_Selector->GetMaxSize();
     if ( limit >= numeric_limits<TMaxSize>::max() ) {
@@ -1575,6 +1667,7 @@ void CAnnot_Collector::x_Initialize0(const SAnnotSelector& selector)
         x_GetTSE_Info();
     }
     m_SearchSegments = selector.GetMaxSearchSegments();
+    m_SearchSegmentsAction = selector.GetMaxSearchSegmentsAction();
     double max_time = selector.GetMaxSearchTime();
     if ( max_time <= 86400 ) { // 24 hours
         m_SearchTime.Start();
@@ -1869,9 +1962,9 @@ void CAnnot_Collector::x_SearchMaster(const CBioseq_Handle& bh,
                 }
             }
             else {
-                const CBioseq_Handle::TId& syns = bh.GetId();
+                const CBioseq_Handle::TId& syns_id = bh.GetId();
                 bool only_gi = tse_info.OnlyGiAnnotIds();
-                ITERATE ( CBioseq_Handle::TId, syn_it, syns ) {
+                ITERATE ( CBioseq_Handle::TId, syn_it, syns_id ) {
                     if ( !only_gi || syn_it->IsGi() ) {
                         x_SearchTSE(tse_it->second, *syn_it,
                                     master_range, 0, check_adaptive);
@@ -2323,23 +2416,26 @@ void CAnnot_Collector::x_Initialize(const SAnnotSelector& selector)
 
 void CAnnot_Collector::x_Sort(void)
 {
+    //CStopWatch sw(CStopWatch::eStart);
     _ASSERT(!m_MappingCollector.get());
     switch ( m_Selector->m_SortOrder ) {
     case SAnnotSelector::eSortOrder_Normal:
-        stable_sort(m_AnnotSet.begin(), m_AnnotSet.end(),
-                    CAnnotObject_Less(m_Selector, m_Scope));
+        gfx::timsort(m_AnnotSet.begin(), m_AnnotSet.end(),
+                     CAnnotObject_Less(m_Selector, m_Scope));
         break;
     case SAnnotSelector::eSortOrder_Reverse:
-        stable_sort(m_AnnotSet.begin(), m_AnnotSet.end(),
-                    CAnnotObject_LessReverse(m_Selector, m_Scope));
+        gfx::timsort(m_AnnotSet.begin(), m_AnnotSet.end(),
+                     CAnnotObject_LessReverse(m_Selector, m_Scope));
         break;
     default:
         // do nothing
         break;
     }
+    //LOG_POST(Info<<"Sorted in "<<sw.Elapsed());
 }
 
 
+inline
 bool
 CAnnot_Collector::x_MatchLimitObject(const CAnnotObject_Info& object) const
 {
@@ -2514,6 +2610,8 @@ bool CAnnot_Collector::x_SearchTSE2(const CTSE_Handle&    tseh,
     tse.UpdateAnnotIndex(id);
     CTSE_Info::TAnnotLockReadGuard guard(tse.GetAnnotLock());
 
+    //CStopWatch sw(CStopWatch::eStart);
+
     if (cvt) {
         cvt->SetSrcId(id);
     }
@@ -2599,6 +2697,8 @@ bool CAnnot_Collector::x_SearchTSE2(const CTSE_Handle&    tseh,
             }
         }
     }
+
+    //LOG_POST(Info<<"Collected annots in "<<sw.Elapsed());
     return found;
 }
 
@@ -2791,14 +2891,16 @@ void CAnnot_Collector::x_SearchRange(const CTSE_Handle&    tseh,
 
             size_t start_size = m_AnnotSet.size(); // for rollback
 
+            // Same annotations may appear more than once if circular.
+            // In this case duplicated annotation entries need to be removed.
             bool need_unique = false;
 
             ITERATE(CHandleRange, rg_it, hr) {
                 CHandleRange::TRange range = rg_it->first;
 
                 for ( CTSE_Info::TRangeMap::const_iterator
-                    aoit(rmap.begin(range));
-                    aoit; ++aoit ) {
+                          aoit(rmap.begin(range));
+                      aoit; ++aoit ) {
                     const CAnnotObject_Info& annot_info =
                         *aoit->second.m_AnnotObject_Info;
 
@@ -2890,14 +2992,14 @@ void CAnnot_Collector::x_SearchRange(const CTSE_Handle&    tseh,
                         CHandleRange::TRange ref_search_range;
                         if ( !ref_minus ) {
                             ref_search_range.Set(ref_from + (loc_view_from - loc_from),
-                                                ref_to + (loc_view_to - loc_to));
+                                                 ref_to + (loc_view_to - loc_to));
                         }
                         else {
                             ref_search_range.Set(ref_from - (loc_view_to - loc_to),
-                                                ref_to - (loc_view_from - loc_from));
+                                                 ref_to - (loc_view_from - loc_from));
                         }
                         ref_rmap.AddRanges(ref_idh).AddRange(ref_search_range,
-                                                            eNa_strand_unknown);
+                                                             eNa_strand_unknown);
 
                         if (m_Selector->m_NoMapping) {
                             x_SearchLoc(ref_rmap, 0, &tseh);
@@ -2907,13 +3009,13 @@ void CAnnot_Collector::x_SearchRange(const CTSE_Handle&    tseh,
                             master_loc_empty->SetEmpty(
                                 const_cast<CSeq_id&>(*id.GetSeqId()));
                             CRef<CSeq_loc_Conversion> locs_cvt(new CSeq_loc_Conversion(
-                                    *master_loc_empty,
-                                    id,
-                                    aoit->first,
-                                    ref_idh,
-                                    ref_from,
-                                    ref_minus,
-                                    m_Scope));
+                                                                   *master_loc_empty,
+                                                                   id,
+                                                                   aoit->first,
+                                                                   ref_idh,
+                                                                   ref_from,
+                                                                   ref_minus,
+                                                                   m_Scope));
                             if ( cvt ) {
                                 locs_cvt->CombineWith(*cvt);
                             }
@@ -2937,6 +3039,48 @@ void CAnnot_Collector::x_SearchRange(const CTSE_Handle&    tseh,
                         continue;
                     }
 
+                    if ( annot_info.GetAnnotIndex() == CSeq_annot_Info::kWholeAnnotIndex ) {
+                        const CSeq_annot_Info& seq_annot = annot_info.GetSeq_annot_Info();
+                        if ( seq_annot.IsSortedTable() ) {
+                            sah.x_Set(seq_annot, tseh);
+                            CHandleRange::TRange hrange = hr.GetOverlappingRange();
+                            for ( CSeq_annot_SortedIter iter =
+                                      seq_annot.StartSortedIterator(hrange);
+                                  iter; ++iter ) {
+
+                                if (m_Selector->HasBitFilter() &&
+                                    !seq_annot.MatchBitFilter(*m_Selector,
+                                                              iter) ) {
+                                    continue;
+                                }
+                                
+                                if (m_Selector->m_CollectTypes) {
+                                    m_AnnotTypes.set(index);
+                                    break;
+                                }
+                                
+                                if (m_Selector->m_CollectNames) {
+                                    m_AnnotNames->insert(annot_name);
+                                    break;
+                                }
+                                
+                                CAnnotObject_Ref annot_ref(sah, iter, cvt);
+                                x_AddObject(annot_ref);
+                                if ( x_NoMoreObjects() ) {
+                                    _ASSERT(!restart);
+                                    enough = true;
+                                    break;
+                                }
+                                
+                                if ( m_Selector->m_CollectSeq_annots ) {
+                                    // Ignore multiple feats from the same seq-annot
+                                    break;
+                                }
+                            }
+                        }
+                        continue;
+                    }
+
                     bool is_circular = aoit->second.m_HandleRange  &&
                         aoit->second.m_HandleRange->GetData().IsCircular();
                     need_unique |= is_circular;
@@ -2958,7 +3102,7 @@ void CAnnot_Collector::x_SearchRange(const CTSE_Handle&    tseh,
                             ref_rg = CHandleRange::TRange(from, to);
                         }
                         annot_ref.GetMappingInfo().SetAnnotObjectRange(ref_rg,
-                                m_Selector->m_FeatProduct);
+                                                                       m_Selector->m_FeatProduct);
                         x_AddObjectMapping(annot_ref, 0,
                                            aoit->second.m_AnnotLocationIndex);
                     }
@@ -2982,7 +3126,7 @@ void CAnnot_Collector::x_SearchRange(const CTSE_Handle&    tseh,
                                 ref_rg = CHandleRange::TRange(from, to);
                             }
                             annot_ref.GetMappingInfo().SetAnnotObjectRange(ref_rg,
-                                m_Selector->m_FeatProduct);
+                                                                           m_Selector->m_FeatProduct);
                         }
                         x_AddObject(annot_ref, cvt,
                                     aoit->second.m_AnnotLocationIndex);
@@ -3010,7 +3154,7 @@ void CAnnot_Collector::x_SearchRange(const CTSE_Handle&    tseh,
                 TAnnotSet::iterator first_added = m_AnnotSet.begin() + start_size;
                 stable_sort(first_added, m_AnnotSet.end());
                 m_AnnotSet.erase(unique(first_added, m_AnnotSet.end()),
-                                m_AnnotSet.end());
+                                 m_AnnotSet.end());
             }
             if ( enough ) {
                 _ASSERT(!restart);
@@ -3158,10 +3302,9 @@ bool CAnnot_Collector::x_SearchLoc(const CHandleRangeMap& loc,
                     }
                 }
                 else {
-                    const CBioseq_Handle::TId& syns =
-                        m_Scope->GetIds(idit->first);
+                    const CBioseq_Handle::TId& ids = m_Scope->GetIds(idit->first);
                     bool only_gi = tse_info.OnlyGiAnnotIds();
-                    ITERATE ( CBioseq_Handle::TId, syn_it, syns ) {
+                    ITERATE ( CBioseq_Handle::TId, syn_it, ids ) {
                         if ( !only_gi || syn_it->IsGi() ) {
                             found |= x_SearchTSE(tse_it->second, *syn_it,
                                                  idit->second, cvt, check_adaptive);
@@ -3364,10 +3507,19 @@ bool CAnnot_Collector::x_SearchMapped(const CSeqMap_CI&     seg,
                    "search time limit exceeded, no annotations found");
     }
     if ( m_SearchSegments != numeric_limits<TMaxSearchSegments>::max() &&
+         x_MaxSearchSegmentsLimitIsReached() ||
          --m_SearchSegments == 0 ) {
-        NCBI_THROW(CAnnotSearchLimitException, eSegmentsLimitExceded,
-                   "CAnnot_Collector: "
-                   "search segments limit exceeded, no annotations found");
+        if ( m_SearchSegmentsAction == SAnnotSelector::eMaxSearchSegmentsThrow ) {
+            NCBI_THROW(CAnnotSearchLimitException, eSegmentsLimitExceded,
+                       "CAnnot_Collector: "
+                       "search segments limit exceeded, no annotations found");
+        }
+        if ( m_SearchSegmentsAction == SAnnotSelector::eMaxSearchSegmentsLog ) {
+            ERR_POST_X(2, "CAnnot_Collector: "
+                       "search segments limit exceeded, no annotations found");
+        }
+        // stop searching
+        return false;
     }
     CHandleRange::TOpenRange master_seg_range(
         seg.GetPosition(),
diff --git a/c++/src/objmgr/annot_object_index.cpp b/c++/src/objmgr/annot_object_index.cpp
index c8016cc..c6c25d6 100644
--- a/c++/src/objmgr/annot_object_index.cpp
+++ b/c++/src/objmgr/annot_object_index.cpp
@@ -1,4 +1,4 @@
-/*  $Id: annot_object_index.cpp 103491 2007-05-04 17:18:18Z kazimird $
+/*  $Id: annot_object_index.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -89,7 +89,7 @@ void SAnnotObjectsIndex::AddInfo(const CAnnotObject_Info& info)
 
 
 void SAnnotObjectsIndex::AddMap(const SAnnotObject_Key& key,
-                                const SAnnotObject_Index& index)
+                                const SAnnotObject_Index& /*index*/)
 {
     m_Keys.push_back(key);
 }
diff --git a/c++/src/objmgr/annot_selector.cpp b/c++/src/objmgr/annot_selector.cpp
index 9afb1b0..aea70d5 100644
--- a/c++/src/objmgr/annot_selector.cpp
+++ b/c++/src/objmgr/annot_selector.cpp
@@ -1,4 +1,4 @@
-/*  $Id: annot_selector.cpp 435052 2014-05-13 17:26:17Z vasilche $
+/*  $Id: annot_selector.cpp 519943 2016-11-21 15:34:20Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -69,6 +69,7 @@ SAnnotSelector::SAnnotSelector(TAnnotType annot,
       m_MaxSize(numeric_limits<size_t>::max()),
       m_MaxSearchSegments(kMax_UInt),
       m_MaxSearchTime(FLT_MAX),
+      m_MaxSearchSegmentsAction(eMaxSearchSegmentsThrow),
       m_NoMapping(false),
       m_AdaptiveDepthFlags(kAdaptive_None),
       m_ExactDepth(false),
@@ -76,7 +77,9 @@ SAnnotSelector::SAnnotSelector(TAnnotType annot,
       m_CollectSeq_annots(false),
       m_CollectTypes(false),
       m_CollectNames(false),
-      m_IgnoreStrand(false)
+      m_IgnoreStrand(false),
+      m_FilterMask(0),
+      m_FilterBits(0)
 {
     if ( feat != CSeqFeatData::e_not_set ) {
         SetFeatType(feat);
@@ -97,6 +100,7 @@ SAnnotSelector::SAnnotSelector(TFeatType feat,
       m_MaxSize(numeric_limits<size_t>::max()),
       m_MaxSearchSegments(kMax_UInt),
       m_MaxSearchTime(FLT_MAX),
+      m_MaxSearchSegmentsAction(eMaxSearchSegmentsThrow),
       m_NoMapping(false),
       m_AdaptiveDepthFlags(kAdaptive_None),
       m_ExactDepth(false),
@@ -104,7 +108,9 @@ SAnnotSelector::SAnnotSelector(TFeatType feat,
       m_CollectSeq_annots(false),
       m_CollectTypes(false),
       m_CollectNames(false),
-      m_IgnoreStrand(false)
+      m_IgnoreStrand(false),
+      m_FilterMask(0),
+      m_FilterBits(0)
 {
 }
 
@@ -121,6 +127,7 @@ SAnnotSelector::SAnnotSelector(TFeatSubtype feat_subtype)
       m_MaxSize(numeric_limits<size_t>::max()),
       m_MaxSearchSegments(kMax_UInt),
       m_MaxSearchTime(FLT_MAX),
+      m_MaxSearchSegmentsAction(eMaxSearchSegmentsThrow),
       m_NoMapping(false),
       m_AdaptiveDepthFlags(kAdaptive_None),
       m_ExactDepth(false),
@@ -128,7 +135,9 @@ SAnnotSelector::SAnnotSelector(TFeatSubtype feat_subtype)
       m_CollectSeq_annots(false),
       m_CollectTypes(false),
       m_CollectNames(false),
-      m_IgnoreStrand(false)
+      m_IgnoreStrand(false),
+      m_FilterMask(0),
+      m_FilterBits(0)
 {
 }
 
@@ -162,6 +171,7 @@ SAnnotSelector& SAnnotSelector::operator=(const SAnnotSelector& sel)
             m_NamedAnnotAccessions.reset
                 (new TNamedAnnotAccessions(*sel.m_NamedAnnotAccessions));
         }
+        m_MaxSearchSegmentsAction = sel.m_MaxSearchSegmentsAction;
         m_NoMapping = sel.m_NoMapping;
         m_AdaptiveDepthFlags = sel.m_AdaptiveDepthFlags;
         m_ExactDepth = sel.m_ExactDepth;
@@ -170,6 +180,8 @@ SAnnotSelector& SAnnotSelector::operator=(const SAnnotSelector& sel)
         m_CollectTypes = sel.m_CollectTypes;
         m_CollectNames = sel.m_CollectNames;
         m_IgnoreStrand = sel.m_IgnoreStrand;
+        m_FilterMask = sel.m_FilterMask;
+        m_FilterBits = sel.m_FilterBits;
         m_AdaptiveTriggers = sel.m_AdaptiveTriggers;
         m_ExcludedTSE = sel.m_ExcludedTSE;
         m_AnnotTypesBitset = sel.m_AnnotTypesBitset;
diff --git a/c++/src/objmgr/annot_types_ci.cpp b/c++/src/objmgr/annot_types_ci.cpp
index d9dd5d4..118b262 100644
--- a/c++/src/objmgr/annot_types_ci.cpp
+++ b/c++/src/objmgr/annot_types_ci.cpp
@@ -1,4 +1,4 @@
-/*  $Id: annot_types_ci.cpp 323253 2011-07-26 16:52:15Z vasilche $
+/*  $Id: annot_types_ci.cpp 519943 2016-11-21 15:34:20Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -233,5 +233,11 @@ const CAnnotTypes_CI::TAnnotNames& CAnnotTypes_CI::GetAnnotNames(void) const
 }
 
 
+bool CAnnotTypes_CI::MaxSearchSegmentsLimitIsReached(void) const
+{
+    return m_DataCollector->x_MaxSearchSegmentsLimitIsReached();
+}
+
+
 END_SCOPE(objects)
 END_NCBI_SCOPE
diff --git a/c++/src/objmgr/bioseq_base_info.cpp b/c++/src/objmgr/bioseq_base_info.cpp
index e12771e..feb62a2 100644
--- a/c++/src/objmgr/bioseq_base_info.cpp
+++ b/c++/src/objmgr/bioseq_base_info.cpp
@@ -1,4 +1,4 @@
-/*  $Id: bioseq_base_info.cpp 489127 2016-01-08 16:52:37Z vasilche $
+/*  $Id: bioseq_base_info.cpp 512047 2016-08-26 14:21:48Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -185,6 +185,7 @@ void CBioseq_Base_Info::x_AddDescrChunkId(const TDescTypeMask& types,
 {
     m_DescrChunks.push_back(id);
     m_DescrTypeMasks.push_back(types);
+    x_SetDescr();
     x_SetNeedUpdate(fNeedUpdate_descr);
 }
 
@@ -300,15 +301,7 @@ void CBioseq_Base_Info::AddSeq_descr(const TDescr& v)
 
 const CSeq_descr::Tdata& CBioseq_Base_Info::x_GetDescList(void) const
 {
-    try {
-        return x_GetDescr().Get();
-    }
-    catch ( exception& ) {
-        if ( !x_IsSetDescr() && IsSetDescr() ) {
-            return const_cast<CBioseq_Base_Info*>(this)->x_SetDescr().Get();
-        }
-        throw;
-    }
+    return x_GetDescr().Get();
 }
 
 
@@ -491,5 +484,23 @@ const CSeqdesc* CBioseq_Base_Info::x_SearchFirstDesc(TDescTypeMask mask) const
 }
 
 
+CBioseq_Base_Info::TDescTypeMask
+CBioseq_Base_Info::x_GetExistingDescrMask(void) const
+{
+    TDescTypeMask mask = 0;
+    if ( x_IsSetDescr() ) {
+        // collect already set descr bits
+        for ( auto& i : x_GetDescr().Get() ) {
+            mask |= 1 << i->Which();
+        }
+    }
+    // add descr mask from chunks
+    for ( auto& i : m_DescrTypeMasks ) {
+        mask |= i;
+    }
+    return mask;
+}
+
+
 END_SCOPE(objects)
 END_NCBI_SCOPE
diff --git a/c++/src/objmgr/bioseq_handle.cpp b/c++/src/objmgr/bioseq_handle.cpp
index d6caeaa..e774d0e 100644
--- a/c++/src/objmgr/bioseq_handle.cpp
+++ b/c++/src/objmgr/bioseq_handle.cpp
@@ -1,4 +1,4 @@
-/*  $Id: bioseq_handle.cpp 499042 2016-04-21 17:39:04Z ivanov $
+/*  $Id: bioseq_handle.cpp 496211 2016-03-24 15:33:11Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objmgr/bioseq_info.cpp b/c++/src/objmgr/bioseq_info.cpp
index e955c2a..7167800 100644
--- a/c++/src/objmgr/bioseq_info.cpp
+++ b/c++/src/objmgr/bioseq_info.cpp
@@ -1,4 +1,4 @@
-/*  $Id: bioseq_info.cpp 499042 2016-04-21 17:39:04Z ivanov $
+/*  $Id: bioseq_info.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -97,6 +97,13 @@ CBioseq_Info::CBioseq_Info(const CBioseq_Info& info, TObjectCopyMap* copy_map)
       m_AssemblyChunk(info.m_AssemblyChunk),
       m_FeatureFetchPolicy(info.m_FeatureFetchPolicy)
 {
+    if ( !copy_map ) {
+        info.x_UpdateComplete();
+        m_DescrChunks.clear();
+        m_AnnotChunks.clear();
+        m_Seq_dataChunks.clear();
+        m_AssemblyChunk = -1;
+    }
     x_SetObject(info, copy_map);
 }
 
@@ -1238,11 +1245,11 @@ const CSeqMap& CBioseq_Info::GetSeqMap(void) const
 int CBioseq_Info::GetTaxId(void) const
 {
     const COrg_ref* org_ref = 0;
-    if ( const CSeqdesc* desc = x_SearchFirstDesc(1<<CSeqdesc::e_Source) ) {
-        org_ref = &desc->GetSource().GetOrg();
+    if ( const CSeqdesc* desc_src = x_SearchFirstDesc(1<<CSeqdesc::e_Source) ) {
+        org_ref = &desc_src->GetSource().GetOrg();
     }
-    else if ( const CSeqdesc* desc = x_SearchFirstDesc(1<<CSeqdesc::e_Org) ) {
-        org_ref = &desc->GetOrg();
+    else if ( const CSeqdesc* desc_org = x_SearchFirstDesc(1<<CSeqdesc::e_Org) ) {
+        org_ref = &desc_org->GetOrg();
     }
     else {
         return 0;
diff --git a/c++/src/objmgr/bioseq_set_info.cpp b/c++/src/objmgr/bioseq_set_info.cpp
index 6c20c3d..75ebb00 100644
--- a/c++/src/objmgr/bioseq_set_info.cpp
+++ b/c++/src/objmgr/bioseq_set_info.cpp
@@ -1,4 +1,4 @@
-/*  $Id: bioseq_set_info.cpp 404642 2013-06-25 22:06:08Z vasilche $
+/*  $Id: bioseq_set_info.cpp 507368 2016-07-18 21:33:41Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -73,6 +73,12 @@ CBioseq_set_Info::CBioseq_set_Info(const CBioseq_set_Info& info,
       m_BioseqChunks(info.m_BioseqChunks),
       m_Bioseq_set_Id(-1)
 {
+    if ( !copy_map ) {
+        info.x_UpdateComplete();
+        m_DescrChunks.clear();
+        m_AnnotChunks.clear();
+        m_BioseqChunks.clear();
+    }
     x_SetObject(info, copy_map);
 }
 
diff --git a/c++/src/objmgr/data_loader.cpp b/c++/src/objmgr/data_loader.cpp
index f8fcd16..36eea40 100644
--- a/c++/src/objmgr/data_loader.cpp
+++ b/c++/src/objmgr/data_loader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: data_loader.cpp 498421 2016-04-15 18:44:37Z ivanov $
+/*  $Id: data_loader.cpp 498345 2016-04-15 14:39:08Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objmgr/data_source.cpp b/c++/src/objmgr/data_source.cpp
index e24336c..02c3314 100644
--- a/c++/src/objmgr/data_source.cpp
+++ b/c++/src/objmgr/data_source.cpp
@@ -1,4 +1,4 @@
-/*  $Id: data_source.cpp 498421 2016-04-15 18:44:37Z ivanov $
+/*  $Id: data_source.cpp 498345 2016-04-15 14:39:08Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objmgr/edits_db_saver.cpp b/c++/src/objmgr/edits_db_saver.cpp
index 5781a69..242f68a 100644
--- a/c++/src/objmgr/edits_db_saver.cpp
+++ b/c++/src/objmgr/edits_db_saver.cpp
@@ -1,4 +1,4 @@
-/*  $Id: edits_db_saver.cpp 398046 2013-05-02 13:20:29Z grichenk $
+/*  $Id: edits_db_saver.cpp 514368 2016-09-21 15:22:14Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -163,6 +163,7 @@ DEFCHOOSER(Replace_annot,   ReplaceAnnot);
 
 #undef DEFCHOOSER
 
+
 template<int type> 
 struct SCmdCreator 
 {
@@ -193,6 +194,8 @@ struct SCmdCreator
 
 };
 
+
+
 template<typename THandle>
 static inline void s_AddDescr(const THandle& handle, const CSeq_descr& descr,
                               IEditsDBEngine& engine)
@@ -204,17 +207,19 @@ static inline void s_AddDescr(const THandle& handle, const CSeq_descr& descr,
 }
 
 void CEditsSaver::AddDescr(const CBioseq_Handle& handle, 
-                           const CSeq_descr& descr, ECallMode mode)
+                           const CSeq_descr& descr, ECallMode)
 {
     s_AddDescr(handle, descr, GetDBEngine());
 }
 
 void CEditsSaver::AddDescr(const CBioseq_set_Handle& handle, 
-                           const CSeq_descr& descr, ECallMode mode)
+                           const CSeq_descr& descr, ECallMode)
 {
     s_AddDescr(handle, descr, GetDBEngine());
 }
 
+
+
 template<typename THandle>
 static inline void s_SetDescr(const THandle& handle, const CSeq_descr& descr,
                               IEditsDBEngine& engine)
@@ -224,17 +229,21 @@ static inline void s_SetDescr(const THandle& handle, const CSeq_descr& descr,
         .SetSet_descr(const_cast<CSeq_descr&>(descr));
     engine.SaveCommand(*cmd); 
 }
+
 void CEditsSaver::SetDescr(const CBioseq_Handle& handle, 
-                           const CSeq_descr& descr, ECallMode mode)
+                           const CSeq_descr& descr, ECallMode)
 {
     s_SetDescr(handle, descr, GetDBEngine());
 }
+
 void CEditsSaver::SetDescr(const CBioseq_set_Handle& handle, 
-                           const CSeq_descr& descr, ECallMode mode)
+                           const CSeq_descr& descr, ECallMode)
 {
     s_SetDescr(handle, descr, GetDBEngine());
 }
 
+
+
 template<typename THandle>
 static inline void s_ResetDescr(const THandle& handle,
                                 IEditsDBEngine& engine)
@@ -243,17 +252,19 @@ static inline void s_ResetDescr(const THandle& handle,
     SCmdCreator<CSeqEdit_Cmd::e_Reset_descr>::CreateCmd(handle,cmd);
     engine.SaveCommand(*cmd); 
 }
-void CEditsSaver::ResetDescr(const CBioseq_Handle& handle, 
-                             ECallMode mode)
+
+void CEditsSaver::ResetDescr(const CBioseq_Handle& handle, ECallMode)
 {
     s_ResetDescr(handle, GetDBEngine());
 }
-void CEditsSaver::ResetDescr(const CBioseq_set_Handle& handle, 
-                             ECallMode mode)
+
+void CEditsSaver::ResetDescr(const CBioseq_set_Handle& handle, ECallMode)
 {
     s_ResetDescr(handle, GetDBEngine());
 }
 
+
+
 template<typename THandle>
 static inline void s_AddDesc(const THandle& handle, 
                              const CSeqdesc& desc,
@@ -264,13 +275,15 @@ static inline void s_AddDesc(const THandle& handle,
         SetAdd_desc(const_cast<CSeqdesc&>(desc));
     engine.SaveCommand(*cmd); 
 }
+
 void CEditsSaver::AddDesc(const CBioseq_Handle& handle, 
-                          const CSeqdesc& desc, ECallMode mode)
+                          const CSeqdesc& desc, ECallMode)
 {
     s_AddDesc(handle, desc, GetDBEngine());
 }
+
 void CEditsSaver::AddDesc(const CBioseq_set_Handle& handle, 
-                          const CSeqdesc& desc, ECallMode mode)
+                          const CSeqdesc& desc, ECallMode)
 {
     s_AddDesc(handle, desc, GetDBEngine());
 }
@@ -285,17 +298,22 @@ static inline void s_RemoveDesc(const THandle& handle,
         SetRemove_desc(const_cast<CSeqdesc&>(desc));
     engine.SaveCommand(*cmd); 
 }
+
 void CEditsSaver::RemoveDesc(const CBioseq_Handle& handle, 
-                             const CSeqdesc& desc, ECallMode mode)
+                             const CSeqdesc& desc, ECallMode)
 {
     s_RemoveDesc(handle, desc, GetDBEngine());
 }
+
 void CEditsSaver::RemoveDesc(const CBioseq_set_Handle& handle, 
-                             const CSeqdesc& desc, ECallMode mode)
+                             const CSeqdesc& desc, ECallMode)
 {
     s_RemoveDesc(handle, desc, GetDBEngine());
 }
+
+
 //------------------------------------------------------------------
+
 template<int>
 struct SSeqAttrChanger;
 
@@ -329,75 +347,86 @@ DEFINSTCH(Seq_data);
 #undef DEFINSTCH
 
 void CEditsSaver::SetSeqInst(const CBioseq_Handle& handle, 
-                             const CSeq_inst& value, 
-                             ECallMode mode)
+                             const CSeq_inst& value,
+                             ECallMode)
 {   
     SSeqAttrChanger<CSeqEdit_Cmd_ChangeSeqAttr::TData::e_Inst>::
         CreateCmd(handle,value,GetDBEngine());
 }
 
 void CEditsSaver::SetSeqInstRepr(const CBioseq_Handle& handle, 
-                                 CSeq_inst::TRepr value, ECallMode mode)
+                                 CSeq_inst::TRepr value,
+                                 ECallMode)
 {
     SSeqAttrChanger<CSeqEdit_Cmd_ChangeSeqAttr::TData::e_Repr>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetSeqInstMol(const CBioseq_Handle& handle, 
-                                CSeq_inst::TMol value, ECallMode mode)
+                                CSeq_inst::TMol value,
+                                ECallMode)
 {
     SSeqAttrChanger<CSeqEdit_Cmd_ChangeSeqAttr::TData::e_Mol>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetSeqInstLength(const CBioseq_Handle& handle, 
                                    CSeq_inst::TLength value,
-                                   ECallMode mode)
+                                   ECallMode)
 {
     SSeqAttrChanger<CSeqEdit_Cmd_ChangeSeqAttr::TData::e_Length>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetSeqInstFuzz(const CBioseq_Handle& handle, 
-                                 const CSeq_inst::TFuzz& value, 
-                                 ECallMode mode)
+                                 const CSeq_inst::TFuzz& value,
+                                 ECallMode)
 {
     SSeqAttrChanger<CSeqEdit_Cmd_ChangeSeqAttr::TData::e_Fuzz>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetSeqInstTopology(const CBioseq_Handle& handle, 
                                      CSeq_inst::TTopology value,
-                                     ECallMode mode)
+                                     ECallMode)
 {
     SSeqAttrChanger<CSeqEdit_Cmd_ChangeSeqAttr::TData::e_Topology>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetSeqInstStrand(const CBioseq_Handle& handle, 
                                    CSeq_inst::TStrand value, 
-                                   ECallMode mode)
+                                   ECallMode)
 {
     SSeqAttrChanger<CSeqEdit_Cmd_ChangeSeqAttr::TData::e_Strand>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetSeqInstExt(const CBioseq_Handle& handle, 
                                 const CSeq_inst::TExt& value, 
-                                ECallMode mode)
+                                ECallMode)
 {
     SSeqAttrChanger<CSeqEdit_Cmd_ChangeSeqAttr::TData::e_Ext>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetSeqInstHist(const CBioseq_Handle& handle, 
                                  const CSeq_inst::THist& value, 
-                                 ECallMode mode)
+                                 ECallMode)
 {
     SSeqAttrChanger<CSeqEdit_Cmd_ChangeSeqAttr::TData::e_Hist>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetSeqInstSeq_data(const CBioseq_Handle& handle, 
                                      const CSeq_inst::TSeq_data& value, 
-                                     ECallMode mode)
+                                     ECallMode)
 {
     SSeqAttrChanger<CSeqEdit_Cmd_ChangeSeqAttr::TData::e_Seq_data>::
         CreateCmd(handle,value,GetDBEngine());
 }
 
+
 static inline 
 void s_ResetSeqAttr(const CBioseq_Handle& handle, 
                     CSeqEdit_Cmd_ResetSeqAttr::TWhat what, 
@@ -409,72 +438,63 @@ void s_ResetSeqAttr(const CBioseq_Handle& handle,
     engine.SaveCommand(*cmd); 
 }
     
-void CEditsSaver::ResetSeqInst(const CBioseq_Handle& handle, 
-                               ECallMode mode)
+void CEditsSaver::ResetSeqInst(const CBioseq_Handle& handle, ECallMode)
 {
-    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_inst,
-                   GetDBEngine());
+    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_inst, GetDBEngine());
 }
-void CEditsSaver::ResetSeqInstRepr(const CBioseq_Handle& handle, 
-                                   ECallMode mode)
+
+void CEditsSaver::ResetSeqInstRepr(const CBioseq_Handle& handle, ECallMode)
 {
-    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_repr,
-                   GetDBEngine());
+    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_repr, GetDBEngine());
 }
-void CEditsSaver::ResetSeqInstMol(const CBioseq_Handle& handle, 
-                                  ECallMode mode)
+
+void CEditsSaver::ResetSeqInstMol(const CBioseq_Handle& handle, ECallMode)
 {
-    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_mol,
-                   GetDBEngine());
+    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_mol, GetDBEngine());
 }
-void CEditsSaver::ResetSeqInstLength(const CBioseq_Handle& handle, 
-                                     ECallMode mode)
+
+void CEditsSaver::ResetSeqInstLength(const CBioseq_Handle& handle, ECallMode)
 {
-    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_length,
-                    GetDBEngine());
+    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_length, GetDBEngine());
 }
-void CEditsSaver::ResetSeqInstFuzz(const CBioseq_Handle& handle, 
-                                   ECallMode mode)
+
+void CEditsSaver::ResetSeqInstFuzz(const CBioseq_Handle& handle, ECallMode)
 {
-    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_fuzz,
-                   GetDBEngine());
+    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_fuzz, GetDBEngine());
 }
-void CEditsSaver::ResetSeqInstTopology(const CBioseq_Handle& handle, 
-                                       ECallMode mode)
+
+void CEditsSaver::ResetSeqInstTopology(const CBioseq_Handle& handle, ECallMode)
 {
-    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_topology,
-                   GetDBEngine());
+    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_topology, GetDBEngine());
 }
-void CEditsSaver::ResetSeqInstStrand(const CBioseq_Handle& handle, 
-                                     ECallMode mode)
+
+void CEditsSaver::ResetSeqInstStrand(const CBioseq_Handle& handle, ECallMode)
 {
-    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_strand,
-                   GetDBEngine());
+    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_strand, GetDBEngine());
 } 
-void CEditsSaver::ResetSeqInstExt(const CBioseq_Handle& handle, 
-                                  ECallMode mode)
+
+void CEditsSaver::ResetSeqInstExt(const CBioseq_Handle& handle, ECallMode)
 {
-    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_ext,
-                   GetDBEngine());
+    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_ext, GetDBEngine());
 }
-void CEditsSaver::ResetSeqInstHist(const CBioseq_Handle& handle, 
-                                   ECallMode mode)
+
+void CEditsSaver::ResetSeqInstHist(const CBioseq_Handle& handle, ECallMode)
 {
-    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_hist,
-                   GetDBEngine());
+    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_hist, GetDBEngine());
 }
-void CEditsSaver::ResetSeqInstSeq_data(const CBioseq_Handle& handle, 
-                                       ECallMode mode)
+
+void CEditsSaver::ResetSeqInstSeq_data(const CBioseq_Handle& handle, ECallMode)
 {
-    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_seq_data,
-                   GetDBEngine());
+    s_ResetSeqAttr(handle, CSeqEdit_Cmd_ResetSeqAttr::eWhat_seq_data, GetDBEngine());
 
 }
 
-    //----------------------------------------------------------------
+
+//----------------------------------------------------------------
+
 void CEditsSaver::AddId(const CBioseq_Handle& handle, 
                         const CSeq_id_Handle& id, 
-                        ECallMode mode)
+                        ECallMode)
 {
     
     CRef<CSeqEdit_Cmd> cmd;
@@ -483,9 +503,10 @@ void CEditsSaver::AddId(const CBioseq_Handle& handle,
     GetDBEngine().SaveCommand(*cmd); 
     GetDBEngine().NotifyIdChanged(id, cmd->GetBlobId());
 }
+
 void CEditsSaver::RemoveId(const CBioseq_Handle& handle, 
-                                const CSeq_id_Handle& id, 
-                                ECallMode mode)
+                           const CSeq_id_Handle& id, 
+                           ECallMode)
 {
     CRef<CSeqEdit_Cmd> cmd;
     SCmdCreator<CSeqEdit_Cmd::e_Remove_id>::CreateCmd(handle,
@@ -500,9 +521,10 @@ static inline CRef<CSeq_id> s_ConvertId(const CSeq_id_Handle& handle)
 {
     return CRef<CSeq_id>(const_cast<CSeq_id*>(&*handle.GetSeqId()));
 }
+
 void CEditsSaver::ResetIds(const CBioseq_Handle& handle, 
                            const TIds& ids,
-                           ECallMode mode)
+                           ECallMode)
 {
     if (ids.empty())
         return;
@@ -520,7 +542,10 @@ void CEditsSaver::ResetIds(const CBioseq_Handle& handle,
 ;
     }
 }
+
+
 //-------------------------------------------------------
+
 template<int>
 struct SSetAttrChanger;
 
@@ -551,101 +576,100 @@ DEFINSTCH(Date);
 
 void CEditsSaver::SetBioseqSetId(const CBioseq_set_Handle& handle,
                                  const CBioseq_set::TId& value, 
-                                 ECallMode mode)
+                                 ECallMode)
 {
     SSetAttrChanger<CSeqEdit_Cmd_ChangeSetAttr::TData::e_Id>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetBioseqSetColl(const CBioseq_set_Handle& handle,
                                    const CBioseq_set::TColl& value, 
-                                   ECallMode mode)
+                                   ECallMode)
 {
     SSetAttrChanger<CSeqEdit_Cmd_ChangeSetAttr::TData::e_Coll>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetBioseqSetLevel(const CBioseq_set_Handle& handle,
                                     CBioseq_set::TLevel value, 
-                                    ECallMode mode)
+                                    ECallMode)
 {
     SSetAttrChanger<CSeqEdit_Cmd_ChangeSetAttr::TData::e_Level>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetBioseqSetClass(const CBioseq_set_Handle& handle,
                                     CBioseq_set::TClass value, 
-                                    ECallMode mode)
+                                    ECallMode)
 {
     SSetAttrChanger<CSeqEdit_Cmd_ChangeSetAttr::TData::e_Class>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetBioseqSetRelease(const CBioseq_set_Handle& handle,
                                       const CBioseq_set::TRelease& value,  
-                                      ECallMode mode)
+                                      ECallMode)
 {
     SSetAttrChanger<CSeqEdit_Cmd_ChangeSetAttr::TData::e_Release>::
         CreateCmd(handle,value,GetDBEngine());
 }
+
 void CEditsSaver::SetBioseqSetDate(const CBioseq_set_Handle& handle,
                                    const CBioseq_set::TDate& value, 
-                                   ECallMode mode)
+                                   ECallMode)
 {
     SSetAttrChanger<CSeqEdit_Cmd_ChangeSetAttr::TData::e_Date>::
         CreateCmd(handle,value,GetDBEngine());
 }
 
+
 static inline 
 void s_ResetSetAttr(const CBioseq_set_Handle& handle, 
                     CSeqEdit_Cmd_ResetSetAttr::TWhat what, 
                     IEditsDBEngine& engine)
 {
     CRef<CSeqEdit_Cmd> cmd;
-    SCmdCreator<CSeqEdit_Cmd::e_Reset_setattr>::CreateCmd(handle,cmd).
-        SetWhat(what);
+    SCmdCreator<CSeqEdit_Cmd::e_Reset_setattr>::CreateCmd(handle,cmd).SetWhat(what);
     engine.SaveCommand(*cmd); 
 }
  
-void CEditsSaver::ResetBioseqSetId(const CBioseq_set_Handle& handle, 
-                                   ECallMode mode)
+void CEditsSaver::ResetBioseqSetId(const CBioseq_set_Handle& handle, ECallMode)
 {
-    s_ResetSetAttr(handle, CSeqEdit_Cmd_ResetSetAttr::eWhat_id,
-                   GetDBEngine());
+    s_ResetSetAttr(handle, CSeqEdit_Cmd_ResetSetAttr::eWhat_id, GetDBEngine());
 } 
-void CEditsSaver::ResetBioseqSetColl(const CBioseq_set_Handle& handle, 
-                                     ECallMode mode)
+
+void CEditsSaver::ResetBioseqSetColl(const CBioseq_set_Handle& handle, ECallMode)
 {
-    s_ResetSetAttr(handle, CSeqEdit_Cmd_ResetSetAttr::eWhat_coll,
-                   GetDBEngine());
+    s_ResetSetAttr(handle, CSeqEdit_Cmd_ResetSetAttr::eWhat_coll, GetDBEngine());
 }
-void CEditsSaver::ResetBioseqSetLevel(const CBioseq_set_Handle& handle, 
-                                      ECallMode mode)
+
+void CEditsSaver::ResetBioseqSetLevel(const CBioseq_set_Handle& handle, ECallMode)
 {
-    s_ResetSetAttr(handle, CSeqEdit_Cmd_ResetSetAttr::eWhat_level,
-                   GetDBEngine());
+    s_ResetSetAttr(handle, CSeqEdit_Cmd_ResetSetAttr::eWhat_level, GetDBEngine());
 }
-void CEditsSaver::ResetBioseqSetClass(const CBioseq_set_Handle& handle, 
-                                      ECallMode mode)
+
+void CEditsSaver::ResetBioseqSetClass(const CBioseq_set_Handle& handle, ECallMode)
 {
-    s_ResetSetAttr(handle, CSeqEdit_Cmd_ResetSetAttr::eWhat_class,
-                   GetDBEngine());
+    s_ResetSetAttr(handle, CSeqEdit_Cmd_ResetSetAttr::eWhat_class, GetDBEngine());
 }
-void CEditsSaver::ResetBioseqSetRelease(const CBioseq_set_Handle& handle, 
-                                             ECallMode mode)
+
+void CEditsSaver::ResetBioseqSetRelease(const CBioseq_set_Handle& handle, ECallMode)
 {
-    s_ResetSetAttr(handle, CSeqEdit_Cmd_ResetSetAttr::eWhat_release,
-                   GetDBEngine());
+    s_ResetSetAttr(handle, CSeqEdit_Cmd_ResetSetAttr::eWhat_release, GetDBEngine());
 }
-void CEditsSaver::ResetBioseqSetDate(const CBioseq_set_Handle& handle,
-                                          ECallMode mode)
+
+void CEditsSaver::ResetBioseqSetDate(const CBioseq_set_Handle& handle, ECallMode)
 {
-    s_ResetSetAttr(handle, CSeqEdit_Cmd_ResetSetAttr::eWhat_date,
-                   GetDBEngine());
+    s_ResetSetAttr(handle, CSeqEdit_Cmd_ResetSetAttr::eWhat_date, GetDBEngine());
 }
   
-    //-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
 
 void CEditsSaver::Attach(const CBioObjectId& old_id,
                          const CSeq_entry_Handle& handle,
                          const CBioseq_Handle& bioseq, 
-                         ECallMode mode)
+                         ECallMode)
 {
     CRef<CSeqEdit_Cmd> cmd;
     SCmdCreator<CSeqEdit_Cmd::e_Attach_seq>::CreateCmd(handle, old_id,cmd).
@@ -678,10 +702,11 @@ static void s_CollectSeqIds(const CSeq_entry& entry, IEditSaver::TIds& ids)
         }
     }
 }
+
 void CEditsSaver::Attach(const CBioObjectId& old_id,
                          const CSeq_entry_Handle& handle, 
                          const CBioseq_set_Handle& bioseq_set, 
-                         ECallMode mode)
+                         ECallMode)
 {
     CRef<CSeqEdit_Cmd> cmd;
     const CBioseq_set& bset = *bioseq_set.GetCompleteBioseq_set();
@@ -695,8 +720,9 @@ void CEditsSaver::Attach(const CBioObjectId& old_id,
     }
     
 }
+
 void CEditsSaver::Detach(const CSeq_entry_Handle& entry, 
-                         const CBioseq_Handle& handle, ECallMode mode)
+                         const CBioseq_Handle& handle, ECallMode)
 {
     CRef<CSeqEdit_Cmd> cmd;
     SCmdCreator<CSeqEdit_Cmd::e_Reset_seqentry>
@@ -707,8 +733,9 @@ void CEditsSaver::Detach(const CSeq_entry_Handle& entry,
     }
 
 }
+
 void CEditsSaver::Detach(const CSeq_entry_Handle& entry, 
-                         const CBioseq_set_Handle& handle, ECallMode mode)
+                         const CBioseq_set_Handle& handle, ECallMode)
 {
     CRef<CSeqEdit_Cmd> cmd;
     const CBioseq_set& bset = *handle.GetCompleteBioseq_set();
@@ -723,8 +750,7 @@ void CEditsSaver::Detach(const CSeq_entry_Handle& entry,
 }
 
 void CEditsSaver::Attach(const CSeq_entry_Handle& entry, 
-                         const CSeq_annot_Handle& annot, 
-                         ECallMode mode)
+                         const CSeq_annot_Handle& annot, ECallMode)
 {
     CRef<CSeqEdit_Cmd> cmd;
     SCmdCreator<CSeqEdit_Cmd::e_Attach_annot>::CreateCmd(entry,cmd).
@@ -734,7 +760,7 @@ void CEditsSaver::Attach(const CSeq_entry_Handle& entry,
 
 void CEditsSaver::Attach(const CBioseq_set_Handle& handle, 
                          const CSeq_entry_Handle& entry, 
-                         int index, ECallMode mode)
+                         int index, ECallMode)
 {
     CRef<CSeqEdit_Cmd> cmd;
     const CSeq_entry& sentry = *entry.GetCompleteSeq_entry();
@@ -750,9 +776,10 @@ void CEditsSaver::Attach(const CBioseq_set_Handle& handle,
         GetDBEngine().NotifyIdChanged(*id,cmd->GetBlobId());
     }
 }
+
 void CEditsSaver::Remove(const CBioseq_set_Handle& handle, 
                          const CSeq_entry_Handle& entry, 
-                         int, ECallMode mode)
+                         int, ECallMode)
 {
     CRef<CSeqEdit_Cmd> cmd;
     const CSeq_entry& sentry = *entry.GetCompleteSeq_entry();
@@ -774,7 +801,9 @@ void CEditsSaver::RemoveTSE(const CTSE_Handle& handle,
                "RemoveTSE(const CTSE_Handle&, ECallMode)");
 }
 */
-    //-----------------------------------------------------------------
+
+
+//-----------------------------------------------------------------
 
 template<int type>
 struct SAnnotCmdPreparer {
@@ -806,7 +835,7 @@ struct SAnnotCmdPreparer {
 
 void CEditsSaver::Replace(const CSeq_feat_Handle& handle,
                           const CSeq_feat& old_value, 
-                          ECallMode mode)
+                          ECallMode)
 {                          
     const CSeq_annot_Handle& annot = handle.GetAnnot();
     CRef<CSeqEdit_Cmd> cmd;
@@ -817,9 +846,10 @@ void CEditsSaver::Replace(const CSeq_feat_Handle& handle,
     GetDBEngine().SaveCommand(*cmd);
 
 }
+
 void CEditsSaver::Replace(const CSeq_align_Handle& handle,
                           const CSeq_align& old_value,
-                          ECallMode mode)
+                          ECallMode)
 {
     const CSeq_annot_Handle& annot = handle.GetAnnot();
     CRef<CSeqEdit_Cmd> cmd;
@@ -829,9 +859,10 @@ void CEditsSaver::Replace(const CSeq_align_Handle& handle,
     c.SetData().SetAlign().SetNvalue(const_cast<CSeq_align&>(*handle.GetSeq_align()));
     GetDBEngine().SaveCommand(*cmd);
 }
+
 void CEditsSaver::Replace(const CSeq_graph_Handle& handle,
                           const CSeq_graph& old_value, 
-                          ECallMode mode)
+                          ECallMode)
 {
     const CSeq_annot_Handle& annot = handle.GetAnnot();
     CRef<CSeqEdit_Cmd> cmd;
@@ -911,6 +942,7 @@ void s_SetSearchParam(CSeqEdit_Cmd_AddAnnot& cmd, const T& new_obj,
     }
 }
 
+
 template<typename T> static inline 
 void s_AddAnnot(const CSeq_annot_Handle& handle, const T& value, 
                 IEditsDBEngine& engine)
@@ -927,27 +959,28 @@ void s_AddAnnot(const CSeq_annot_Handle& handle, const T& value,
     engine.SaveCommand(*cmd); 
 }
 
-
 void CEditsSaver::Add(const CSeq_annot_Handle& handle,
                       const CSeq_feat& value, 
-                      ECallMode mode)
+                      ECallMode)
 {
     s_AddAnnot(handle, value, GetDBEngine());
 }
 
 void CEditsSaver::Add(const CSeq_annot_Handle& handle,
                       const CSeq_align& value, 
-                      ECallMode mode)
+                      ECallMode)
 {
     s_AddAnnot(handle, value, GetDBEngine());
 }
+
 void CEditsSaver::Add(const CSeq_annot_Handle& handle,
                       const CSeq_graph& value, 
-                      ECallMode mode)
+                      ECallMode)
 {
     s_AddAnnot(handle, value, GetDBEngine());
 }
 
+
 template<typename T> static inline
 void s_RemoveAnnot(const CSeq_entry_Handle& entry,
                    const CSeq_annot_Handle& annot,
@@ -965,22 +998,24 @@ void s_RemoveAnnot(const CSeq_entry_Handle& entry,
 
 
 }
+
 void CEditsSaver::Remove(const CSeq_annot_Handle& handle, 
                          const CSeq_feat& old_value,
-                         ECallMode mode)
+                         ECallMode)
 {
     s_RemoveAnnot(handle.GetParentEntry(), handle, old_value, GetDBEngine());
 }
 
 void CEditsSaver::Remove(const CSeq_annot_Handle& handle, 
                          const CSeq_align& old_value,
-                         ECallMode mode)
+                         ECallMode)
 {
     s_RemoveAnnot(handle.GetParentEntry(), handle, old_value, GetDBEngine());
 }
+
 void CEditsSaver::Remove(const CSeq_annot_Handle& handle, 
                          const CSeq_graph& old_value,
-                         ECallMode mode)
+                         ECallMode)
 {
     s_RemoveAnnot(handle.GetParentEntry(), handle, old_value, GetDBEngine());
 }
@@ -988,7 +1023,7 @@ void CEditsSaver::Remove(const CSeq_annot_Handle& handle,
 
 void CEditsSaver::Remove(const CSeq_entry_Handle& entry, 
                          const CSeq_annot_Handle& annot, 
-                         ECallMode mode)
+                         ECallMode)
 {
     CConstRef<CSeq_annot> annots = annot.GetCompleteSeq_annot();
     switch (annots->GetData().Which()) {
@@ -1021,5 +1056,6 @@ void CEditsSaver::Remove(const CSeq_entry_Handle& entry,
     }
 }
 
+
 END_SCOPE(objects)
 END_NCBI_SCOPE
diff --git a/c++/src/objmgr/gc_assembly_parser.cpp b/c++/src/objmgr/gc_assembly_parser.cpp
index 1b413af..01fa7ae 100644
--- a/c++/src/objmgr/gc_assembly_parser.cpp
+++ b/c++/src/objmgr/gc_assembly_parser.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gc_assembly_parser.cpp 495032 2016-03-14 14:26:36Z ivanov $
+/*  $Id: gc_assembly_parser.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -131,8 +131,8 @@ void CGC_Assembly_Parser::x_ParseGCAssembly(const CGC_Assembly& gc_assembly,
                     x_ParseGCSequence(seq.GetSingle(), NULL, entry, null);
                 }
                 else {
-                    ITERATE(CGC_Replicon::TSequence::TSet, it, seq.GetSet()) {
-                        x_ParseGCSequence(**it, NULL, entry, null);
+                    ITERATE(CGC_Replicon::TSequence::TSet, its, seq.GetSet()) {
+                        x_ParseGCSequence(**its, NULL, entry, null);
                     }
                 }
             }
diff --git a/c++/src/objmgr/mapped_feat.cpp b/c++/src/objmgr/mapped_feat.cpp
index ddcb06f..c729784 100644
--- a/c++/src/objmgr/mapped_feat.cpp
+++ b/c++/src/objmgr/mapped_feat.cpp
@@ -1,4 +1,4 @@
-/*  $Id: mapped_feat.cpp 439336 2014-06-27 16:08:17Z vasilche $
+/*  $Id: mapped_feat.cpp 499886 2016-04-28 19:54:10Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -88,19 +88,28 @@ CMappedFeat& CMappedFeat::Set(CAnnot_Collector& collector,
 {
     _ASSERT(feat_ref.IsFeat());
 
+    m_Seq_annot = feat_ref.GetSeq_annot_Handle();
     m_CreatedOriginalFeat.Reset();
-    if ( feat_ref.IsSNPFeat() ) {
-        m_FeatIndex = feat_ref.GetAnnotIndex() | kSNPTableBit;
+    if ( feat_ref.IsSNPTableFeat() ) {
+        m_FeatIndex = feat_ref.GetAnnotIndex() | kNoAnnotObjectInfo;
         if ( !collector.m_CreatedOriginal ) {
             collector.m_CreatedOriginal.Reset(new CCreatedFeat_Ref);
         }
         m_CreatedFeat = collector.m_CreatedOriginal;
         _ASSERT(IsTableSNP());
     }
+    else if ( feat_ref.IsSortedSeqTableFeat() ) {
+        m_FeatIndex = feat_ref.GetAnnotIndex() | kNoAnnotObjectInfo;
+        if ( !collector.m_CreatedOriginal ) {
+            collector.m_CreatedOriginal.Reset(new CCreatedFeat_Ref);
+        }
+        m_CreatedFeat = collector.m_CreatedOriginal;
+        _ASSERT(IsSortedTableFeat());
+    }
     else if ( feat_ref.GetAnnotObject_Info().IsRegular() ) {
         m_FeatIndex = feat_ref.GetAnnotIndex();
         m_CreatedFeat.Reset();
-        _ASSERT(!IsTableSNP());
+        _ASSERT(IsPlainFeat());
     }
     else {
         m_FeatIndex = feat_ref.GetAnnotIndex();
@@ -108,9 +117,8 @@ CMappedFeat& CMappedFeat::Set(CAnnot_Collector& collector,
             collector.m_CreatedOriginal.Reset(new CCreatedFeat_Ref);
         }
         m_CreatedFeat = collector.m_CreatedOriginal;
-        _ASSERT(!IsTableSNP());
+        _ASSERT(IsTableFeat());
     }
-    m_Seq_annot = feat_ref.GetSeq_annot_Handle();
 
     m_MappingInfoPtr = &feat_ref.GetMappingInfo();
     m_MappedFeat.ResetRefs();
diff --git a/c++/src/objmgr/objmgr_exception.cpp b/c++/src/objmgr/objmgr_exception.cpp
index f376c60..2a53209 100644
--- a/c++/src/objmgr/objmgr_exception.cpp
+++ b/c++/src/objmgr/objmgr_exception.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objmgr_exception.cpp 494477 2016-03-07 19:25:35Z ivanov $
+/*  $Id: objmgr_exception.cpp 493168 2016-02-24 19:28:38Z vasilche $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objmgr/prefetch_actions.cpp b/c++/src/objmgr/prefetch_actions.cpp
index 98057d5..bdaebfb 100644
--- a/c++/src/objmgr/prefetch_actions.cpp
+++ b/c++/src/objmgr/prefetch_actions.cpp
@@ -1,4 +1,4 @@
-/*  $Id: prefetch_actions.cpp 219673 2011-01-12 20:08:15Z vasilche $
+/*  $Id: prefetch_actions.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -87,7 +87,7 @@ CPrefetchBioseq::CPrefetchBioseq(const CScopeSource& scope,
 }
 
 
-bool CPrefetchBioseq::Execute(CRef<CPrefetchRequest> token)
+bool CPrefetchBioseq::Execute(CRef<CPrefetchRequest> /*token*/)
 {
     if ( !GetResult() && GetSeq_id() ) {
         m_Result = GetScope().GetBioseqHandle(GetSeq_id());
diff --git a/c++/src/objmgr/scope.cpp b/c++/src/objmgr/scope.cpp
index c233c51..d47185a 100644
--- a/c++/src/objmgr/scope.cpp
+++ b/c++/src/objmgr/scope.cpp
@@ -1,4 +1,4 @@
-/*  $Id: scope.cpp 491606 2016-02-08 11:59:50Z ivanov $
+/*  $Id: scope.cpp 490799 2016-01-28 19:44:01Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objmgr/scope_impl.cpp b/c++/src/objmgr/scope_impl.cpp
index 942ca4e..1ddfe39 100644
--- a/c++/src/objmgr/scope_impl.cpp
+++ b/c++/src/objmgr/scope_impl.cpp
@@ -1,4 +1,4 @@
-/*  $Id: scope_impl.cpp 496835 2016-03-31 15:49:15Z ivanov $
+/*  $Id: scope_impl.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -939,8 +939,8 @@ void CScope_Impl::x_ClearCacheOnNewData(const TIds& seq_ids,
         size_t add_count = seq_ids.size();
         size_t old_count = m_Seq_idMap.size();
         size_t scan_time = add_count + old_count;
-        double lookup_time = min(add_count, old_count)*
-            (2. * log(max(add_count, old_count)+2.));
+        double lookup_time = (double)min(add_count, old_count) *
+                             (2. * log((double)max(add_count, old_count)+2.));
         if ( scan_time < lookup_time ) {
             // scan both
             TIds::const_iterator it1 = seq_ids.begin();
@@ -1053,7 +1053,7 @@ void CScope_Impl::x_ClearAnnotCache(void)
 }
 
 
-void CScope_Impl::x_ClearCacheOnNewAnnot(const CTSE_Info& new_tse)
+void CScope_Impl::x_ClearCacheOnNewAnnot(const CTSE_Info& /*new_tse*/)
 {
     //if ( 1 ) return;
     x_ClearAnnotCache();
@@ -1086,7 +1086,7 @@ void CScope_Impl::x_ClearCacheOnNewDS(void)
 }
 
 
-void CScope_Impl::x_ClearCacheOnRemoveData(const CTSE_Info* old_tse)
+void CScope_Impl::x_ClearCacheOnRemoveData(const CTSE_Info* /*old_tse*/)
 {
     // Clear removed bioseq handles
     for ( TSeq_idMap::iterator it = m_Seq_idMap.begin();
@@ -1141,7 +1141,7 @@ void CScope_Impl::x_ClearCacheOnRemoveSeqId(const CSeq_id_Handle& id,
 }
 
 
-void CScope_Impl::x_ClearCacheOnRemoveAnnot(const CTSE_Info& old_tse)
+void CScope_Impl::x_ClearCacheOnRemoveAnnot(const CTSE_Info& /*old_tse*/)
 {
     // Clear annot cache
     x_ClearAnnotCache();
@@ -3220,10 +3220,19 @@ void CScope_Impl::GetAccVers(TIds& ret,
             remaining = sx_CountFalse(loaded);
         }
     }
-    if ( remaining && (flags & CScope::fThrowOnMissing) ) {
+    if ( remaining && (flags & CScope::fThrowOnMissingSequence) ) {
         NCBI_THROW(CObjMgrException, eFindFailed,
                    "CScope::GetAccVers(): some sequences not found");
     }
+    if ( (flags & CScope::fThrowOnMissingData) ) {
+        // check if each requested id has accession
+        for ( size_t i = 0; i < count; ++i ) {
+            if ( loaded[i] && !ret[i] ) {
+                NCBI_THROW(CObjMgrException, eMissingData,
+                           "CScope::GetAccVers(): some sequences have no acc");
+            }
+        }
+    }
 
     sorted_seq_ids.RestoreOrder(ret);
 }
@@ -3282,10 +3291,19 @@ void CScope_Impl::GetGis(TGIs& ret,
             remaining = sx_CountFalse(loaded);
         }
     }
-    if ( remaining && (flags & CScope::fThrowOnMissing) ) {
+    if ( remaining && (flags & CScope::fThrowOnMissingSequence) ) {
         NCBI_THROW(CObjMgrException, eFindFailed,
                    "CScope::GetGis(): some sequences not found");
     }
+    if ( (flags & CScope::fThrowOnMissingData) ) {
+        // check if each requested id has accession
+        for ( size_t i = 0; i < count; ++i ) {
+            if ( loaded[i] && !ret[i] ) {
+                NCBI_THROW(CObjMgrException, eMissingData,
+                           "CScope::GetGis(): some sequences have no GI");
+            }
+        }
+    }
 
     sorted_seq_ids.RestoreOrder(ret);
 }
diff --git a/c++/src/objmgr/scope_info.cpp b/c++/src/objmgr/scope_info.cpp
index 38f99e9..eaac751 100644
--- a/c++/src/objmgr/scope_info.cpp
+++ b/c++/src/objmgr/scope_info.cpp
@@ -1,4 +1,4 @@
-/*  $Id: scope_info.cpp 474694 2015-07-30 19:29:47Z vasilche $
+/*  $Id: scope_info.cpp 514917 2016-09-27 11:52:34Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -402,7 +402,7 @@ void CDataSource_ScopeInfo::ReleaseTSELock(CTSE_ScopeInfo& tse)
     CUnlockedTSEsGuard guard;
     {{
         CTSE_ScopeInternalLock unlocked;
-        TTSE_LockSetMutex::TWriteLockGuard guard(m_TSE_UnlockQueueMutex);
+        TTSE_LockSetMutex::TWriteLockGuard tse_guard(m_TSE_UnlockQueueMutex);
         if ( tse.m_TSE_LockCounter.Get() > 0 ) {
             // relocked already
             return;
@@ -1454,13 +1454,16 @@ void CTSE_ScopeInfo::RemoveLastInfoLock(CScopeInfo_Base& info)
         // already unlocked
         return;
     }
+    CRef<CScope_Impl> scope;
     CRef<CTSE_ScopeInfo> self;
+    CUnlockedTSEsGuard guard;
     {{
-        CMutexGuard guard(m_TSE_LockMutex);
+        CMutexGuard guard_mtx(m_TSE_LockMutex);
         if ( info.m_LockCounter.Get() > 0 ) {
             // already locked again
             return;
         }
+        scope = m_DS_Info->m_Scope; // to prevent premature deletion of scope
         self = this; // to prevent deletion of this while mutex is locked.
         info.m_TSE_Handle.Reset();
     }}
@@ -1581,6 +1584,7 @@ void CTSE_ScopeInfo::RemoveAnnot(CSeq_annot_ScopeInfo& info)
 
 
 // Action A7.
+#ifdef _DEBUG
 void CTSE_ScopeInfo::x_CheckAdded(CScopeInfo_Base& parent,
                                   CScopeInfo_Base& child)
 {
@@ -1594,6 +1598,11 @@ void CTSE_ScopeInfo::x_CheckAdded(CScopeInfo_Base& parent,
     _ASSERT(child.m_LockCounter.Get() > 0);
     _ASSERT(x_SameTSE(parent.GetTSE_Handle().x_GetTSE_Info()));
 }
+#else  /* _DEBUG */
+void CTSE_ScopeInfo::x_CheckAdded(CScopeInfo_Base& /*parent*/,
+                                  CScopeInfo_Base& /*child*/)
+{}
+#endif
 
 
 // Action A7.
diff --git a/c++/src/objmgr/seq_annot_info.cpp b/c++/src/objmgr/seq_annot_info.cpp
index 33ba990..913a79a 100644
--- a/c++/src/objmgr/seq_annot_info.cpp
+++ b/c++/src/objmgr/seq_annot_info.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_annot_info.cpp 496424 2016-03-28 15:16:13Z ivanov $
+/*  $Id: seq_annot_info.cpp 518671 2016-11-07 15:26:21Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -90,6 +90,10 @@ CSeq_annot_Info::CSeq_annot_Info(const CSeq_annot_Info& info,
     : TParent(info, copy_map),
       m_ChunkId(info.GetChunkId())
 {
+    if ( !copy_map ) {
+        info.x_UpdateComplete();
+        m_ChunkId = 0;
+    }
     x_SetObject(info, copy_map);
 }
 
@@ -356,7 +360,7 @@ namespace {
 
 
 void CSeq_annot_Info::x_SetObject(const CSeq_annot_Info& info,
-                                  TObjectCopyMap* copy_map)
+                                  TObjectCopyMap* /*copy_map*/)
 {
     _ASSERT(!m_SNP_Info && !m_Object);
     m_Object = sx_ShallowCopy(info.x_GetObject());
@@ -463,6 +467,8 @@ void CSeq_annot_Info::x_InitLocsList(TLocs& objs)
 
 void CSeq_annot_Info::x_InitFeatTable(TSeq_table& table)
 {
+    m_Table_Info = new CSeqTableInfo(table);
+
     _ASSERT(m_ObjectIndex.GetInfos().empty());
     if ( !CSeqTableInfo::IsGoodFeatTable(table) ) {
         // index whole Seq-table
@@ -471,14 +477,18 @@ void CSeq_annot_Info::x_InitFeatTable(TSeq_table& table)
         _ASSERT(m_ObjectIndex.GetInfos().size() == 1u);
     }
     else {
+        SAnnotTypeSelector type = m_Table_Info->GetType();
+
+        if ( IsSortedTable() ) {
+            // sorted table of small elements,
+            // index it as a single entry,
+            // then use sorted position for lookup
+            m_ObjectIndex.AddInfo(CAnnotObject_Info(*this, kWholeAnnotIndex, type));
+            return;
+        }
+
         // index each row separately
         TAnnotIndex rows = table.GetNum_rows();
-        SAnnotTypeSelector type
-            (SAnnotTypeSelector::TFeatType(table.GetFeat_type()));
-        if ( table.IsSetFeat_subtype() ) {
-            type.SetFeatSubtype
-                (SAnnotTypeSelector::TFeatSubtype(table.GetFeat_subtype()));
-        }
         for ( TAnnotIndex index = 0; index < rows; ++index ) {
             m_ObjectIndex.AddInfo(CAnnotObject_Info(*this, index, type));
         }
@@ -512,7 +522,6 @@ void CSeq_annot_Info::x_InitAnnotList(const CSeq_annot_Info& info)
         data.SetIds() = src_data.GetIds();
         break;
     case C_Data::e_Seq_table:
-        //data.SetSeq_table(src_data.S
         x_InitFeatTable(data.SetSeq_table());
         break;
     default:
@@ -705,7 +714,7 @@ void CSeq_annot_Info::x_InitFeatKeys(CTSE_Info& tse)
 {
     _ASSERT(m_ObjectIndex.GetInfos().size() >= m_Object->GetData().GetFtable().size());
     size_t object_count = m_ObjectIndex.GetInfos().size();
-    m_ObjectIndex.ReserveMapSize(size_t(object_count*1.1));
+    m_ObjectIndex.ReserveMapSize(size_t(double(object_count)*1.1));
 
     SAnnotObject_Key key;
     SAnnotObject_Index index;
@@ -747,7 +756,7 @@ void CSeq_annot_Info::x_InitFeatKeys(CTSE_Info& tse)
                     continue;
                 }
                 key.m_Handle = hrit->first;
-                index.m_Flags = hr.GetStrandsFlag();
+                index.m_Flags = (SAnnotObject_Index::TFlags)hr.GetStrandsFlag();
                 if ( multi_id ) {
                     index.SetMultiIdFlag();
                 }
@@ -989,9 +998,6 @@ bool CSeq_annot_Info::IsTableFeatPartial(const CAnnotObject_Info& info) const
 
 void CSeq_annot_Info::x_InitFeatTableKeys(CTSE_Info& tse)
 {
-    const CSeq_table& feat_table = m_Object->GetData().GetSeq_table();
-    m_Table_Info = new CSeqTableInfo(feat_table);
-    
     CConstRef<CMasterSeqSegments> master = tse.GetMasterSeqSegments();
 
     if ( !m_Table_Info->IsFeatTable() ) {
@@ -1019,12 +1025,12 @@ void CSeq_annot_Info::x_InitFeatTableKeys(CTSE_Info& tse)
             const CHandleRange& hr = hrit->second;
             key.m_Range = hr.GetOverlappingRange();
             if ( key.m_Range.Empty() ) {
-                ERR_POST_X(7, "Empty region in "<<GetDescription()<<" "<<
-                           MSerial_AsnText<<*info.GetFeatFast());
+                ERR_POST_X(7, "Empty region in "<<GetDescription()<<
+                           " Seq-table location "<<MSerial_AsnText<<*loc);
                 continue;
             }
             key.m_Handle = hrit->first;
-            index.m_Flags = hr.GetStrandsFlag();
+            index.m_Flags = (SAnnotObject_Index::TFlags)hr.GetStrandsFlag();
             if ( multi_id ) {
                 index.SetMultiIdFlag();
             }
@@ -1047,7 +1053,6 @@ void CSeq_annot_Info::x_InitFeatTableKeys(CTSE_Info& tse)
     }
 
     size_t object_count = m_ObjectIndex.GetInfos().size();
-    _ASSERT(object_count == size_t(feat_table.GetNum_rows()));
     m_ObjectIndex.ReserveMapSize(object_count);
 
     SAnnotObject_Key key;
@@ -1059,6 +1064,21 @@ void CSeq_annot_Info::x_InitFeatTableKeys(CTSE_Info& tse)
         m_ObjectIndex.GetInfos().begin();
     for ( size_t row = 0; row < object_count; ++row, ++it ) {
         CAnnotObject_Info& info = *it;
+        if ( info.GetAnnotIndex() == kWholeAnnotIndex ) {
+            size_t keys_begin = m_ObjectIndex.GetKeys().size();
+            index.m_AnnotObject_Info = &info;
+            index.m_AnnotLocationIndex = 0;
+            index.m_Flags = index.fStrand_both;
+            index.m_HandleRange.Reset();
+            CConstRef<CSeq_loc> loc = m_Table_Info->GetTableLocation();
+            _ASSERT(loc && loc->IsInt()); // checked in x_InitFeatTable()
+            key.m_Handle = CSeq_id_Handle::GetHandle(loc->GetInt().GetId());
+            key.m_Range = loc->GetTotalRange();
+            x_Map(mapper, key, index);
+            x_UpdateObjectKeys(info, keys_begin);
+            continue;
+        }
+
         if ( info.IsRemoved() ) {
             continue;
         }
@@ -1070,7 +1090,7 @@ void CSeq_annot_Info::x_InitFeatTableKeys(CTSE_Info& tse)
         bool partial = m_Table_Info->IsPartial(row);
         for ( index.m_AnnotLocationIndex = 0;
               index.m_AnnotLocationIndex < 2;
-              index.m_AnnotLocationIndex += 1 ) {
+              index.m_AnnotLocationIndex++ ) {
             // index by location, then by product
             const CSeqTableLocColumns& loc =
                 index.m_AnnotLocationIndex == 0?
@@ -1086,12 +1106,12 @@ void CSeq_annot_Info::x_InitFeatTableKeys(CTSE_Info& tse)
                         const CHandleRange& hr = hrit->second;
                         key.m_Range = hr.GetOverlappingRange();
                         if ( key.m_Range.Empty() ) {
-                            ERR_POST_X(8, "Empty region in "<<GetDescription()<<" "<<
-                                       MSerial_AsnText<<*info.GetFeatFast());
+                            ERR_POST_X(8, "Empty region in "<<GetDescription()<<
+                                       " Seq-table row "<<row);
                             continue;
                         }
                         key.m_Handle = hrit->first;
-                        index.m_Flags = hr.GetStrandsFlag();
+                        index.m_Flags = (SAnnotObject_Index::TFlags)hr.GetStrandsFlag();
                         if ( multi_id ) {
                             index.SetMultiIdFlag();
                         }
@@ -1277,7 +1297,7 @@ void CSeq_annot_Info::x_MapAnnotObject(CAnnotObject_Info& info)
                 continue;
             }
             key.m_Handle = hrit->first;
-            index.m_Flags = hr.GetStrandsFlag();
+            index.m_Flags = (SAnnotObject_Index::TFlags)hr.GetStrandsFlag();
             if ( multi_id ) {
                 index.SetMultiIdFlag();
             }
@@ -1931,5 +1951,95 @@ void CSeq_annot_Info::ClearFeatIds(TAnnotIndex index,
 }
 
 
+bool CSeq_annot_Info::IsSortedTable(void) const
+{
+    return m_Table_Info && m_Table_Info->IsSorted();
+}
+
+
+bool CSeq_annot_Info::TableFeat_HasLabel(TAnnotIndex index) const
+{
+    if ( m_SNP_Info ) {
+        return m_SNP_Info->HasLabel(index);
+    }
+    else {
+        _ASSERT(m_Table_Info);
+        return m_Table_Info->HasLabel(index);
+    }
+}
+
+
+string CSeq_annot_Info::TableFeat_GetLabel(TAnnotIndex index) const
+{
+    if ( m_SNP_Info ) {
+        return m_SNP_Info->GetLabel(index);
+    }
+    else {
+        _ASSERT(m_Table_Info);
+        return m_Table_Info->GetLabel(index);
+    }
+}
+
+
+CSeq_annot_SortedIter
+CSeq_annot_Info::StartSortedIterator(CRange<TSeqPos> range) const
+{
+    CSeq_annot_SortedIter iter;
+    _ASSERT(IsSortedTable());
+    TSeqPos max_len = m_Table_Info->GetSortedMaxLength();
+    _ASSERT(max_len > 0);
+    TSeqPos min_pos = max(range.GetFrom(), max_len-1) - (max_len-1);
+    size_t num_rows = m_Table_Info->GetNumRows();
+    size_t a = 0, b = num_rows;
+    while ( b-a > 1 ) {
+        size_t m = a + (b-a)/2;
+        TSeqPos pos = m_Table_Info->GetLocationFrom(m);
+        if ( pos < min_pos ) {
+            a = m;
+        }
+        else {
+            b = m;
+        }
+    }
+    iter.m_Table_Info = m_Table_Info;
+    iter.m_RequestRange = range;
+    iter.m_ObjectRow = a;
+    iter.m_NumRows = num_rows;
+    iter.x_Settle();
+    return iter;
+}
+
+
+inline
+bool CSeq_annot_SortedIter::x_Valid(void)
+{
+    if ( m_Table_Info->RowIsDisabled(m_ObjectRow) ) {
+        return false;
+    }
+    m_ObjectRange = m_Table_Info->GetLocationRange(m_ObjectRow);
+    if ( m_ObjectRange.GetFrom() >= m_RequestRange.GetToOpen() ) {
+        m_NumRows = m_ObjectRow;
+        return true;
+    }
+    return m_ObjectRange.GetToOpen() > m_RequestRange.GetFrom();
+}
+
+
+void CSeq_annot_SortedIter::x_Settle(void)
+{
+    while ( *this && !x_Valid() ) {
+        ++m_ObjectRow;
+    }
+}
+
+
+bool CSeq_annot_Info::MatchBitFilter(const SAnnotSelector& sel,
+                                     const CSeq_annot_SortedIter& iter) const
+{
+    _ASSERT(IsSortedTable());
+    return m_Table_Info->MatchBitFilter(sel, iter.GetRow());
+}
+
+
 END_SCOPE(objects)
 END_NCBI_SCOPE
diff --git a/c++/src/objmgr/seq_entry_info.cpp b/c++/src/objmgr/seq_entry_info.cpp
index 3b52c50..03cfb66 100644
--- a/c++/src/objmgr/seq_entry_info.cpp
+++ b/c++/src/objmgr/seq_entry_info.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_entry_info.cpp 203738 2010-09-01 19:02:10Z vasilche $
+/*  $Id: seq_entry_info.cpp 518178 2016-11-01 11:46:07Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -73,6 +73,9 @@ CSeq_entry_Info::CSeq_entry_Info(const CSeq_entry_Info& info,
     : TParent(info, copy_map),
       m_Which(CSeq_entry::e_not_set)
 {
+    if ( !copy_map ) {
+        info.x_UpdateComplete();
+    }
     x_SetObject(info, copy_map);
 }
 
@@ -432,8 +435,60 @@ void CSeq_entry_Info::x_UpdateAnnotIndexContents(CTSE_Info& tse)
 }
 
 
+inline
+void CSeq_entry_Info::x_UpdateSkeleton() const
+{
+    if ( !m_Object ) {
+        GetTSE_Info().x_LoadDelayedMainChunk();
+    }
+}
+
+
+void CSeq_entry_Info::x_Update(TNeedUpdateFlags flags) const
+{
+    x_UpdateSkeleton();
+    TParent::x_Update(flags);
+}
+
+
+CSeq_entry::E_Choice CSeq_entry_Info::Which(void) const
+{
+    x_UpdateSkeleton();
+    return m_Which;
+}
+
+
+CConstRef<CSeq_entry> CSeq_entry_Info::GetSeq_entrySkeleton(void) const
+{
+    x_UpdateSkeleton();
+    return m_Object;   
+}
+
+
+CSeq_entry& CSeq_entry_Info::x_GetObject(void)
+{
+    x_UpdateSkeleton();
+    return *m_Object;
+}
+
+
+const CSeq_entry& CSeq_entry_Info::x_GetObject(void) const
+{
+    x_UpdateSkeleton();
+    return *m_Object;
+}
+
+
+const CBioseq_Base_Info& CSeq_entry_Info::x_GetBaseInfo(void) const
+{
+    x_UpdateSkeleton();
+    return *m_Contents;
+}
+
+
 bool CSeq_entry_Info::IsSetDescr(void) const
 {
+    x_UpdateSkeleton();
     // x_Update(fNeedUpdate_descr);
     return m_Contents && m_Contents->IsSetDescr();
 }
@@ -538,7 +593,9 @@ void CSeq_entry_Info::RemoveAnnot(CRef<CSeq_annot_Info> annot)
 void CSeq_entry_Info::x_SetBioseqChunkId(TChunkId _DEBUG_ARG(chunk_id))
 {
     _ASSERT(chunk_id == kBioseqChunkId);
-    x_CheckWhich(CSeq_entry::e_not_set);
+    //x_CheckWhich(CSeq_entry::e_not_set);
+    _ASSERT(!m_Object);
+    _ASSERT(!m_Contents);
     x_SetNeedUpdate(CTSE_Info::fNeedUpdate_bioseq);
     m_Which = CSeq_entry::e_Seq;
 }
diff --git a/c++/src/objmgr/seq_feat_handle.cpp b/c++/src/objmgr/seq_feat_handle.cpp
index 5ad6067..b3f053b 100644
--- a/c++/src/objmgr/seq_feat_handle.cpp
+++ b/c++/src/objmgr/seq_feat_handle.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_feat_handle.cpp 483571 2015-11-02 17:33:20Z vasilche $
+/*  $Id: seq_feat_handle.cpp 499886 2016-04-28 19:54:10Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -36,6 +36,7 @@
 #include <objmgr/scope.hpp>
 #include <objmgr/impl/seq_annot_info.hpp>
 #include <objmgr/impl/snp_annot_info.hpp>
+#include <objmgr/impl/seq_table_info.hpp>
 #include <objmgr/impl/scope_impl.hpp>
 #include <objmgr/impl/annot_collector.hpp>
 
@@ -69,7 +70,7 @@ CSeq_feat_Handle::CSeq_feat_Handle(const CSeq_annot_Handle& annot,
                                    CCreatedFeat_Ref& created_ref)
     : m_Seq_annot(annot),
       m_FeatIndex(TFeatIndex(annot.x_GetInfo().x_GetSNP_annot_Info().GetIndex(snp_info))
-                  | kSNPTableBit),
+                  | kNoAnnotObjectInfo),
       m_CreatedFeat(&created_ref)
 {
     _ASSERT(IsTableSNP());
@@ -108,27 +109,39 @@ const CSeq_annot_SNP_Info& CSeq_feat_Handle::x_GetSNP_annot_Info(void) const
 
 bool CSeq_feat_Handle::IsTableSNP(void) const
 {
-    return (m_FeatIndex & kSNPTableBit) != 0;
+    return !x_HasAnnotObjectInfo() &&
+        x_GetSeq_annot_Info().x_HasSNP_annot_Info();
+}
+
+
+bool CSeq_feat_Handle::IsSortedTableFeat(void) const
+{
+    return !x_HasAnnotObjectInfo() &&
+        x_GetSeq_annot_Info().IsSortedTable();
 }
 
 
 bool CSeq_feat_Handle::IsPlainFeat(void) const
 {
-    return (m_FeatIndex & kSNPTableBit) == 0 &&
+    return x_HasAnnotObjectInfo() &&
         x_GetAnnotObject_InfoAny().IsRegular();
 }
 
 
 bool CSeq_feat_Handle::IsTableFeat(void) const
 {
-    return (m_FeatIndex & kSNPTableBit) == 0 &&
-        !x_GetAnnotObject_InfoAny().IsRegular();
+    if ( x_HasAnnotObjectInfo() ) {
+        return !x_GetAnnotObject_InfoAny().IsRegular();
+    }
+    else {
+        return x_GetSeq_annot_Info().IsSortedTable();
+    }
 }
 
 
 const CAnnotObject_Info& CSeq_feat_Handle::x_GetAnnotObject_InfoAny(void) const
 {
-    if ( IsTableSNP() ) {
+    if ( !x_HasAnnotObjectInfo() ) {
         NCBI_THROW(CObjMgrException, eInvalidHandle,
                    "CSeq_feat_Handle::x_GetAnnotObject: not Seq-feat info");
     }
@@ -200,15 +213,33 @@ CConstRef<CSeq_feat> CSeq_feat_Handle::GetSeq_feat(void) const
 
 bool CSeq_feat_Handle::IsSetPartial(void) const
 {
-    // table SNP features do not have partial
-    return !IsTableSNP() && GetSeq_feat()->IsSetPartial();
+    if ( x_HasAnnotObjectInfo() ) {
+        return GetSeq_feat()->IsSetPartial();
+    }
+    else if ( IsTableSNP() ) {
+        // table SNP features do not have partial
+        return false;
+    }
+    else {
+        // TODO
+        return GetSeq_feat()->IsSetPartial();
+    }
 }
 
 
 bool CSeq_feat_Handle::GetPartial(void) const
 {
-    // table SNP features do not have partial
-    return !IsTableSNP() && GetSeq_feat()->GetPartial();
+    if ( x_HasAnnotObjectInfo() ) {
+        return GetSeq_feat()->GetPartial();
+    }
+    else if ( IsTableSNP() ) {
+        // table SNP features do not have partial
+        return false;
+    }
+    else {
+        // TODO
+        return GetSeq_feat()->GetPartial();
+    }
 }
 
 
@@ -229,10 +260,11 @@ bool CSeq_feat_Handle::IsSetData(void) const
     if ( !*this ) {
         return false;
     }
-    if ( !IsTableSNP() ) {
+    if ( x_HasAnnotObjectInfo() ) {
         return GetSeq_feat()->IsSetData();
     }
     else {
+        // SNP table or sorted Seq-table features have data
         return true;
     }
 }
@@ -240,27 +272,40 @@ bool CSeq_feat_Handle::IsSetData(void) const
 
 CSeq_id_Handle CSeq_feat_Handle::GetLocationId(void) const
 {
-    if ( IsTableSNP() ) {
+    if ( x_HasAnnotObjectInfo() ) {
+        CConstRef<CSeq_loc> loc(&GetLocation());
+        if ( const CSeq_id* id = loc->GetId() ) {
+            return CSeq_id_Handle::GetHandle(*id);
+        }
+        return CSeq_id_Handle();
+    }
+    else if ( IsTableSNP() ) {
         return CSeq_id_Handle::GetHandle(GetSNPSeq_id());
     }
-    CConstRef<CSeq_loc> loc(&GetLocation());
-    const CSeq_id* id = loc->GetId();
-    if ( id ) {
-        return CSeq_id_Handle::GetHandle(*id);
+    else {
+        // TODO
+        CConstRef<CSeq_loc> loc(&GetLocation());
+        if ( const CSeq_id* id = loc->GetId() ) {
+            return CSeq_id_Handle::GetHandle(*id);
+        }
+        return CSeq_id_Handle();
     }
-    return CSeq_id_Handle();
 }
 
 
 CSeq_feat_Handle::TRange CSeq_feat_Handle::GetRange(void) const
 {
-    if ( !IsTableSNP() ) {
+    if ( x_HasAnnotObjectInfo() ) {
         return GetSeq_feat()->GetLocation().GetTotalRange();
     }
-    else {
+    else if ( IsTableSNP() ) {
         const SSNP_Info& info = x_GetSNP_Info();
         return TRange(info.GetFrom(), info.GetTo());
     }
+    else {
+        // TODO
+        return GetSeq_feat()->GetLocation().GetTotalRange();
+    }
 }
 
 
@@ -345,11 +390,14 @@ void CSeq_feat_Handle::GetSNPQualityCodeOs(vector<char>& os) const
 
 bool CSeq_feat_Handle::IsRemoved(void) const
 {
-    if ( IsTableSNP() ) {
+    if ( x_HasAnnotObjectInfo() ) {
+        return x_GetAnnotObject_InfoAny().IsRemoved();
+    }
+    else if ( IsTableSNP() ) {
         return x_GetSNP_InfoAny().IsRemoved();
     }
     else {
-        return x_GetAnnotObject_InfoAny().IsRemoved();
+        return false;
     }
 }
 
@@ -370,6 +418,34 @@ void CSeq_feat_Handle::Replace(const CSeq_feat& new_feat) const
 // Methods redirected to corresponding Seq-feat object
 /////////////////////////////////////////////////////////////////////////////
 
+CSeqFeatData::E_Choice CSeq_feat_Handle::GetFeatType(void) const
+{
+    if ( x_HasAnnotObjectInfo() ) {
+        return x_GetAnnotObject_Info().GetFeatType();
+    }
+    else if ( IsTableSNP() ) {
+        return CSeqFeatData::e_Imp;
+    }
+    else {
+        return x_GetSeq_annot_Info().GetTableInfo().GetType().GetFeatType();
+    }
+}
+
+
+CSeqFeatData::ESubtype CSeq_feat_Handle::GetFeatSubtype(void) const
+{
+    if ( x_HasAnnotObjectInfo() ) {
+        return x_GetAnnotObject_Info().GetFeatSubtype();
+    }
+    else if ( IsTableSNP() ) {
+        return CSeqFeatData::eSubtype_variation;
+    }
+    else {
+        return x_GetSeq_annot_Info().GetTableInfo().GetType().GetFeatSubtype();
+    }
+}
+
+
 const CGene_ref* CSeq_feat_Handle::GetGeneXref(void) const
 {
     return GetSeq_feat()->GetGeneXref();
@@ -698,8 +774,9 @@ CSeq_annot_ftable_CI::CSeq_annot_ftable_CI(const CSeq_annot_Handle& annot,
     }
     m_Feat.m_Seq_annot = annot;
     m_Feat.m_FeatIndex = 0;
-    if ( m_Flags & fIncludeTable && annot.x_GetInfo().x_HasSNP_annot_Info() ) {
-        m_Feat.m_FeatIndex |= m_Feat.kSNPTableBit;
+    if ( (m_Flags & fIncludeTable) &&
+         annot.x_GetInfo().x_HasSNP_annot_Info() ) {
+        m_Feat.m_FeatIndex |= m_Feat.kNoAnnotObjectInfo;
     }
     x_Settle();
 }
@@ -726,7 +803,7 @@ void CSeq_annot_ftable_CI::x_Settle(void)
         bool is_snp_table = m_Feat.IsTableSNP();
         if ( is_snp_table ) {
             end = GetAnnot().x_GetInfo().x_GetSNPFeatCount()
-                | m_Feat.kSNPTableBit;
+                | m_Feat.kNoAnnotObjectInfo;
         }
         else {
             end = GetAnnot().x_GetInfo().x_GetAnnotCount();
@@ -759,8 +836,9 @@ CSeq_annot_ftable_I::CSeq_annot_ftable_I(const CSeq_annot_EditHandle& annot,
     }
     m_Feat.m_Seq_annot = annot;
     m_Feat.m_FeatIndex = 0;
-    if ( m_Flags & fIncludeTable && annot.x_GetInfo().x_HasSNP_annot_Info() ) {
-        m_Feat.m_FeatIndex |= m_Feat.kSNPTableBit;
+    if ( (m_Flags & fIncludeTable) &&
+         annot.x_GetInfo().x_HasSNP_annot_Info() ) {
+        m_Feat.m_FeatIndex |= m_Feat.kNoAnnotObjectInfo;
     }
     x_Settle();
 }
@@ -787,7 +865,7 @@ void CSeq_annot_ftable_I::x_Settle(void)
         bool is_snp_table = m_Feat.IsTableSNP();
         if ( is_snp_table ) {
             end = GetAnnot().x_GetInfo().x_GetSNPFeatCount()
-                | m_Feat.kSNPTableBit;
+                | m_Feat.kNoAnnotObjectInfo;
         }
         else {
             end = GetAnnot().x_GetInfo().x_GetAnnotCount();
diff --git a/c++/src/objmgr/seq_id_sort.cpp b/c++/src/objmgr/seq_id_sort.cpp
index 7b4009e..0b8761f 100644
--- a/c++/src/objmgr/seq_id_sort.cpp
+++ b/c++/src/objmgr/seq_id_sort.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_id_sort.cpp 496835 2016-03-31 15:49:15Z ivanov $
+/*  $Id: seq_id_sort.cpp 495071 2016-03-14 17:45:32Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objmgr/seq_loc_cvt.cpp b/c++/src/objmgr/seq_loc_cvt.cpp
index b08b06f..3694f68 100644
--- a/c++/src/objmgr/seq_loc_cvt.cpp
+++ b/c++/src/objmgr/seq_loc_cvt.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_loc_cvt.cpp 493417 2016-02-26 18:49:07Z ivanov $
+/*  $Id: seq_loc_cvt.cpp 504874 2016-06-20 16:37:02Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -998,7 +998,12 @@ void CSeq_loc_Conversion::ConvertCdregion(CAnnotObject_Ref& ref,
     else {
         new_cd.ResetOrf();
     }
-    new_cd.SetFrame(src_cd.GetFrame());
+    if ( src_cd.IsSetFrame() ) {
+        new_cd.SetFrame(src_cd.GetFrame());
+    }
+    else {
+        new_cd.ResetFrame();
+    }
     if ( src_cd.IsSetConflict() ) {
         new_cd.SetConflict(src_cd.GetConflict());
     }
@@ -1555,7 +1560,12 @@ void CSeq_loc_Conversion_Set::ConvertCdregion(CAnnotObject_Ref& ref,
     else {
         new_cd.ResetOrf();
     }
-    new_cd.SetFrame(src_cd.GetFrame());
+    if ( src_cd.IsSetFrame() ) {
+        new_cd.SetFrame(src_cd.GetFrame());
+    }
+    else {
+        new_cd.ResetFrame();
+    }
     if ( src_cd.IsSetConflict() ) {
         new_cd.SetConflict(src_cd.GetConflict());
     }
diff --git a/c++/src/objmgr/seq_loc_mapper.cpp b/c++/src/objmgr/seq_loc_mapper.cpp
index 29d7a5e..f705cc9 100644
--- a/c++/src/objmgr/seq_loc_mapper.cpp
+++ b/c++/src/objmgr/seq_loc_mapper.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_loc_mapper.cpp 479439 2015-09-21 13:04:11Z grichenk $
+/*  $Id: seq_loc_mapper.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -131,11 +131,7 @@ TSeqPos CScope_Mapper_Sequence_Info::GetSequenceLength(const CSeq_id_Handle& idh
         return kInvalidSeqPos;
     }
     h = m_Scope.GetScope().GetBioseqHandle(idh);
-    if ( !h ) {
-        NCBI_THROW(CAnnotMapperException, eUnknownLength,
-                    "Can not get sequence length -- unknown seq-id");
-    }
-    return h.GetBioseqLength();
+    return h ? h.GetBioseqLength() : kInvalidSeqPos;
 }
 
 
@@ -168,7 +164,7 @@ ENa_strand s_IndexToStrand(size_t idx)
 CSeq_loc_Mapper::CSeq_loc_Mapper(CMappingRanges* mapping_ranges,
                                  CScope*         scope)
     : CSeq_loc_Mapper_Base(mapping_ranges,
-                           new CScope_Mapper_Sequence_Info(scope)),
+                           CSeq_loc_Mapper_Options(new CScope_Mapper_Sequence_Info(scope))),
       m_Scope(scope)
 {
 }
@@ -177,7 +173,7 @@ CSeq_loc_Mapper::CSeq_loc_Mapper(CMappingRanges* mapping_ranges,
 CSeq_loc_Mapper::CSeq_loc_Mapper(const CSeq_feat&  map_feat,
                                  EFeatMapDirection dir,
                                  CScope*           scope)
-    : CSeq_loc_Mapper_Base(new CScope_Mapper_Sequence_Info(scope)),
+    : CSeq_loc_Mapper_Base(CSeq_loc_Mapper_Options(new CScope_Mapper_Sequence_Info(scope))),
       m_Scope(scope)
 {
     x_InitializeFeat(map_feat, dir);
@@ -186,46 +182,43 @@ CSeq_loc_Mapper::CSeq_loc_Mapper(const CSeq_feat&  map_feat,
 
 CSeq_loc_Mapper::CSeq_loc_Mapper(const CSeq_loc& source,
                                  const CSeq_loc& target,
-                                 CScope* scope)
-    : CSeq_loc_Mapper_Base(new CScope_Mapper_Sequence_Info(scope)),
+                                 CScope*         scope)
+    : CSeq_loc_Mapper_Base(CSeq_loc_Mapper_Options(new CScope_Mapper_Sequence_Info(scope))),
       m_Scope(scope)
 {
     x_InitializeLocs(source, target);
 }
 
 
-CSeq_loc_Mapper::CSeq_loc_Mapper(const CSeq_align& map_align,
-                                 const CSeq_id&    to_id,
-                                 CScope*           scope,
-                                 TMapOptions       opts)
-    : CSeq_loc_Mapper_Base(new CScope_Mapper_Sequence_Info(scope)),
+CSeq_loc_Mapper::CSeq_loc_Mapper(const CSeq_align&       map_align,
+                                 const CSeq_id&          to_id,
+                                 CScope*                 scope,
+                                 CSeq_loc_Mapper_Options options)
+    : CSeq_loc_Mapper_Base(options.SetMapperSequenceInfo(new CScope_Mapper_Sequence_Info(scope))),
       m_Scope(scope)
 {
-    m_MapOptions = opts;
     x_InitializeAlign(map_align, to_id);
 }
 
 
-CSeq_loc_Mapper::CSeq_loc_Mapper(const CSeq_align& map_align,
-                                 size_t            to_row,
-                                 CScope*           scope,
-                                 TMapOptions       opts)
-    : CSeq_loc_Mapper_Base(new CScope_Mapper_Sequence_Info(scope)),
+CSeq_loc_Mapper::CSeq_loc_Mapper(const CSeq_align&       map_align,
+                                 size_t                  to_row,
+                                 CScope*                 scope,
+                                 CSeq_loc_Mapper_Options options)
+    : CSeq_loc_Mapper_Base(options.SetMapperSequenceInfo(new CScope_Mapper_Sequence_Info(scope))),
       m_Scope(scope)
 {
-    m_MapOptions = opts;
     x_InitializeAlign(map_align, to_row);
 }
 
 
 CSeq_loc_Mapper::CSeq_loc_Mapper(CBioseq_Handle   target_seq,
                                  ESeqMapDirection direction,
-                                 TMapOptions      opts)
-    : CSeq_loc_Mapper_Base(new CScope_Mapper_Sequence_Info(
-                           &target_seq.GetScope())),
+                                 CSeq_loc_Mapper_Options options)
+    : CSeq_loc_Mapper_Base(options.SetMapperSequenceInfo(new CScope_Mapper_Sequence_Info(
+                           &target_seq.GetScope()))),
       m_Scope(&target_seq.GetScope())
 {
-    m_MapOptions = opts;
     CConstRef<CSeq_id> top_level_id = target_seq.GetSeqId();
     if ( !top_level_id ) {
         // Bioseq handle has no id, try to get one.
@@ -253,11 +246,10 @@ CSeq_loc_Mapper::CSeq_loc_Mapper(const CSeqMap&   seq_map,
                                  ESeqMapDirection direction,
                                  const CSeq_id*   top_level_id,
                                  CScope*          scope,
-                                 TMapOptions      opts)
-    : CSeq_loc_Mapper_Base(new CScope_Mapper_Sequence_Info(scope)),
+                                 CSeq_loc_Mapper_Options options)
+    : CSeq_loc_Mapper_Base(options.SetMapperSequenceInfo(new CScope_Mapper_Sequence_Info(scope))),
       m_Scope(scope)
 {
-    m_MapOptions = opts;
     x_InitializeSeqMap(seq_map, top_level_id, direction);
     x_PreserveDestinationLocs();
 }
@@ -266,12 +258,11 @@ CSeq_loc_Mapper::CSeq_loc_Mapper(const CSeqMap&   seq_map,
 CSeq_loc_Mapper::CSeq_loc_Mapper(CBioseq_Handle   target_seq,
                                  ESeqMapDirection direction,
                                  SSeqMapSelector  selector,
-                                 TMapOptions      opts)
-    : CSeq_loc_Mapper_Base(new CScope_Mapper_Sequence_Info(
-                           &target_seq.GetScope())),
+                                 CSeq_loc_Mapper_Options options)
+    : CSeq_loc_Mapper_Base(options.SetMapperSequenceInfo(new CScope_Mapper_Sequence_Info(
+                           &target_seq.GetScope()))),
       m_Scope(&target_seq.GetScope())
 {
-    m_MapOptions = opts;
     CConstRef<CSeq_id> top_id = target_seq.GetSeqId();
     if ( !top_id ) {
         // Bioseq handle has no id, try to get one.
@@ -299,11 +290,10 @@ CSeq_loc_Mapper::CSeq_loc_Mapper(const CSeqMap&   seq_map,
                                  SSeqMapSelector  selector,
                                  const CSeq_id*   top_level_id,
                                  CScope*          scope,
-                                 TMapOptions      opts)
-    : CSeq_loc_Mapper_Base(new CScope_Mapper_Sequence_Info(scope)),
+                                 CSeq_loc_Mapper_Options options)
+    : CSeq_loc_Mapper_Base(options.SetMapperSequenceInfo(new CScope_Mapper_Sequence_Info(scope))),
       m_Scope(scope)
 {
-    m_MapOptions = opts;
     x_InitializeSeqMap(seq_map,
                        selector,
                        top_level_id,
@@ -315,12 +305,11 @@ CSeq_loc_Mapper::CSeq_loc_Mapper(const CSeqMap&   seq_map,
 CSeq_loc_Mapper::CSeq_loc_Mapper(size_t                 depth,
                                  const CBioseq_Handle&  top_level_seq,
                                  ESeqMapDirection       direction,
-                                 TMapOptions            opts)
-    : CSeq_loc_Mapper_Base(new CScope_Mapper_Sequence_Info(
-                           &top_level_seq.GetScope())),
+                                 CSeq_loc_Mapper_Options options)
+    : CSeq_loc_Mapper_Base(options.SetMapperSequenceInfo(new CScope_Mapper_Sequence_Info(
+                           &top_level_seq.GetScope()))),
       m_Scope(&top_level_seq.GetScope())
 {
-    m_MapOptions = opts;
     if (depth > 0) {
         depth--;
         x_InitializeSeqMap(top_level_seq.GetSeqMap(),
@@ -344,11 +333,10 @@ CSeq_loc_Mapper::CSeq_loc_Mapper(size_t           depth,
                                  ESeqMapDirection direction,
                                  const CSeq_id*   top_level_id,
                                  CScope*          scope,
-                                 TMapOptions      opts)
-    : CSeq_loc_Mapper_Base(new CScope_Mapper_Sequence_Info(scope)),
+                                 CSeq_loc_Mapper_Options options)
+    : CSeq_loc_Mapper_Base(options.SetMapperSequenceInfo(new CScope_Mapper_Sequence_Info(scope))),
       m_Scope(scope)
 {
-    m_MapOptions = opts;
     if (depth > 0) {
         depth--;
         x_InitializeSeqMap(top_level_seq, depth, top_level_id, direction);
@@ -367,7 +355,7 @@ CSeq_loc_Mapper::CSeq_loc_Mapper(const CGC_Assembly& gc_assembly,
                                  EGCAssemblyAlias    to_alias,
                                  CScope*             scope,
                                  EScopeFlag          scope_flag)
-    : CSeq_loc_Mapper_Base(new CScope_Mapper_Sequence_Info(scope)),
+    : CSeq_loc_Mapper_Base(CSeq_loc_Mapper_Options(new CScope_Mapper_Sequence_Info(scope))),
       m_Scope(scope)
 {
     // While parsing GC-Assembly the mapper will need to add virtual
@@ -378,7 +366,7 @@ CSeq_loc_Mapper::CSeq_loc_Mapper(const CGC_Assembly& gc_assembly,
         if ( scope ) {
             m_Scope.GetScope().AddScope(*scope);
         }
-        m_SeqInfo.Reset(new CScope_Mapper_Sequence_Info(m_Scope));
+        m_MapOptions.SetMapperSequenceInfo(new CScope_Mapper_Sequence_Info(m_Scope));
     }
     x_InitGCAssembly(gc_assembly, to_alias);
 }
@@ -389,11 +377,10 @@ CSeq_loc_Mapper::CSeq_loc_Mapper(const CGC_Assembly& gc_assembly,
                                  SSeqMapSelector     selector,
                                  CScope*             scope,
                                  EScopeFlag          scope_flag,
-                                 TMapOptions         opts)
-    : CSeq_loc_Mapper_Base(new CScope_Mapper_Sequence_Info(scope)),
+                                 CSeq_loc_Mapper_Options options)
+    : CSeq_loc_Mapper_Base(options.SetMapperSequenceInfo(new CScope_Mapper_Sequence_Info(scope))),
       m_Scope(scope)
 {
-    m_MapOptions = opts;
     // While parsing GC-Assembly the mapper will need to add virtual
     // bioseqs to the scope. To keep the original scope clean of them,
     // create a new scope and add the original one as a child.
@@ -402,7 +389,7 @@ CSeq_loc_Mapper::CSeq_loc_Mapper(const CGC_Assembly& gc_assembly,
         if ( scope ) {
             m_Scope.GetScope().AddScope(*scope);
         }
-        m_SeqInfo.Reset(new CScope_Mapper_Sequence_Info(m_Scope));
+        m_MapOptions.SetMapperSequenceInfo(new CScope_Mapper_Sequence_Info(m_Scope));
     }
     CGC_Assembly_Parser parser(gc_assembly);
     CRef<CSeq_entry> entry = parser.GetTSE();
@@ -468,7 +455,7 @@ void CSeq_loc_Mapper::x_InitializeSeqMap(CSeqMap_CI       seg_it,
                                          const CSeq_id*   top_id,
                                          ESeqMapDirection direction)
 {
-    if (m_MapOptions & fMapSingleLevel) {
+    if (m_MapOptions.GetMapSingleLevel()) {
         x_InitializeSeqMapSingleLevel(seg_it, top_id, direction);
     }
     else if (direction == eSeqMap_Up) {
@@ -755,8 +742,8 @@ void CSeq_loc_Mapper::x_InitGCAssembly(const CGC_Assembly& gc_assembly,
                     x_InitGCSequence(seq.GetSingle(), to_alias);
                 }
                 else {
-                    ITERATE(CGC_Replicon::TSequence::TSet, it, seq.GetSet()) {
-                        x_InitGCSequence(**it, to_alias);
+                    ITERATE(CGC_Replicon::TSequence::TSet, tseq, seq.GetSet()) {
+                        x_InitGCSequence(**tseq, to_alias);
                     }
                 }
             }
@@ -952,7 +939,7 @@ void CSeq_loc_Mapper::x_InitGCSequence(const CGC_Sequence& gc_seq,
             x_AddConversion(gc_seq.GetSeq_id(), 0, eNa_strand_unknown,
                 *dst_id, 0, eNa_strand_unknown,
                 hlen != kInvalidSeqPos ? hlen : TRange::GetWholeLength(),
-                false, 0, hlen, hlen, hlen);
+                false, 0, hlen, hlen);
         }
         else if (to_alias == eGCA_UCSC  ||  to_alias == eGCA_Refseq) {
             TSynonyms synonyms;
diff --git a/c++/src/objmgr/seq_map.cpp b/c++/src/objmgr/seq_map.cpp
index 7814796..d808737 100644
--- a/c++/src/objmgr/seq_map.cpp
+++ b/c++/src/objmgr/seq_map.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_map.cpp 499042 2016-04-21 17:39:04Z ivanov $
+/*  $Id: seq_map.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -397,11 +397,11 @@ size_t CSeqMap::x_FindSegment(TSeqPos pos, CScope* scope) const
         return resolved - 1;
     }
     else {
-        TSegments::const_iterator end = m_Segments.begin()+resolved;
+        TSegments::const_iterator itend = m_Segments.begin()+resolved;
         TSegments::const_iterator it = 
-            upper_bound(m_Segments.begin(), end,
+            upper_bound(m_Segments.begin(), itend,
                         pos, SPosLessSegment());
-        if ( it == end ) {
+        if ( it == itend ) {
             return size_t(-1);
         }
         return it - m_Segments.begin();
@@ -845,7 +845,7 @@ bool CSeqMap::HasSegmentOfType(ESegmentType type) const
     if ( m_HasSegments == 0 ) {
         THasSegments flags = 0;
         ITERATE ( TSegments, it, m_Segments ) {
-            flags |= 1<<it->m_SegType;
+            flags = flags | THasSegments(1 << it->m_SegType);
         }
         m_HasSegments = flags;
     }
@@ -1531,7 +1531,12 @@ bool CSeqMap::x_DoUpdateSeq_inst(CSeq_inst& inst)
             CSeq_literal& lit = dseq.SetLiteral();
             lit.SetLength(x_GetSegmentLength(index, 0));
             lit.ResetSeq_data();
-            lit.ResetFuzz();
+            if ( seg.m_UnknownLength ) {
+                lit.SetFuzz().SetLim(CInt_fuzz::eLim_unk);
+            }
+            else {
+                lit.ResetFuzz();
+            }
         }
         else {
             _ASSERT(seg.m_SegType == eSeqRef);
@@ -1557,7 +1562,7 @@ bool CSeqMap::x_DoUpdateSeq_inst(CSeq_inst& inst)
 }
 
 
-void CSeqMap::SetRepr(CSeq_inst::TRepr repr)
+void CSeqMap::SetRepr(CSeq_inst::TRepr /*repr*/)
 {
 }
 
diff --git a/c++/src/objmgr/seq_map_ci.cpp b/c++/src/objmgr/seq_map_ci.cpp
index 6010198..2e18d79 100644
--- a/c++/src/objmgr/seq_map_ci.cpp
+++ b/c++/src/objmgr/seq_map_ci.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_map_ci.cpp 499042 2016-04-21 17:39:04Z ivanov $
+/*  $Id: seq_map_ci.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -355,7 +355,7 @@ TSeqPos CSeqMap_CI_SegmentInfo::x_GetTopOffset(void) const
 int CSeqMap_CI_SegmentInfo::x_GetSequenceClass(void) const
 {
     if ( m_SequenceClass == -1 ) {
-        m_SequenceClass = m_SeqMap->x_GetSequenceClass();
+        m_SequenceClass = (Int1)m_SeqMap->x_GetSequenceClass();
     }
     return m_SequenceClass;
 }
diff --git a/c++/src/objmgr/seq_map_switch.cpp b/c++/src/objmgr/seq_map_switch.cpp
index 0870b73..c31f3f4 100644
--- a/c++/src/objmgr/seq_map_switch.cpp
+++ b/c++/src/objmgr/seq_map_switch.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_map_switch.cpp 444133 2014-08-21 16:53:43Z vasilche $
+/*  $Id: seq_map_switch.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -550,19 +550,19 @@ void CSeqMapSwitchPoint::ChangeSwitchPoint(TSeqPos pos, TSeqPos add)
     }
     if ( right_add ) { // change right segment first
         TSeqPos len = right.GetLength() + right_add;
-        TSeqPos pos = right.GetRefPosition();
+        TSeqPos p = right.GetRefPosition();
         if ( !m_RightMinusStrand ) {
-            pos -= right_add;
+            p -= right_add;
         }
-        seq_map.SetSegmentRef(right, len, m_RightId, pos, m_RightMinusStrand);
+        seq_map.SetSegmentRef(right, len, m_RightId, p, m_RightMinusStrand);
     }
     if ( left_add ) {
         TSeqPos len = left.GetLength() + left_add;
-        TSeqPos pos = left.GetRefPosition();
+        TSeqPos p   = left.GetRefPosition();
         if ( m_LeftMinusStrand ) {
-            pos -= left_add;
+            p -= left_add;
         }
-        seq_map.SetSegmentRef(left, len, m_LeftId, pos, m_LeftMinusStrand);
+        seq_map.SetSegmentRef(left, len, m_LeftId, p, m_LeftMinusStrand);
     }
 }
 
diff --git a/c++/src/objmgr/seq_table_info.cpp b/c++/src/objmgr/seq_table_info.cpp
index bd1412d..72b8083 100644
--- a/c++/src/objmgr/seq_table_info.cpp
+++ b/c++/src/objmgr/seq_table_info.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_table_info.cpp 484034 2015-11-05 18:59:10Z vasilche $
+/*  $Id: seq_table_info.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -70,6 +70,13 @@ bool CSeqTableColumnInfo::x_ThrowUnsetValue(void) const
 }
 
 
+bool CSeqTableColumnInfo::IsSingular(void) const
+{
+    const CSeqTable_column& col = *m_Column;
+    return col.IsSetDefault() && !col.IsSetData() && !col.IsSetSparse();
+}
+
+
 const string* CSeqTableColumnInfo::GetStringPtr(size_t row,
                                                 bool force) const
 {
@@ -555,6 +562,18 @@ CSeq_id_Handle CSeqTableLocColumns::GetIdHandle(size_t row) const
 }
 
 
+TSeqPos CSeqTableLocColumns::GetFrom(size_t row) const
+{
+    _ASSERT(!m_Loc);
+    _ASSERT(m_From);
+    int from;
+    if ( !m_From || !m_From.GetValue(row, from) ) {
+        return 0;
+    }
+    return from;
+}
+
+
 CRange<TSeqPos> CSeqTableLocColumns::GetRange(size_t row) const
 {
     _ASSERT(!m_Loc);
@@ -764,6 +783,9 @@ CSeqTableInfo::CSeqTableInfo(const CSeq_table& feat_table)
 
 void CSeqTableInfo::x_Initialize(const CSeq_table& feat_table)
 {
+    m_Seq_table = &feat_table;
+    m_IsSorted = false;
+    m_SortedMaxLength = 0;
     ITERATE ( CSeq_table::TColumns, it, feat_table.GetColumns() ) {
         const CSeqTable_column& col = **it;
         const CSeqTable_column_info& type = col.GetHeader();
@@ -786,6 +808,16 @@ void CSeqTableInfo::x_Initialize(const CSeq_table& feat_table)
                     m_ColumnsById.insert(TColumnsById::value_type(id, col));
                 }
             }
+            if ( name == "Seq-table location" ) {
+                if ( m_TableLocation ) {
+                    ERR_POST("Duplicate 'Seq-table location' column");
+                }
+                try {
+                    CSeqTableColumnInfo info(col);
+                    m_TableLocation = info.GetSeq_loc(0);
+                }
+                NCBI_CATCH("Bad 'Seq-table location' column");
+            }
         }
         if ( !IsFeatTable() ) {
             continue;
@@ -865,11 +897,29 @@ void CSeqTableInfo::x_Initialize(const CSeq_table& feat_table)
             else if ( name == "disabled" ) {
                 if ( m_Disabled ) {
                     NCBI_THROW_FMT(CAnnotException, eOtherError,
-                                   "Duplicate disabled column");
+                                   "Duplicate disabled column ");
                 }
                 m_Disabled = CSeqTableColumnInfo(col);
                 continue;
             }
+            else if ( name == "Seq-table location" ) {
+                // already processed above
+                continue;
+            }
+            else if ( name == "Sorted, max length" ) {
+                if ( m_SortedMaxLength ) {
+                    ERR_POST("Duplicate 'Sorted, max length' column");
+                }
+                try {
+                    CSeqTableColumnInfo info(col);
+                    int value;
+                    if ( info.GetValue(0, value) ) {
+                        m_SortedMaxLength = value;
+                    }
+                }
+                NCBI_CATCH("Bad 'Sorted, max length' column");
+                continue;
+            }
             if ( !setter ) {
                 try {
                     setter = new CSeqTableSetAnyFeatField(name);
@@ -888,6 +938,11 @@ void CSeqTableInfo::x_Initialize(const CSeq_table& feat_table)
         m_Location.ParseDefaults();
         m_Product.ParseDefaults();
     }
+
+    m_IsSorted = x_IsSorted();
+    if ( !m_IsSorted ) {
+        m_SortedMaxLength = 0;
+    }
 }
 
 
@@ -896,14 +951,58 @@ CSeqTableInfo::~CSeqTableInfo()
 }
 
 
+SAnnotTypeSelector CSeqTableInfo::GetType(void) const
+{
+    _ASSERT(IsFeatTable());
+    const CSeq_table& table = *m_Seq_table;
+    SAnnotTypeSelector type(CSeqFeatData::E_Choice(table.GetFeat_type()));
+    if ( table.IsSetFeat_subtype() ) {
+        type.SetFeatSubtype(CSeqFeatData::ESubtype(table.GetFeat_subtype()));
+    }
+    return type;
+}
+
+
 CConstRef<CSeq_loc> CSeqTableInfo::GetTableLocation(void) const
 {
-    try {
-        return GetColumn("Seq-table location").GetSeq_loc(0);
+    return m_TableLocation;
+}
+
+
+TSeqPos CSeqTableInfo::GetSortedMaxLength(void) const
+{
+    return m_SortedMaxLength;
+}
+
+
+bool CSeqTableInfo::x_IsSorted(void) const
+{
+    // 1. no product
+    // 2. location has singular Seq-id
+    // 3. location is either simple interval or simple point
+    // 4. has whole table location that is Seq-interval
+    // 5. sorted max length information is present, and has suitable value
+    if ( m_Product.IsSet() ) {
+        return false;
+    }
+    if ( !m_Location.IsSet() || m_Location.IsRealLoc() || !m_Location.m_Id ) {
+        return false;
+    }
+    if ( !m_Location.m_Id.IsSingular() ) {
+        return false;
+    }
+    if ( !m_Location.m_Is_simple ||
+         !(m_Location.m_Is_simple_point || m_Location.m_Is_simple_interval) ) {
+        return false;
+    }
+    if ( !m_TableLocation || !m_TableLocation->IsInt() ) {
+        return false;
     }
-    catch ( exception& /*ignored*/ ) {
-        return null;
+    if ( !m_SortedMaxLength ||
+         m_SortedMaxLength > m_TableLocation->GetInt().GetLength()/16 ) {
+        return false;
     }
+    return true;
 }
 
 
@@ -928,14 +1027,14 @@ void CSeqTableInfo::UpdateSeq_feat(size_t row,
         feat.SetLocation(*seq_loc);
     }
     if ( m_Product.IsSet() ) {
-        CRef<CSeq_loc> seq_loc;
-        CRef<CSeq_point> seq_pnt;
-        CRef<CSeq_interval> seq_int;
+        CRef<CSeq_loc> s_loc;
+        CRef<CSeq_point> s_pnt;
+        CRef<CSeq_interval> s_int;
         if ( feat.IsSetProduct() ) {
-            seq_loc = &feat.SetProduct();
+            s_loc = &feat.SetProduct();
         }
-        m_Product.UpdateSeq_loc(row, seq_loc, seq_pnt, seq_int);
-        feat.SetProduct(*seq_loc);
+        m_Product.UpdateSeq_loc(row, s_loc, s_pnt, s_int);
+        feat.SetProduct(*s_loc);
     }
     if ( m_Partial ) {
         bool val = false;
@@ -949,6 +1048,69 @@ void CSeqTableInfo::UpdateSeq_feat(size_t row,
 }
 
 
+bool CSeqTableInfo::HasLabel(size_t /*index*/) const
+{
+    for ( auto& c : m_ExtraColumns ) {
+        const CSeqTable_column& col = *c.first.Get();
+        const CSeqTable_column_info& col_info = col.GetHeader();
+        if ( col_info.IsSetField_name() ) {
+            const string& name = col_info.GetField_name();
+            if ( !name.empty() && name[0] == 'Q' ) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+
+string CSeqTableInfo::GetLabel(size_t index) const
+{
+    CNcbiOstrstream str;
+    char sep = '/';
+    for ( auto& c : m_ExtraColumns ) {
+        const CSeqTable_column& col = *c.first.Get();
+        const CSeqTable_column_info& col_info = col.GetHeader();
+        if ( col_info.IsSetField_name() ) {
+            const string& name = col_info.GetField_name();
+            if ( !name.empty() && name[0] == 'Q' ) {
+                str << sep;
+                sep = ' ';
+                str << name.substr(2);
+                const string* value_ptr = c.first.GetStringPtr(index);
+                if ( value_ptr && !value_ptr->empty() ) {
+                    str << '=' << *value_ptr;
+                }
+            }
+        }
+    }
+    return CNcbiOstrstreamToString(str);
+}
+
+
+bool CSeqTableInfo::MatchBitFilter(const SAnnotSelector& sel,
+                                   size_t index) const
+{
+    for ( auto& c : m_ExtraColumns ) {
+        const CSeqTable_column& col = *c.first.Get();
+        const CSeqTable_column_info& col_info = col.GetHeader();
+        if ( col_info.IsSetField_name() ) {
+            const string& name = col_info.GetField_name();
+            if ( name == "E.QualityCodes" ) {
+                const vector<char>* bytes = c.first.GetBytesPtr(index);
+                if ( !bytes || bytes->size() != 8 ) {
+                    continue;
+                }
+                Uint8 bits = *reinterpret_cast<const Uint8*>(bytes->data());
+                return (bits & sel.GetFilterMask()) == sel.GetFilterBits();
+            }
+        }
+    }
+    // assume match if no quality bit info is set
+    return true;
+}
+
+
 const CSeqTableColumnInfo*
 CSeqTableInfo::FindColumn(int field_id) const
 {
diff --git a/c++/src/objmgr/seq_table_setters.cpp b/c++/src/objmgr/seq_table_setters.cpp
index 4013db3..9a71178 100644
--- a/c++/src/objmgr/seq_table_setters.cpp
+++ b/c++/src/objmgr/seq_table_setters.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_table_setters.cpp 458003 2015-01-29 19:47:52Z vasilche $
+/*  $Id: seq_table_setters.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -53,35 +53,35 @@ CSeqTableSetFeatField::~CSeqTableSetFeatField()
 }
 
 
-void CSeqTableSetFeatField::SetInt(CSeq_feat& feat, int value) const
+void CSeqTableSetFeatField::SetInt(CSeq_feat&, int value) const
 {
     NCBI_THROW_FMT(CAnnotException, eOtherError,
                    "Incompatible Seq-feat field value: "<<value);
 }
 
 
-void CSeqTableSetFeatField::SetInt8(CSeq_feat& feat, Int8 value) const
+void CSeqTableSetFeatField::SetInt8(CSeq_feat&, Int8 value) const
 {
     NCBI_THROW_FMT(CAnnotException, eOtherError,
                    "Incompatible Seq-feat field value: "<<value);
 }
 
 
-void CSeqTableSetFeatField::SetReal(CSeq_feat& feat, double value) const
+void CSeqTableSetFeatField::SetReal(CSeq_feat&, double value) const
 {
     NCBI_THROW_FMT(CAnnotException, eOtherError,
                    "Incompatible Seq-feat field value: "<<value);
 }
 
 
-void CSeqTableSetFeatField::SetString(CSeq_feat& feat, const string& value) const
+void CSeqTableSetFeatField::SetString(CSeq_feat&, const string& value) const
 {
     NCBI_THROW_FMT(CAnnotException, eOtherError,
                    "Incompatible Seq-feat field value: "<<value);
 }
 
 
-void CSeqTableSetFeatField::SetBytes(CSeq_feat& feat, const vector<char>& value) const
+void CSeqTableSetFeatField::SetBytes(CSeq_feat&, const vector<char>& /*value*/) const
 {
     NCBI_THROW_FMT(CAnnotException, eOtherError,
                    "Incompatible Seq-feat field value: vector<char>");
@@ -94,28 +94,28 @@ CSeqTableSetLocField::~CSeqTableSetLocField()
 }
 
 
-void CSeqTableSetLocField::SetInt(CSeq_loc& loc, int value) const
+void CSeqTableSetLocField::SetInt(CSeq_loc&, int value) const
 {
     NCBI_THROW_FMT(CAnnotException, eOtherError,
                    "Incompatible Seq-loc field value: "<<value);
 }
 
 
-void CSeqTableSetLocField::SetInt8(CSeq_loc& loc, Int8 value) const
+void CSeqTableSetLocField::SetInt8(CSeq_loc&, Int8 value) const
 {
     NCBI_THROW_FMT(CAnnotException, eOtherError,
                    "Incompatible Seq-loc field value: "<<value);
 }
 
 
-void CSeqTableSetLocField::SetReal(CSeq_loc& loc, double value) const
+void CSeqTableSetLocField::SetReal(CSeq_loc&, double value) const
 {
     NCBI_THROW_FMT(CAnnotException, eOtherError,
                    "Incompatible Seq-loc field value: "<<value);
 }
 
 
-void CSeqTableSetLocField::SetString(CSeq_loc& loc, const string& value) const
+void CSeqTableSetLocField::SetString(CSeq_loc&, const string& value) const
 {
     NCBI_THROW_FMT(CAnnotException, eOtherError,
                    "Incompatible Seq-loc field value: "<<value);
@@ -181,7 +181,7 @@ CSeqTableSetExt::CSeqTableSetExt(const CTempString& fullname)
     : name(fullname.substr(2))
 {
     if ( name.find('.') != NPOS ) {
-        NStr::Tokenize(name, ".", subfields);
+        NStr::Split(name, ".", subfields);
         name = subfields.back();
         subfields.pop_back();
     }
@@ -195,9 +195,9 @@ CUser_field& CSeqTableSetExt::x_SetField(CSeq_feat& feat) const
         CUser_object::TData* next_data = 0;
         NON_CONST_ITERATE ( CUser_object::TData, it2, *data ) {
             const CObject_id& id = (*it2)->GetLabel();
-            CUser_field::TData& data = (*it2)->SetData();
-            if ( data.IsFields() && id.IsStr() && id.GetStr() == *it ) {
-                next_data = &data.SetFields();
+            CUser_field::TData& data2 = (*it2)->SetData();
+            if ( data2.IsFields() && id.IsStr() && id.GetStr() == *it ) {
+                next_data = &data2.SetFields();
                 break;
             }
         }
@@ -225,7 +225,7 @@ void CSeqTableSetExt::SetInt(CSeq_feat& feat, int value) const
 void CSeqTableSetExt::SetInt8(CSeq_feat& feat, Int8 value) const
 {
     // TODO: Int8 in User-field
-    x_SetField(feat).SetData().SetInt(value);
+    x_SetField(feat).SetData().SetInt((int)value);
 }
 
 
diff --git a/c++/src/objmgr/seq_vector.cpp b/c++/src/objmgr/seq_vector.cpp
index bca8f40..ad57171 100644
--- a/c++/src/objmgr/seq_vector.cpp
+++ b/c++/src/objmgr/seq_vector.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_vector.cpp 465024 2015-04-16 13:13:41Z vasilche $
+/*  $Id: seq_vector.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -71,7 +71,7 @@ CNcbi2naRandomizer::CNcbi2naRandomizer(CRandom& gen)
             if ( !na4  ||  (na4 & (1 << bit)) ) {
                 bit_count++;
                 bases[bit] = 1;
-                set_bit = bit;
+                set_bit = (char)bit;
             }
             else {
                 bases[bit] = 0;
@@ -95,7 +95,7 @@ CNcbi2naRandomizer::CNcbi2naRandomizer(CRandom& gen)
                     rnd -= bases[base];
                     continue;
                 }
-                m_RandomTable[na4][i] = base;
+                m_RandomTable[na4][i] = (char)base;
                 bases[base]--;
                 break;
             }
@@ -499,7 +499,7 @@ void x_Append8To2(string& dst_str, char& dst_c, TSeqPos dst_pos,
     if ( dst_pos&3 ) {
         char c = dst_c;
         for ( ; count && (dst_pos&3); --count, ++dst_pos ) {
-            c = (c<<2)|*unpacked++;
+            c = char((c<<2)|*unpacked++);
         }
         if ( (dst_pos&3) == 0 ) {
             dst_str += c;
@@ -517,8 +517,8 @@ void x_Append8To2(string& dst_str, char& dst_c, TSeqPos dst_pos,
     char packed_buffer[kBufferSize/4];
     char* packed_end = packed_buffer;
     for ( ; count >= 4; count -= 4, unpacked += 4 ) {
-        *packed_end++ =
-            (unpacked[0]<<6)|(unpacked[1]<<4)|(unpacked[2]<<2)|unpacked[3];
+        *packed_end++ = char(
+            (unpacked[0]<<6)|(unpacked[1]<<4)|(unpacked[2]<<2)|unpacked[3] );
     }
     dst_str.append(packed_buffer, packed_end);
     switch ( count ) {
@@ -526,10 +526,10 @@ void x_Append8To2(string& dst_str, char& dst_c, TSeqPos dst_pos,
         dst_c = unpacked[0];
         break;
     case 2:
-        dst_c = (unpacked[0]<<2)|unpacked[1];
+        dst_c = char((unpacked[0]<<2)|unpacked[1]);
         break;
     case 3:
-        dst_c = (unpacked[0]<<4)|(unpacked[1]<<2)|unpacked[2];
+        dst_c = char((unpacked[0]<<4)|(unpacked[1]<<2)|unpacked[2]);
         break;
     default:
         dst_c = 0;
@@ -571,9 +571,9 @@ void x_Append2To2(string& dst, char& dst_c, TSeqPos dst_pos,
     if ( dst_pos&3 ) {
         // align dst_pos
         TSeqPos add = 4-(dst_pos&3);
-        char c = (dst_c<<(add*2))|(src[src_pos>>2]&((1<<(add*2))-1));
+        char c = char((dst_c<<(add*2))|(src[src_pos>>2]&((1<<(add*2))-1)));
         if ( count < add ) {
-            dst_c = c >> (2*(add-count));
+            dst_c = char(c >> (2*(add-count)));
             return;
         }
         dst += c;
@@ -592,7 +592,7 @@ void x_Append2To2(string& dst, char& dst_c, TSeqPos dst_pos,
     size_t rem = count&3;
     if ( rem ) {
         _ASSERT(!(src_pos&3));
-        dst_c = (src[pos+octets]&255)>>(2*(4-rem));
+        dst_c = char((src[pos+octets]&255)>>(2*(4-rem)));
     }
 }
 
diff --git a/c++/src/objmgr/snp_annot_info.cpp b/c++/src/objmgr/snp_annot_info.cpp
index 2bd6142..6337349 100644
--- a/c++/src/objmgr/snp_annot_info.cpp
+++ b/c++/src/objmgr/snp_annot_info.cpp
@@ -1,4 +1,4 @@
-/*  $Id: snp_annot_info.cpp 497230 2016-04-05 13:28:50Z ivanov $
+/*  $Id: snp_annot_info.cpp 514368 2016-09-21 15:22:14Z ivanov $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
@@ -199,7 +199,7 @@ SSNP_Info::ESNP_Type SSNP_Info::ParseSeq_feat(const CSeq_feat& feat,
                     if ( value < 0 || value > kMax_Weight ) {
                         return eSNP_Complex_WeightBadValue;
                     }
-                    m_Weight |= TWeight(value) << (int)fWeightFlagBits;
+                    m_Weight |= TWeight(TWeight(value) << (int)fWeightFlagBits);
                 }
                 catch ( exception& ) {
                     return eSNP_Complex_WeightBadValue;
@@ -312,15 +312,15 @@ SSNP_Info::ESNP_Type SSNP_Info::ParseSeq_feat(const CSeq_feat& feat,
                 if ( value < 0 || value > kMax_Weight ) {
                     return eSNP_Complex_WeightBadValue;
                 }
-                m_Weight |= TWeight(value) << (int)fWeightFlagBits;
+                m_Weight |= TWeight(TWeight(value) << (int)fWeightFlagBits);
             }
         }
         else if ( kId_dbSnpQAdata == ext_id_str ) {
-            const CUser_object::TData& data = ext.GetData();
-            if ( data.empty() ) {
+            const CUser_object::TData& snp_data = ext.GetData();
+            if ( snp_data.empty() ) {
                 return eSNP_Complex_BadQAdata;
             }
-            ITERATE ( CUser_object::TData, it, data ) {
+            ITERATE ( CUser_object::TData, it, snp_data ) {
                 const CUser_field& field = **it;
                 const CObject_id& id = field.GetLabel();
                 if ( id.Which() != CObject_id::e_Str ) {
@@ -782,6 +782,26 @@ void SSNP_Info::UpdateSeq_feat(CRef<CSeq_feat>& feat_ref,
 }
 
 
+string SSNP_Info::GetLabel(const CSeq_annot_SNP_Info& annot) const
+{
+    CNcbiOstrstream str;
+    size_t count = 0;
+    for (; count < kMax_AllelesCount; ++count) {
+        TAlleleIndex allele_index = m_AllelesIndices[count];
+        if ( allele_index == kNo_AlleleIndex ) {
+            break;
+        }
+        str << (count == 0? '/': ' ');
+        str << "replace";
+        const string& allele = annot.x_GetAllele(allele_index);
+        if ( !allele.empty() ) {
+            str << '=' << allele;
+        }
+    }
+    return CNcbiOstrstreamToString(str);
+}
+
+
 /////////////////////////////////////////////////////////////////////////////
 // CSeq_annot_SNP_Info
 /////////////////////////////////////////////////////////////////////////////
diff --git a/c++/src/objmgr/split/annot_piece.cpp b/c++/src/objmgr/split/annot_piece.cpp
index 8c5ee0b..0532947 100644
--- a/c++/src/objmgr/split/annot_piece.cpp
+++ b/c++/src/objmgr/split/annot_piece.cpp
@@ -1,4 +1,4 @@
-/*  $Id: annot_piece.cpp 402825 2013-06-10 20:54:14Z vasilche $
+/*  $Id: annot_piece.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -277,7 +277,7 @@ size_t CAnnotPieces::CountAnnotObjects(void) const
                 cnt = 1;
             }
             size_t id_refs = p.m_Location.size();
-            ref_count += double(cnt) / id_refs;
+            ref_count += (double)cnt / (double)id_refs;
         }
     }
     return size_t(ref_count + .5);
diff --git a/c++/src/objmgr/split/blob_splitter_impl.cpp b/c++/src/objmgr/split/blob_splitter_impl.cpp
index a107ddb..634eccc 100644
--- a/c++/src/objmgr/split/blob_splitter_impl.cpp
+++ b/c++/src/objmgr/split/blob_splitter_impl.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blob_splitter_impl.cpp 444534 2014-08-25 18:35:52Z vasilche $
+/*  $Id: blob_splitter_impl.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -489,7 +489,8 @@ void CBlobSplitterImpl::SplitPieces(CAnnotPieces& pieces)
             // calculate maximum piece length
             // how many chunks to make from these annotations
             size_t chunk_count =
-                size_t(double(objs.m_Size.GetZipSize())/m_Params.m_ChunkSize
+                size_t(double(objs.m_Size.GetZipSize()) /
+                       double(m_Params.m_ChunkSize)
                        +.5);
             // length of sequence covered by annotations
             size_t whole_length = objs.m_IdRange.GetLength();
diff --git a/c++/src/objmgr/split/blob_splitter_maker.cpp b/c++/src/objmgr/split/blob_splitter_maker.cpp
index 673e6dc..8e3851b 100644
--- a/c++/src/objmgr/split/blob_splitter_maker.cpp
+++ b/c++/src/objmgr/split/blob_splitter_maker.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blob_splitter_maker.cpp 457860 2015-01-28 20:06:17Z vasilche $
+/*  $Id: blob_splitter_maker.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -647,8 +647,8 @@ namespace {
     void AddBioseqIds(CID2S_Bioseq_Ids& ret, const set<CSeq_id_Handle>& ids)
     {
         TGiSet gi_set;
-        typedef set<CConstRef<CSeq_id>, SLessSeq_id> TIdSet;
-        TIdSet id_set;
+        typedef set<CConstRef<CSeq_id>, SLessSeq_id> TLessIdSet;
+        TLessIdSet id_set;
         ITERATE ( set<CSeq_id_Handle>, it, ids ) {
             if ( it->IsGi() ) {
                 gi_set.insert(it->GetGi());
@@ -659,7 +659,7 @@ namespace {
         }
         
         ForEachGiRange(gi_set, FAddGiRangeToBioseqIds(ret));
-        ITERATE ( TIdSet, it, id_set ) {
+        ITERATE ( TLessIdSet, it, id_set ) {
             CRef<CID2S_Bioseq_Ids::C_E> elem(new CID2S_Bioseq_Ids::C_E);
             elem->SetSeq_id(const_cast<CSeq_id&>(**it));
             ret.Set().push_back(elem);
@@ -1020,24 +1020,24 @@ void CBlobSplitterImpl::MakeID2Chunk(TChunkId chunk_id, const SChunkInfo& info)
         CRef<CID2S_Chunk_Content> content(new CID2S_Chunk_Content);
         CID2S_Chunk_Content::TFeat_ids& store = content->SetFeat_ids();
         ITERATE ( SFeatIds::TSplitIds, it, feat_ids.m_SplitIds ) {
-            CRef<CID2S_Seq_feat_Ids_Info> info(new CID2S_Seq_feat_Ids_Info);
+            CRef<CID2S_Seq_feat_Ids_Info> info_ids(new CID2S_Seq_feat_Ids_Info);
             if ( !it->first.first.empty() ) {
                 SAllAnnotTypes types;
                 types.Add(it->first.first);
-                types.SetFeatTypes(info->SetFeat_types());
+                types.SetFeatTypes(info_ids->SetFeat_types());
             }
             if ( !it->first.second.empty() ) {
                 SAllAnnotTypes types;
                 types.Add(it->first.second);
-                types.SetFeatTypes(info->SetXref_types());
+                types.SetFeatTypes(info_ids->SetXref_types());
             }
             ITERATE ( SFeatIds::TFeatIdsInt, fit, it->second.first ) {
-                info->SetLocal_ids().push_back(*fit);
+                info_ids->SetLocal_ids().push_back(*fit);
             }
             ITERATE ( SFeatIds::TFeatIdsStr, fit, it->second.second ) {
-                info->SetLocal_str_ids().push_back(*fit);
+                info_ids->SetLocal_str_ids().push_back(*fit);
             }
-            store.push_back(info);
+            store.push_back(info_ids);
         }
         chunk_content.push_back(content);
     }
diff --git a/c++/src/objmgr/split/id_range.cpp b/c++/src/objmgr/split/id_range.cpp
index 9531d90..0501b80 100644
--- a/c++/src/objmgr/split/id_range.cpp
+++ b/c++/src/objmgr/split/id_range.cpp
@@ -1,4 +1,4 @@
-/*  $Id: id_range.cpp 460165 2015-02-25 15:37:24Z vasilche $
+/*  $Id: id_range.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -214,7 +214,7 @@ void CSeqsRange::Add(const CSeq_align& obj, const CBlobSplitterImpl& impl)
 
 
 void CSeqsRange::Add(const CDense_seg& denseg,
-                     const CBlobSplitterImpl& impl)
+                     const CBlobSplitterImpl& /*impl*/)
 {
     size_t dim    = denseg.GetDim();
     size_t numseg = denseg.GetNumseg();
@@ -246,7 +246,7 @@ void CSeqsRange::Add(const CDense_seg& denseg,
 
 
 void CSeqsRange::Add(const CDense_diag& diag,
-                     const CBlobSplitterImpl& impl)
+                     const CBlobSplitterImpl& /*impl*/)
 {
     size_t dim = diag.GetDim();
     if ( dim != diag.GetIds().size() ) {
@@ -267,7 +267,7 @@ void CSeqsRange::Add(const CDense_diag& diag,
 
 
 void CSeqsRange::Add(const CPacked_seg& packed,
-                     const CBlobSplitterImpl& impl)
+                     const CBlobSplitterImpl& /*impl*/)
 {
     size_t dim    = packed.GetDim();
     size_t numseg = packed.GetNumseg();
@@ -299,7 +299,7 @@ void CSeqsRange::Add(const CPacked_seg& packed,
 
 
 void CSeqsRange::Add(const CSpliced_seg& spliced,
-                     const CBlobSplitterImpl& impl)
+                     const CBlobSplitterImpl& /*impl*/)
 {
     const CSeq_id* gen_id = spliced.IsSetGenomic_id() ?
         &spliced.GetGenomic_id() : 0;
@@ -329,7 +329,7 @@ void CSeqsRange::Add(const CSpliced_seg& spliced,
 
 
 void CSeqsRange::Add(const CSparse_seg& sparse,
-                     const CBlobSplitterImpl& impl)
+                     const CBlobSplitterImpl& /*impl*/)
 {
     size_t row = 0;
     ITERATE ( CSparse_seg::TRows, it, sparse.GetRows() ) {
diff --git a/c++/src/objmgr/split/object_splitinfo.cpp b/c++/src/objmgr/split/object_splitinfo.cpp
index 8ca483b..d1811f7 100644
--- a/c++/src/objmgr/split/object_splitinfo.cpp
+++ b/c++/src/objmgr/split/object_splitinfo.cpp
@@ -1,4 +1,4 @@
-/*  $Id: object_splitinfo.cpp 403742 2013-06-18 15:26:09Z grichenk $
+/*  $Id: object_splitinfo.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -510,7 +510,7 @@ CPlace_SplitInfo::~CPlace_SplitInfo(void)
 
 
 CSeq_descr_SplitInfo::CSeq_descr_SplitInfo(const CPlaceId& place_id,
-                                           TSeqPos seq_length,
+                                           TSeqPos /*seq_length*/,
                                            const CSeq_descr& descr,
                                            const SSplitterParams& params)
     : m_Descr(&descr)
diff --git a/c++/src/objmgr/split/size.cpp b/c++/src/objmgr/split/size.cpp
index f6aa816..2d9913a 100644
--- a/c++/src/objmgr/split/size.cpp
+++ b/c++/src/objmgr/split/size.cpp
@@ -1,4 +1,4 @@
-/*  $Id: size.cpp 444532 2014-08-25 18:35:16Z vasilche $
+/*  $Id: size.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -50,7 +50,7 @@ CSize::CSize(const CAsnSizer& sizer)
 CSize::CSize(TDataSize asn_size, double ratio)
     : m_Count(1),
       m_AsnSize(asn_size),
-      m_ZipSize(TDataSize(asn_size*ratio+.5))
+      m_ZipSize(TDataSize(double(asn_size)*ratio + .5))
 {
 }
 
@@ -99,8 +99,8 @@ CNcbiOstream& CSize::Print(CNcbiOstream& out) const
     return out <<
         "Cnt:" << setw(5) << m_Count << ", " <<
         setiosflags(ios::fixed) << setprecision(2) <<
-        "Asn:" << setw(8) << GetAsnSize()*(1./1024) << " KB, " <<
-        "Zip:" << setw(8) << GetZipSize()*(1./1024) << " KB, " <<
+        "Asn:" << setw(8) << (double)GetAsnSize()*(1./1024) << " KB, " <<
+        "Zip:" << setw(8) << (double)GetZipSize()*(1./1024) << " KB, " <<
         setprecision(3) <<
         "Ratio: " << GetRatio();
 }
diff --git a/c++/src/objmgr/split_parser.cpp b/c++/src/objmgr/split_parser.cpp
index d0fb017..e4d8059 100644
--- a/c++/src/objmgr/split_parser.cpp
+++ b/c++/src/objmgr/split_parser.cpp
@@ -1,4 +1,4 @@
-/*  $Id: split_parser.cpp 490251 2016-01-22 15:40:54Z vasilche $
+/*  $Id: split_parser.cpp 518178 2016-11-01 11:46:07Z ivanov $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
@@ -49,10 +49,8 @@ BEGIN_SCOPE(objects)
 
 void CSplitParser::Attach(CTSE_Info& tse, const CID2S_Split_Info& split)
 {
-    if ( !tse.HasSeq_entry() ) {
-        if ( split.IsSetSkeleton() ) {
-            tse.SetSeq_entry(const_cast<CSeq_entry&>(split.GetSkeleton()));
-        }
+    if ( split.IsSetSkeleton() && tse.HasNoSeq_entry() ) {
+        tse.SetSeq_entry(const_cast<CSeq_entry&>(split.GetSkeleton()));
     }
     CTSE_Split_Info& sinfo = tse.GetSplitInfo();
     ITERATE ( CID2S_Split_Info::TChunks, it, split.GetChunks() ) {
diff --git a/c++/src/objmgr/tse_assigner.cpp b/c++/src/objmgr/tse_assigner.cpp
index 4f85ad7..88bcd9e 100644
--- a/c++/src/objmgr/tse_assigner.cpp
+++ b/c++/src/objmgr/tse_assigner.cpp
@@ -1,4 +1,4 @@
-/*  $Id: tse_assigner.cpp 485106 2015-11-18 18:58:49Z vasilche $
+/*  $Id: tse_assigner.cpp 504373 2016-06-14 18:05:35Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -67,9 +67,12 @@ CBioseq_Base_Info& ITSE_Assigner::x_GetBase(CTSE_Info& tse_info,
     if ( place.first ) {
         return x_GetBioseq(tse_info, place.first);
     }
-    else {
+    else if ( place.second ) {
         return x_GetBioseq_set(tse_info, place.second);
     }
+    else {
+        return const_cast<CBioseq_Base_Info&>(tse_info.x_GetBaseInfo());
+    }
 }
 
 
diff --git a/c++/src/objmgr/tse_handle.cpp b/c++/src/objmgr/tse_handle.cpp
index fababb8..2658879 100644
--- a/c++/src/objmgr/tse_handle.cpp
+++ b/c++/src/objmgr/tse_handle.cpp
@@ -1,4 +1,4 @@
-/*  $Id: tse_handle.cpp 434022 2014-05-01 19:40:00Z vasilche $
+/*  $Id: tse_handle.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -426,7 +426,7 @@ const CScopeInfo_Base::TIndexIds* CScopeInfo_Base::GetIndexIds(void) const
 }
 
 
-bool CScopeInfo_Base::x_Check(TCheckFlags zero_counter_mode) const
+bool CScopeInfo_Base::x_Check(TCheckFlags /*zero_counter_mode*/) const
 {
     return true;
 /*
diff --git a/c++/src/objmgr/tse_info.cpp b/c++/src/objmgr/tse_info.cpp
index b1f6e97..c66d058 100644
--- a/c++/src/objmgr/tse_info.cpp
+++ b/c++/src/objmgr/tse_info.cpp
@@ -1,4 +1,4 @@
-/*  $Id: tse_info.cpp 469582 2015-06-05 18:36:59Z vasilche $
+/*  $Id: tse_info.cpp 518178 2016-11-01 11:46:07Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -195,7 +195,7 @@ CTSE_Info::CTSE_Info(const CTSE_Lock& tse)
     m_LoadState = eLoaded;
 
     // update Seq-inst object with split data
-    tse->x_Update(fNeedUpdate_children_seq_data);
+    tse->x_Update(fNeedUpdate_children_seq_data|fNeedUpdate_children_bioseq);
     x_SetObject(*tse, &m_BaseTSE->m_ObjectCopyMap);
     x_TSEAttach(*this);
 
@@ -339,7 +339,7 @@ void CTSE_Info::SetUsedMemory(size_t size)
 
 void CTSE_Info::SetSeq_entry(CSeq_entry& entry, CTSE_SetObjectInfo* set_info)
 {
-    if ( Which() != CSeq_entry::e_not_set ) {
+    if ( m_Which != CSeq_entry::e_not_set ) {
         if ( m_LoadState == eNotLoaded ) {
             Reset();
             m_Object.Reset();
@@ -1011,8 +1011,10 @@ void CTSE_Info::UpdateAnnotIndex(CTSE_Info_Object& object)
         if (HasDataSource())
             guard.Guard(GetDataSource());
         TAnnotLockWriteGuard guard2(GetAnnotLock());
+        //CStopWatch sw(CStopWatch::eStart);
         object.x_UpdateAnnotIndex(*this);
         _ASSERT(!object.x_DirtyAnnotIndex());
+        //LOG_POST(Info<<"Updated annot index in "<<sw.Elapsed());
     }
 }
 
@@ -1370,6 +1372,14 @@ bool CTSE_Info::x_NeedsDelayedMainChunk(void) const
 }
 
 
+void CTSE_Info::x_LoadDelayedMainChunk(void) const
+{
+    if ( m_Split ) {
+        m_Split->x_LoadDelayedMainChunk();
+    }
+}
+
+
 void CTSE_Info::x_AddFeaturesById(TAnnotObjects& objects,
                                   const SFeatIdIndex& index,
                                   TFeatIdInt id,
@@ -1958,7 +1968,12 @@ void CTSE_Info::SetBioseqUpdater(CRef<CBioseqUpdater> updater)
 string CTSE_Info::GetDescription(void) const
 {
     string ret;
-    ret = GetBlobId().ToString();
+    if ( m_BlobId ) {
+        ret = GetBlobId().ToString();
+    }
+    else {
+        ret = NStr::PtrToString(this);
+    }
     if ( GetName().IsNamed() ) {
         ret += '/';
         ret += GetName().GetName();
diff --git a/c++/src/objmgr/tse_split_info.cpp b/c++/src/objmgr/tse_split_info.cpp
index f86578a..a0c7d3d 100644
--- a/c++/src/objmgr/tse_split_info.cpp
+++ b/c++/src/objmgr/tse_split_info.cpp
@@ -1,4 +1,4 @@
-/*  $Id: tse_split_info.cpp 471824 2015-07-01 17:23:26Z vasilche $
+/*  $Id: tse_split_info.cpp 518178 2016-11-01 11:46:07Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -193,6 +193,15 @@ bool CTSE_Split_Info::x_NeedsDelayedMainChunk(void) const
 }
 
 
+void CTSE_Split_Info::x_LoadDelayedMainChunk(void) const
+{
+    TChunks::const_iterator iter = m_Chunks.end(), begin = m_Chunks.begin();
+    while ( iter != begin && (--iter)->first >= kMax_Int-1 ) {
+        iter->second->Load();
+    }
+}
+
+
 // chunk attach
 void CTSE_Split_Info::AddChunk(CTSE_Chunk_Info& chunk_info)
 {
diff --git a/c++/src/objmgr/unsupp_editsaver.cpp b/c++/src/objmgr/unsupp_editsaver.cpp
index 462d338..f3ab9fc 100644
--- a/c++/src/objmgr/unsupp_editsaver.cpp
+++ b/c++/src/objmgr/unsupp_editsaver.cpp
@@ -1,4 +1,4 @@
-/*  $Id: unsupp_editsaver.cpp 103491 2007-05-04 17:18:18Z kazimird $
+/*  $Id: unsupp_editsaver.cpp 514368 2016-09-21 15:22:14Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -438,7 +438,7 @@ void CUnsupportedEditSaver::Remove(const CSeq_entry_Handle&,
 
 void CUnsupportedEditSaver::Attach(const CBioseq_set_Handle&, 
                             const CSeq_entry_Handle&, 
-                            int Index, ECallMode)
+                            int /*Index*/, ECallMode)
 {
     NCBI_THROW(CUnsupportedEditSaverException,
                eUnsupported,
@@ -446,7 +446,7 @@ void CUnsupportedEditSaver::Attach(const CBioseq_set_Handle&,
 }
 void CUnsupportedEditSaver::Remove(const CBioseq_set_Handle&, 
                                    const CSeq_entry_Handle&, 
-                                   int Index, ECallMode)
+                                   int /*Index*/, ECallMode)
 {
     NCBI_THROW(CUnsupportedEditSaverException,
                eUnsupported,
diff --git a/c++/src/objmgr/util/Makefile.util.lib b/c++/src/objmgr/util/Makefile.util.lib
index 39cb3a6..bc691eb 100644
--- a/c++/src/objmgr/util/Makefile.util.lib
+++ b/c++/src/objmgr/util/Makefile.util.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.util.lib 472056 2015-07-06 19:29:12Z gotvyans $
+# $Id: Makefile.util.lib 501626 2016-05-17 17:32:10Z kornbluh $
 
 # Build library "xobjutil"
 ###############################
@@ -11,7 +11,7 @@ LIB = xobjutil
 
 DLL_LIB = $(SOBJMGR_LIBS)
 
-WATCHERS = ucko vasilche kornbluh
+WATCHERS = ucko vasilche
 
 
 
diff --git a/c++/src/objmgr/util/create_defline.cpp b/c++/src/objmgr/util/create_defline.cpp
index 8aec30e..6452347 100644
--- a/c++/src/objmgr/util/create_defline.cpp
+++ b/c++/src/objmgr/util/create_defline.cpp
@@ -187,7 +187,7 @@ void x_CleanAndCompress(string& dest, const CTempString& instr)
     while (left > 0) {
         next = *in++;
 
-        two_chars = (two_chars << 8) | next;
+        two_chars = Uint2((two_chars << 8) | next);
 
         switch (two_chars)
         {
@@ -448,6 +448,7 @@ void CDeflineGenerator::x_SetFlags (
     m_Strain.clear();
 
     m_IsUnverified = false;
+    m_IsPseudogene = false;
     m_TargetedLocus.clear();
 
     m_rEnzyme.clear();
@@ -564,9 +565,10 @@ void CDeflineGenerator::x_SetFlags (
         fGenbank = 1 << 3,
         fEmbl    = 1 << 4,
         fTitle   = 1 << 5,
-        fPdb     = 1 << 6
+        fPdb     = 1 << 6,
+        fComment = 1 << 7
     };
-    int needed_desc_choices = fMolinfo | fUser | fSource | fGenbank | fEmbl;
+    int needed_desc_choices = fMolinfo | fUser | fSource | fGenbank | fEmbl | fComment;
 
     CSeqdesc_CI::TDescChoices desc_choices;
     desc_choices.reserve(7);
@@ -577,6 +579,7 @@ void CDeflineGenerator::x_SetFlags (
     // determining m_HTGTech requires a descriptor scan.
     desc_choices.push_back(CSeqdesc::e_Genbank);
     desc_choices.push_back(CSeqdesc::e_Embl);
+    desc_choices.push_back(CSeqdesc::e_Comment);
     if (! m_Reconstruct) {
         needed_desc_choices |= fTitle;
         desc_choices.push_back(CSeqdesc::e_Title);
@@ -676,6 +679,20 @@ void CDeflineGenerator::x_SetFlags (
             break;
         }
 
+        case CSeqdesc::e_Comment:
+        {
+            // process comment
+            if ((needed_desc_choices & fComment) == 0) {
+                continue; // already covered
+            }
+
+            const string& comment = desc_it->GetComment();
+            if (NStr::Find (comment, "[CAUTION] Could be the product of a pseudogene") != string::npos) {
+                m_IsPseudogene = true;
+            }
+            break;
+        }
+
         case CSeqdesc::e_Source:
             if ((needed_desc_choices & fSource) != 0) {
                 m_Source.Reset(&desc_it->GetSource());
@@ -1502,6 +1519,8 @@ CConstRef<CSeq_feat> CDeflineGenerator::x_GetLongestProtein (
     return CConstRef<CSeq_feat> ();
 }
 
+// m_LocalAnnotsOnly test is unnecessary because feature iterator is built on local features only
+//  sqd-4081: it appears that test still does matter. reinstated and even more rigorously applied.
 CConstRef<CGene_ref> CDeflineGenerator::x_GetGeneRefViaCDS (
     const CMappedFeat& mapped_cds)
 
@@ -1567,8 +1586,18 @@ static CConstRef<CBioSource> x_GetSourceFeatViaCDS  (
         */
         cds_loc = &cds_feat->GetLocation();
         if (cds_loc) {
+            CRef<CSeq_loc> cleaned_location( new CSeq_loc );
+            cleaned_location->Assign( *cds_loc );
+            if (cleaned_location->IsSetStrand()  &&  IsReverse(cleaned_location->GetStrand())) {
+                CRef<CSeq_loc> rev_loc(SeqLocRevCmpl(*cleaned_location, &scope));
+                cleaned_location->Assign(*rev_loc);
+            }
+            /*
+            CConstRef<CSeq_feat> src_feat
+                = GetOverlappingSource (*cleaned_location, scope);
+            */
             CConstRef<CSeq_feat> src_feat
-                = GetOverlappingSource (*cds_loc, scope);
+                = GetBestOverlappingFeat (*cleaned_location, CSeqFeatData::eSubtype_biosrc, eOverlap_SubsetRev, scope);
             if (src_feat) {
                 const CSeq_feat& feat = *src_feat;
                 if (feat.IsSetData()) {
@@ -1785,12 +1814,12 @@ void CDeflineGenerator::x_SetTitleFromProtein (
                 }
             }
         }
-        if (m_MainTitle.empty()) {
+        if (m_MainTitle.empty()  &&  !m_LocalAnnotsOnly) {
             if (prp.IsSetDesc()) {
                 m_MainTitle = prp.GetDesc();
             }
         }
-        if (m_MainTitle.empty()) {
+        if (m_MainTitle.empty()  &&  !m_LocalAnnotsOnly) {
             FOR_EACH_ACTIVITY_ON_PROT (act_itr, prp) {
                 const string& str = *act_itr;
                 m_MainTitle = str;
@@ -1824,20 +1853,18 @@ void CDeflineGenerator::x_SetTitleFromProtein (
         }
     }
 
-    if (m_MainTitle.empty()) {
+    if (m_MainTitle.empty()  &&  !m_LocalAnnotsOnly) {
         m_MainTitle = "unnamed protein product";
-        if (!m_LocalAnnotsOnly) {
-            gene = x_GetGeneRefViaCDS (mapped_cds);
-            if (gene) {
-                const CGene_ref& grp = *gene;
-                if (grp.IsSetLocus_tag()) {
-                    locus_tag = grp.GetLocus_tag();
-                }
-            }
-            if (! locus_tag.empty()) {
-                m_MainTitle += " " + string(locus_tag);
+        gene = x_GetGeneRefViaCDS (mapped_cds);
+        if (gene) {
+            const CGene_ref& grp = *gene;
+            if (grp.IsSetLocus_tag()) {
+                locus_tag = grp.GetLocus_tag();
             }
         }
+        if (! locus_tag.empty()) {
+            m_MainTitle += " " + string(locus_tag);
+        }
     }
 
     if (mapped_cds) {
@@ -2133,6 +2160,10 @@ void CDeflineGenerator::x_SetPrefix (
         }
     } else if (m_Multispecies && m_IsWP) {
         prefix = "MULTISPECIES: ";
+    } else if (m_IsPseudogene) {
+        if (m_MainTitle.find ("PUTATIVE PSEUDOGENE") == NPOS) {
+            prefix = "PUTATIVE PSEUDOGENE: ";
+        }
     }
 }
 
diff --git a/c++/src/objmgr/util/feature.cpp b/c++/src/objmgr/util/feature.cpp
index fbc0f0f..6719334 100644
--- a/c++/src/objmgr/util/feature.cpp
+++ b/c++/src/objmgr/util/feature.cpp
@@ -1,4 +1,4 @@
-/*  $Id: feature.cpp 499447 2016-04-26 14:17:39Z ivanov $
+/*  $Id: feature.cpp 517781 2016-10-27 16:29:06Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -106,8 +106,12 @@ void s_GetTypeLabel(const CSeq_feat& feat, string* label, TFeatLabelFlags flags)
     
     // Determine typelabel
     CSeqFeatData::ESubtype idx = feat.GetData().GetSubtype();
-    if ( idx != CSeqFeatData::eSubtype_bad ) {
-        tlabel = feat.GetData().GetKey();
+    if (idx != CSeqFeatData::eSubtype_bad) {
+        if (feat.GetData().IsProt() && idx != CSeqFeatData::eSubtype_prot) {
+            tlabel = feat.GetData().GetKey(CSeqFeatData::eVocabulary_genbank);
+        } else {
+            tlabel = feat.GetData().GetKey();
+        }
         if (feat.GetData().IsImp()) {
             if ( tlabel == "variation" ) {
                 tlabel = "Variation";
@@ -458,7 +462,7 @@ static bool s_GetImpLabel
         // else if the key is repeat_unit or repeat_region
         } else if (NStr::EqualNocase(key, "repeat_unit")  ||
                    NStr::EqualNocase(key, "repeat_region")) {
-            if (feat.IsSetQual()) {
+            if (feat.IsSetQual() && (0 == (flags & fFGL_NoQualifiers))) {
                 // Loop thru the feature qualifiers
                 const CSeq_feat_Base::TQual & qual = feat.GetQual(); // must store reference since ITERATE macro evaluates 3rd arg multiple times
                 ITERATE( CSeq_feat::TQual, it, qual ) {
@@ -477,7 +481,7 @@ static bool s_GetImpLabel
             }
         // else if the key is STS
         } else if (NStr::EqualNocase(key, "STS")) {
-            if (feat.IsSetQual()) {
+            if (feat.IsSetQual() && (0 == (flags & fFGL_NoQualifiers))) {
                 const CSeq_feat_Base::TQual & qual = feat.GetQual(); // must store reference since ITERATE macro evaluates 3rd arg multiple times
                 ITERATE( CSeq_feat::TQual, it, qual ) {
                     if (NStr::EqualNocase((*it)->GetQual(),"standard_name"))
@@ -503,8 +507,8 @@ static bool s_GetImpLabel
                 }
             }
         // else if the key is misc_feature
-        } else if (NStr::EqualNocase(key, "misc_feature")) {
-            if (feat.IsSetQual()) {
+        } else if (!NStr::EqualNocase(key, "misc_feature")) {
+            if (feat.IsSetQual() && (0 == (flags & fFGL_NoQualifiers))) {
                 // Look for a single qualifier qual in order of preference 
                 // "standard_name", "function", "number", any and
                 // append to tlabel and return if found
@@ -540,7 +544,7 @@ static bool s_GetImpLabel
                     return false;
                 }
             }
-        }
+        } 
     } 
     return false;                
 }
@@ -702,12 +706,12 @@ void s_GetContentLabel
     }
     
     // Put Seq-feat qual into label
-    if (feat.IsSetQual()) {
+    if (feat.IsSetQual() && (0 == (flags & fFGL_NoQualifiers))) {
         string prefix("/");
         const CSeq_feat_Base::TQual & qual = feat.GetQual(); // must store reference since ITERATE macro evaluates 3rd arg multiple times
         ITERATE( CSeq_feat::TQual, it, qual ) {
             tlabel += prefix + (**it).GetQual();
-            prefix = " ";
+            prefix = " /";
             if (!(**it).GetVal().empty()) {
                 tlabel += "=" + (**it).GetVal();
             }
@@ -1040,6 +1044,12 @@ struct STypeLink
     bool CanHaveGeneParent(void) const;
     bool CanHaveCommonGene(void) const;
 
+    // special cdregion to mRNA/VDJ_segment/C_range link
+    const CSeqFeatData::ESubtype* GetMultiParentTypes() const;
+    
+    // check for overlap by intervals
+    bool OverlapByIntervals() const;
+
     CSeqFeatData::ESubtype m_StartType;   // initial feature type
     CSeqFeatData::ESubtype m_CurrentType; // current link child type
     CSeqFeatData::ESubtype m_ParentType;  // current link parent type
@@ -1080,6 +1090,9 @@ STypeLink::STypeLink(CSeqFeatData::ESubtype subtype,
         m_ByProduct = true;
         m_ParentType = CSeqFeatData::eSubtype_cdregion;
         break;
+    case CSeqFeatData::eSubtype_ncRNA:
+        m_ParentType = CSeqFeatData::eSubtype_preRNA;
+        break;
     default:
         m_ParentType = CSeqFeatData::eSubtype_gene;
         break;
@@ -1099,6 +1112,35 @@ inline bool STypeLink::CanHaveCommonGene(void) const
 }
 
 
+const CSeqFeatData::ESubtype* STypeLink::GetMultiParentTypes() const
+{
+    if ( !m_ByProduct &&
+         m_StartType == CSeqFeatData::eSubtype_cdregion &&
+         m_CurrentType == CSeqFeatData::eSubtype_cdregion &&
+         m_ParentType == CSeqFeatData::eSubtype_mRNA ) {
+        // cdregion to mRNA can also link to C_region or VDJ_segment
+        static const CSeqFeatData::ESubtype sm_SpecialVDJTypes[] = {
+            CSeqFeatData::eSubtype_mRNA,
+            CSeqFeatData::eSubtype_C_region,
+            CSeqFeatData::eSubtype_V_segment,
+            CSeqFeatData::eSubtype_D_segment,
+            CSeqFeatData::eSubtype_J_segment,
+            CSeqFeatData::eSubtype_bad
+        };
+        return sm_SpecialVDJTypes;
+    }
+    return 0;
+}
+
+
+inline bool STypeLink::OverlapByIntervals() const
+{
+    return ( m_StartType == CSeqFeatData::eSubtype_cdregion &&
+             m_CurrentType == CSeqFeatData::eSubtype_cdregion &&
+             m_ParentType == CSeqFeatData::eSubtype_mRNA );
+}
+
+
 void STypeLink::Next(void)
 {
     if ( m_CurrentType == CSeqFeatData::eSubtype_prot ) {
@@ -1244,6 +1286,10 @@ namespace {
     {
         return
             type == CSeqFeatData::eSubtype_mRNA ||
+            type == CSeqFeatData::eSubtype_C_region ||
+            type == CSeqFeatData::eSubtype_V_segment ||
+            type == CSeqFeatData::eSubtype_D_segment ||
+            type == CSeqFeatData::eSubtype_J_segment ||
             type == CSeqFeatData::eSubtype_cdregion;
     }
 
@@ -1271,8 +1317,8 @@ namespace {
                 return false;
             }
             CConstRef<CSeq_feat> f = feat.GetSeq_feat();
-            const CSeq_feat::TQual& qual = f->GetQual();
-            ITERATE ( CSeq_feat::TQual, it, qual ) {
+            const CSeq_feat::TQual& quals = f->GetQual();
+            ITERATE ( CSeq_feat::TQual, it, quals ) {
                 if ( (*it)->IsSetVal() ) {
                     const string& qual = (*it)->GetQual();
                     if ( qual == kQual_orig_protein_id ||
@@ -1295,8 +1341,8 @@ namespace {
                 return;
             }
             CConstRef<CSeq_feat> f = feat.GetSeq_feat();
-            const CSeq_feat::TQual& qual = f->GetQual();
-            ITERATE ( CSeq_feat::TQual, it, qual ) {
+            const CSeq_feat::TQual& quals = f->GetQual();
+            ITERATE ( CSeq_feat::TQual, it, quals ) {
                 if ( (*it)->IsSetVal() ) {
                     const string& qual = (*it)->GetQual();
                     if ( qual == kQual_orig_protein_id ) {
@@ -1349,9 +1395,7 @@ namespace {
                                    TSeqPos circular_length)
     {
         EOverlapType overlap_type = eOverlap_Contained;
-        if ( link.m_StartType == CSeqFeatData::eSubtype_cdregion &&
-             link.m_CurrentType == CSeqFeatData::eSubtype_cdregion &&
-             link.m_ParentType == CSeqFeatData::eSubtype_mRNA ) {
+        if ( link.OverlapByIntervals() ) {
             overlap_type = eOverlap_CheckIntervals;
         }
         if ( link.m_ParentType == CSeqFeatData::eSubtype_gene &&
@@ -1382,6 +1426,7 @@ namespace {
     {
         if ( feat_type != parent_type ) {
             for ( STypeLink link(feat_type); link; ++link ) {
+                // TODO: VDJ
                 if ( link.m_ParentType == parent_type ) {
                     return true;
                 }
@@ -1430,10 +1475,17 @@ namespace {
             if ( xref.IsSetId() ) {
                 const CFeat_id& id = xref.GetId();
                 if ( id.IsLocal() ) {
-                    CSeq_feat_Handle feat1 =
-                        tse.GetFeatureWithId(link.m_ParentType, id.GetLocal());
-                    if ( feat1 ) {
-                        return feat1;
+                    if ( const CSeqFeatData::ESubtype* type_ptr = link.GetMultiParentTypes() ) {
+                        for ( ; *type_ptr != CSeqFeatData::eSubtype_bad; ++type_ptr ) {
+                            if ( CSeq_feat_Handle feat1 = tse.GetFeatureWithId(*type_ptr, id.GetLocal()) ) {
+                                return feat1;
+                            }
+                        }
+                    }
+                    else {
+                        if ( CSeq_feat_Handle feat1 = tse.GetFeatureWithId(link.m_ParentType, id.GetLocal()) ) {
+                            return feat1;
+                        }
                     }
                 }
             }
@@ -1467,6 +1519,11 @@ namespace {
     
         Int8 best_overlap = kMax_I8;
         SAnnotSelector sel(link.m_ParentType);
+        if ( const CSeqFeatData::ESubtype* type_ptr = link.GetMultiParentTypes() ) {
+            for ( ; *type_ptr != CSeqFeatData::eSubtype_bad; ++type_ptr ) {
+                sel.IncludeFeatSubtype(*type_ptr);
+            }
+        }
         sel.SetByProduct(link.m_ByProduct);
         for (CFeat_CI it(feat.GetScope(), c_loc, sel); it; ++it) {
             Int8 overlap = TestForOverlap64(it->GetLocation(),
@@ -1490,8 +1547,8 @@ namespace {
 ///   parent-child relationship:
 ///   1.1. operon, gap cannot have a parent,
 ///   1.2. gene can have operon as a parent,
-///   1.3. mRNA can have gene as a parent,
-///   1.4. cdregion can have mRNA as a parent,
+///   1.3. mRNA, VDJ_segment, and C_region can have gene as a parent,
+///   1.4. cdregion can have mRNA, VDJ_segment, or C_region as a parent,
 ///   1.5. prot can have cdregion as a parent (by its product location),
 ///   1.6. mat_peptide, sig_peptide can have prot as a parent,
 ///   1.x. all other feature types can have gene as a parent.
@@ -1552,6 +1609,10 @@ namespace {
                     m_Info = info;
                 }
             }
+        void CheckBest(const SBestInfo& b)
+            {
+                CheckBest(b.m_Quality, b.m_Overlap, b.m_Info);
+            }
 
         Int1 m_Quality;
         Int8 m_Overlap;
@@ -2200,7 +2261,7 @@ static void s_CollectBestOverlaps(CFeatTree::TFeatArray& features,
                         overlap = -1;
                     }
                     if ( overlap >= 0 ) {
-                        ci->m_Best->CheckBest(quality-1, overlap, pc->m_Info);
+                        ci->m_Best->CheckBest((Int1)(quality-1), overlap, pc->m_Info);
                     }
                 }
             }
@@ -2241,12 +2302,36 @@ void CFeatTree::x_AssignParentsByOverlap(TFeatArray& features,
     if ( !m_Index ) {
         m_Index = new CFeatTreeIndex;
     }
-    TRangeArray& parents = m_Index->GetIndex(link, m_InfoArray);
-    if ( parents.empty() ) {
-        return;
-    }
+    // TODO: multi-children/multi-parent assignment
     TBestArray bests;
-    s_CollectBestOverlaps(features, bests, link, parents, this);
+    if ( const CSeqFeatData::ESubtype* type_ptr = link.GetMultiParentTypes() ) {
+        for ( ; *type_ptr != CSeqFeatData::eSubtype_bad; ++type_ptr ) {
+            TRangeArray& parents = m_Index->GetIndex(*type_ptr, link.m_ByProduct, m_InfoArray);
+            if ( parents.empty() ) {
+                continue;
+            }
+            TBestArray bests1;
+            s_CollectBestOverlaps(features, bests1, link, parents, this);
+            if ( bests.empty() ) {
+                swap(bests, bests1);
+            }
+            else {
+                for ( size_t i = 0; i < bests1.size(); ++i ) {
+                    bests[i].CheckBest(bests1[i]);
+                }
+            }
+        }
+        if ( bests.empty() ) {
+            return;
+        }
+    }
+    else {
+        TRangeArray& parents = m_Index->GetIndex(link, m_InfoArray);
+        if ( parents.empty() ) {
+            return;
+        }
+        s_CollectBestOverlaps(features, bests, link, parents, this);
+    }
     size_t cnt = features.size();
     _ASSERT(bests.size() == cnt);
 
@@ -2626,9 +2711,15 @@ void CFeatTree::AddFeaturesFor(CScope& scope, const CSeq_loc& loc,
     }
     if ( top_type != bottom_type ) {
         for ( STypeLink link(bottom_type); link; ++link ) {
-            CSeqFeatData::ESubtype parent_type = link.m_ParentType;
-            sel.IncludeFeatSubtype(parent_type);
-            if ( parent_type == top_type ) {
+            if ( const CSeqFeatData::ESubtype* type_ptr = link.GetMultiParentTypes() ) {
+                for ( ; *type_ptr != CSeqFeatData::eSubtype_bad; ++type_ptr ) {
+                    sel.IncludeFeatSubtype(*type_ptr);
+                }
+            }
+            else {
+                sel.IncludeFeatSubtype(link.m_ParentType);
+            }
+            if ( link.m_ParentType == top_type ) {
                 break;
             }
         }
@@ -2913,7 +3004,7 @@ typedef vector<TMappedFeatScore> TMappedFeatScores;
 
 static
 void GetOverlappingFeatures(CScope& scope, const CSeq_loc& loc,
-                            CSeqFeatData::E_Choice feat_type,
+                            CSeqFeatData::E_Choice /*feat_type*/,
                             CSeqFeatData::ESubtype feat_subtype,
                             sequence::EOverlapType overlap_type,
                             TMappedFeatScores& feats,
@@ -2981,10 +3072,10 @@ void GetOverlappingFeatures(CScope& scope, const CSeq_loc& loc,
                 single_id = 0;
             }
             if ( single_id ) {
-                CBioseq_Handle h = scope.GetBioseqHandle(*single_id);
-                if ( h && h.IsSetInst_Topology() &&
-                     h.GetInst_Topology() == CSeq_inst::eTopology_circular ) {
-                    circular_length = h.GetBioseqLength();
+                CBioseq_Handle h1 = scope.GetBioseqHandle(*single_id);
+                if ( h1 && h1.IsSetInst_Topology() &&
+                     h1.GetInst_Topology() == CSeq_inst::eTopology_circular ) {
+                    circular_length = h1.GetBioseqLength();
                 }
             }
         }
@@ -3263,6 +3354,11 @@ ELocationInFrame IsLocationInFrame (const CSeq_feat_Handle& cds, const CSeq_loc&
         return eLocationInFrame_NotIn;
     }
 
+    sequence::ECompare cmp = sequence::Compare(cds.GetLocation(), loc, &(cds.GetScope()));
+    if (cmp != sequence::eContains && cmp != sequence::eSame) {
+        return eLocationInFrame_NotIn;
+    }
+
     unsigned int frame = 0;
     if (cds.IsSetData() && cds.GetData().IsCdregion()) {
         const CCdregion& cdr = cds.GetData().GetCdregion();
@@ -3336,8 +3432,13 @@ bool PromoteCDSToNucProtSet(objects::CSeq_feat_Handle& orig_feat)
     if (orig_feat.IsSetPseudo() && orig_feat.GetPseudo()) {
         return false;
     }
-    CBioseq_Handle nuc_bsh = orig_feat.GetScope().GetBioseqHandle(orig_feat.GetLocation());
-    if (!nuc_bsh) {
+    CBioseq_Handle nuc_bsh;
+    try {
+        nuc_bsh = orig_feat.GetScope().GetBioseqHandle(orig_feat.GetLocation());
+        if (!nuc_bsh) {
+            return false;
+        }
+    } catch (...) {
         return false;
     }
 
@@ -3370,8 +3471,8 @@ bool PromoteCDSToNucProtSet(objects::CSeq_feat_Handle& orig_feat)
             if (!ftable) {
                 CRef<CSeq_annot> new_annot(new CSeq_annot());
                 new_annot->SetData().SetFtable();
-                CSeq_entry_EditHandle eh = parent_seh.GetEditHandle();
-                ftable = eh.AttachAnnot(*new_annot);
+                CSeq_entry_EditHandle h = parent_seh.GetEditHandle();
+                ftable = h.AttachAnnot(*new_annot);
             }
 
             CSeq_annot_EditHandle old_annot = annot_handle.GetEditHandle();
@@ -3613,7 +3714,7 @@ bool sFeatureGetChildrenOfSubtypeFaster(
     feature::CFeatTree& featTree)
 //  ----------------------------------------------------------------------------
 {
-    const CSeq_feat& ff = mf.GetOriginalFeature();
+    //const CSeq_feat& ff = mf.GetOriginalFeature();
 
     vector<CMappedFeat> c = featTree.GetChildren(mf);
     for (vector<CMappedFeat>::iterator it = c.begin(); it != c.end(); it++) {
@@ -3636,7 +3737,7 @@ bool sFeatureGetChildrenOfSubtype(
     vector<CMappedFeat>& children)
 //  ----------------------------------------------------------------------------
 {
-    const CSeq_feat& ff = mf.GetOriginalFeature();
+    //const CSeq_feat& ff = mf.GetOriginalFeature();
     feature::CFeatTree myTree;
     myTree.AddFeaturesFor(mf, subtype, mf.GetFeatSubtype());
 
@@ -3770,13 +3871,19 @@ bool sGetFeatureGeneBiotypeWrapper(
             biotype = "ncRNA";
             return true;
         }
-        string rnaClass = ext.GetGen().GetClass();
-        if (rnaClass == "other") {
+        if (ext.IsGen()  &&  ext.GetGen().IsSetClass()) {
+            string rnaClass = ext.GetGen().GetClass();
+            if (rnaClass == "other") {
+                biotype = "ncRNA";
+                return true;
+            }
+            biotype = rnaClass;
+            return true;
+        }
+        else {
             biotype = "ncRNA";
             return true;
         }
-        biotype = rnaClass;
-        return true;
     }
 
     //2b
diff --git a/c++/src/objmgr/util/obj_sniff.cpp b/c++/src/objmgr/util/obj_sniff.cpp
index 1364221..4cd0d19 100644
--- a/c++/src/objmgr/util/obj_sniff.cpp
+++ b/c++/src/objmgr/util/obj_sniff.cpp
@@ -1,4 +1,4 @@
-/*  $Id: obj_sniff.cpp 464944 2015-04-15 15:49:50Z vasilche $
+/*  $Id: obj_sniff.cpp 518489 2016-11-03 16:06:30Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -127,7 +127,8 @@ CObjectsSniffer::CObjectsSniffer(void)
     : m_TopLevelObjectCount(0),
       m_StreamPos(0),
       m_DiscardCurrObj(false),
-      m_DiscardObjInfo(false)
+      m_DiscardObjInfo(false),
+      m_ReportErrors(false)
 {
 }
 
@@ -175,6 +176,7 @@ void CObjectsSniffer::Probe(CObjectIStream& input)
     m_TopLevelObjectCount = 0;
     m_TopLevelMap.clear();
 
+#if 0
     if ( input.GetDataFormat() == eSerial_AsnText ||
          input.GetDataFormat() == eSerial_Xml ) {
         ProbeText(input);
@@ -182,6 +184,9 @@ void CObjectsSniffer::Probe(CObjectIStream& input)
     else {
         ProbeASN1_Bin(input);
     }
+#else
+    ProbeAny(input);
+#endif
 
     //
     // Reset(clean) the hooks
@@ -194,7 +199,7 @@ void CObjectsSniffer::Probe(CObjectIStream& input)
 
 
 inline
-void CObjectsSniffer::x_ReadObject(CObjectIStream& input,
+bool CObjectsSniffer::x_ReadObject(CObjectIStream& input,
                                    CObjectTypeInfo type_info)
 {
     CObjectInfo object_info(type_info);
@@ -203,6 +208,7 @@ void CObjectsSniffer::x_ReadObject(CObjectIStream& input,
     if ( !GetDiscardObjectInfo() ) {
         m_TopLevelMap.push_back(SObjectDescription(type_info, m_StreamPos));
     }
+    return true;
 }
 
 
@@ -214,7 +220,7 @@ bool CObjectsSniffer::x_TryReadObject(CObjectIStream& input,
         x_ReadObject(input, object_info);
         return true;
     }
-    catch ( CSerialException& /*ignored*/ ) {
+    catch ( CException& /*ignored*/ ) {
         input.SetStreamPos(m_StreamPos);
         Reset();
         return false;
@@ -330,6 +336,67 @@ void CObjectsSniffer::ProbeASN1_Bin(CObjectIStream& input)
     }
 }
 
+void CObjectsSniffer::ProbeAny(CObjectIStream& input)
+{
+    string format_name("Unknown format");  // for LOG_POST messages
+    switch (input.GetDataFormat())
+    {
+    case eSerial_AsnText:   format_name = "ASN.1 text";   break;
+    case eSerial_AsnBinary: format_name = "ASN.1 binary"; break;
+    case eSerial_Xml:       format_name = "XML";          break;
+    case eSerial_Json:      format_name = "JSON";         break;
+    default:  break;
+    }
+    set<TTypeInfo> known_types;
+    for ( const SCandidateInfo& c : m_Candidates ) {
+        known_types.insert( c.type_info.GetTypeInfo());
+    }
+    string tname;
+
+    try {
+        for ( ; !input.EndOfData(); ) {
+            set<TTypeInfo> matching_types = input.GuessDataType(known_types);
+            set<TTypeInfo>& candidates = matching_types.empty() ? known_types : matching_types;
+            bool report = m_ReportErrors && matching_types.size() == 1;
+            input.ReadFileHeader();
+            m_StreamPos = input.GetStreamPos();
+
+            bool found = false;
+            for (const TTypeInfo& type_info : candidates) {
+                tname = type_info->GetName();
+                found = (report && x_ReadObject(input, type_info)) ||
+                                x_TryReadObject(input, type_info);
+                if ( found ) {
+                    LOG_POST_X(2, Info 
+                                << format_name << " top level object found: "
+                                << type_info->GetName());
+                    break;
+                }
+            }
+            if ( !found ) {
+                // no matching candidate
+                break;
+            }
+        }
+    }
+    catch ( CEofException& /*ignored*/ ) {
+        // no more objects
+        return;
+    }
+    catch ( bad_alloc& /*rethrown*/ ) {
+        // no more memory
+        input.SetStreamPos(m_StreamPos);
+        throw;
+    }
+    catch ( exception& e ) {
+        input.SetStreamPos(m_StreamPos);
+        LOG_POST_X(3, Info << "Exception reading "
+                   << format_name << " " << e.what());
+        throw;
+    }
+
+}
+
 
 END_SCOPE(objects)
 END_NCBI_SCOPE
diff --git a/c++/src/objmgr/util/objutil.cpp b/c++/src/objmgr/util/objutil.cpp
index 4dd7c34..dff15ec 100644
--- a/c++/src/objmgr/util/objutil.cpp
+++ b/c++/src/objmgr/util/objutil.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objutil.cpp 487384 2015-12-17 13:38:09Z ivanov $
+/*  $Id: objutil.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -837,7 +837,7 @@ void CleanAndCompress(string& dest, const CTempString& instr)
     while (left > 0) {
         next = *in++;
 
-        two_chars = (two_chars << 8) | next;
+        two_chars = Uint2((two_chars << 8) | next);
 
         switch (two_chars)
         {
@@ -1541,8 +1541,9 @@ static const char* kAANames[] = {
 const char* GetAAName(unsigned char aa, bool is_ascii)
 {
     if (is_ascii) {
-        aa = CSeqportUtil::GetMapToIndex
-            (CSeq_data::e_Ncbieaa, CSeq_data::e_Ncbistdaa, aa);
+        aa = (unsigned char)
+             CSeqportUtil::GetMapToIndex(CSeq_data::e_Ncbieaa,
+                                         CSeq_data::e_Ncbistdaa, aa);
     }
     return (aa < sizeof(kAANames)/sizeof(*kAANames)) ? kAANames[aa] : "OTHER";
 }
@@ -1620,7 +1621,7 @@ const string strLinkBaseProt(
     "https://www.ncbi.nlm.nih.gov/protein/" );
 
 const string strLinkBaseEntrezViewer(
-    "http://www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?val=" ); // https forwarded to http
+    "https://www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?val=" ); // https forwarded to http
 
 const string strLinkBaseTaxonomy( 
     "https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?" );
@@ -1784,7 +1785,7 @@ void TryToSanitizeHtml(string &str)
     string result;
     // The "* 1.1" should keep up efficient in most cases since data tends not to have
     // too many characters that need escaping.
-    result.reserve(1 + (int)(str.length() * 1.1));
+    result.reserve(1 + (int)((double)str.length() * 1.1));
     TryToSanitizeHtml(result, str);
 
     // swap is faster than assignment
diff --git a/c++/src/objmgr/util/seq_loc_util.cpp b/c++/src/objmgr/util/seq_loc_util.cpp
index 05b2115..63effb7 100644
--- a/c++/src/objmgr/util/seq_loc_util.cpp
+++ b/c++/src/objmgr/util/seq_loc_util.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_loc_util.cpp 497817 2016-04-11 14:48:09Z ivanov $
+/*  $Id: seq_loc_util.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -960,7 +960,7 @@ int SeqLocPartialCheck(const CSeq_loc& loc, CScope* scope)
 //  Implementation of SeqLocRevCmpl()
 //
 
-CSeq_loc* SeqLocRevCmpl(const CSeq_loc& loc, CScope* scope)
+CSeq_loc* SeqLocRevCmpl(const CSeq_loc& loc, CScope*)
 {
     CReverseComplementHelper helper;
     return GetReverseComplement( loc, &helper );
@@ -1020,8 +1020,8 @@ void s_SeqLocToRangeInfoMap(const CSeq_loc& loc,
         CSeq_id_Handle id = s_GetSynHandle(it.GetSeq_id_Handle(), syns, scope);
         infos[id].push_back(info);
     }
-    NON_CONST_ITERATE(TRangeInfoMap, it, infos) {
-        it->second.sort();
+    NON_CONST_ITERATE(TRangeInfoMap, info, infos) {
+        info->second.sort();
     }
 }
 
@@ -1331,9 +1331,9 @@ void s_SeqLocToRangeInfoMapByStrand(const CSeq_loc&         loc,
             infos[id].first.push_back(info);
         }
     }
-    NON_CONST_ITERATE(TRangeInfoMapByStrand, it, infos) {
-        it->second.first.sort();
-        it->second.second.sort();
+    NON_CONST_ITERATE(TRangeInfoMapByStrand, info, infos) {
+        info->second.first.sort();
+        info->second.second.sort();
     }
 }
 
@@ -1348,7 +1348,7 @@ typedef map<CSeq_id_Handle, STopologyInfo> TTopologyMap;
 
 STopologyInfo s_GetTopology(CSeq_id_Handle idh,
                             TTopologyMap&  topologies,
-                            EOverlapFlags flags,
+                            TOverlapFlags flags,
                             CScope*       scope)
 {
     TTopologyMap::const_iterator found = topologies.find(idh);
@@ -1379,7 +1379,7 @@ void s_SeqLocToTotalRangesInfoMapByStrand(const CSeq_loc&         loc,
                                           TRangeInfoMapByStrand&  infos,
                                           TSynMap&                syns,
                                           TTopologyMap&           topologies,
-                                          EOverlapFlags           flags,
+                                          TOverlapFlags           flags,
                                           CScope*                 scope)
 {
     CSeq_loc_CI it(loc,
@@ -1462,9 +1462,9 @@ void s_SeqLocToTotalRangesInfoMapByStrand(const CSeq_loc&         loc,
             infos[last_id].first.push_back(total_range);
         }
     }
-    NON_CONST_ITERATE(TRangeInfoMapByStrand, it, infos) {
-        it->second.first.sort();
-        it->second.second.sort();
+    NON_CONST_ITERATE(TRangeInfoMapByStrand, info, infos) {
+        info->second.first.sort();
+        info->second.second.sort();
     }
 }
 
@@ -1650,7 +1650,7 @@ Int8 s_Test_Extremes(const CSeq_loc& loc1,
                      EOverlapType    type,
                      TSynMap&        syns,
                      TTopologyMap&   topologies,
-                     EOverlapFlags   flags,
+                     TOverlapFlags   flags,
                      CScope*         scope)
 {
     // Here we accept only two overlap types.
@@ -1752,7 +1752,7 @@ Int8 s_Test_Interval(const CSeq_loc& loc1,
                      const CSeq_loc& loc2,
                      TSynMap&        syns,
                      TTopologyMap&   topologies,
-                     EOverlapFlags   flags,
+                     TOverlapFlags   flags,
                      CScope*         scope)
 {
     TRangeInfoMapByStrand ranges1, ranges2;
@@ -1808,7 +1808,7 @@ Int8 s_Test_Interval(const CSeq_loc& loc1,
 Int8 s_TestForOverlapEx(const CSeq_loc& loc1,
                         const CSeq_loc& loc2,
                         EOverlapType    type,
-                        EOverlapFlags   flags,
+                        TOverlapFlags   flags,
                         TSeqPos         circular_len,
                         CScope*         scope)
 {
@@ -1955,7 +1955,7 @@ Int8 TestForOverlapEx(const CSeq_loc& loc1,
                       const CSeq_loc& loc2,
                       EOverlapType    type,
                       CScope*         scope,
-                      EOverlapFlags   flags)
+                      TOverlapFlags   flags)
 {
     return s_TestForOverlapEx(loc1, loc2, type, flags, kInvalidSeqPos, scope);
 }
diff --git a/c++/src/objmgr/util/seqtitle.cpp b/c++/src/objmgr/util/seqtitle.cpp
index 27c4ec7..4dc00fc 100644
--- a/c++/src/objmgr/util/seqtitle.cpp
+++ b/c++/src/objmgr/util/seqtitle.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqtitle.cpp 485361 2015-11-20 17:03:51Z ucko $
+/*  $Id: seqtitle.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -972,7 +972,7 @@ static string s_TitleFromBioSource(const CBioSource& source,
     string title = NStr::TruncateSpaces(name + strain + chromosome + clone
                                         + map_ + plasmid + sfx);
     if ( !title.empty()  &&  islower((unsigned char) title[0])) {
-        title[0] = toupper((unsigned char) title[0]);
+        title[0] = (char)toupper((unsigned char) title[0]);
     }
 
     return title;
@@ -1179,7 +1179,7 @@ static string s_TitleFromChromosome(const CBioSource& source,
     result = NStr::Replace(result, "Plasmid", "plasmid");
     result = NStr::Replace(result, "Element", "element");
     if (!result.empty()) {
-        result[0] = toupper((unsigned char) result[0]);
+        result[0] = (char)toupper((unsigned char) result[0]);
     }
     return result;
 }
diff --git a/c++/src/objmgr/util/sequence.cpp b/c++/src/objmgr/util/sequence.cpp
index 3d63fbe..edf3028 100644
--- a/c++/src/objmgr/util/sequence.cpp
+++ b/c++/src/objmgr/util/sequence.cpp
@@ -1,4 +1,4 @@
-/*  $Id: sequence.cpp 499689 2016-04-27 17:17:49Z ivanov $
+/*  $Id: sequence.cpp 520790 2016-12-01 16:46:36Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -892,6 +892,7 @@ void GetOverlappingFeatures(const CSeq_loc& loc,
     }
 
     CConstRef<CSeq_feat> feat_ref;
+    TOverlapFlags overlap_flags = fOverlap_Default;
 
     CBioseq_Handle bioseq_handle;
     CRange<TSeqPos> range;
@@ -934,10 +935,10 @@ void GetOverlappingFeatures(const CSeq_loc& loc,
                 circular_id = 0;
             }
             if ( circular_id ) {
-                CBioseq_Handle bioseq_handle = scope.GetBioseqHandle(*circular_id);
-                if ( bioseq_handle && bioseq_handle.IsSetInst_Topology() &&
-                     bioseq_handle.GetInst_Topology() == CSeq_inst::eTopology_circular ) {
-                    circular_length = bioseq_handle.GetBioseqLength();
+                CBioseq_Handle bseq_handle = scope.GetBioseqHandle(*circular_id);
+                if ( bseq_handle && bseq_handle.IsSetInst_Topology() &&
+                     bseq_handle.GetInst_Topology() == CSeq_inst::eTopology_circular ) {
+                    circular_length = bseq_handle.GetBioseqLength();
                 }
             }
         }
@@ -1018,6 +1019,7 @@ void GetOverlappingFeatures(const CSeq_loc& loc,
         cleaned_loc->Assign( loc );
         if( opts & fBestFeat_IgnoreStrand ) {
             cleaned_loc->SetStrand(eNa_strand_plus);
+            overlap_flags |= fOverlap_IgnoreTopology;
         }
         if( plugin ) {
             plugin->processLoc( bioseq_handle, cleaned_loc, circular_length );
@@ -1052,17 +1054,40 @@ void GetOverlappingFeatures(const CSeq_loc& loc,
 
             try {
                 // treat subset as a special case
-                Int8 cur_diff = ( !revert_locations_this_iteration ) ?
-                    TestForOverlap64(*candidate_feat_loc,
-                    *cleaned_loc_this_iteration,
-                    overlap_type_this_iteration,
-                    circular_length,
-                    &scope) :
-                TestForOverlap64(*cleaned_loc_this_iteration,
-                    *candidate_feat_loc,
-                    overlap_type_this_iteration,
-                    circular_length,
-                    &scope);
+                Int8 cur_diff = -1;
+                if ( !revert_locations_this_iteration ) {
+                    if (overlap_flags == fOverlap_Default) {
+                        cur_diff = TestForOverlap64(*candidate_feat_loc,
+                            *cleaned_loc_this_iteration,
+                            overlap_type_this_iteration,
+                            circular_length,
+                            &scope);
+                    }
+                    else {
+                        cur_diff = TestForOverlapEx(*candidate_feat_loc,
+                            *cleaned_loc_this_iteration,
+                            overlap_type_this_iteration,
+                            &scope,
+                            overlap_flags);
+                    }
+                }
+                else {
+                    if (overlap_flags == fOverlap_Default) {
+                        cur_diff = TestForOverlap64(*cleaned_loc_this_iteration,
+                            *candidate_feat_loc,
+                            overlap_type_this_iteration,
+                            circular_length,
+                            &scope);
+                    }
+                    else {
+                        cur_diff = TestForOverlapEx(*cleaned_loc_this_iteration,
+                            *candidate_feat_loc,
+                            overlap_type_this_iteration,
+                            &scope,
+                            overlap_flags);
+                    }
+                }
+
                 if( plugin ) {
                     plugin->postProcessDiffAmount( cur_diff, cleaned_loc_this_iteration, 
                         candidate_feat_loc, scope, sel, circular_length );
@@ -1152,7 +1177,13 @@ CConstRef<CSeq_feat> GetmRNAforCDS(const CSeq_feat& cds, CScope& scope)
         /* using FeatID from feature cross-references:
         * if CDS refers to an mRNA by feature ID, use that feature
         */
-        CBioseq_Handle bsh = scope.GetBioseqHandle(cds.GetLocation());
+        CBioseq_Handle bsh;
+        try {
+            bsh = scope.GetBioseqHandle(cds.GetLocation());
+        } catch (CException& ex) {
+            // multi-accession location, can't do this check
+            return CConstRef<CSeq_feat>(NULL);
+        }
         CTSE_Handle tse = bsh.GetTSE_Handle();
         ITERATE(CSeq_feat::TXref, it, cds.GetXref()) {
             if ((*it)->IsSetId() && (*it)->GetId().IsLocal() && (*it)->GetId().GetLocal().IsId()) {
@@ -1241,24 +1272,174 @@ CConstRef<CSeq_feat> GetOverlappingGene(
     const CSeq_loc& loc, CScope& scope,
     ETransSplicing eTransSplicing )
 {
-    int opt = 0;
     switch ( eTransSplicing ) {
     case eTransSplicing_Auto:
         {
             ENa_strand strand = loc.GetStrand();
             if (strand == eNa_strand_both  ||  strand == eNa_strand_other) {
-                opt = fBestFeat_IgnoreStrand;
+                // Mixed strand indicates trans-splicing must be on.
+                return GetOverlappingGene(loc, scope, eTransSplicing_Yes);
             }
+            // Try with trans-splicing on first. If it finds nothing, try
+            // to turn it off.
+            CConstRef<CSeq_feat> ret = GetOverlappingGene(loc, scope, eTransSplicing_Yes);
+            return ret ? ret : GetOverlappingGene(loc, scope, eTransSplicing_No);
         }
-        break;
     case eTransSplicing_Yes:
-        opt = fBestFeat_IgnoreStrand;
-        break;
-    default:
-        break;
+        {
+            // If trans-splicing is on, the result must be a multi-range gene.
+            CConstRef<CSeq_feat> ret = GetBestOverlappingFeat(loc,
+                CSeqFeatData::eSubtype_gene,
+                eOverlap_Contained, scope, fBestFeat_IgnoreStrand);
+            if ( ret ) {
+                CSeq_loc_CI it(ret->GetLocation());
+                ++it;
+                if ( !it ) ret.Reset();
+            }
+            return ret;
+        }
+    case eTransSplicing_No:
+        {
+            // Multi-range genes assume trans-splicing=on and should not be included
+            // when it's off.
+            CConstRef<CSeq_feat> ret = GetBestOverlappingFeat(loc,
+                CSeqFeatData::eSubtype_gene,
+                eOverlap_Contained, scope, 0);
+            if ( ret ) {
+                CSeq_loc_CI it(ret->GetLocation());
+                ++it;
+                if ( it ) ret.Reset();
+            }
+            return ret;
+        }
     }
-    return GetBestOverlappingFeat(loc, CSeqFeatData::eSubtype_gene,
-        eOverlap_Contained, scope, opt);
+    return null;
+}
+
+
+bool IsTransSpliced(const CSeq_feat& feat)
+{
+    if (feat.IsSetExcept_text() && NStr::Find(feat.GetExcept_text(), "trans-splicing") != string::npos) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+
+bool IsPseudo(const CSeq_feat& feat, CScope& scope)
+{
+    if (feat.IsSetPseudo() && feat.GetPseudo()) {
+        return true;
+    }
+    if (feat.IsSetQual()) {
+        ITERATE(CSeq_feat::TQual, it, feat.GetQual()) {
+            if ((*it)->IsSetQual() && NStr::EqualNocase((*it)->GetQual(), "pseudogene")) {
+                return true;
+            }
+        }
+    }
+    if (feat.GetData().IsGene()) {
+        if (feat.GetData().GetGene().IsSetPseudo() && feat.GetData().GetGene().GetPseudo()) {
+            return true;
+        }
+    } else {
+        if (feat.IsSetXref()) {
+            ITERATE(CSeq_feat::TXref, it, feat.GetXref()) {
+                if ((*it)->IsSetData() && (*it)->GetData().IsGene() &&
+                    (*it)->GetData().GetGene().IsSetPseudo() &&
+                    (*it)->GetData().GetGene().GetPseudo()) {
+                    return true;
+                }
+            }
+        }
+        CConstRef<CSeq_feat> gene = GetGeneForFeature(feat, scope);
+        if (gene && IsPseudo(*gene, scope)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+
+CConstRef<CSeq_feat> GetLocalGeneByLocus(const string& locus, bool use_tag, CBioseq_Handle bsh)
+{
+    CTSE_Handle tse = bsh.GetTSE_Handle();
+    const CBioseq& b = *(bsh.GetCompleteBioseq());
+
+    CTSE_Handle::TSeq_feat_Handles potentials = tse.GetGenesWithLocus(locus, use_tag);
+    ITERATE(CTSE_Handle::TSeq_feat_Handles, p, potentials) {
+        ITERATE(CBioseq::TId, id, b.GetId()) {
+            CSeq_id::E_SIC cmp = p->GetLocationId().GetSeqId()->Compare(**id);
+            if (cmp == CSeq_id::e_YES) {
+                return p->GetSeq_feat();
+            } else if (cmp == CSeq_id::e_NO) {
+                break;
+            }
+        }
+    }
+    return CConstRef<CSeq_feat>(NULL);
+}
+
+
+CConstRef<CSeq_feat> GetLocalGeneByXref(const CGene_ref& gene, CBioseq_Handle bsh)
+{
+    if (gene.IsSetLocus_tag() && !(gene.GetLocus_tag().empty())) {
+        CConstRef<CSeq_feat> f = GetLocalGeneByLocus(gene.GetLocus_tag(), true, bsh);
+        if (f) {
+            return f;
+        }
+    }
+    if (gene.IsSetLocus() && !(gene.GetLocus().empty())) {
+        CConstRef<CSeq_feat> f = GetLocalGeneByLocus(gene.GetLocus(), false, bsh);
+        if (f) {
+            return f;
+        }
+    }
+    return CConstRef<CSeq_feat>(NULL);
+}
+
+
+CConstRef<CSeq_feat> GetGeneForFeature(const CSeq_feat& feat, CScope& scope)
+{
+    if (feat.IsSetXref()) {
+        CBioseq_Handle bsh = GetBioseqFromSeqLoc(feat.GetLocation(), scope);
+        if (!bsh) {
+            return CConstRef<CSeq_feat>();
+        }
+        CTSE_Handle tse = bsh.GetTSE_Handle();
+        ITERATE(CSeq_feat::TXref, xit, feat.GetXref()) {
+            if ((*xit)->IsSetData() && (*xit)->GetData().IsGene() && (*xit)->GetData().GetGene().IsSuppressed()) {
+                return (CConstRef <CSeq_feat>());
+            }
+            if ((*xit)->IsSetId() && (*xit)->GetId().IsLocal() &&
+                (!(*xit)->IsSetData() || (*xit)->GetData().IsGene())) {
+                const CTSE_Handle::TFeatureId& feat_id = (*xit)->GetId().GetLocal();
+                CTSE_Handle::TSeq_feat_Handles far_feats = tse.GetFeaturesWithId(CSeqFeatData::eSubtype_gene, feat_id);
+                if (far_feats.size() > 0) {
+                    return far_feats.front().GetSeq_feat();
+                }
+                // if xref claims to point to gene feature but gene feature does not exist,
+                // return NULL
+                if ((*xit)->IsSetData() && (*xit)->GetData().IsGene()) {
+                    return CConstRef<CSeq_feat>();
+                }
+            } else if ((*xit)->IsSetData() && (*xit)->GetData().IsGene()) {
+                const CGene_ref& gene = (*xit)->GetData().GetGene();
+                return GetLocalGeneByXref(gene, bsh);
+            } 
+        }
+    }
+
+    CConstRef <CSeq_feat> gf = GetOverlappingGene(feat.GetLocation(), scope, IsTransSpliced(feat) ? sequence::eTransSplicing_Yes : sequence::eTransSplicing_Auto);
+    if (gf) {
+        ECompare cmp = Compare(gf->GetLocation(), feat.GetLocation(), &scope, fCompareOverlapping);
+        if (cmp == eContains || cmp == eSame) {
+            return gf;
+        }
+    }
+
+    return CConstRef <CSeq_feat>();
 }
 
 
@@ -1602,8 +1783,7 @@ GetBestCdsForMrna(const CSeq_feat& mrna_feat,
             if (obj_iter->IsSetType()  &&
                 obj_iter->GetType().IsStr()  &&
                 obj_iter->GetType().GetStr() == "MrnaProteinLink") {
-                string prot_id_str = obj_iter->GetField("protein seqID")
-                    .GetData().GetStr();
+                prot_id_str = obj_iter->GetField("protein seqID").GetData().GetStr();
                 break;
             }
         }
@@ -1851,9 +2031,6 @@ CConstRef<CSeq_feat> GetBestGeneForCds(const CSeq_feat& cds_feat,
             return feat_ref;
         }
 
-        string ref_str;
-        ref->GetLabel(&ref_str);
-
         ITERATE (TFeatScores, feat_it, feats) {
             const CSeq_feat& feat = *feat_it->second;
 
@@ -2403,7 +2580,7 @@ END_SCOPE(sequence)
 
 CFastaOstream::CFastaOstream(CNcbiOstream& out)
     : m_Out(out),
-      m_Flags(fInstantiateGaps | fAssembleParts),
+      m_Flags(fInstantiateGaps | fAssembleParts | fEnableGI),
       m_GapMode(eGM_letters)
 {
     m_Gen.reset(new sequence::CDeflineGenerator);
@@ -2500,6 +2677,33 @@ static bool s_ShouldUseOriginalID (const CBioseq& seq)
     return true;
 }
 
+void CFastaOstream::x_WriteAsFasta(const CBioseq& bioseq)
+{
+    bool is_na = bioseq.GetInst().GetMol() != CSeq_inst::eMol_aa;
+    CConstRef<CSeq_id> best_id = FindBestChoice(bioseq.GetId(),
+        is_na ? CSeq_id::FastaNARank
+        : CSeq_id::FastaAARank);
+
+    // RW-139, no GI in FASTA output
+    if (best_id.NotEmpty())
+    {
+        if ((m_Flags & fEnableGI) && !best_id->IsGi())
+        {
+            // FastA format
+            // Here we have something like:
+            //      gi|###|SOME_ACCESSION|title
+
+            ITERATE(CBioseq::TId, id, bioseq.GetId()) {
+                if ((*id)->IsGi()) {
+                    (*id)->WriteAsFasta(m_Out);
+                    m_Out << '|';
+                    break;
+                }
+            }
+        }
+        best_id->WriteAsFasta(m_Out);
+    }
+}
 
 void CFastaOstream::x_WriteSeqIds(const CBioseq& bioseq,
                                   const CSeq_loc* location)
@@ -2526,10 +2730,10 @@ void CFastaOstream::x_WriteSeqIds(const CBioseq& bioseq,
         if (! NStr::IsBlank(origID)) {
             m_Out << "lcl|" << origID;
         } else {
-            CSeq_id::WriteAsFasta(m_Out, bioseq);
+            x_WriteAsFasta(bioseq);
         }
     } else {
-        CSeq_id::WriteAsFasta(m_Out, bioseq);
+        x_WriteAsFasta(bioseq);
     }
 
     if (have_range) {
@@ -2809,12 +3013,21 @@ void CFastaOstream::x_GetMaskingStates(TMSMap& masking_state,
 
     if (m_SoftMask.NotEmpty()  ||  m_HardMask.NotEmpty()) {
         _ASSERT(base_seq_id);
-        CSeq_loc whole;
-        whole.SetWhole().Assign(*base_seq_id);
         if (location) {
-            mapper.Reset(new CSeq_loc_Mapper(*location, whole, scope));
+            CSeq_loc loc2;
+            try {
+                TSeqPos length = sequence::GetLength(*location, scope);
+                loc2.SetInt().SetId().Assign(*base_seq_id);
+                loc2.SetInt().SetFrom(0);
+                loc2.SetInt().SetTo(length - 1);
+            } catch (exception&) {
+                loc2.SetWhole().Assign(*base_seq_id);
+            }
+            mapper.Reset(new CSeq_loc_Mapper(*location, loc2, scope));
         } else {
             // still useful for filtering out locations on other sequences
+            CSeq_loc whole;
+            whole.SetWhole().Assign(*base_seq_id);
             mapper.Reset(new CSeq_loc_Mapper(whole, whole, scope));
         }
         mapper->SetMergeAll();
@@ -2927,7 +3140,7 @@ void CFastaOstream::x_WriteSequence(const CSeqVector& vec,
         if ((m_GapMode != native_gap_mode || (m_Flags & fInstantiateGaps) == 0)
             &&  it.GetGapSizeForward()) 
         {
-            TSeqPos gap_size = it.SkipGap();
+            TSeqPos gap_size = it.GetGapSizeForward();
             if (m_GapMode == eGM_one_dash
                 ||  (m_Flags & fInstantiateGaps) == 0) {
                 m_Out << "-\n";
@@ -2936,10 +3149,8 @@ void CFastaOstream::x_WriteSequence(const CSeqVector& vec,
                 if (rem_line < m_Width) {
                     m_Out << '\n';
                 }
-                CSeqMap_CI smci = vec.GetSeqMap().FindSegment
-                    (it.GetPos() - gap_size, &vec.GetScope());
-                _ASSERT(smci.GetType() == CSeqMap::eSeqGap);
-                if (smci.IsUnknownLength()) {
+                _ASSERT(it.GetCurrentSeqMap_CI().GetType() == CSeqMap::eSeqGap);
+                if (it.GetCurrentSeqMap_CI().IsUnknownLength()) {
                     // conventional designation, regardless of nominal length
                     if( gap_size > 0 && (m_Flags & fKeepUnknGapNomLen) != 0 )
                     {
@@ -2953,8 +3164,8 @@ void CFastaOstream::x_WriteSequence(const CSeqVector& vec,
                 // print gap mods, if requested
                 if( (m_Flags & fShowGapModifiers) != 0 )
                 {
-                    CConstRef<CSeq_literal> pGapLiteral = 
-                        smci.GetRefGapLiteral();
+                    CConstRef<CSeq_literal> pGapLiteral =
+                        it.GetCurrentSeqMap_CI().GetRefGapLiteral();
                     if( pGapLiteral &&
                         FIELD_IS_SET_AND_IS(*pGapLiteral, Seq_data, Gap) )
                     {
@@ -2987,6 +3198,7 @@ void CFastaOstream::x_WriteSequence(const CSeqVector& vec,
                     rem_line -= rem_gap;
                 }
             }
+            it.SkipGap();
             if (rem_state >= gap_size) {
                 rem_state -= gap_size;
             } else {
@@ -3380,6 +3592,7 @@ void x_Translate(const Container& seq,
     size_t length = usable_size / 3;
     bool check_start = (is_5prime_complete && frame == 0);
     bool first_time = true;
+    char aa = '\0';
 
     for (i = 0;  i < length;  ++i) {
 
@@ -3394,9 +3607,11 @@ void x_Translate(const Container& seq,
 
         // save translated amino acid
         if (first_time  &&  check_start) {
-            prot.append(1, tbl.GetStartResidue(state));
+            aa = tbl.GetStartResidue(state);
+            prot.append(1, aa);
         } else {
-            prot.append(1, tbl.GetCodonResidue(state));
+            aa = tbl.GetCodonResidue(state);
+            prot.append(1, aa);
         }
 
         first_time = false;
@@ -3418,10 +3633,20 @@ void x_Translate(const Container& seq,
         // save translated amino acid
         char c = tbl.GetCodonResidue(state);
         if (first_time  &&  check_start) {
-            prot.append(1, tbl.GetStartResidue(state));
+            aa = tbl.GetStartResidue(state);
+            prot.append(1, aa);
         } else if (c != 'X') {
             // if padding was needed, trim ambiguous last residue
-            prot.append(1, tbl.GetCodonResidue(state));
+            aa = tbl.GetCodonResidue(state);
+            prot.append(1, aa);
+        }
+    }
+
+    if ( aa != '*' && include_stop && (! mod) && prot.size() > 0 ) {
+        // check for stop codon that normally encodes an amino acid
+        aa = tbl.GetStartResidue(state);
+        if (aa == '*') {
+            prot[prot.size()-1] = aa;
         }
     }
 
@@ -3684,27 +3909,27 @@ CRef<CBioseq> CSeqTranslator::TranslateToProtein(const CSeq_feat& cds,
                 sequence::eOffset_FromStart,
                 &scope);
             seq_pos -= frame;
-            string::size_type i = seq_pos / 3;
-            if (i < prot_len) {
+            string::size_type j = seq_pos / 3;
+            if (j < prot_len) {
                 const CCode_break::C_Aa& c_aa = brk->GetAa();
                 if (c_aa.IsNcbieaa()) {
                     CDelta_ext::Tdata::iterator seg_it = prot->SetInst().SetExt().SetDelta().Set().begin();
                     string::size_type offset = 0;
                     while (seg_it != prot->SetInst().SetExt().SetDelta().Set().end()
-                        && offset + (*seg_it)->GetLiteral().GetLength() < i) {
+                        && offset + (*seg_it)->GetLiteral().GetLength() < j) {
                         offset += (*seg_it)->GetLiteral().GetLength();
                         ++seg_it;
                     }
                     if (seg_it != prot->SetInst().SetExt().SetDelta().Set().end()
                         && !(*seg_it)->GetLiteral().GetSeq_data().IsGap()) {
                         if ((*seg_it)->GetLiteral().GetSeq_data().IsIupacaa()) {
-                            (*seg_it)->SetLiteral().SetSeq_data().SetIupacaa().Set()[i - offset] = c_aa.GetNcbieaa();
+                            (*seg_it)->SetLiteral().SetSeq_data().SetIupacaa().Set()[j - offset] = c_aa.GetNcbieaa();
                         } else {
-                            (*seg_it)->SetLiteral().SetSeq_data().SetNcbieaa().Set()[i - offset] = c_aa.GetNcbieaa();
+                            (*seg_it)->SetLiteral().SetSeq_data().SetNcbieaa().Set()[j - offset] = c_aa.GetNcbieaa();
                         }
                     }
                 }
-            } else if (i == prot_len) {
+            } else if (j == prot_len) {
                 // add terminal exception
                 const CCode_break::C_Aa& c_aa = brk->GetAa();
                 if (c_aa.IsNcbieaa() && c_aa.GetNcbieaa() == 42) {
@@ -3771,28 +3996,10 @@ CRef<CBioseq> CSeqTranslator::TranslateToProtein(const CSeq_feat& cds,
 
 bool CSeqTranslator::ChangeDeltaProteinToRawProtein(CRef<CBioseq> protein)
 {
-    if (!protein || !protein->IsAa() || !protein->IsSetInst() || !protein->GetInst().IsSetRepr()
-        || protein->GetInst().GetRepr() != objects::CSeq_inst::eRepr_delta
-        || !protein->GetInst().IsSetExt()
-        || !protein->GetInst().GetExt().IsDelta()) {
+    if (!protein || !protein->IsAa() || !protein->IsSetInst()) {
         return false;
     }
-    // can only do this if all elements are literal
-    ITERATE (objects::CDelta_ext::Tdata, it, protein->GetInst().GetExt().GetDelta().Get()) {
-        if (!(*it)->IsLiteral()) {
-            return false;
-        }
-    }
-
-    objects::CSeqVector prot_vec(*protein);
-    prot_vec.SetCoding(objects::CSeq_data::e_Iupacaa);
-    string buffer = "";
-    prot_vec.GetSeqData(0, protein->GetLength(), buffer);
-    protein->SetInst().ResetExt();
-    protein->SetInst().SetRepr(objects::CSeq_inst::eRepr_raw);
-    protein->SetInst().SetSeq_data().SetIupacaa().Set(buffer);
-    protein->SetInst().SetLength(TSeqPos(buffer.length()));
-    return true;
+    return protein->SetInst().ConvertDeltaToRaw();
 }
 
 
@@ -4001,7 +4208,7 @@ void CCdregion_translate::TranslateCdregion (string& prot,
                                              bool include_stop,
                                              bool remove_trailing_X,
                                              bool* alt_start,
-                                             ETranslationLengthProblemOptions options)
+                                             ETranslationLengthProblemOptions /*options*/)
 {
     CSeq_feat feat;
     feat.SetLocation(const_cast<CSeq_loc&>(loc));
@@ -4011,24 +4218,21 @@ void CCdregion_translate::TranslateCdregion (string& prot,
 }
 
 
-void CCdregion_translate::TranslateCdregion
-(string& prot,
- const CSeq_feat& cds,
- CScope& scope,
- bool include_stop,
- bool remove_trailing_X,
- bool* alt_start,
- ETranslationLengthProblemOptions options)
+void CCdregion_translate::TranslateCdregion (
+        string& prot,
+        const CSeq_feat& cds,
+        CScope& scope,
+        bool include_stop,
+        bool remove_trailing_X,
+        bool* alt_start,
+        ETranslationLengthProblemOptions /*options*/)
 {
     _ASSERT(cds.GetData().IsCdregion());
-
     prot.erase();
-
     CBioseq_Handle bsh = scope.GetBioseqHandle(cds.GetLocation());
     if ( !bsh ) {
         return;
     }
-
     CSeqTranslator::Translate(cds, bsh.GetScope(), prot,
                               include_stop, remove_trailing_X, alt_start);
 }
diff --git a/c++/src/objmgr/util/weight.cpp b/c++/src/objmgr/util/weight.cpp
index 82a712a..5289947 100644
--- a/c++/src/objmgr/util/weight.cpp
+++ b/c++/src/objmgr/util/weight.cpp
@@ -1,4 +1,4 @@
-/*  $Id: weight.cpp 444535 2014-08-25 18:36:18Z vasilche $
+/*  $Id: weight.cpp 514368 2016-09-21 15:22:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -118,18 +118,20 @@ double GetProteinWeight(const CSeq_feat& feat, CScope& scope,
     /// find out if the molecule is complete
     CMolInfo::TCompleteness comp = CMolInfo::eCompleteness_unknown;
     const CProt_ref& prot = feat.GetData().GetProt();
+    
     switch (prot.GetProcessed()) {
     case CProt_ref::eProcessed_not_set:
     case CProt_ref::eProcessed_preprotein:
         /// follow the molecule's setting
         break;
-
     case CProt_ref::eProcessed_mature:
     case CProt_ref::eProcessed_signal_peptide:
     case CProt_ref::eProcessed_transit_peptide:
         /// trust the location as-is
         comp = CMolInfo::eCompleteness_partial;
         break;
+    default:
+        ;
     }
 
     if (comp == CMolInfo::eCompleteness_unknown) {
diff --git a/c++/src/objtools/align_format/align_format_util.cpp b/c++/src/objtools/align_format/align_format_util.cpp
index dda7311..558f778 100644
--- a/c++/src/objtools/align_format/align_format_util.cpp
+++ b/c++/src/objtools/align_format/align_format_util.cpp
@@ -1,4 +1,4 @@
-/*  $Id: align_format_util.cpp 500368 2016-05-04 12:06:21Z ivanov $
+/*  $Id: align_format_util.cpp 520428 2016-11-28 18:25:18Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  *   blast formatter utilities
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: align_format_util.cpp 500368 2016-05-04 12:06:21Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 
 #include <math.h> // For use of ceil
@@ -46,6 +41,7 @@ static char const rcsid[] = "$Id: align_format_util.cpp 500368 2016-05-04 12:06:
 #include <corelib/ncbiutil.hpp>
 #include <corelib/ncbiobj.hpp>
 #include <corelib/ncbifile.hpp>
+#include <corelib/metareg.hpp>
 #include <html/htmlhelper.hpp>
 #include <cgi/cgictx.hpp>
 #include <util/tables/raw_scoremat.h>
@@ -204,9 +200,9 @@ void CAlignFormatUtil::BlastPrintError(list<SBlastError>&
 void  CAlignFormatUtil::PrintTildeSepLines(string str, size_t line_len,
                                            CNcbiOstream& out) {
     
-    list<string> split_line;
+    vector<string> split_line;
     NStr::Split(str, "~", split_line);
-    ITERATE(list<string>, iter, split_line) {
+    ITERATE(vector<string>, iter, split_line) {
         x_WrapOutputLine(*iter,  line_len, out);
     }
 }
@@ -508,9 +504,21 @@ CAlignFormatUtil::GetSeqIdString(const list<CRef<CSeq_id> > & ids, bool believe_
 {
     string all_id_str = NcbiEmptyString;
     CRef<CSeq_id> wid = FindBestChoice(ids, CSeq_id::WorstRank);
+
     if (wid && (wid->Which()!= CSeq_id::e_Local || believe_local_id)){
         TGi gi = FindGi(ids);
-        if (strncmp(wid->AsFastaString().c_str(), "lcl|", 4) == 0) {
+
+        bool use_long_seqids = false;
+        CNcbiApplication* app = CNcbiApplication::Instance();
+        if (app) {
+            const CNcbiRegistry& registry = app->GetConfig();
+            use_long_seqids = (registry.Get("BLAST", "LONG_SEQID") == "1");
+        }
+        if (!use_long_seqids) {
+
+            all_id_str = GetBareId(*wid);
+        }
+        else if (strncmp(wid->AsFastaString().c_str(), "lcl|", 4) == 0) {
             if(gi == ZERO_GI){
                 all_id_str =  wid->AsFastaString().substr(4);
             } else {
@@ -695,6 +703,7 @@ void CAlignFormatUtil::GetAlnScores(const CSeq_align& aln,
                             score, bits, evalue, sum_n, num_ident, use_this_gi, comp_adj_method);
         }
     }	
+    if(use_this_gi.size() == 0) GetUseThisSequence(aln,use_this_gi);
 }
 
 string CAlignFormatUtil::GetGnlID(const CDbtag& dtg)
@@ -2989,7 +2998,7 @@ string CAlignFormatUtil::MapTemplate(string inpString,string tmplParamName,Int8
 {
     string outString;
     string tmplParam = "<@" + tmplParamName + "@>";
-    NStr::Replace(inpString,tmplParam,NStr::IntToString(templParamVal),outString);
+    NStr::Replace(inpString,tmplParam,NStr::NumericToString(templParamVal),outString);
     return outString;
 }
 
@@ -3001,6 +3010,61 @@ string CAlignFormatUtil::MapTemplate(string inpString,string tmplParamName,strin
     return outString;
 }
 
+string CAlignFormatUtil::MapSpaceTemplate(string inpString,string tmplParamName,string templParamVal, unsigned int maxParamValLength, int spacesFormatFlag)
+{
+    templParamVal = AddSpaces(templParamVal, maxParamValLength, spacesFormatFlag);
+    string outString = MapTemplate(inpString,tmplParamName,templParamVal);    
+
+    return outString;
+}
+
+
+string CAlignFormatUtil::AddSpaces(string paramVal, unsigned int maxParamValLength, int spacesFormatFlag)
+{
+    //if(!spacePos.empty()) {
+        string spaceString;        
+        if(maxParamValLength >= paramVal.size()) {
+            unsigned int numSpaces = maxParamValLength - paramVal.size() + 1;
+            if(spacesFormatFlag & eSpacePosToCenter) {
+                numSpaces = numSpaces/2;
+            }
+            for(size_t i=0; i < numSpaces ; i++){
+                spaceString += " ";
+            }
+        }
+        else {
+            paramVal = paramVal.substr(0, maxParamValLength - 3) + "...";
+            spaceString += " ";
+        }
+        if(spacesFormatFlag & eSpacePosAtLineEnd) {
+            paramVal = paramVal + spaceString;
+        }        
+        else if(spacesFormatFlag & eSpacePosToCenter) {
+            paramVal = spaceString + paramVal + spaceString;
+        }
+        else {
+            paramVal = spaceString + paramVal;
+        }
+        if(spacesFormatFlag & eAddEOLAtLineStart) paramVal = "\n" + paramVal;
+        if(spacesFormatFlag & eAddEOLAtLineStart) paramVal = paramVal + "\n";        
+    //}
+    
+    return paramVal;
+}
+
+string CAlignFormatUtil::GetProtocol()
+{
+    CNcbiIfstream  config_file(".ncbirc");
+    CNcbiRegistry config_reg(config_file);
+    string httpProt = "https:";
+    if(!config_reg.Empty()) {
+        if(config_reg.HasEntry("BLASTFMTUTIL","PROTOCOL")) {
+            httpProt = config_reg.Get("BLASTFMTUTIL","PROTOCOL");
+        }
+    }        
+    return httpProt;
+}
+
 static string s_MapCommonUrlParams(string urlTemplate, CAlignFormatUtil::SSeqURLInfo *seqUrlInfo)
 {
     string db,logstr_moltype;
@@ -3115,10 +3179,17 @@ string CAlignFormatUtil::GetIDUrlGen(SSeqURLInfo *seqUrlInfo,const CBioseq::TId*
         url_link = s_MapCommonUrlParams(l_EntrezUrl, seqUrlInfo);
         
         if(!seqUrlInfo->useTemplates) {
+            string httpProt = kDefaultProtocol;
+            if(m_Reg && !m_Reg->Empty()) {
+                if(m_Reg->HasEntry("BLASTFMTUTIL","PROTOCOL")) {
+                    httpProt = m_Reg->Get("BLASTFMTUTIL","PROTOCOL");
+                }
+            }                    
 			url_link = CAlignFormatUtil::MapTemplate(url_link,"acc",seqUrlInfo->accession);                 
             temp_class_info = (!seqUrlInfo->defline.empty())? CAlignFormatUtil::MapTemplate(temp_class_info,"defline",NStr::JavaScriptEncode(seqUrlInfo->defline)):temp_class_info;
             url_link = CAlignFormatUtil::MapTemplate(url_link,"cssInf",(seqUrlInfo->addCssInfo) ? temp_class_info.c_str() : "");
             url_link = CAlignFormatUtil::MapTemplate(url_link,"target",seqUrlInfo->new_win ? "TARGET=\"EntrezView\"" : "");
+            url_link = CAlignFormatUtil::MapTemplate(url_link,"protocol",httpProt);
         }	           
             
     } else {//seqid general, dbtag specified		
@@ -3480,7 +3551,7 @@ string  CAlignFormatUtil::GetFASTALinkURL(SSeqURLInfo *seqUrlInfo,
         linkUrl = seqUrlInfo->seqUrl;    
         vector<string> parts;
         //SNP accession=dbSNP:rs35885954
-        NStr::Split(seqUrlInfo->accession,":rs",parts,NStr::eMergeDelims); 
+        NStr::Split(seqUrlInfo->accession,":rs",parts,NStr::fSplit_MergeDelimiters); 
         string rs;
         if(parts.size() > 1) {
             rs = parts[1];
@@ -3706,13 +3777,38 @@ s_GetBlastScore(const container&  scoreList,
 }
 
 
+void CAlignFormatUtil::GetUseThisSequence(const CSeq_align& aln,list<TGi>& use_this_gi)
+                                    
+{
+    const string k_GiPrefix = "gi:";
 
+    if(!aln.CanGetExt() || aln.GetExt().size() == 0) return;
+    const CUser_object &user = *(aln.GetExt().front());
+
+    if (user.IsSetType() && user.GetType().IsStr() && user.GetType().GetStr() == "use_this_seqid" && user.IsSetData()) {
+        const CUser_object::TData& fields = user.GetData();            
+        for (CUser_object::TData::const_iterator fit = fields.begin();  fit != fields.end(); ++fit) {
+            const CUser_field& field = **fit;                 
+
+            if (field.IsSetLabel() && field.GetLabel().IsStr() && field.GetLabel().GetStr() == "SEQIDS" && 
+                                                                     field.IsSetData()  &&  field.GetData().IsStrs()) {
+                const CUser_field::C_Data::TStrs& strs = field.GetData().GetStrs();                                                            
+                ITERATE(CUser_field::TData::TStrs, acc_iter, strs) {
+                    if(NStr::StartsWith(*acc_iter,k_GiPrefix)) { //will be used when switch to 64bit GIs
+                        string strGi = NStr::Replace(*acc_iter,k_GiPrefix,"");
+                        TGi gi = NStr::StringToInt8(strGi);
+                        use_this_gi.push_back(gi);
+                    }                        
+                }
+            }                
+        }
+    }
+}
 
 CAlignFormatUtil::SSeqAlignSetCalcParams* 
 CAlignFormatUtil::GetSeqAlignSetCalcParamsFromASN(const CSeq_align_set& alnSet)
 {
-    bool hasScore = false;
-
+    bool hasScore = false;    
     double evalue = -1;
     double bitScore = -1;
     double totalBitScore = -1;
@@ -3726,9 +3822,8 @@ CAlignFormatUtil::GetSeqAlignSetCalcParamsFromASN(const CSeq_align_set& alnSet)
     
     const CSeq_align& aln = *(alnSet.Get().front()); 
 
-    hasScore = s_GetBlastScore(aln.GetScore(),evalue,bitScore, totalBitScore,percentCoverage,percentIdent,hspNum,totalLen,rawScore,sum_n,use_this_gi);
-        
-        
+    hasScore = s_GetBlastScore(aln.GetScore(),evalue,bitScore, totalBitScore,percentCoverage,percentIdent,hspNum,totalLen,rawScore,sum_n,use_this_gi);    
+       
     if(!hasScore){
         const CSeq_align::TSegs& seg = aln.GetSegs();
         if(seg.Which() == CSeq_align::C_Segs::e_Std){
@@ -3742,6 +3837,11 @@ CAlignFormatUtil::GetSeqAlignSetCalcParamsFromASN(const CSeq_align_set& alnSet)
                             evalue,bitScore, totalBitScore,percentCoverage,percentIdent,hspNum,totalLen,rawScore,sum_n,use_this_gi);
         }
     }
+
+
+    if(use_this_gi.size() == 0) GetUseThisSequence(aln,use_this_gi);
+
+
     auto_ptr<SSeqAlignSetCalcParams> seqSetInfo(new SSeqAlignSetCalcParams);
     seqSetInfo->evalue = evalue;    
     seqSetInfo->bit_score = bitScore;    
@@ -3768,6 +3868,18 @@ CRef<CSeq_id> CAlignFormatUtil::GetDisplayIds(const CBioseq_Handle& handle,
                                 TGi& gi)
                                            
 {
+    int taxid = 0;
+    CRef<CSeq_id> wid = CAlignFormatUtil::GetDisplayIds(handle, aln_id, use_this_gi, gi, taxid);    
+    return wid;
+}
+
+CRef<CSeq_id> CAlignFormatUtil::GetDisplayIds(const CBioseq_Handle& handle,
+                                const CSeq_id& aln_id,
+                                list<TGi>& use_this_gi,
+                                TGi& gi,
+                                int& taxid)
+                                           
+{
     const CRef<CBlast_def_line_set> bdlRef = CSeqDB::ExtractBlastDefline(handle);
     const list< CRef< CBlast_def_line > > &bdl = (bdlRef.Empty()) ? list< CRef< CBlast_def_line > >() : bdlRef->Get();
        
@@ -3775,6 +3887,7 @@ CRef<CSeq_id> CAlignFormatUtil::GetDisplayIds(const CBioseq_Handle& handle,
     CRef<CSeq_id> wid;    
 
     gi = ZERO_GI;
+    taxid = 0;
     if(bdl.empty()){
         wid = FindBestChoice(*ids, CSeq_id::WorstRank);        
         gi = FindGi(*ids);    
@@ -3785,6 +3898,9 @@ CRef<CSeq_id> CAlignFormatUtil::GetDisplayIds(const CBioseq_Handle& handle,
             const CBioseq::TId* cur_id = &((*iter)->GetSeqid());
             TGi cur_gi =  FindGi(*cur_id);    
             wid = FindBestChoice(*cur_id, CSeq_id::WorstRank);
+            if ((*iter)->IsSetTaxid() && (*iter)->CanGetTaxid()){
+                taxid = (*iter)->GetTaxid();
+            }
             if (!use_this_gi.empty()) {
                 ITERATE(list<TGi>, iter_gi, use_this_gi){
                     if(cur_gi == *iter_gi){
@@ -3811,6 +3927,7 @@ CRef<CSeq_id> CAlignFormatUtil::GetDisplayIds(const CBioseq_Handle& handle,
     return wid;
 }
 
+
 TGi CAlignFormatUtil::GetDisplayIds(const list< CRef< CBlast_def_line > > &bdl,
                                               const CSeq_id& aln_id,
                                               list<TGi>& use_this_gi)
@@ -3966,5 +4083,20 @@ string CAlignFormatUtil::GetTitle(const CBioseq_Handle & bh)
 	return t;
 }
 
+string CAlignFormatUtil::GetBareId(const CSeq_id& id)
+{
+    string retval; 
+
+    if (id.IsGi() || id.IsPrf() || id.IsPir()) {
+        retval = id.AsFastaString();
+    }
+    else {
+        retval = id.GetSeqIdString(true);
+    }
+
+    return retval;
+}
+
+
 END_SCOPE(align_format)
 END_NCBI_SCOPE
diff --git a/c++/src/objtools/align_format/aln_printer.cpp b/c++/src/objtools/align_format/aln_printer.cpp
index def3029..aa86894 100644
--- a/c++/src/objtools/align_format/aln_printer.cpp
+++ b/c++/src/objtools/align_format/aln_printer.cpp
@@ -1,6 +1,4 @@
-static char const rcsid[] = "$Id: ";
-
-/*
+/*  $Id: aln_printer.cpp 500404 2016-05-04 14:59:01Z camacho $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -34,7 +32,6 @@ Author: Greg Boratyn
 Contents: Printer for standard multiple sequence alignmnet formats
 
 ******************************************************************************/
-
 #include <ncbi_pch.hpp>
 #include <objmgr/bioseq_handle.hpp>
 #include <objmgr/util/sequence.hpp>
diff --git a/c++/src/objtools/align_format/format_flags.cpp b/c++/src/objtools/align_format/format_flags.cpp
index 6006952..c09fd00 100644
--- a/c++/src/objtools/align_format/format_flags.cpp
+++ b/c++/src/objtools/align_format/format_flags.cpp
@@ -1,4 +1,4 @@
-/*  $Id: format_flags.cpp 495725 2016-03-21 14:24:26Z ivanov $
+/*  $Id: format_flags.cpp 518046 2016-10-31 14:58:35Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -36,7 +36,7 @@ BEGIN_SCOPE(align_format)
 const string kArgOutputFormat("outfmt");
 const int kDfltArgOutputFormat = 0;
 string kDfltArgTabularOutputFmt =
-    "qseqid sseqid pident length mismatch gapopen qstart qend sstart send "
+    "qaccver saccver pident length mismatch gapopen qstart qend sstart send "
     "evalue bitscore";
 const string kDfltArgTabularOutputFmtTag("std");
 
@@ -223,11 +223,14 @@ const string kArgProduceHtml("html");
 const bool kDfltArgProduceHtml = false;
 const size_t kDfltLineLength = 60;
 
-const size_t kNumSAMOutputFormatSpecifiers = 1;
+const size_t kNumSAMOutputFormatSpecifiers = 2;
 const SSAMFormatSpec sc_SAMFormatSpecifiers[kNumSAMOutputFormatSpecifiers] = {
     SSAMFormatSpec("SQ",
                    "Include Sequence Data",
-                   eSAM_SeqData)
+                   eSAM_SeqData),
+    SSAMFormatSpec("SR",
+                   "Subject as Reference Seq",
+                   eSAM_SubjAsRefSeq)
 };
 
 string DescribeSAMOutputFormatSpecifiers()
diff --git a/c++/src/objtools/align_format/seqalignfilter.cpp b/c++/src/objtools/align_format/seqalignfilter.cpp
index 348b51e..017dee3 100644
--- a/c++/src/objtools/align_format/seqalignfilter.cpp
+++ b/c++/src/objtools/align_format/seqalignfilter.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqalignfilter.cpp 482214 2015-10-21 16:33:04Z zaretska $
+/*  $Id: seqalignfilter.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file seqalignfilter.cpp
 /// Implementation of the alignment filtering class.
 ///
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqalignfilter.cpp 482214 2015-10-21 16:33:04Z zaretska $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 
 #include <objtools/align_format/seqalignfilter.hpp>
diff --git a/c++/src/objtools/align_format/showalign.cpp b/c++/src/objtools/align_format/showalign.cpp
index b947818..fd678c5 100644
--- a/c++/src/objtools/align_format/showalign.cpp
+++ b/c++/src/objtools/align_format/showalign.cpp
@@ -1,4 +1,4 @@
-/*  $Id: showalign.cpp 489117 2016-01-08 16:18:48Z zaretska $
+/*  $Id: showalign.cpp 519417 2016-11-15 18:30:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,13 +29,9 @@
  *   Sequence alignment display
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: showalign.cpp 489117 2016-01-08 16:18:48Z zaretska $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 
+#include <objtools/align_format/align_format_util.hpp>
 #include <objtools/align_format/showalign.hpp>
 
 #include <corelib/ncbiexpt.hpp>
@@ -121,7 +117,7 @@ const string k_DefaultMaskSeqLocTempl = "<font color=\"<@color@>\"><@alndata@></
 
 #ifdef USE_ORG_IMPL
 static string k_GetSeqSubmitForm[] = {"<FORM  method=\"post\" \
-action=\"http://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?SUBMIT=y\" \
+action=\"//www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?SUBMIT=y\" \
 name=\"%s%d\"><input type=button value=\"Get selected sequences\" \
 onClick=\"finalSubmit(%d, 'getSeqAlignment%d', 'getSeqGi', '%s%d', %d)\"><input \
 type=\"hidden\" name=\"db\" value=\"\"><input type=\"hidden\" name=\"term\" \
@@ -129,7 +125,7 @@ value=\"\"><input type=\"hidden\" name=\"doptcmdl\" value=\"docsum\"><input \
 type=\"hidden\" name=\"cmd\" value=\"search\"></form>",
                                      
                                      "<FORM  method=\"POST\" \
-action=\"http://www.ncbi.nlm.nih.gov/Traces/trace.cgi\" \
+action=\"//www.ncbi.nlm.nih.gov/Traces/trace.cgi\" \
 name=\"%s%d\"><input type=button value=\"Get selected sequences\" \
 onClick=\"finalSubmit(%d, 'getSeqAlignment%d', 'getSeqGi', '%s%d', %d)\"><input \
 type=\"hidden\" name=\"val\" value=\"\"><input \
@@ -144,7 +140,7 @@ type=\"button\" value=\"Deselect all\" onClick=\"handleCheckAll('deselect', \
 
 
 static string k_GetTreeViewForm =  "<FORM  method=\"post\" \
-action=\"http://www.ncbi.nlm.nih.gov/blast/treeview/blast_tree_view.cgi?request=page&rid=%s&queryID=%s&distmode=on\" \
+action=\"//www.ncbi.nlm.nih.gov/blast/treeview/blast_tree_view.cgi?request=page&rid=%s&queryID=%s&distmode=on\" \
 name=\"tree%s%d\" target=\"trv%s\"> \
 <input type=button value=\"Distance tree of results\" onClick=\"extractCheckedSeq('getSeqAlignment%d', 'getSeqGi', 'tree%s%d')\"> \
 <input type=\"hidden\" name=\"sequenceSet\" value=\"\"><input type=\"hidden\" name=\"screenWidth\" value=\"\"></form>";
@@ -164,7 +160,8 @@ CDisplaySeqalign::CDisplaySeqalign(const CSeq_align_set& seqalign,
       m_Seqloc(mask_seqloc),
       m_QueryFeature(external_feature),
       m_Scope(scope),
-      m_LinkoutDB(NULL)
+      m_LinkoutDB(NULL),
+      m_UseLongSeqIds(false)
 {
     m_AlignOption = 0;
     m_SeqLocChar = eX;
@@ -198,6 +195,14 @@ CDisplaySeqalign::CDisplaySeqalign(const CSeq_align_set& seqalign,
     CAlignFormatUtil::GetAsciiProteinMatrix(matrix_name 
                                        ? matrix_name 
                                        : BLAST_DEFAULT_MATRIX, mtx);
+
+    // Use default score matrix if one with the provided name was not found.
+    // This may happen for a user's score matrix that was read from a file
+    // (using BLASTMAT environment variable).
+    if (mtx.GetData().empty()) {
+        CAlignFormatUtil::GetAsciiProteinMatrix(BLAST_DEFAULT_MATRIX, mtx);
+    }
+
     // -RMH- --- Need to see if we can retrieve our matrix this way.
     //           for now don't initialize if empty
     //_ASSERT(!mtx.GetData().empty());
@@ -2260,6 +2265,7 @@ CDisplaySeqalign::x_PrintDefLine(const CBioseq_Handle& bsp_handle,SAlnInfo* aln_
                                  
 {
     CNcbiOstrstream out;                
+    CNcbiEnvironment env;
     /* Facilitates comparing formatted output using diff */
     static string kLengthString("Length=");
 #ifdef CTOOLKIT_COMPATIBLE
@@ -2271,7 +2277,7 @@ CDisplaySeqalign::x_PrintDefLine(const CBioseq_Handle& bsp_handle,SAlnInfo* aln_
         value_set = true;
     }
 #endif /* CTOOLKIT_COMPATIBLE */
-		
+
     if(bsp_handle){
         const CRef<CSeq_id> wid =
             FindBestChoice(bsp_handle.GetBioseqCore()->GetId(), 
@@ -2307,15 +2313,24 @@ CDisplaySeqalign::x_PrintDefLine(const CBioseq_Handle& bsp_handle,SAlnInfo* aln_
                 out<<alnDispParams->id_url;
             }
                 
-            if(m_AlignOption&eShowGi && alnDispParams->gi > ZERO_GI){
+            if(m_AlignOption&eShowGi && alnDispParams->gi > ZERO_GI &&
+               !alnDispParams->seqID->IsGi()){
                 out<<"gi|"<<alnDispParams->gi<<"|";
-                    }     
+            }     
             if(!((alnDispParams->seqID->AsFastaString().find("gnl|BL_ORD_ID") != string::npos) ||
 		alnDispParams->seqID->AsFastaString().find("lcl|Subject_") != string::npos)){
                 if (strncmp(alnDispParams->seqID->AsFastaString().c_str(), "lcl|", 4) == 0) 
                          out << alnDispParams->label;
-		else
-                	alnDispParams->seqID->WriteAsFasta(out);
+                else {
+                    if (m_UseLongSeqIds || ((m_AlignOption & eShowGi) &&
+                                            alnDispParams->gi > ZERO_GI)) {
+                        alnDispParams->seqID->WriteAsFasta(out);
+                    }
+                    else {
+                        out << CAlignFormatUtil::GetBareId(*alnDispParams->seqID);
+                    }
+
+                }
             }
             if(m_AlignOption&eHtml){
                 if(alnDispParams->id_url != NcbiEmptyString){
@@ -2382,7 +2397,8 @@ CDisplaySeqalign::x_PrintDefLine(const CBioseq_Handle& bsp_handle,SAlnInfo* aln_
                         out<< alnDispParams->id_url;
                     }
                 
-                    if(m_AlignOption&eShowGi && alnDispParams->gi > ZERO_GI){
+                    if(m_AlignOption&eShowGi && alnDispParams->gi > ZERO_GI &&
+                       !alnDispParams->seqID->IsGi()){
                         out<<"gi|"<<alnDispParams->gi<<"|";
                     }     
                     if(!(alnDispParams->seqID->AsFastaString().find("gnl|BL_ORD_ID") != string::npos) ||
@@ -2391,7 +2407,16 @@ CDisplaySeqalign::x_PrintDefLine(const CBioseq_Handle& bsp_handle,SAlnInfo* aln_
                             out << alnDispParams->label;
                     	}
                     	else {
-                            alnDispParams->seqID->WriteAsFasta(out);
+                            if (m_UseLongSeqIds ||
+                                ((m_AlignOption & eShowGi) &&
+                                 alnDispParams->gi > ZERO_GI)) {
+
+                                alnDispParams->seqID->WriteAsFasta(out);
+                            }
+                            else {
+                                out << CAlignFormatUtil::GetBareId(
+                                                       *alnDispParams->seqID);
+                            }
                     	}
                     }
                     if(m_AlignOption&eHtml){
@@ -3661,13 +3686,19 @@ CDisplaySeqalign::x_MapDefLine(SAlnDispParams *alnDispParams,bool isFirst, bool
 	string alnDefLine  = CAlignFormatUtil::MapTemplate(m_AlignTemplates->alnDefLineTmpl,"alnSeqSt",firstSeqClassInfo);
 	*/
     string alnDefLine = m_AlignTemplates->alnDefLineTmpl;
+    CNcbiEnvironment env;
 
 	string alnGi = (m_AlignOption&eShowGi && alnDispParams->gi > ZERO_GI) ?
         "gi|" + NStr::NumericToString(alnDispParams->gi) + "|" : "";
 	string seqid;					
     if(!(alnDispParams->seqID->AsFastaString().find("gnl|BL_ORD_ID") != string::npos) || 
 	alnDispParams->seqID->AsFastaString().find("lcl|Subject_") != string::npos){							 
-		seqid = alnDispParams->seqID->AsFastaString();        
+        if (m_UseLongSeqIds) {
+            seqid = alnDispParams->seqID->AsFastaString();
+        }
+        else {
+            seqid = CAlignFormatUtil::GetBareId(*alnDispParams->seqID);
+        }
     }
 	
 	if(alnDispParams->id_url != NcbiEmptyString) {
@@ -3717,6 +3748,7 @@ CDisplaySeqalign::x_InitDefLinesHeader(const CBioseq_Handle& bsp_handle,SAlnInfo
 {
     string deflines;	
     string firstDefline;
+    CNcbiEnvironment env;
 	list<TGi>& use_this_gi = aln_vec_info->use_this_gi;    
     if(bsp_handle){        
         const CRef<CBlast_def_line_set> bdlRef =  CSeqDB::ExtractBlastDefline(bsp_handle);        
@@ -3735,7 +3767,13 @@ CDisplaySeqalign::x_InitDefLinesHeader(const CBioseq_Handle& bsp_handle,SAlnInfo
 			string alnDefLine = x_MapDefLine(alnDispParams,isFirst,false,false,seqLength);
 		    m_CurrAlnID_Lbl = (alnDispParams->gi != ZERO_GI) ?
                 NStr::NumericToString(alnDispParams->gi) : alnDispParams->label;			
-            m_CurrAlnAccession = alnDispParams->seqID->AsFastaString();
+            if (m_UseLongSeqIds) {
+                m_CurrAlnAccession = alnDispParams->seqID->AsFastaString();
+            }
+            else {
+                m_CurrAlnAccession = CAlignFormatUtil::GetBareId(
+                                                   *alnDispParams->seqID);
+            }
             if(m_AlignTemplates != NULL) {
                 x_InitAlignLinks(alnDispParams->seqUrlInfo,bdl,alnDispParams->seqID,eDisplayResourcesLinks);
             }
@@ -3767,7 +3805,15 @@ CDisplaySeqalign::x_InitDefLinesHeader(const CBioseq_Handle& bsp_handle,SAlnInfo
                         firstGi = alnGi;
 						
                         //This should probably change on dispId
-                        m_CurrAlnAccession = alnDispParams->seqID->AsFastaString();
+                        if (m_UseLongSeqIds) {
+                            m_CurrAlnAccession =
+                                alnDispParams->seqID->AsFastaString();
+                        }
+                        else {
+                            m_CurrAlnAccession =
+                                CAlignFormatUtil::GetBareId(
+                                                      *alnDispParams->seqID);
+                        }
                         if(m_CurrAlnAccession.find("gnl|BL_ORD_ID") != string::npos ||
 				m_CurrAlnAccession.find("lcl|Subject_") != string::npos){ 
 							///Get first token of the title
@@ -4644,10 +4690,10 @@ void CDisplaySeqalign::x_PreProcessSingleAlign(CSeq_align_set::Tdata::const_iter
 }
 
 
-void CDisplaySeqalign::DisplayPairwiseSeqalign(CNcbiOstream& out,hash_set <string> selectedIDs) //(blast_rank = 1,2...)
+void CDisplaySeqalign::DisplayPairwiseSeqalign(CNcbiOstream& out,unordered_set <string> selectedIDs) //(blast_rank = 1,2...)
 {
     string alignRows;
-    hash_set <string> :: const_iterator idsIter;
+    unordered_set <string> :: const_iterator idsIter;
 
     CSeq_align_set actual_aln_list;
     //Not sure we need this - check with Jean
diff --git a/c++/src/objtools/align_format/showdefline.cpp b/c++/src/objtools/align_format/showdefline.cpp
index 15ce163..fad406c 100644
--- a/c++/src/objtools/align_format/showdefline.cpp
+++ b/c++/src/objtools/align_format/showdefline.cpp
@@ -1,4 +1,4 @@
-/* $Id: showdefline.cpp 489117 2016-01-08 16:18:48Z zaretska $
+/* $Id: showdefline.cpp 517104 2016-10-20 17:33:21Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  *   Display blast defline
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: showdefline.cpp 489117 2016-01-08 16:18:48Z zaretska $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiexpt.hpp>
 #include <corelib/ncbiutil.hpp>
@@ -58,6 +53,7 @@ static char const rcsid[] = "$Id: showdefline.cpp 489117 2016-01-08 16:18:48Z za
 #include <objects/blastdb/defline_extra.hpp>
 
 #include <objtools/align_format/showdefline.hpp>
+#include <objtools/align_format/align_format_util.hpp>
 #include <objtools/blast/seqdb_reader/seqdb.hpp>    // for CSeqDB::ExtractBlastDefline
 
 #include <stdio.h>
@@ -304,6 +300,7 @@ void CShowBlastDefline::x_FillDeflineAndId(const CBioseq_Handle& handle,
     sdl->linkout = 0;
     sdl->is_new = false;
     sdl->was_checked = false;
+    sdl->taxid = 0;
 
     //get psiblast stuff
     
@@ -328,7 +325,7 @@ void CShowBlastDefline::x_FillDeflineAndId(const CBioseq_Handle& handle,
         }
     }        
     //get id (sdl->id, sdl-gi)    
-    sdl->id = CAlignFormatUtil::GetDisplayIds(handle,aln_id,use_this_gi,sdl->gi);
+    sdl->id = CAlignFormatUtil::GetDisplayIds(handle,aln_id,use_this_gi,sdl->gi,sdl->taxid);
     sdl->alnIDFasta = aln_id.AsFastaString();
 
     //get linkout
@@ -505,6 +502,7 @@ CShowBlastDefline::CShowBlastDefline(const CSeq_align_set& seqalign,
     m_DeflineTemplates = NULL;
     m_StartIndex = 0;
     m_PositionIndex = -1;
+    m_AppLogInfo = NULL;
 }
 
 CShowBlastDefline::~CShowBlastDefline()
@@ -638,6 +636,8 @@ void CShowBlastDefline::x_InitDefline(void)
 
 void CShowBlastDefline::x_DisplayDefline(CNcbiOstream & out)
 {
+    bool use_long_seqids = (m_Option & eLongSeqId) != 0;
+
     if(!(m_Option & eNoShowHeader)) {
         if((m_PsiblastStatus == eFirstPass) ||
            (m_PsiblastStatus == eRepeatPass)){
@@ -731,7 +731,7 @@ void CShowBlastDefline::x_DisplayDefline(CNcbiOstream & out)
         if((m_Option & eHtml) && (sdl->id_url != NcbiEmptyString)) {
             out << sdl->id_url;
         }
-        if(m_Option & eShowGi){
+        if((m_Option & eShowGi) && !sdl->id->IsGi()){
             if(sdl->gi > ZERO_GI){
                 line_component = "gi|" + NStr::NumericToString(sdl->gi) + "|";
                 out << line_component;
@@ -741,7 +741,16 @@ void CShowBlastDefline::x_DisplayDefline(CNcbiOstream & out)
         if(!sdl->id.Empty()){
             if(!(sdl->id->AsFastaString().find("gnl|BL_ORD_ID") != string::npos || 
 		sdl->id->AsFastaString().find("lcl|Subject_") != string::npos)){
-            	string idStr = sdl->id->AsFastaString();
+                string idStr;
+                if (use_long_seqids ||
+                    // use long sequence ids if more than one id is printed
+                    ((m_Option & eShowGi) && sdl->gi > ZERO_GI)) {
+
+                    idStr = sdl->id->AsFastaString();
+                }
+                else {
+                    idStr = CAlignFormatUtil::GetBareId(*sdl->id);
+                }
             	if (strncmp(idStr.c_str(), "lcl|", 4) == 0) {
             		idStr = sdl->id->AsFastaString().substr(4);
             	}
@@ -1542,7 +1551,15 @@ string CShowBlastDefline::x_FormatDeflineTableLine(SDeflineInfo* sdl,SScoreInfo*
         deflFastaSeq = NStr::TruncateSpaces(sdl->alnIDFasta);        
         deflAccs = sdl->id->AsFastaString();
     }
-    
+    //Setup applog info structure
+    if(m_AppLogInfo && (m_AppLogInfo->currInd < m_AppLogInfo->topMatchesNum)) {
+        m_AppLogInfo->deflIdVec.push_back(deflId);
+        m_AppLogInfo->taxidVec.push_back(NStr::IntToString(sdl->taxid));
+        m_AppLogInfo->queryCoverageVec.push_back(NStr::IntToString(iter->percent_coverage));
+        m_AppLogInfo->percentIdentityVec.push_back(NStr::IntToString(iter->percent_identity));
+        m_AppLogInfo->currInd++;
+    }
+
     //If gi - deflFrmID and deflId are the same and equal to gi "555",deflFastaSeq will have "gi|555"
     //If gnl - deflFrmID=number, deflId=ti:number,deflFastaSeq=gnl|xxx
     //like  "268252125","ti:268252125","gnl|ti|961433.m" or "961433.m" and "GNOMON:961433.m" "gnl|GNOMON|961433.m"    
diff --git a/c++/src/objtools/align_format/tabular.cpp b/c++/src/objtools/align_format/tabular.cpp
index 4413fa7..5bdb42c 100644
--- a/c++/src/objtools/align_format/tabular.cpp
+++ b/c++/src/objtools/align_format/tabular.cpp
@@ -1,4 +1,4 @@
-/* $Id: tabular.cpp 499247 2016-04-25 11:33:02Z ivanov $
+/* $Id: tabular.cpp 518048 2016-10-31 14:59:16Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
 /// @file: tabular.cpp
 /// Formatting of pairwise sequence alignments in tabular form.
 /// One line is printed for each alignment with tab-delimited fielalnVec. 
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: tabular.cpp 499247 2016-04-25 11:33:02Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 
 #include <objects/seqloc/Seq_id.hpp>
@@ -270,6 +265,10 @@ void CBlastTabularInfo::x_PrintSubjectAllAccessions(void)
 
 void CBlastTabularInfo::x_PrintSubjectTaxId()
 {
+	if(m_SubjectTaxId == 0) {
+		m_Ostream << NA;
+		return;
+	}
        m_Ostream << m_SubjectTaxId;
 }
 
@@ -289,6 +288,10 @@ void CBlastTabularInfo::x_PrintSubjectTaxIds()
 
 void CBlastTabularInfo::x_PrintSubjectBlastName()
 {
+	if(m_SubjectBlastName == kEmptyStr) {
+		m_Ostream << NA;
+		return;
+	}
 	m_Ostream << m_SubjectBlastName;
 }
 
@@ -308,6 +311,10 @@ void CBlastTabularInfo::x_PrintSubjectBlastNames()
 
 void CBlastTabularInfo::x_PrintSubjectSuperKingdom()
 {
+	if(m_SubjectSuperKingdom == kEmptyStr) {
+		m_Ostream << NA;
+		return;
+	}
 	m_Ostream << m_SubjectSuperKingdom;
 }
 
@@ -327,6 +334,10 @@ void CBlastTabularInfo::x_PrintSubjectSuperKingdoms()
 
 void CBlastTabularInfo::x_PrintSubjectSciName()
 {
+	if(m_SubjectSciName == kEmptyStr) {
+		m_Ostream << NA;
+		return;
+	}
 	m_Ostream << m_SubjectSciName;
 }
 
@@ -346,6 +357,10 @@ void CBlastTabularInfo::x_PrintSubjectSciNames()
 
 void CBlastTabularInfo::x_PrintSubjectCommonName()
 {
+	if(m_SubjectCommonName == kEmptyStr) {
+		m_Ostream << NA;
+		return;
+	}
 	m_Ostream << m_SubjectCommonName;
 }
 
@@ -755,7 +770,6 @@ int CBlastTabularInfo::SetFields(const CSeq_align& align,
         SetScores(score, bit_score, evalue);
     }
 
-    bool query_is_na = false, subject_is_na = false;
     bool bioseqs_found = true;
     // Extract the full query id from the correspondintg Bioseq handle.
     if (x_IsFieldRequested(eQuerySeqId) || x_IsFieldRequested(eQueryGi) ||
@@ -767,7 +781,6 @@ int CBlastTabularInfo::SetFields(const CSeq_align& align,
             const CBioseq_Handle& query_bh = 
                 scope.GetBioseqHandle(align.GetSeq_id(0));
             SetQueryId(query_bh);
-            query_is_na = query_bh.IsNa();
             if(m_QueryRange.NotEmpty())
             	m_QueryLength = m_QueryRange.GetLength();
             else
@@ -823,7 +836,6 @@ int CBlastTabularInfo::SetFields(const CSeq_align& align,
             if(setSubjectId) {
             	SetSubjectId(subject_bh);
             }
-            subject_is_na = subject_bh.IsNa();
             m_SubjectLength = subject_bh.GetBioseqLength();
 
             if(setSubjectIds || setSubjectTaxInfo || setSubjectTitle || setSubjectTaxInfoAll) {
@@ -898,15 +910,18 @@ int CBlastTabularInfo::SetFields(const CSeq_align& align,
     // Std-segs are produced only for translated searches; Dense-diags only for 
     // ungapped, not translated searches.
     const bool kTranslated = align.GetSegs().IsStd();
-
+    bool query_is_na = CSeq_inst::IsNa(scope.GetSequenceType(align.GetSeq_id(0)));
+    bool subject_is_na = CSeq_inst::IsNa(scope.GetSequenceType(align.GetSeq_id(1)));
     if (kTranslated) {
         CRef<CSeq_align> densegAln = align.CreateDensegFromStdseg();
         // When both query and subject are translated, i.e. tblastx, convert
         // to a special type of Dense-seg.
-        if (query_is_na && subject_is_na)
+        if (query_is_na && subject_is_na) {
             finalAln = densegAln->CreateTranslatedDensegFromNADenseg();
-        else
+        }
+        else {
             finalAln = densegAln;
+        }
     } else if (align.GetSegs().IsDendiag()) {
         finalAln = CAlignFormatUtil::CreateDensegFromDendiag(align);
     }
@@ -1065,6 +1080,13 @@ int CBlastTabularInfo::SetFields(const CSeq_align& align,
         }
 
     }
+    else {
+    	if (x_IsFieldRequested(eSubjFrame) || x_IsFieldRequested(eFrames)) {
+    		if ((s_start - s_end) > 0 ) {
+    			subject_frame = -1;
+    		}
+    	}
+    }
     SetCounts(num_ident, align_length, num_gaps, num_gap_opens, num_positives,
               query_frame, subject_frame);
     }
diff --git a/c++/src/objtools/align_format/taxFormat.cpp b/c++/src/objtools/align_format/taxFormat.cpp
index be579ec..4e9e683 100644
--- a/c++/src/objtools/align_format/taxFormat.cpp
+++ b/c++/src/objtools/align_format/taxFormat.cpp
@@ -1,4 +1,4 @@
-/*  $Id: taxFormat.cpp 490145 2016-01-21 16:35:07Z zaretska $
+/*  $Id: taxFormat.cpp 504856 2016-06-20 15:36:19Z zaretska $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  *   Sequence alignment display
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: taxFormat.cpp 490145 2016-01-21 16:35:07Z zaretska $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objects/taxon1/taxon1.hpp>
 #include <objects/taxon1/Taxon2_data.hpp>
@@ -61,14 +56,19 @@ USING_SCOPE(sequence);
 BEGIN_SCOPE(align_format)
 
 
-
 CTaxFormat::CTaxFormat(const CSeq_align_set& seqalign, 
                        CScope& scope,
-                       bool connectToTaxServer)
+                       unsigned int displayOption,
+                       bool connectToTaxServer,
+                       unsigned int lineLength)
+                      
                       
     : m_SeqalignSetRef(&seqalign),
       m_Scope(scope),
-      m_ConnectToTaxServer(connectToTaxServer)
+      m_DisplayOption(displayOption),
+      m_ConnectToTaxServer(connectToTaxServer),
+      m_LineLength(lineLength) //used for text output
+      
 {
     m_TaxClient = NULL;    
     m_TaxTreeLoaded = false;    
@@ -77,6 +77,14 @@ CTaxFormat::CTaxFormat(const CSeq_align_set& seqalign,
     m_TaxTreeinfo = NULL;
     m_BlastResTaxInfo = NULL;    
     m_Debug = false;
+
+    m_MaxAccLength = 0;
+    m_MaxDescrLength = 0;
+    m_MaxScoreLength = 0;
+    m_MaxEvalLength = 0;
+    m_LineLength = (m_LineLength < kMinLineLength) ? kMinLineLength : m_LineLength;
+
+    m_Protocol = CAlignFormatUtil::GetProtocol();
     
     if(m_ConnectToTaxServer) {        
         x_InitTaxClient();        
@@ -93,16 +101,17 @@ CTaxFormat::CTaxFormat(const CSeq_align_set& seqalign,
         m_TaxBrowserURL = m_Reg->Get("TAX_BROWSER","BLASTFMTUTIL");
     }
     m_TaxBrowserURL = (m_TaxBrowserURL.empty()) ? kTaxBrowserURL : m_TaxBrowserURL;
+    m_TaxBrowserURL = CAlignFormatUtil::MapTemplate(m_TaxBrowserURL,"protocol",m_Protocol);
 
     
         
     m_TaxFormatTemplates = new STaxFormatTemplates;        
 
     m_TaxFormatTemplates->blastNameLink = kBlastNameLink;
-    m_TaxFormatTemplates->orgReportTable = kOrgReportTable;
-    m_TaxFormatTemplates->orgReportOrganismHeader = kOrgReportOrganismHeader; ///< Template for displaying header
-    m_TaxFormatTemplates->orgReportTableHeader  = kOrgReportTableHeader; ///< Template for displaying header
-    m_TaxFormatTemplates->orgReportTableRow = kOrgReportTableRow;
+    m_TaxFormatTemplates->orgReportTable = (m_DisplayOption == eHtml) ? kOrgReportTable : kOrgReportTxtTable;
+    m_TaxFormatTemplates->orgReportOrganismHeader = (m_DisplayOption == eHtml) ? kOrgReportOrganismHeader : kOrgReportTxtOrganismHeader; ///< Template for displaying header
+    m_TaxFormatTemplates->orgReportTableHeader  = (m_DisplayOption == eHtml) ? kOrgReportTableHeader : kOrgReportTxtTableHeader; ///< Template for displaying header
+    m_TaxFormatTemplates->orgReportTableRow = (m_DisplayOption == eHtml) ? kOrgReportTableRow : kOrgReportTxtTableRow;
 
     m_TaxFormatTemplates->taxIdToSeqsMap = kTaxIdToSeqsMap;
 
@@ -351,7 +360,8 @@ void CTaxFormat::DisplayOrgReport(CNcbiOstream& out)
         int taxid = m_BlastResTaxInfo->orderedTaxids[i];
         STaxInfo seqsForTaxID = m_BlastResTaxInfo->seqTaxInfoMap[taxid];
         
-        string orgHeader = (m_ConnectToTaxServer) ? m_TaxFormatTemplates->orgReportOrganismHeader : kOrgReportOrganismHeaderNoTaxConnect;
+        string orgHeader = (m_ConnectToTaxServer) ? m_TaxFormatTemplates->orgReportOrganismHeader : 
+                                                    (m_DisplayOption == eHtml) ? kOrgReportOrganismHeaderNoTaxConnect : kOrgReportTxtOrganismHeaderNoTaxConnect;        
         orgHeader = x_MapTaxInfoTemplate(orgHeader,seqsForTaxID);
         string prevTaxid,nextTaxid, hidePrevTaxid, hideNextTaxid, hideTop;
         const string kDisabled = "disabled=\"disabled\"";
@@ -389,9 +399,19 @@ void CTaxFormat::DisplayOrgReport(CNcbiOstream& out)
         string taxIdToSeqsRow = CAlignFormatUtil::MapTemplate(m_TaxFormatTemplates->taxIdToSeqsMap,"giList",seqsForTaxID.giList);
         taxIdToSeqsRow = CAlignFormatUtil::MapTemplate(taxIdToSeqsRow,"taxid",taxid);
         taxIdToSeqsMap += taxIdToSeqsRow;
-    }
+    }   
     orgReportData = CAlignFormatUtil::MapTemplate(m_TaxFormatTemplates->orgReportTable,"table_rows",orgReportData);
-    orgReportData = CAlignFormatUtil::MapTemplate(orgReportData,"taxidToSeqsMap",taxIdToSeqsMap);    
+    if(m_DisplayOption == eText) {
+        string reportCaption = CAlignFormatUtil::AddSpaces(kOrgReportTxtTableCaption,m_LineLength,CAlignFormatUtil::eSpacePosToCenter | CAlignFormatUtil::eAddEOLAtLineStart);
+        orgReportData = CAlignFormatUtil::MapTemplate(orgReportData,"org_report_caption",reportCaption);
+        orgReportData = CAlignFormatUtil::MapSpaceTemplate(orgReportData,"acc_hd",kOrgAccTxtTableHeader,m_MaxAccLength);                
+        orgReportData = CAlignFormatUtil::MapSpaceTemplate(orgReportData,"descr_hd",kOrgDescrTxtTableHeader,m_MaxDescrLength,CAlignFormatUtil::eSpacePosToCenter);                
+        orgReportData = CAlignFormatUtil::MapSpaceTemplate(orgReportData,"score_hd",kOrgScoreTxtTableHeader,m_MaxScoreLength);
+        orgReportData = CAlignFormatUtil::MapSpaceTemplate(orgReportData,"evalue_hd",kOrgEValueTxtTableHeader,m_MaxEvalLength);        
+    }
+    else {        
+        orgReportData = CAlignFormatUtil::MapTemplate(orgReportData,"taxidToSeqsMap",taxIdToSeqsMap);    
+    }
     out << orgReportData;
 }
 
@@ -755,6 +775,14 @@ bool CTaxFormat::isTaxidInAlign(int taxid)
     return ret;    
 }
 
+void CTaxFormat::x_InitTextFormatInfo(CTaxFormat::SSeqInfo *seqInfo)
+{
+    m_MaxAccLength = max(max(m_MaxAccLength,(unsigned int)seqInfo->label.size()),(unsigned int)kOrgAccTxtTableHeader.size());    
+    m_MaxDescrLength = max(max(m_MaxDescrLength,(unsigned int)seqInfo->title.size()),(unsigned int)kOrgDescrTxtTableHeader.size());        
+    m_MaxScoreLength = max(max(m_MaxScoreLength,(unsigned int)seqInfo->bit_score.size()),(unsigned int)kOrgScoreTxtTableHeader.size());    
+    m_MaxEvalLength = max(max(m_MaxEvalLength,(unsigned int)seqInfo->evalue.size()),(unsigned int)kOrgEValueTxtTableHeader.size());    
+    m_MaxDescrLength =  m_LineLength - m_MaxAccLength - m_MaxScoreLength - m_MaxEvalLength - 4;//4 for spaces in between            
+ }
 
 CTaxFormat::SSeqInfo *CTaxFormat::x_FillTaxDispParams(const CBioseq_Handle& bsp_handle,
                                     double bits, 
@@ -764,11 +792,14 @@ CTaxFormat::SSeqInfo *CTaxFormat::x_FillTaxDispParams(const CBioseq_Handle& bsp_
 	seqInfo->gi = FindGi(bsp_handle.GetBioseqCore()->GetId());
 	seqInfo->seqID = FindBestChoice(bsp_handle.GetBioseqCore()->GetId(),CSeq_id::WorstRank);
 	seqInfo->label =  CAlignFormatUtil::GetLabel(seqInfo->seqID);//Just accession without db part like ref| or pdbd|		
-    seqInfo->bit_score = bits;
-    seqInfo->evalue = evalue;        
+
+    string total_bit_score_buf, raw_score_buf;
+    CAlignFormatUtil::GetScoreString(evalue, bits, 0, 0, seqInfo->evalue, seqInfo->bit_score, total_bit_score_buf,raw_score_buf);           
+
     seqInfo->displGi = seqInfo->gi;
     seqInfo->taxid = 0;	
 	seqInfo->title = CDeflineGenerator().GenerateDefline(bsp_handle);			    
+    if(m_DisplayOption == eText) x_InitTextFormatInfo(seqInfo); 
     return seqInfo;
 }
 
@@ -801,8 +832,10 @@ CTaxFormat::SSeqInfo *CTaxFormat::x_FillTaxDispParams(const CRef< CBlast_def_lin
 		seqInfo->gi =  gi;
 		seqInfo->seqID = FindBestChoice(ids, CSeq_id::WorstRank);		
 		seqInfo->label =  CAlignFormatUtil::GetLabel(seqInfo->seqID);//Just accession without db part like ref| or pdbd|		
-        seqInfo->bit_score = bits;
-        seqInfo->evalue = evalue;         
+
+        string total_bit_score_buf, raw_score_buf;
+        CAlignFormatUtil::GetScoreString(evalue, bits, 0, 0, seqInfo->evalue, seqInfo->bit_score, total_bit_score_buf,raw_score_buf);
+
 	    int taxid = 0;
 		
 		if(bdl->IsSetTaxid() &&  bdl->CanGetTaxid()){
@@ -817,6 +850,7 @@ CTaxFormat::SSeqInfo *CTaxFormat::x_FillTaxDispParams(const CRef< CBlast_def_lin
         if(seqInfo->title.empty()) {
             seqInfo->title = CDeflineGenerator().GenerateDefline(bsp_handle);            
         }        
+        if(m_DisplayOption == eText) x_InitTextFormatInfo(seqInfo);
 	}    	
     return seqInfo;
 }
@@ -872,7 +906,7 @@ void CTaxFormat::x_InitTaxInfoMap(void)
         catch (const CException&){
             continue;
         }                
-    }        
+    }                
 }
 
 void CTaxFormat::x_InitBlastDBTaxInfo(CTaxFormat::SSeqInfo *seqInfo)    
@@ -917,22 +951,27 @@ string CTaxFormat::x_MapSeqTemplate(string seqTemplate, STaxInfo &taxInfo)
     
     return reportTableRow;
 }
-
-
+        
 string CTaxFormat::x_MapSeqTemplate(string seqTemplate, SSeqInfo *seqInfo)
 {
-    string evalue_buf, bit_score_buf, total_bit_score_buf, raw_score_buf;
-    CAlignFormatUtil::GetScoreString(seqInfo->evalue, seqInfo->bit_score, 0, 0,
-                                             evalue_buf, bit_score_buf, total_bit_score_buf,raw_score_buf);
-
-    string reportTableRow = CAlignFormatUtil::MapTemplate(seqTemplate,"acc",seqInfo->label);    
-    reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"gi",NStr::NumericToString(seqInfo->gi));
-    reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"disp_gi",NStr::NumericToString(seqInfo->displGi));    
-    reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"descr",seqInfo->title);
-    reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"descr_abbr",seqInfo->title.substr(0,60));//for standalone output    
-    reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"score",bit_score_buf);
-    reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"evalue",evalue_buf);           
+    string reportTableRow = CAlignFormatUtil::MapTemplate(seqTemplate,"gi",NStr::NumericToString(seqInfo->gi));
+    reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"disp_gi",NStr::NumericToString(seqInfo->displGi));        
+    reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"descr_abbr",seqInfo->title.substr(0,60));//for standalone output        
     reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"rid",m_Rid);
+
+    if(m_DisplayOption == eText) {
+        reportTableRow = CAlignFormatUtil::MapSpaceTemplate(reportTableRow,"acc",seqInfo->label,m_MaxAccLength);                
+        reportTableRow = CAlignFormatUtil::MapSpaceTemplate(reportTableRow,"descr_text",seqInfo->title,m_MaxDescrLength);                
+        reportTableRow = CAlignFormatUtil::MapSpaceTemplate(reportTableRow,"score",seqInfo->bit_score,m_MaxScoreLength);
+        reportTableRow = CAlignFormatUtil::MapSpaceTemplate(reportTableRow,"evalue",seqInfo->evalue,m_MaxEvalLength);
+    }
+    else {
+        reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"acc",seqInfo->label);    
+        reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"descr",seqInfo->title);
+        reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"score",seqInfo->bit_score);
+        reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"evalue",seqInfo->evalue);           
+        reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"protocol",m_Protocol);
+    }
     return reportTableRow;
 }
 
@@ -942,7 +981,12 @@ string CTaxFormat::x_MapTaxInfoTemplate(string tableRowTemplate,STaxInfo &taxInf
     reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"scientific_name",taxInfo.scientificName);
     string commonName = (taxInfo.commonName != taxInfo.scientificName) ? "(" + taxInfo.commonName + ")" : "";    
     reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"common_name",commonName);        
-    reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"blast_name",taxInfo.blastName);                    
+    reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"blast_name",taxInfo.blastName);      
+    if(m_DisplayOption == eText) {
+        string txtOrgValue = reportTableRow;//Contains <@scientific_name@>[<@blast_name@>] mapped
+        reportTableRow = CAlignFormatUtil::AddSpaces(txtOrgValue,m_LineLength,CAlignFormatUtil::eSpacePosToCenter | CAlignFormatUtil::eAddEOLAtLineStart | CAlignFormatUtil::eAddEOLAtLineEnd);
+    }
+    
     reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"bl_taxid",taxInfo.blNameTaxid);
     reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"taxid",taxInfo.taxid);
     reportTableRow = CAlignFormatUtil::MapTemplate(reportTableRow,"taxBrowserURL",m_TaxBrowserURL);    
diff --git a/c++/src/objtools/align_format/unit_test/Makefile.align_format_unit_test.app b/c++/src/objtools/align_format/unit_test/Makefile.align_format_unit_test.app
index f80cadf..8454ce9 100644
--- a/c++/src/objtools/align_format/unit_test/Makefile.align_format_unit_test.app
+++ b/c++/src/objtools/align_format/unit_test/Makefile.align_format_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.align_format_unit_test.app 482779 2015-10-26 18:46:34Z boratyng $
+# $Id: Makefile.align_format_unit_test.app 500410 2016-05-04 15:43:09Z gouriano $
 
 APP = align_format_unit_test
 SRC = showdefline_unit_test showalign_unit_test blast_test_util \
@@ -9,8 +9,8 @@ CXXFLAGS = $(FAST_CXXFLAGS)
 LDFLAGS = $(FAST_LDFLAGS)
 
 LIB_ = test_boost $(BLAST_DB_DATA_LOADER_LIBS) align_format taxon1 blastdb_format \
-	gene_info xalnmgr xcgi xhtml seqmasks_io seqdb blast_services xobjutil \
-        $(OBJREAD_LIBS) xnetblastcli xnetblast blastdb scoremat tables xalnmgr $(OBJMGR_LIBS)
+        gene_info xalnmgr xcgi xhtml seqmasks_io seqdb blast_services xobjutil \
+	$(OBJREAD_LIBS) xnetblastcli xnetblast blastdb scoremat tables $(OBJMGR_LIBS)
 
 LIB = $(LIB_:%=%$(STATIC))
 LIBS = $(CMPRS_LIBS) $(NETWORK_LIBS) $(DL_LIBS) $(ORIG_LIBS)
diff --git a/c++/src/objtools/align_format/unit_test/data/in_showalign_use_this_gi_ext.asn b/c++/src/objtools/align_format/unit_test/data/in_showalign_use_this_gi_ext.asn
new file mode 100755
index 0000000..ce40960
--- /dev/null
+++ b/c++/src/objtools/align_format/unit_test/data/in_showalign_use_this_gi_ext.asn
@@ -0,0 +1,1073 @@
+Seq-annot ::= {
+  desc {
+    user {
+      type str "Hist Seqalign",
+      data {
+        {
+          label str "Hist Seqalign",
+          data bool TRUE
+        }
+      }
+    },
+    user {
+      type str "Blast Type",
+      data {
+        {
+          label str "psiblast",
+          data int 10
+        }
+      }
+    },
+    user {
+      type str "Blast Database Title",
+      data {
+        {
+          label str "All non-redundant GenBank CDS
+ translations+PDB+SwissProt+PIR+PRF excluding environmental samples from WGS
+ projects",
+          data bool FALSE
+        }
+      }
+    }
+  },
+  data align {
+    {
+      type partial,
+      dim 2,
+      score {
+        {
+          id str "score",
+          value int 1237
+        },
+        {
+          id str "blast_score",
+          value int 1237
+        },
+        {
+          id str "e_value",
+          value real { 811021147991027, 10, -186 }
+        },
+        {
+          id str "bit_score",
+          value real { 48110010768981, 10, -11 }
+        },
+        {
+          id str "num_ident",
+          value int 232
+        },
+        {
+          id str "comp_adjustment_method",
+          value int 2
+        },        
+        {
+          id str "num_positives",
+          value int 232
+        },
+        {
+          id str "hsp_percent_coverage",
+          value real { 1, 10, 2 }
+        },
+        {
+          id str "pc_ident",
+          value real { 1, 10, 0 }
+        },
+        {
+          id str "seq_evalue",
+          value real { 811021147991027, 10, -186 }
+        },
+        {
+          id str "seq_bit_score",
+          value real { 48110010768981, 10, -11 }
+        },
+        {
+          id str "seq_total_bit_score",
+          value real { 48110010768981, 10, -11 }
+        },
+        {
+          id str "seq_percent_coverage",
+          value int 100
+        },
+        {
+          id str "seq_percent_identity",
+          value int 100
+        },
+        {
+          id str "seq_hspnum",
+          value int 1
+        },
+        {
+          id str "seq_align_totlen",
+          value real { 232, 10, 0 }
+        }
+      },
+      segs denseg {
+        dim 2,
+        numseg 1,
+        ids {
+          gi 129295,
+          gi 129295
+        },
+        starts {
+          0,
+          0
+        },
+        lens {
+          232
+        },
+        strands {
+          unknown,
+          unknown
+        }
+      },
+      ext {
+        {
+          type str "use_this_seqid",
+          data {
+            {
+              label str "SEQIDS",
+              num 2,
+              data strs {
+                "gi:129295"              
+              }
+            }
+          }
+        }
+      }
+    },
+    {
+      type partial,
+      dim 2,
+      score {
+        {
+          id str "score",
+          value int 1228
+        },
+        {
+          id str "blast_score",
+          value int 1228
+        },
+        {
+          id str "e_value",
+          value real { 48986488021524, 10, -181 }
+        },
+        {
+          id str "bit_score",
+          value real { 477633311506554, 10, -12 }
+        },
+        {
+          id str "num_ident",
+          value int 229
+        },
+        {
+          id str "comp_adjustment_method",
+          value int 2
+        },        
+        {
+          id str "num_positives",
+          value int 230
+        },
+        {
+          id str "hsp_percent_coverage",
+          value real { 1, 10, 2 }
+        },
+        {
+          id str "pc_ident",
+          value real { 987068965517241, 10, -15 }
+        },
+        {
+          id str "seq_evalue",
+          value real { 48986488021524, 10, -181 }
+        },
+        {
+          id str "seq_bit_score",
+          value real { 477633311506554, 10, -12 }
+        },
+        {
+          id str "seq_total_bit_score",
+          value real { 477633311506554, 10, -12 }
+        },
+        {
+          id str "seq_percent_coverage",
+          value int 100
+        },
+        {
+          id str "seq_percent_identity",
+          value int 99
+        },
+        {
+          id str "seq_hspnum",
+          value int 1
+        },
+        {
+          id str "seq_align_totlen",
+          value real { 232, 10, 0 }
+        }
+      },
+      segs denseg {
+        dim 2,
+        numseg 1,
+        ids {
+          gi 129295,
+          gi 448824824
+        },
+        starts {
+          0,
+          156
+        },
+        lens {
+          232
+        },
+        strands {
+          unknown,
+          unknown
+        }
+      },
+      ext {
+        {
+          type str "use_this_seqid",
+          data {
+            {
+              label str "SEQIDS",
+              num 2,
+              data strs {       
+                "gi:448824824"
+              }
+            }
+          }
+        }
+      }
+    },
+    {
+      type partial,
+      dim 2,
+      score {
+        {
+          id str "score",
+          value int 1226
+        },
+        {
+          id str "blast_score",
+          value int 1226
+        },
+        {
+          id str "e_value",
+          value real { 170841590304487, 10, -181 }
+        },
+        {
+          id str "bit_score",
+          value real { 476862912354719, 10, -12 }
+        },
+        {
+          id str "num_ident",
+          value int 229
+        },
+        {
+          id str "comp_adjustment_method",
+          value int 2
+        },        
+        {
+          id str "num_positives",
+          value int 230
+        },
+        {
+          id str "hsp_percent_coverage",
+          value real { 1, 10, 2 }
+        },
+        {
+          id str "pc_ident",
+          value real { 987068965517241, 10, -15 }
+        },
+        {
+          id str "seq_evalue",
+          value real { 170841590304487, 10, -181 }
+        },
+        {
+          id str "seq_bit_score",
+          value real { 476862912354719, 10, -12 }
+        },
+        {
+          id str "seq_total_bit_score",
+          value real { 476862912354719, 10, -12 }
+        },
+        {
+          id str "seq_percent_coverage",
+          value int 100
+        },
+        {
+          id str "seq_percent_identity",
+          value int 99
+        },
+        {
+          id str "seq_hspnum",
+          value int 1
+        },
+        {
+          id str "seq_align_totlen",
+          value real { 232, 10, 0 }
+        }
+      },
+      segs denseg {
+        dim 2,
+        numseg 1,
+        ids {
+          gi 129295,
+          gi 510032768
+        },
+        starts {
+          0,
+          170
+        },
+        lens {
+          232
+        },
+        strands {
+          unknown,
+          unknown
+        }
+      },
+      ext {
+        {
+          type str "use_this_seqid",
+          data {
+            {
+              label str "SEQIDS",
+              num 2,
+              data strs {       
+                "gi:510032768"
+              }
+            }
+          }
+        }
+      }
+    },
+    {
+      type partial,
+      dim 2,
+      score {
+        {
+          id str "score",
+          value int 1133
+        },
+        {
+          id str "blast_score",
+          value int 1133
+        },
+        {
+          id str "e_value",
+          value real { 237944940659373, 10, -167 }
+        },
+        {
+          id str "bit_score",
+          value real { 441039351794405, 10, -12 }
+        },
+        {
+          id str "num_ident",
+          value int 211
+        },
+        {
+          id str "comp_adjustment_method",
+          value int 2
+        },        
+        {
+          id str "num_positives",
+          value int 224
+        },
+        {
+          id str "hsp_percent_coverage",
+          value real { 1, 10, 2 }
+        },
+        {
+          id str "pc_ident",
+          value real { 90948275862069, 10, -14 }
+        },
+        {
+          id str "seq_evalue",
+          value real { 237944940659373, 10, -167 }
+        },
+        {
+          id str "seq_bit_score",
+          value real { 441039351794405, 10, -12 }
+        },
+        {
+          id str "seq_total_bit_score",
+          value real { 441039351794405, 10, -12 }
+        },
+        {
+          id str "seq_percent_coverage",
+          value int 100
+        },
+        {
+          id str "seq_percent_identity",
+          value int 91
+        },
+        {
+          id str "seq_hspnum",
+          value int 1
+        },
+        {
+          id str "seq_align_totlen",
+          value real { 232, 10, 0 }
+        }
+      },
+      segs denseg {
+        dim 2,
+        numseg 1,
+        ids {
+          gi 129295,
+          gi 733881413
+        },
+        starts {
+          0,
+          170
+        },
+        lens {
+          232
+        },
+        strands {
+          unknown,
+          unknown
+        }
+      },
+      ext {
+        {
+          type str "use_this_seqid",
+          data {
+            {
+              label str "SEQIDS",
+              num 2,
+              data strs {       
+                "gi:733881413"
+              }
+            }
+          }
+        }
+      }
+    },
+    {
+      type partial,
+      dim 2,
+      score {
+        {
+          id str "score",
+          value int 990
+        },
+        {
+          id str "blast_score",
+          value int 990
+        },
+        {
+          id str "e_value",
+          value real { 656868398284742, 10, -146 }
+        },
+        {
+          id str "bit_score",
+          value real { 385955812438224, 10, -12 }
+        },
+        {
+          id str "num_ident",
+          value int 181
+        },
+        {
+          id str "comp_adjustment_method",
+          value int 2
+        },        
+        {
+          id str "num_positives",
+          value int 207
+        },
+        {
+          id str "hsp_percent_coverage",
+          value real { 1, 10, 2 }
+        },
+        {
+          id str "pc_ident",
+          value real { 780172413793103, 10, -15 }
+        },
+        {
+          id str "seq_evalue",
+          value real { 656868398284742, 10, -146 }
+        },
+        {
+          id str "seq_bit_score",
+          value real { 385955812438224, 10, -12 }
+        },
+        {
+          id str "seq_total_bit_score",
+          value real { 385955812438224, 10, -12 }
+        },
+        {
+          id str "seq_percent_coverage",
+          value int 100
+        },
+        {
+          id str "seq_percent_identity",
+          value int 78
+        },
+        {
+          id str "seq_hspnum",
+          value int 1
+        },
+        {
+          id str "seq_align_totlen",
+          value real { 232, 10, 0 }
+        }
+      },
+      segs denseg {
+        dim 2,
+        numseg 1,
+        ids {
+          gi 129295,
+          gi 385145541
+        },
+        starts {
+          0,
+          156
+        },
+        lens {
+          232
+        },
+        strands {
+          unknown,
+          unknown
+        }
+      },
+      ext {
+        {
+          type str "use_this_seqid",
+          data {
+            {
+              label str "SEQIDS",
+              num 2,
+              data strs {       
+                "gi:385145541"
+              }
+            }
+          }
+        }
+      }
+    },
+    {
+      type partial,
+      dim 2,
+      score {
+        {
+          id str "score",
+          value int 985
+        },
+        {
+          id str "blast_score",
+          value int 985
+        },
+        {
+          id str "e_value",
+          value real { 30817206154261, 10, -144 }
+        },
+        {
+          id str "bit_score",
+          value real { 384029814558637, 10, -12 }
+        },
+        {
+          id str "num_ident",
+          value int 180
+        },
+        {
+          id str "comp_adjustment_method",
+          value int 2
+        },        
+        {
+          id str "num_positives",
+          value int 207
+        },
+        {
+          id str "hsp_percent_coverage",
+          value real { 1, 10, 2 }
+        },
+        {
+          id str "pc_ident",
+          value real { 775862068965517, 10, -15 }
+        },
+        {
+          id str "seq_evalue",
+          value real { 30817206154261, 10, -144 }
+        },
+        {
+          id str "seq_bit_score",
+          value real { 384029814558637, 10, -12 }
+        },
+        {
+          id str "seq_total_bit_score",
+          value real { 384029814558637, 10, -12 }
+        },
+        {
+          id str "seq_percent_coverage",
+          value int 100
+        },
+        {
+          id str "seq_percent_identity",
+          value int 78
+        },
+        {
+          id str "seq_hspnum",
+          value int 1
+        },
+        {
+          id str "seq_align_totlen",
+          value real { 232, 10, 0 }
+        }
+      },
+      segs denseg {
+        dim 2,
+        numseg 1,
+        ids {
+          gi 129295,
+          gi 71897377
+        },
+        starts {
+          0,
+          156
+        },
+        lens {
+          232
+        },
+        strands {
+          unknown,
+          unknown
+        }
+      },
+      ext {
+        {
+          type str "use_this_seqid",
+          data {
+            {
+              label str "SEQIDS",
+              num 2,
+              data strs {
+                "gi:129296",
+                "gi:212900",
+                "gi:71897377",
+                "gi:385145537",
+                "gi:385145539"
+              }
+            }
+          }
+        }
+      }
+    },
+    {
+      type partial,
+      dim 2,
+      score {
+        {
+          id str "score",
+          value int 977
+        },
+        {
+          id str "blast_score",
+          value int 977
+        },
+        {
+          id str "e_value",
+          value real { 588602003232089, 10, -144 }
+        },
+        {
+          id str "bit_score",
+          value real { 380948217951298, 10, -12 }
+        },
+        {
+          id str "num_ident",
+          value int 178
+        },
+        {
+          id str "comp_adjustment_method",
+          value int 2
+        },        
+        {
+          id str "num_positives",
+          value int 209
+        },
+        {
+          id str "hsp_percent_coverage",
+          value real { 1, 10, 2 }
+        },
+        {
+          id str "pc_ident",
+          value real { 767241379310345, 10, -15 }
+        },
+        {
+          id str "seq_evalue",
+          value real { 588602003232089, 10, -144 }
+        },
+        {
+          id str "seq_bit_score",
+          value real { 380948217951298, 10, -12 }
+        },
+        {
+          id str "seq_total_bit_score",
+          value real { 380948217951298, 10, -12 }
+        },
+        {
+          id str "seq_percent_coverage",
+          value int 100
+        },
+        {
+          id str "seq_percent_identity",
+          value int 77
+        },
+        {
+          id str "seq_hspnum",
+          value int 1
+        },
+        {
+          id str "seq_align_totlen",
+          value real { 232, 10, 0 }
+        }
+      },
+      segs denseg {
+        dim 2,
+        numseg 1,
+        ids {
+          gi 129295,
+          gi 733881415
+        },
+        starts {
+          0,
+          156
+        },
+        lens {
+          232
+        },
+        strands {
+          unknown,
+          unknown
+        }
+      },
+      ext {
+        {
+          type str "use_this_seqid",
+          data {
+            {
+              label str "SEQIDS",
+              num 2,
+              data strs {      
+                "gi:733881415"
+              }
+            }
+          }
+        }
+      }
+    },
+    {
+      type partial,
+      dim 2,
+      score {
+        {
+          id str "score",
+          value int 958
+        },
+        {
+          id str "blast_score",
+          value int 958
+        },
+        {
+          id str "e_value",
+          value real { 17920560600765, 10, -142 }
+        },
+        {
+          id str "bit_score",
+          value real { 373629426008868, 10, -12 }
+        },
+        {
+          id str "num_ident",
+          value int 175
+        },
+        {
+          id str "comp_adjustment_method",
+          value int 2
+        },        
+        {
+          id str "num_positives",
+          value int 214
+        },
+        {
+          id str "hsp_percent_coverage",
+          value real { 1, 10, 2 }
+        },
+        {
+          id str "pc_ident",
+          value real { 754310344827586, 10, -15 }
+        },
+        {
+          id str "seq_evalue",
+          value real { 17920560600765, 10, -142 }
+        },
+        {
+          id str "seq_bit_score",
+          value real { 373629426008868, 10, -12 }
+        },
+        {
+          id str "seq_total_bit_score",
+          value real { 373629426008868, 10, -12 }
+        },
+        {
+          id str "seq_percent_coverage",
+          value int 100
+        },
+        {
+          id str "seq_percent_identity",
+          value int 75
+        },
+        {
+          id str "seq_hspnum",
+          value int 1
+        },
+        {
+          id str "seq_align_totlen",
+          value real { 232, 10, 0 }
+        }
+      },
+      segs denseg {
+        dim 2,
+        numseg 1,
+        ids {
+          gi 129295,
+          gi 697456700
+        },
+        starts {
+          0,
+          0
+        },
+        lens {
+          232
+        },
+        strands {
+          unknown,
+          unknown
+        }
+      },
+      ext {
+        {
+          type str "use_this_seqid",
+          data {
+            {
+              label str "SEQIDS",
+              num 2,
+              data strs {       
+                "gi:697456700"
+              }
+            }
+          }
+        }
+      }
+    },
+    {
+      type partial,
+      dim 2,
+      score {
+        {
+          id str "score",
+          value int 958
+        },
+        {
+          id str "blast_score",
+          value int 958
+        },
+        {
+          id str "e_value",
+          value real { 232892966327255, 10, -143 }
+        },
+        {
+          id str "bit_score",
+          value real { 373629426008868, 10, -12 }
+        },
+        {
+          id str "num_ident",
+          value int 174
+        },
+        {
+          id str "comp_adjustment_method",
+          value int 2
+        },        
+        {
+          id str "num_positives",
+          value int 211
+        },
+        {
+          id str "hsp_percent_coverage",
+          value real { 1, 10, 2 }
+        },
+        {
+          id str "pc_ident",
+          value real { 75, 10, -2 }
+        },
+        {
+          id str "seq_evalue",
+          value real { 232892966327255, 10, -143 }
+        },
+        {
+          id str "seq_bit_score",
+          value real { 373629426008868, 10, -12 }
+        },
+        {
+          id str "seq_total_bit_score",
+          value real { 373629426008868, 10, -12 }
+        },
+        {
+          id str "seq_percent_coverage",
+          value int 100
+        },
+        {
+          id str "seq_percent_identity",
+          value int 75
+        },
+        {
+          id str "seq_hspnum",
+          value int 1
+        },
+        {
+          id str "seq_align_totlen",
+          value real { 232, 10, 0 }
+        }
+      },
+      segs denseg {
+        dim 2,
+        numseg 1,
+        ids {
+          gi 129295,
+          gi 677552130
+        },
+        starts {
+          0,
+          0
+        },
+        lens {
+          232
+        },
+        strands {
+          unknown,
+          unknown
+        }
+      },
+      ext {
+        {
+          type str "use_this_seqid",
+          data {
+            {
+              label str "SEQIDS",
+              num 2,
+              data strs {       
+                "gi:677552130"
+              }
+            }
+          }
+        }
+      }
+    },
+    {
+      type partial,
+      dim 2,
+      score {
+        {
+          id str "score",
+          value int 955
+        },
+        {
+          id str "blast_score",
+          value int 955
+        },
+        {
+          id str "e_value",
+          value real { 62217975104378, 10, -142 }
+        },
+        {
+          id str "bit_score",
+          value real { 372473827281116, 10, -12 }
+        },
+        {
+          id str "num_ident",
+          value int 175
+        },
+        {
+          id str "comp_adjustment_method",
+          value int 2
+        },        
+        {
+          id str "num_positives",
+          value int 211
+        },
+        {
+          id str "hsp_percent_coverage",
+          value real { 1, 10, 2 }
+        },
+        {
+          id str "pc_ident",
+          value real { 754310344827586, 10, -15 }
+        },
+        {
+          id str "seq_evalue",
+          value real { 62217975104378, 10, -142 }
+        },
+        {
+          id str "seq_bit_score",
+          value real { 372473827281116, 10, -12 }
+        },
+        {
+          id str "seq_total_bit_score",
+          value real { 372473827281116, 10, -12 }
+        },
+        {
+          id str "seq_percent_coverage",
+          value int 100
+        },
+        {
+          id str "seq_percent_identity",
+          value int 75
+        },
+        {
+          id str "seq_hspnum",
+          value int 1
+        },
+        {
+          id str "seq_align_totlen",
+          value real { 232, 10, 0 }
+        }
+      },
+      segs denseg {
+        dim 2,
+        numseg 1,
+        ids {
+          gi 129295,
+          gi 679011882
+        },
+        starts {
+          0,
+          0
+        },
+        lens {
+          232
+        },
+        strands {
+          unknown,
+          unknown
+        }
+      },
+      ext {
+        {
+          type str "use_this_seqid",
+          data {
+            {
+              label str "SEQIDS",
+              num 2,
+              data strs {       
+                "gi:679011882"
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+
+
+
diff --git a/c++/src/objtools/align_format/unit_test/showalign_unit_test.cpp b/c++/src/objtools/align_format/unit_test/showalign_unit_test.cpp
index 09faa1a..91e8115 100644
--- a/c++/src/objtools/align_format/unit_test/showalign_unit_test.cpp
+++ b/c++/src/objtools/align_format/unit_test/showalign_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: showalign_unit_test.cpp 482204 2015-10-21 15:34:36Z zaretska $
+/*  $Id: showalign_unit_test.cpp 520429 2016-11-28 18:25:40Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -113,7 +113,42 @@ BOOST_AUTO_TEST_CASE(TestTGIConversion)
     BOOST_REQUIRE(output.find("gi|385145539") != NPOS);        
 }
 
-bool TestSimpleAlignment(CBlastOM::ELocation location)
+BOOST_AUTO_TEST_CASE(TestTGIConversionExt)
+{
+    const string seqAlignFileName_in = "data/in_showalign_use_this_gi_ext.asn";
+    CRef<CSeq_annot> san(new CSeq_annot);
+  
+    ifstream in(seqAlignFileName_in.c_str());
+    in >> MSerial_AsnText >> *san;
+    in.close();
+    
+    CRef<CSeq_align_set> fileSeqAlignSet(new CSeq_align_set);  
+    fileSeqAlignSet->Set() = san->GetData().GetAlign();     
+
+    const string kDbName("nr");
+    const CBlastDbDataLoader::EDbType kDbType(CBlastDbDataLoader::eProtein);      
+    TestUtil::CBlastOM tmp_data_loader(kDbName, kDbType, CBlastOM::eLocal);        
+    CRef<CScope> scope = tmp_data_loader.NewScope();
+    
+    CDisplaySeqalign ds(*fileSeqAlignSet, *scope);
+    ds.SetDbName(kDbName);
+    ds.SetDbType((kDbType == CBlastDbDataLoader::eProtein));
+    int flags = CDisplaySeqalign::eShowBlastInfo |
+        CDisplaySeqalign::eShowGi | 
+        CDisplaySeqalign::eShowBlastStyleId;
+    ds.SetAlignOption(flags);
+    ds.SetSeqLocChar(CDisplaySeqalign::eLowerCase);
+    CNcbiOstrstream output_stream;
+    ds.DisplaySeqalign(output_stream);
+    string output = CNcbiOstrstreamToString(output_stream);        
+    BOOST_REQUIRE(output.find("gi|212900") != NPOS);
+    BOOST_REQUIRE(output.find("gi|385145537") != NPOS);
+    BOOST_REQUIRE(output.find("gi|385145539") != NPOS);
+    BOOST_REQUIRE(output.find("gi|129296") != NPOS);
+    BOOST_REQUIRE(output.find("gi|71897377") != NPOS);
+}
+
+bool TestSimpleAlignment(CBlastOM::ELocation location, bool long_seqids)
 {
     const string seqAlignFileName_in = "data/blastn.vs.ecoli.asn";
     CRef<CSeq_annot> san(new CSeq_annot);
@@ -135,14 +170,22 @@ bool TestSimpleAlignment(CBlastOM::ELocation location)
     ds.SetDbName(kDbName);
     ds.SetDbType((kDbType == CBlastDbDataLoader::eNucleotide));
     int flags = CDisplaySeqalign::eShowBlastInfo |
-        CDisplaySeqalign::eShowGi | 
         CDisplaySeqalign::eShowBlastStyleId;
+    if (long_seqids) {
+        flags |= CDisplaySeqalign::eShowGi;
+        ds.UseLongSequenceIds();
+    }
     ds.SetAlignOption(flags);
     ds.SetSeqLocChar(CDisplaySeqalign::eLowerCase);
     CNcbiOstrstream output_stream;
     ds.DisplaySeqalign(output_stream);
     string output = CNcbiOstrstreamToString(output_stream);    
-    BOOST_REQUIRE(output.find(">gi|1788470|gb|AE000304.1|AE000304 ") != NPOS);
+    if (!long_seqids) {
+        BOOST_REQUIRE(output.find(">AE000304.1 ") != NPOS);
+    }
+    else {
+        BOOST_REQUIRE(output.find(">gi|1788470|gb|AE000304.1|AE000304 ") != NPOS);
+    }
     BOOST_REQUIRE(output.find("Escherichia coli K-12 MG1655 section 9 of 400 of ") != NPOS ||
                   output.find("Escherichia coli K12 MG1655 section 9 of 400 of ") != NPOS);
     BOOST_REQUIRE(output.find("Sbjct  259   GCCTGATGCGACGCTGGCGCGTCTTATCAGGCCTAC  294") != NPOS);
@@ -171,12 +214,14 @@ NCBITEST_AUTO_INIT()
 
 BOOST_AUTO_TEST_CASE(TestSimpleAlignment_LocalBlastDBLoader)
 {
-    BOOST_REQUIRE(TestSimpleAlignment(CBlastOM::eLocal));
+    BOOST_REQUIRE(TestSimpleAlignment(CBlastOM::eLocal, false));
+    BOOST_REQUIRE(TestSimpleAlignment(CBlastOM::eLocal, true));
 }
 
 BOOST_AUTO_TEST_CASE(TestSimpleAlignment_RmtBlastDBLoader)
 {
-   BOOST_REQUIRE(TestSimpleAlignment(CBlastOM::eRemote));
+    BOOST_REQUIRE(TestSimpleAlignment(CBlastOM::eRemote, false));
+    BOOST_REQUIRE(TestSimpleAlignment(CBlastOM::eRemote, true));
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/c++/src/objtools/align_format/unit_test/showdefline_unit_test.cpp b/c++/src/objtools/align_format/unit_test/showdefline_unit_test.cpp
index 5a3b9e1..db7a085 100644
--- a/c++/src/objtools/align_format/unit_test/showdefline_unit_test.cpp
+++ b/c++/src/objtools/align_format/unit_test/showdefline_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: showdefline_unit_test.cpp 478164 2015-09-04 14:48:17Z fongah2 $
+/*  $Id: showdefline_unit_test.cpp 507726 2016-07-21 14:42:04Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -115,15 +115,15 @@ struct CShowBlastDeflineTest : public CShowBlastDefline {
                   CShowBlastDefline::SScoreInfo* si, 
                   int index)
     {
-        TGi gi_list[] = {GI_FROM(TIntId, 18426812), GI_FROM(TIntId, 6680636)};
+        TGi gi_list[] = {GI_CONST(18426812), GI_CONST(6680636)};
         string defline[] = {"adenosine deaminase [Rattus norvegicus]", 
                             "adenosine deaminase [Mus musculus]"};
         string evalue_string[] = {"2e-141", "3e-141"};
         string bit_string[] = {"503", "502"};
         int sum_n[] = {1, 1};
                 
-        string id_url[] = {"<a title=\"Show report for NP_569083.1\" href=\"//www.ncbi.nlm.nih.gov/nucleotide/18426812?report=genbank&log$=nucltop&blast_rank=1&RID=\" >",
-                           "<a title=\"Show report for NP_031424.1\" href=\"//www.ncbi.nlm.nih.gov/nucleotide/6680636?report=genbank&log$=nucltop&blast_rank=1&RID=\" >"};
+        string id_url[] = {"<a title=\"Show report for NP_569083.1\" href=\"https://www.ncbi.nlm.nih.gov/nucleotide/18426812?report=genbank&log$=nucltop&blast_rank=1&RID=\" >",
+                           "<a title=\"Show report for NP_031424.1\" href=\"https://www.ncbi.nlm.nih.gov/nucleotide/6680636?report=genbank&log$=nucltop&blast_rank=1&RID=\" >"};
         string score_url[] = {"<a href=#18426812>", "<a href=#6680636>"};
         bool is_new[] = {false, false};
         bool was_checked[] = {false, false};
diff --git a/c++/src/objtools/align_format/unit_test/tabularinof_unit_test.cpp b/c++/src/objtools/align_format/unit_test/tabularinof_unit_test.cpp
index 38a1b49..4d101b9 100644
--- a/c++/src/objtools/align_format/unit_test/tabularinof_unit_test.cpp
+++ b/c++/src/objtools/align_format/unit_test/tabularinof_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: tabularinof_unit_test.cpp 495725 2016-03-21 14:24:26Z ivanov $
+/*  $Id: tabularinof_unit_test.cpp 516292 2016-10-12 14:27:10Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -96,8 +96,8 @@ BOOST_AUTO_TEST_CASE(StandardOutput) {
 
     string output = CNcbiOstrstreamToString(output_stream);
 
-    BOOST_REQUIRE(output.find("gi|1786181|gb|AE000111.1|AE000111	gi|1786181|gb|AE000111.1|AE000111	100.000	10596	0	0	1	10596") != NPOS);
-    BOOST_REQUIRE(output.find("gi|1786181|gb|AE000111.1|AE000111	gi|1787084|gb|AE000188.1|AE000188	97.059	34	1	0	5567	5600	1088") != NPOS);
+    BOOST_REQUIRE(output.find("AE000111.1	AE000111.1	100.000	10596	0	0	1	10596") != NPOS);
+    BOOST_REQUIRE(output.find("AE000111.1	AE000188.1	97.059	34	1	0	5567	5600	1088") != NPOS);
     BOOST_REQUIRE(output.find("# BLAST processed 1 queries") != NPOS);
 }
 
@@ -300,13 +300,16 @@ BOOST_AUTO_TEST_CASE(SubjectTitlesOutput) {
 		"X12497	XP_010832415	PREDICTED: interleukin-1 alpha [Bison bison bison]",
 		"X12497	BAE76004	Interleukin-1 alpha [Bubalus carabanensis]",
 		"X12497	XP_006056051	PREDICTED: interleukin-1 alpha [Bubalus bubalis]",
-		"X12497	NP_001277833	interleukin 1, alpha [Bubalus bubalis]"};
+		"X12497	NP_001277833	interleukin-1 alpha [Bubalus bubalis]"};
 
     	string output = CNcbiOstrstreamToString(output_stream);
     	vector<string> results;
     	NStr::Split(output, "\n", results);
     	for(unsigned int i=0; i < 8; i++) {
-    	    BOOST_REQUIRE(results[i].find(ref[i]) != NPOS);
+            CNcbiOstrstream oss;
+            oss << "Failed to find '" << ref[i] << "' in '" << output;
+            string msg = CNcbiOstrstreamToString(oss);
+    	    BOOST_REQUIRE_MESSAGE(results[i].find(ref[i]) != NPOS, msg);
     	}
     }
 
@@ -329,11 +332,14 @@ BOOST_AUTO_TEST_CASE(SubjectTitlesOutput) {
             "PREDICTED: interleukin-1 alpha [Bison bison bison]",
             "Interleukin-1 alpha [Bubalus carabanensis]",
             "PREDICTED: interleukin-1 alpha [Bubalus bubalis]<>interleukin-1 alpha [Bubalus bubalis]<>Interleukin-1 alpha [Bubalus bubalis x Bubalus carabanensis]",
-            "interleukin 1, alpha [Bubalus bubalis]<>Interleukin-1 alpha [Bubalus bubalis]"}; 
+            "interleukin-1 alpha [Bubalus bubalis]<>Interleukin-1 alpha [Bubalus bubalis]"}; 
     	vector<string> results;
     	NStr::Split(output, "\n", results);
     	for(unsigned int i=0; i < 8; i++) {
-    	    BOOST_REQUIRE(results[i].find(ref[i]) != NPOS);
+            CNcbiOstrstream oss;
+            oss << "Failed to find '" << ref[i] << "' in '" << output;
+            string msg = CNcbiOstrstreamToString(oss);
+    	    BOOST_REQUIRE_MESSAGE(results[i].find(ref[i]) != NPOS, msg);
     	}
     }
 }
diff --git a/c++/src/objtools/align_format/vectorscreen.cpp b/c++/src/objtools/align_format/vectorscreen.cpp
index c0fe8b6..bd1b443 100644
--- a/c++/src/objtools/align_format/vectorscreen.cpp
+++ b/c++/src/objtools/align_format/vectorscreen.cpp
@@ -1,4 +1,4 @@
-/*  $Id: vectorscreen.cpp 441136 2014-07-21 17:54:53Z jianye $
+/*  $Id: vectorscreen.cpp 506273 2016-07-06 14:18:55Z zaretska $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  *   vector screen graphic (using HTML table) 
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: vectorscreen.cpp 441136 2014-07-21 17:54:53Z jianye $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/align_format/vectorscreen.hpp>
 #include <util/range.hpp>
@@ -325,7 +320,7 @@ CVecscreen::CVecscreen(const CSeq_align_set& seqalign, TSeqPos master_length){
     m_ImagePath = "./";
     m_MasterLen = master_length;
     m_FinalSeqalign = new CSeq_align_set;
-    m_HelpDocsUrl = "http://www.ncbi.nlm.nih.gov/tools/vecscreen/about/";    
+    m_HelpDocsUrl = "//www.ncbi.nlm.nih.gov/tools/vecscreen/about/";    
     m_ShowWeakMatch = true;
 }
 
diff --git a/c++/src/objtools/alnmgr/Makefile.alnmgr.lib b/c++/src/objtools/alnmgr/Makefile.alnmgr.lib
index fac02e9..15b8d33 100644
--- a/c++/src/objtools/alnmgr/Makefile.alnmgr.lib
+++ b/c++/src/objtools/alnmgr/Makefile.alnmgr.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.alnmgr.lib 468535 2015-05-26 13:23:32Z ucko $
+# $Id: Makefile.alnmgr.lib 502200 2016-05-23 14:42:40Z vakatov $
 
 # Build library "xalnmgr"
 #################################
@@ -12,8 +12,7 @@ SRC = aln_builders aln_converters aln_generators aln_seqid aln_serial	\
 
 DLL_LIB = tables
 
-WATCHERS = todorov dicuccio grichenk
-
+WATCHERS = grichenk
 
 
 USES_LIBRARIES =  \
diff --git a/c++/src/objtools/alnmgr/Makefile.in b/c++/src/objtools/alnmgr/Makefile.in
index ad1383d..0490511 100644
--- a/c++/src/objtools/alnmgr/Makefile.in
+++ b/c++/src/objtools/alnmgr/Makefile.in
@@ -1,7 +1,9 @@
-# $Id: Makefile.in 369976 2012-07-25 15:20:22Z grichenk $
+# $Id: Makefile.in 502200 2016-05-23 14:42:40Z vakatov $
 
 LIB_PROJ = alnmgr
 SUB_PROJ = demo unit_test
 
+WATCHERS = grichenk
+
 srcdir = @srcdir@
 include @builddir@/Makefile.meta
diff --git a/c++/src/objtools/alnmgr/aln_builders.cpp b/c++/src/objtools/alnmgr/aln_builders.cpp
index 414113e..7fed646 100644
--- a/c++/src/objtools/alnmgr/aln_builders.cpp
+++ b/c++/src/objtools/alnmgr/aln_builders.cpp
@@ -1,4 +1,4 @@
-/*  $Id: aln_builders.cpp 498721 2016-04-19 13:29:11Z ivanov $
+/*  $Id: aln_builders.cpp 498677 2016-04-18 22:27:18Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/alnmgr/alnvec.cpp b/c++/src/objtools/alnmgr/alnvec.cpp
index f077bd2..53e6099 100644
--- a/c++/src/objtools/alnmgr/alnvec.cpp
+++ b/c++/src/objtools/alnmgr/alnvec.cpp
@@ -1,4 +1,4 @@
-/*  $Id: alnvec.cpp 414872 2013-09-27 13:44:10Z ucko $
+/*  $Id: alnvec.cpp 520514 2016-11-29 16:11:43Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -971,7 +971,8 @@ int CAlnVec::CalculateScore(TNumrow row1, TNumrow row2) const
                                     size2 - start2,
                                     buff2);
             }
-            score += CalculateScore(buff1, buff2, isAA1, isAA2);
+            score += CalculateScore(buff1, buff2, isAA1, isAA2,
+                GetGenCode(row1), GetGenCode(row2));
         }
 
         index1 += numrows;
diff --git a/c++/src/objtools/alnmgr/score_builder_base.cpp b/c++/src/objtools/alnmgr/score_builder_base.cpp
index 4a2b488..08470b6 100644
--- a/c++/src/objtools/alnmgr/score_builder_base.cpp
+++ b/c++/src/objtools/alnmgr/score_builder_base.cpp
@@ -1,4 +1,4 @@
-/*  $Id: score_builder_base.cpp 474106 2015-07-24 21:06:03Z vasilche $
+/*  $Id: score_builder_base.cpp 495880 2016-03-22 14:14:37Z chetvern $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -412,7 +412,8 @@ static void s_GetCountIdentityMismatch(CScope& scope, const CSeq_align& align,
                          part_start += part_len;
                      }
                  } else {
-                     aln_identities += s_IntersectionLength(ranges, product_span);
+                     has_non_standard = true;
+                     break;
                  }
              }
              if ( !has_non_standard ) {
diff --git a/c++/src/objtools/alnmgr/sparse_aln.cpp b/c++/src/objtools/alnmgr/sparse_aln.cpp
index d06df79..9b92459 100644
--- a/c++/src/objtools/alnmgr/sparse_aln.cpp
+++ b/c++/src/objtools/alnmgr/sparse_aln.cpp
@@ -1,4 +1,4 @@
-/*  $Id: sparse_aln.cpp 498721 2016-04-19 13:29:11Z ivanov $
+/*  $Id: sparse_aln.cpp 520514 2016-11-29 16:11:43Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -445,15 +445,18 @@ CSeqVector& CSparseAln::x_GetSeqVector(TNumrow row) const
 
 int CSparseAln::x_GetGenCode(TNumrow row) const
 {
-    int gencode = kDefaultGenCode;
-    try {
-        CBioseq_Handle h = GetBioseqHandle(row);
-        if ( h ) {
-            gencode = sequence::GetOrg_ref(h).GetGcode();
-        }
-    }
-    catch (...) {}
-    return gencode;
+    CBioseq_Handle h = GetBioseqHandle(row);
+    if ( !h ) return kDefaultGenCode;
+
+    // Try to use bio-source first.
+    CConstRef<CBioSource> src(sequence::GetBioSource(h));
+    if ( src ) return src->GetGenCode();
+
+    // Fallback to org-ref.
+    CConstRef<COrg_ref> ref(sequence::GetOrg_refOrNull(h));
+    if ( ref ) return ref->GetGcode();
+
+    return kDefaultGenCode;
 }
 
 
diff --git a/c++/src/objtools/blast/blastdb_format/Makefile.blastdb_format.lib b/c++/src/objtools/blast/blastdb_format/Makefile.blastdb_format.lib
index fefa51a..9cfbe04 100644
--- a/c++/src/objtools/blast/blastdb_format/Makefile.blastdb_format.lib
+++ b/c++/src/objtools/blast/blastdb_format/Makefile.blastdb_format.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.blastdb_format.lib 432686 2014-04-16 18:59:06Z rackerst $
+# $Id: Makefile.blastdb_format.lib 516388 2016-10-13 12:25:09Z ivanov $
 
 WATCHERS = camacho
 
@@ -6,7 +6,7 @@ ASN_DEP = blastdb seqset
 
 ###  BASIC PROJECT SETTINGS
 LIB = blastdb_format
-SRC = seq_writer blastdb_dataextract blastdb_formatter
+SRC = seq_writer blastdb_dataextract blastdb_formatter seq_formatter
 # OBJ =
 
 CPPFLAGS = -DNCBI_MODULE=BLASTDB $(ORIG_CPPFLAGS)
diff --git a/c++/src/objtools/blast/blastdb_format/blastdb_dataextract.cpp b/c++/src/objtools/blast/blastdb_format/blastdb_dataextract.cpp
index 92cb928..29b1802 100644
--- a/c++/src/objtools/blast/blastdb_format/blastdb_dataextract.cpp
+++ b/c++/src/objtools/blast/blastdb_format/blastdb_dataextract.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastdb_dataextract.cpp 479437 2015-09-21 12:40:14Z madden $
+/*  $Id: blastdb_dataextract.cpp 521160 2016-12-06 15:25:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /** @file blastdb_dataextract.cpp
  *  Defines classes which extract data from a BLAST database
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: blastdb_dataextract.cpp 479437 2015-09-21 12:40:14Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/blastdb_format/invalid_data_exception.hpp>
 #include <objtools/blast/blastdb_format/blastdb_dataextract.hpp>
@@ -53,6 +48,8 @@ USING_SCOPE(objects);
 #define NOT_AVAILABLE "N/A"
 #define SEPARATOR ";"
 
+extern string GetBareId(const CSeq_id& id);
+
 void CBlastDBExtractor::SetSeqId(const CBlastDBSeqId &id, bool get_data) {
     m_Defline.Reset();
     m_Gi = ZERO_GI;
@@ -289,8 +286,14 @@ void CBlastDBExtractor::x_SetGi2SeqIdMap()
             }
         }
         CRef<CSeq_id> theId = FindBestChoice((*bd)->GetSeqid(), CSeq_id::WorstRank);
-        if (gi != INVALID_GI)
-            gi2id[gi] = theId->AsFastaString();
+        if (gi != INVALID_GI) {
+            if (m_UseLongSeqIds) {
+                gi2id[gi] = theId->AsFastaString();
+            }
+            else {
+                gi2id[gi] = GetBareId(*theId);
+            }
+        }
     }
 	m_Gi2SeqIdMap.first = m_Oid;
 	m_Gi2SeqIdMap.second.swap(gi2id);
@@ -348,11 +351,18 @@ string CBlastDBExtractor::ExtractSeqId() {
     if (theId->IsGeneral() && theId->GetGeneral().GetDb() == "BL_ORD_ID") {
         	return NOT_AVAILABLE;
     }
-    string retval = theId->AsFastaString();
+    string retval;
+
+    if (m_UseLongSeqIds) {
+        retval = theId->AsFastaString();
 
-    // Remove "lcl|" on local ID.
-    if(theId->IsLocal())
-	retval = retval.erase(0, 4);
+        // Remove "lcl|" on local ID.
+        if(theId->IsLocal())
+            retval = retval.erase(0, 4);
+    }
+    else {
+        retval = GetBareId(*theId);
+    }
 
     return retval;
 }
@@ -538,8 +548,8 @@ string CBlastDBExtractor::ExtractSuperKingdom() {
 //    }
 //}
 
+    static const string kNoMasksFound = "none";
 string CBlastDBExtractor::ExtractMaskingData() {
-    static const string kNoMasksFound("none");
 #if ((defined(NCBI_COMPILER_WORKSHOP) && (NCBI_COMPILER_VERSION <= 550))  ||  \
      defined(NCBI_COMPILER_MIPSPRO))
     return kNoMasksFound;
@@ -585,30 +595,18 @@ string CBlastDBExtractor::ExtractSeqLen() {
     return NStr::IntToString(m_BlastDb.GetSeqLength(m_Oid));
 }
 
-// Calculates hash for a buffer in IUPACna (NCBIeaa for proteins) format.
-// NOTE: if sequence is in a different format, the function below can be modified to convert
-// each byte into IUPACna encoding on the fly.
-static int s_GetHash(const char* buffer, int length)
-{
-    CChecksum crc(CChecksum::eCRC32ZIP);
-
-    for(int ii = 0; ii < length; ii++) {
-        if (buffer[ii] != '\n')
-            crc.AddChars(buffer+ii,1);
-    }
-    return (crc.GetChecksum() ^ (0xFFFFFFFFL));
-}
-
 string CBlastDBExtractor::ExtractHash() {
     string seq;
     m_BlastDb.GetSequenceAsString(m_Oid, seq);
-    return NStr::IntToString(s_GetHash(seq.c_str(), seq.size()));
+    return NStr::IntToString(CBlastSeqUtil::GetSeqHash(seq.c_str(), seq.size()));
 }
 
+#define CTRL_A "\001"
+
 static void s_ReplaceCtrlAsInTitle(CRef<CBioseq> bioseq)
 {
     static const string kTarget(" >gi|");
-    static const string kCtrlA = string(1, '\001') + string("gi|");
+    static const string kCtrlA = string(CTRL_A) + string("gi|");
     NON_CONST_ITERATE(CSeq_descr::Tdata, desc, bioseq->SetDescr().Set()) {
         if ((*desc)->Which() == CSeqdesc::e_Title) {
             NStr::ReplaceInPlace((*desc)->SetTitle(), kTarget, kCtrlA);
@@ -617,9 +615,10 @@ static void s_ReplaceCtrlAsInTitle(CRef<CBioseq> bioseq)
     }
 }
 
-static string s_GetTitle(CConstRef<CBioseq> bioseq)
+static string s_GetTitle(const CBioseq & bioseq)
 {
-    ITERATE(CSeq_descr::Tdata, desc, bioseq->GetDescr().Get()) {
+    _ASSERT(bioseq.CanGetDescr());
+    ITERATE(CSeq_descr::Tdata, desc, bioseq.GetDescr().Get()) {
         if ((*desc)->Which() == CSeqdesc::e_Title) {
             return (*desc)->GetTitle();
         }
@@ -627,16 +626,52 @@ static string s_GetTitle(CConstRef<CBioseq> bioseq)
     return string();
 }
 
+/// Auxiliary function to format the defline for FASTA output format
+static string
+s_ConfigureDeflineTitle(const string& title, bool use_ctrl_a)
+{
+    static const string kStandardSeparator(" >");
+    const string kSeparator(use_ctrl_a ? CTRL_A : kStandardSeparator);
+    string retval;
+    list<string> tokens;
+    NStr::Split(title, kStandardSeparator, tokens, NStr::fSplit_ByPattern);
+    int idx = 0;
+    for (auto token : tokens) {
+        if (idx++ == 0) {
+            retval += token;
+            continue;
+        }
+        SIZE_TYPE pos = token.find(' ');
+        const string kPossibleId(token, 0, pos != NPOS ? pos : token.length());
+        CBioseq::TId seqids;
+        
+        try { 
+            CSeq_id::ParseIDs(seqids, kPossibleId, CSeq_id::fParse_PartialOK);
+        } catch (const CException& e) {} 
+
+        if (!seqids.empty()) {
+            retval += kSeparator;
+            CRef<CSeq_id> id = FindBestChoice(seqids, CSeq_id::Score);
+            retval += GetBareId(*id);
+            if (pos != NPOS)
+                retval += token.substr(pos, token.length() - pos);
+        } else {
+            retval += kStandardSeparator + token;
+        }
+    }
+    return retval;
+}
+
 string CBlastDBExtractor::ExtractFasta(const CBlastDBSeqId &id) {
     stringstream out("");
 
     CFastaOstream fasta(out);
     fasta.SetWidth(m_LineWidth);
-    fasta.SetAllFlags(CFastaOstream::fKeepGTSigns);
+    fasta.SetAllFlags(CFastaOstream::fKeepGTSigns|CFastaOstream::fEnableGI);
 
     SetSeqId(id, true);
 
-    if (m_UseCtrlA) {
+    if (m_UseCtrlA && m_UseLongSeqIds) {
         s_ReplaceCtrlAsInTitle(m_Bioseq);
     }
 
@@ -669,16 +704,31 @@ string CBlastDBExtractor::ExtractFasta(const CBlastDBSeqId &id) {
     }
 
     try { 
-	if (seqid->IsLocal())
-	{
-		string lcl_tmp = seqid->AsFastaString();
-		lcl_tmp = lcl_tmp.erase(0, 4);
-		out << ">" << lcl_tmp << " " << s_GetTitle(m_Bioseq) << '\n';
-		CScope scope(*CObjectManager::GetInstance());
-		fasta.WriteSequence(scope.AddBioseq(*m_Bioseq), range); 
-	}
-	else
-		fasta.Write(*m_Bioseq, range); 
+        if (m_UseLongSeqIds) {
+            if (seqid->IsLocal()) {
+                string lcl_tmp = seqid->AsFastaString();
+                lcl_tmp = lcl_tmp.erase(0, 4);
+                out << ">" << lcl_tmp << " " << s_GetTitle(*m_Bioseq) << '\n';
+                CScope scope(*CObjectManager::GetInstance());
+                fasta.WriteSequence(scope.AddBioseq(*m_Bioseq), range); 
+            }
+            else  {
+                fasta.Write(*m_Bioseq, range); 
+            }
+        }
+        else {
+
+            out << '>';
+            CRef<CSeq_id> id = FindBestChoice(m_Bioseq->GetId(), CSeq_id::Score);
+            out << GetBareId(*id);
+
+            string title = s_GetTitle(*m_Bioseq.GetNonNullPointer());
+            out << ' ' << s_ConfigureDeflineTitle(title, m_UseCtrlA);
+            out << endl;
+
+            CScope scope(*CObjectManager::GetInstance());
+            fasta.WriteSequence(scope.AddBioseq(*m_Bioseq), range); 
+        }
     }
     catch (const CObjmgrUtilException& e) {
         if (e.GetErrCode() == CObjmgrUtilException::eBadLocation) {
@@ -747,4 +797,247 @@ void CBlastDBExtractor::SetConfig(TSeqRange range, objects::ENa_strand strand,
 	m_FiltAlgoId = filt_algo_id;
 }
 
+void CBlastDeflineUtil::ExtractDataFromBlastDeflineSet(const CBlast_def_line_set & dl_set,
+        											   vector<string> & results,
+        											   BlastDeflineFields fields,
+        											   string target_id,
+        											   bool use_long_id)
+{
+	CSeq_id target_seq_id (target_id, CSeq_id::fParse_PartialOK | CSeq_id::fParse_Default);
+	Int8 num_id = NStr::StringToNumeric<Int8>(target_id, NStr::fConvErr_NoThrow);
+	bool can_be_gi = errno ? false: true;
+	ITERATE(CBlast_def_line_set::Tdata, itr, dl_set.Get()) {
+		 ITERATE(CBlast_def_line::TSeqid, id, (*itr)->GetSeqid()) {
+
+			 if ((*id)->Match(target_seq_id) || (can_be_gi && (*id)->IsGi() && ((*id)->GetGi() == num_id))) {
+				 CBlastDeflineUtil::ExtractDataFromBlastDefline( **itr, results, fields, use_long_id);
+				 return;
+			 }
+		 }
+	}
+
+	NCBI_THROW(CException, eInvalid, "Failed to find target id " + target_id);
+}
+
+static string s_CheckName(const string & name)
+{
+        if(name == "-") return NOT_AVAILABLE;
+        if(name == "unclassified") return NOT_AVAILABLE;
+
+        return name;
+}
+
+void CBlastDeflineUtil::ExtractDataFromBlastDefline(const CBlast_def_line & dl,
+				                            	    vector<string> & results,
+				                                    BlastDeflineFields fields,
+				                                    bool use_long_id)
+{
+	results.clear();
+	results.resize(CBlastDeflineUtil::max_index, kEmptyStr);
+	if (fields.gi == 1) {
+         results[CBlastDeflineUtil::gi] = NOT_AVAILABLE;
+		 ITERATE(CBlast_def_line::TSeqid, id, dl.GetSeqid()) {
+			 if ((*id)->IsGi()) {
+				 TGi gi = (*id)->GetGi();
+				 results[CBlastDeflineUtil::gi] = NStr::NumericToString(gi);
+				 break;
+			 }
+	     }
+	}
+	if ((fields.accession == 1) || (fields.seq_id == 1)) {
+		 CRef<CSeq_id> theId = FindBestChoice(dl.GetSeqid(), CSeq_id::WorstRank);
+		 if(fields.seq_id == 1) {
+        	 results[CBlastDeflineUtil::seq_id] = theId->AsFastaString();
+		 }
+		 if(fields.accession == 1) {
+			 results[CBlastDeflineUtil::accession] = GetBareId(*theId);
+		 }
+	}
+	if(fields.title == 1) {
+		if(dl.IsSetTitle()) {
+        	 results[CBlastDeflineUtil::title] = dl.GetTitle();
+		}
+		else {
+        	 results[CBlastDeflineUtil::title] = NOT_AVAILABLE;
+		}
+	}
+	if ((fields.tax_id == 1) || (fields.tax_names == 1)) {
+		unsigned int tax_id = 0;
+		if (dl.IsSetTaxid()) {
+			tax_id = dl.GetTaxid();
+		}
+
+		if (fields.tax_id == 1) {
+			results[CBlastDeflineUtil::tax_id] = NStr::NumericToString(tax_id);
+		}
+
+		if (fields.tax_names == 1) {
+			try {
+				SSeqDBTaxInfo taxinfo;
+			    CSeqDB::GetTaxInfo(tax_id, taxinfo);
+			    results[CBlastDeflineUtil::scientific_name] = taxinfo.scientific_name;
+			    results[CBlastDeflineUtil::common_name] = taxinfo.common_name;
+			    results[CBlastDeflineUtil::blast_name] = s_CheckName(taxinfo.blast_name);
+			    results[CBlastDeflineUtil::super_kingdom] = s_CheckName(taxinfo.s_kingdom);
+	        } catch (const CException&) {
+			    results[CBlastDeflineUtil::scientific_name] = NOT_AVAILABLE;
+			    results[CBlastDeflineUtil::common_name] = NOT_AVAILABLE;
+			    results[CBlastDeflineUtil::blast_name] = NOT_AVAILABLE;
+			    results[CBlastDeflineUtil::super_kingdom] = NOT_AVAILABLE;
+			}
+		}
+	}
+
+	if ((fields.leaf_node_tax_ids == 1) || (fields.leaf_node_tax_names == 1)) {
+		set<int>  tax_id_set = dl.GetLeafTaxIds();
+		if (tax_id_set.empty()) {
+			if (dl.IsSetTaxid()) {
+				tax_id_set.insert(dl.GetTaxid());
+			}
+			else {
+				tax_id_set.insert(0);
+			}
+		}
+
+		string separator = kEmptyStr;
+		ITERATE(set<int>, itr, tax_id_set) {
+			if (fields.leaf_node_tax_names == 1) {
+				try {
+					SSeqDBTaxInfo taxinfo;
+					CSeqDB::GetTaxInfo(*itr, taxinfo);
+					results[CBlastDeflineUtil::leaf_node_scientific_names] += separator + taxinfo.scientific_name;
+					results[CBlastDeflineUtil::leaf_node_common_names] += separator + taxinfo.common_name;
+				} catch (const CException&) {
+				    results[CBlastDeflineUtil::leaf_node_scientific_names] += separator + NOT_AVAILABLE;
+				    results[CBlastDeflineUtil::leaf_node_common_names] += separator + NOT_AVAILABLE;
+				}
+			}
+		    results[CBlastDeflineUtil::leaf_node_tax_ids] += separator + NStr::NumericToString(*itr);
+			separator = SEPARATOR;
+		}
+	}
+
+	if (fields.membership == 1) {
+		int membership = 0;
+		if(dl.IsSetMemberships()) {
+			 ITERATE(CBlast_def_line::TMemberships, memb_int, dl.GetMemberships()) {
+				 membership += *memb_int;
+			 }
+		}
+		results[CBlastDeflineUtil::membership] = NStr::NumericToString(membership);
+	}
+
+	if (fields.pig == 1) {
+		int pig = -1;
+        if (dl.IsSetOther_info()) {
+        	ITERATE(CBlast_def_line::TOther_info, itr, dl.GetOther_info()) {
+        		if (*itr != -1) {
+        			pig = *itr;
+        			break;
+		        }
+		    }
+		}
+        results[CBlastDeflineUtil::pig] = NStr::NumericToString(pig);
+	}
+	if(fields.links == 1) {
+		if (dl.IsSetLinks()) {
+			ITERATE(CBlast_def_line::TLinks, links_int, dl.GetLinks()) {
+				results[CBlastDeflineUtil::links] += NStr::IntToString(*links_int) + SEPARATOR;
+			}
+		}
+		else {
+			results[CBlastDeflineUtil::links] = NOT_AVAILABLE;
+		}
+	}
+
+	if(fields.asn_defline == 1) {
+		CNcbiOstrstream tmp;
+		tmp << MSerial_AsnText << dl;
+		results[CBlastDeflineUtil::asn_defline] = CNcbiOstrstreamToString(tmp);
+	}
+}
+
+void CBlastDeflineUtil::ProcessFastaDeflines(CBioseq & bioseq, string & out, bool use_ctrla)
+{
+	out = kEmptyStr;
+    const CSeq_id* id = bioseq.GetFirstId();
+    if (!id) {
+        return;
+    }
+     if (id->IsGeneral() &&
+         id->GetGeneral().GetDb() == "BL_ORD_ID") {
+         out = ">"  + s_GetTitle(bioseq) + '\n';
+     }
+     else if (id->IsLocal()) {
+         string lcl_tmp = id->AsFastaString();
+         lcl_tmp = lcl_tmp.erase(0,4);
+         out = ">" + lcl_tmp + " " + s_GetTitle(bioseq) + '\n';
+     }
+     else {
+
+        out = '>';
+        id = FindBestChoice(bioseq.GetId(), CSeq_id::Score);
+        out += GetBareId(*id) + ' ';
+
+        string title = s_GetTitle(bioseq);
+        out += s_ConfigureDeflineTitle(title, use_ctrla);
+        out += '\n';
+     }
+}
+
+// Calculates hash for a buffer in IUPACna (NCBIeaa for proteins) format.
+// NOTE: if sequence is in a different format, the function below can be modified to convert
+// each byte into IUPACna encoding on the fly.
+Uint4 CBlastSeqUtil::GetSeqHash(const char* buffer, int length)
+{
+    CChecksum crc(CChecksum::eCRC32ZIP);
+
+    for(int ii = 0; ii < length; ii++) {
+        if (buffer[ii] != '\n')
+            crc.AddChars(buffer+ii,1);
+    }
+    return (crc.GetChecksum() ^ (0xFFFFFFFFL));
+}
+
+void CBlastSeqUtil::ApplySeqMask(string & seq, const CSeqDB::TSequenceRanges & masks, const TSeqRange r)
+{
+	if(r.Empty()) {
+		ITERATE(CSeqDB::TSequenceRanges, itr, masks) {
+			transform(&seq[itr->first], &seq[itr->second],
+			                      &seq[itr->first], (int (*)(int))tolower);
+		}
+	}
+	else {
+		const TSeqPos r_from = r.GetFrom();
+		ITERATE(CSeqDB::TSequenceRanges, itr, masks) {
+			TSeqRange mask (*itr);
+			if(mask.GetFrom() > r.GetTo()) {
+				break;
+			}
+			TSeqRange  tmp = r.IntersectionWith(mask);
+			if(!tmp.Empty()) {
+				transform(&seq[tmp.GetFrom() -r_from], &seq[tmp.GetToOpen() - r_from],
+		                  &seq[tmp.GetFrom() -r_from], (int (*)(int))tolower);
+			}
+		}
+	}
+}
+
+void CBlastSeqUtil::GetReverseStrandSeq(string & seq)
+{
+	CSeqManip::ReverseComplement(seq, CSeqUtil::e_Iupacna, 0, seq.size());
+}
+
+string CBlastSeqUtil::GetMasksString(const CSeqDB::TSequenceRanges & masks)
+{
+	if (masks.empty()) {
+		return kNoMasksFound;
+	}
+	CNcbiOstrstream out;
+	ITERATE(CSeqDB::TSequenceRanges, range, masks) {
+		out << range->first << "-" << range->second << SEPARATOR;
+	}
+	return CNcbiOstrstreamToString(out);
+}
+
 END_NCBI_SCOPE
diff --git a/c++/src/objtools/blast/blastdb_format/blastdb_formatter.cpp b/c++/src/objtools/blast/blastdb_format/blastdb_formatter.cpp
index 2f2c45b..8cdbe24 100644
--- a/c++/src/objtools/blast/blastdb_format/blastdb_formatter.cpp
+++ b/c++/src/objtools/blast/blastdb_format/blastdb_formatter.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blastdb_formatter.cpp 376122 2012-09-26 20:46:35Z camacho $
+/*  $Id: blastdb_formatter.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  *  Implementation of the CBlastDbFormatter class
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: blastdb_formatter.cpp 376122 2012-09-26 20:46:35Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/blastdb_format/invalid_data_exception.hpp>
 #include <objtools/blast/blastdb_format/blastdb_formatter.hpp>
diff --git a/c++/src/objtools/blast/blastdb_format/seq_formatter.cpp b/c++/src/objtools/blast/blastdb_format/seq_formatter.cpp
new file mode 100644
index 0000000..69201f3
--- /dev/null
+++ b/c++/src/objtools/blast/blastdb_format/seq_formatter.cpp
@@ -0,0 +1,543 @@
+/*  $Id:
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author: Amelia Fong
+ *
+ */
+
+/** @file seq_formatter.cpp
+ *  Implementation of the CBlastDB_Formatter classes
+ */
+
+#include <ncbi_pch.hpp>
+#include <objtools/blast/blastdb_format/seq_formatter.hpp>
+#include <objtools/blast/blastdb_format/blastdb_dataextract.hpp>
+#include <objtools/blast/blastdb_format/invalid_data_exception.hpp>
+#include <objects/seq/Seqdesc.hpp>
+#include <objects/seq/Seq_descr.hpp>
+#include <numeric>      // for std::accumulate
+#include <objmgr/object_manager.hpp>
+#include <objmgr/scope.hpp>
+
+BEGIN_NCBI_SCOPE
+USING_SCOPE(objects);
+
+
+
+static void s_GetSeqMask(CSeqDB & db, CSeqDB::TOID oid, int algo_id, CSeqDB::TSequenceRanges & masks)
+{
+#if ((defined(NCBI_COMPILER_WORKSHOP) && (NCBI_COMPILER_VERSION <= 550))  ||  \
+     defined(NCBI_COMPILER_MIPSPRO))
+    return;
+#else
+    db.GetMaskData(oid, algo_id, masks);
+#endif
+}
+
+CBlastDB_SeqFormatter::CBlastDB_SeqFormatter(const string& format_spec, CSeqDB& blastdb, CNcbiOstream& out)
+    : m_Out(out), m_FmtSpec(format_spec), m_BlastDb(blastdb), m_GetDefline(false), m_OtherFields(0)
+{
+	memset(&m_DeflineFields, 0, sizeof(CBlastDeflineUtil::BlastDeflineFields));
+
+    // Record where the offsets where the replacements must occur
+	string sp = kEmptyStr;
+    for (SIZE_TYPE i = 0; i < m_FmtSpec.size(); i++) {
+        if (m_FmtSpec[i] == '%') {
+        	if ( m_FmtSpec[i+1] == '%') {
+        	    // remove the escape character for '%'
+        		i++;
+        		sp += m_FmtSpec[i];
+        	    continue;
+        	}
+        	i++;
+            m_ReplTypes.push_back(m_FmtSpec[i]);
+            m_Seperators.push_back(sp);
+            sp = kEmptyStr;
+        }
+        else {
+        	sp += m_FmtSpec[i];
+        }
+    }
+    m_Seperators.push_back(sp);
+
+    if (m_ReplTypes.empty() || (m_ReplTypes.size() + 1 != m_Seperators.size())) {
+        NCBI_THROW(CInvalidDataException, eInvalidInput,
+                   "Invalid format specification");
+    }
+
+  	x_DataRequired();
+}
+
+void CBlastDB_SeqFormatter::x_DataRequired()
+{
+	ITERATE(vector<char>, fmt, m_ReplTypes) {
+	switch (*fmt) {
+		case 's':
+			m_OtherFields |= (1 << e_seq);
+			break;
+		case 'h':
+			m_OtherFields |= (1 << e_hash);
+			break;
+		case 'a':
+			m_DeflineFields.accession = 1;
+			m_GetDefline = true;
+			break;
+		case 'i':
+			m_DeflineFields.seq_id = 1;
+			m_GetDefline = true;
+			break;
+		case 'g':
+			m_DeflineFields.gi = 1;
+			m_GetDefline = true;
+			break;
+		case 't':
+			m_DeflineFields.title = 1;
+			m_GetDefline = true;
+			break;
+		case 'T':
+			m_DeflineFields.tax_id = 1;
+			m_GetDefline = true;
+			break;
+		case 'X':
+			m_DeflineFields.leaf_node_tax_ids = 1;
+			m_GetDefline = true;
+			break;
+		case 'P':
+			m_DeflineFields.pig = 1;
+			m_GetDefline = true;
+			break;
+		case 'L':
+		case 'B':
+		case 'K':
+		case 'S':
+			m_DeflineFields.tax_names = 1;
+			m_GetDefline = true;
+			break;
+		case 'C':
+		case 'N':
+			m_DeflineFields.leaf_node_tax_names = 1;
+			m_GetDefline = true;
+			break;
+		case 'e':
+			m_DeflineFields.membership = 1;
+			m_GetDefline = true;
+			break;
+		case 'm':
+			m_OtherFields |= (1 << e_mask);
+			break;
+		case 'n':
+			m_DeflineFields.links = 1;
+			m_GetDefline = true;
+			break;
+		case 'd':
+			m_DeflineFields.asn_defline = 1;
+			m_GetDefline = true;
+			break;
+		default:
+		 break;
+	}
+    }
+}
+
+
+void CBlastDB_SeqFormatter::x_Print(CSeqDB::TOID oid, vector<string> & defline_data, vector<string> & other_fields)
+{
+    for(unsigned int i =0; i < m_ReplTypes.size(); i++) {
+    	m_Out << m_Seperators[i];
+        switch (m_ReplTypes[i]) {
+
+        case 's':
+            m_Out << other_fields[e_seq];
+            break;
+
+        case 'a':
+            m_Out << defline_data[CBlastDeflineUtil::accession];
+            break;
+
+        case 'i':
+        	m_Out << defline_data[CBlastDeflineUtil::seq_id];
+            break;
+
+        case 'g':
+            m_Out << defline_data[CBlastDeflineUtil::gi];
+            break;
+
+        case 'o':
+            m_Out << NStr::NumericToString(oid);
+            break;
+
+        case 't':
+            m_Out << defline_data[CBlastDeflineUtil::title];
+            break;
+
+        case 'h':
+        	m_Out << other_fields[e_hash];
+            break;
+
+        case 'l':
+            m_Out << NStr::NumericToString(m_BlastDb.GetSeqLength(oid));
+            break;
+
+        case 'T':
+            m_Out << defline_data[CBlastDeflineUtil::tax_id];
+            break;
+
+        case 'X':
+            m_Out << defline_data[CBlastDeflineUtil::leaf_node_tax_ids];
+            break;
+
+        case 'P':
+            m_Out << defline_data[CBlastDeflineUtil::pig];
+            break;
+
+        case 'L':
+            m_Out << defline_data[CBlastDeflineUtil::common_name];
+            break;
+
+        case 'C':
+            m_Out << defline_data[CBlastDeflineUtil::leaf_node_common_names];
+            break;
+
+        case 'B':
+            m_Out << defline_data[CBlastDeflineUtil::blast_name];
+            break;
+
+        case 'K':
+            m_Out << defline_data[CBlastDeflineUtil::super_kingdom];
+            break;
+
+        case 'S':
+            m_Out << defline_data[CBlastDeflineUtil::scientific_name];
+            break;
+
+        case 'N':
+            m_Out << defline_data[CBlastDeflineUtil::leaf_node_scientific_names];
+            break;
+
+        case 'm':
+        	m_Out << other_fields[e_mask];
+            break;
+
+        case 'e':
+            m_Out << defline_data[CBlastDeflineUtil::membership];
+            break;
+
+        case 'n':
+            m_Out << defline_data[CBlastDeflineUtil::links];
+            break;
+
+        case 'd':
+        	m_Out << defline_data[CBlastDeflineUtil::asn_defline];
+        	break;
+        default:
+            CNcbiOstrstream os;
+            os << "Unrecognized format specification: '%" << m_ReplTypes[i] << "'";
+            NCBI_THROW(CInvalidDataException, eInvalidInput,
+                       CNcbiOstrstreamToString(os));
+        }
+    }
+    m_Out << m_Seperators.back();
+    m_Out << endl;
+}
+
+string CBlastDB_SeqFormatter::x_GetSeqHash(CSeqDB::TOID oid)
+{
+	string seq;
+	m_BlastDb.GetSequenceAsString(oid, seq);
+	CNcbiOstrstream os;
+	os << std::showbase << std::hex << std::uppercase << CBlastSeqUtil::GetSeqHash(seq.c_str(), seq.size());
+	return CNcbiOstrstreamToString(os);
+}
+
+static const string kNoMask = "none";
+string CBlastDB_SeqFormatter::x_GetSeqMask(CSeqDB::TOID oid, int algo_id)
+{
+	CSeqDB::TSequenceRanges masks;
+	s_GetSeqMask(m_BlastDb, oid, algo_id, masks);
+	return CBlastSeqUtil::GetMasksString(masks);
+}
+
+void CBlastDB_SeqFormatter::x_GetSeq(CSeqDB::TOID oid, const CBlastDB_FormatterConfig & config, string & seq)
+{
+	TSeqRange r;
+	if(config.m_SeqRange.NotEmpty()) {
+		TSeqPos length = m_BlastDb.GetSeqLength(oid);
+	    r = config.m_SeqRange;
+	    if((TSeqPos)length <= config.m_SeqRange.GetTo()) {
+	    	r.SetTo(length-1);
+	    }
+	}
+	if(r.Empty()) {
+	   	m_BlastDb.GetSequenceAsString(oid, seq);
+	}
+	else {
+	   	m_BlastDb.GetSequenceAsString(oid, seq, r);
+	}
+	if(config.m_FiltAlgoId >= 0) {
+	    CSeqDB::TSequenceRanges masks;
+	    s_GetSeqMask(m_BlastDb, oid, config.m_FiltAlgoId, masks);
+	    if(!masks.empty()) {
+	    	if(r.Empty()) {
+	    		CBlastSeqUtil::ApplySeqMask(seq, masks);
+	    	}
+	    	else {
+	    		CBlastSeqUtil::ApplySeqMask(seq, masks, r);
+	    	}
+	    }
+	}
+	if(config.m_Strand == eNa_strand_minus) {
+		CBlastSeqUtil::GetReverseStrandSeq(seq);
+	}
+}
+
+int CBlastDB_SeqFormatter::Write(CSeqDB::TOID oid, const CBlastDB_FormatterConfig & config, string target_id)
+{
+	int status = -1;
+    vector<string> other_fields(e_max_other_fields, kEmptyStr);
+    string mask = kEmptyStr;
+    if (m_OtherFields) {
+    	if (m_OtherFields & (1 << e_seq)) {
+    		x_GetSeq(oid, config, other_fields[e_seq]);
+    	}
+    	if (m_OtherFields & (1 << e_hash)) {
+    		other_fields[e_hash] = x_GetSeqHash(oid);
+    	}
+    	if (m_OtherFields & (1 << e_mask)) {
+    		other_fields[e_mask] = x_GetSeqMask(oid, config.m_FmtAlgoId);
+    	}
+    }
+    if (m_GetDefline) {
+    	CRef<CBlast_def_line_set> df_set = m_BlastDb.GetHdr(oid);
+    	if(df_set.Empty()) {
+    		return status;
+    	}
+    	if (target_id == kEmptyStr) {
+    		if(m_DeflineFields.asn_defline == 1) {
+    			m_Out << MSerial_AsnText << *df_set;
+    			return 0;
+    		}
+    		ITERATE(CBlast_def_line_set::Tdata, itr, df_set->Get()) {
+    			vector<string> defline_data(CBlastDeflineUtil::max_index, kEmptyStr);
+    			CBlastDeflineUtil::ExtractDataFromBlastDefline(**itr, defline_data, m_DeflineFields, false);
+    			x_Print(oid, defline_data, other_fields);
+    		}
+    	}
+    	else {
+   			vector<string> defline_data(CBlastDeflineUtil::max_index, kEmptyStr);
+    		CBlastDeflineUtil::ExtractDataFromBlastDeflineSet(*df_set, defline_data, m_DeflineFields, target_id, false);
+   			x_Print(oid, defline_data, other_fields);
+    	}
+    }
+    else {
+		vector<string> defline_data(CBlastDeflineUtil::max_index, kEmptyStr);
+		x_Print(oid, defline_data, other_fields);
+    }
+    return 0;
+}
+
+static void s_ReplaceCtrlAsInTitle(CBioseq & bioseq)
+{
+    static const string kTarget(" >gi|");
+    static const string kCtrlA = string(1, '\001') + string("gi|");
+    NON_CONST_ITERATE(CSeq_descr::Tdata, desc, bioseq.SetDescr().Set()) {
+        if ((*desc)->Which() == CSeqdesc::e_Title) {
+            NStr::ReplaceInPlace((*desc)->SetTitle(), kTarget, kCtrlA);
+            break;
+        }
+    }
+}
+
+void CBlastDB_SeqFormatter::DumpAll(const CBlastDB_FormatterConfig & config)
+{
+	for (int i = 0; m_BlastDb.CheckOrFindOID(i); i++) {
+		Write(i, config);
+	}
+}
+
+CBlastDB_FastaFormatter::CBlastDB_FastaFormatter(CSeqDB& blastdb, CNcbiOstream& out, TSeqPos width, bool useLongSeqId)
+    :  m_BlastDb(blastdb), m_Out(out), m_fasta(out), m_UseLongSeqIds(useLongSeqId)
+{
+	m_fasta.SetAllFlags(CFastaOstream::fKeepGTSigns|CFastaOstream::fNoExpensiveOps|CFastaOstream::fEnableGI);
+	m_fasta.SetWidth(width);
+}
+
+static void
+s_GetMaskSeqLoc(const CSeqDB::TSequenceRanges & mask_ranges, CSeq_loc & seq_loc)
+{
+	 ITERATE(CSeqDB::TSequenceRanges, itr, mask_ranges) {
+		 	 CRef<CSeq_loc> mask(new CSeq_loc());
+		 	 mask->SetInt().SetFrom(itr->first);
+		 	 mask->SetInt().SetTo(itr->second-1);
+		 	 seq_loc.SetMix().Set().push_back(mask);
+	 }
+}
+
+int CBlastDB_FastaFormatter::Write(CSeqDB::TOID oid, const CBlastDB_FormatterConfig & config, string target_id)
+{
+	int status = -1;
+	CRef<CBioseq> bioseq = m_BlastDb.GetBioseq(oid);
+	if(target_id != kEmptyStr) {
+		CSeq_id seq_id(target_id, CSeq_id::fParse_PartialOK | CSeq_id::fParse_Default);
+		Int8 num_id = NStr::StringToNumeric<Int8>(target_id, NStr::fConvErr_NoThrow);
+		if(errno) {
+			CSeq_id seq_id(target_id, CSeq_id::fParse_PartialOK | CSeq_id::fParse_Default);
+			bioseq = m_BlastDb.GetBioseq(oid, ZERO_GI, &seq_id);
+		}
+		else {
+			bioseq = m_BlastDb.GetBioseq(oid, num_id);
+		}
+	}
+	else {
+		bioseq = m_BlastDb.GetBioseq(oid);
+	}
+	if (bioseq.Empty()) {
+		return status;
+	}
+
+	if(config.m_Strand == eNa_strand_minus) {
+		m_fasta.SetFlag(CFastaOstream::fReverseStrand);
+	}
+	else {
+		m_fasta.ResetFlag(CFastaOstream::fReverseStrand);
+	}
+    if(config.m_FiltAlgoId != -1) {
+    	CSeqDB::TSequenceRanges masks;
+    	s_GetSeqMask(m_BlastDb, oid, config.m_FiltAlgoId, masks);
+    	if(!masks.empty()) {
+    		CRef<CSeq_loc> mask_loc(new CSeq_loc);
+    		s_GetMaskSeqLoc(masks, *mask_loc);
+    		mask_loc->SetId( *(FindBestChoice(bioseq->GetId(), CSeq_id::BestRank)));
+    		m_BlastDb.GetMaskData(oid, config.m_FiltAlgoId, masks);
+    		m_fasta.SetMask(CFastaOstream::eSoftMask, mask_loc);
+    	}
+    }
+    else {
+    	CRef<CSeq_loc> empty;
+    	m_fasta.SetMask(CFastaOstream::eSoftMask, empty);
+    }
+
+    CRef<CSeq_loc> range;
+    if(config.m_SeqRange.NotEmpty()) {
+    	TSeqPos length = m_BlastDb.GetSeqLength(oid);
+    	TSeqRange r = config.m_SeqRange;
+        if((TSeqPos)length <= config.m_SeqRange.GetTo()) {
+        	r.SetTo(length-1);
+    	}
+        if(!r.Empty()) {
+        	range.Reset(new CSeq_loc(*(FindBestChoice(bioseq->GetId(), CSeq_id::BestRank)), r.GetFrom(), r.GetTo()));
+        }
+    }
+    if(m_UseLongSeqIds) {
+    	if (config.m_UseCtrlA) {
+    		s_ReplaceCtrlAsInTitle(*bioseq);
+    	}
+    	CScope scope(*CObjectManager::GetInstance());
+    	if(range.Empty()) {
+    		m_fasta.Write(scope.AddBioseq(*bioseq));
+    	}
+    	else {
+    		m_fasta.Write(scope.AddBioseq(*bioseq), range.GetPointer());
+    	}
+    }
+    else {
+    	string fasta_deflines = kEmptyStr;
+    	CBlastDeflineUtil::ProcessFastaDeflines(*bioseq, fasta_deflines, config.m_UseCtrlA);
+    	m_Out << fasta_deflines;
+    	CScope scope(*CObjectManager::GetInstance());
+    	if(range.Empty()) {
+    		m_fasta.WriteSequence(scope.AddBioseq(*bioseq));
+    	}
+    	else {
+    		m_fasta.WriteSequence(scope.AddBioseq(*bioseq), range.GetPointer());
+    	}
+   }
+   return 0;
+}
+
+void CBlastDB_FastaFormatter::DumpAll(const CBlastDB_FormatterConfig & config)
+{
+    if(config.m_Strand == eNa_strand_minus) {
+    	m_fasta.SetAllFlags(CFastaOstream::fKeepGTSigns|CFastaOstream::fNoExpensiveOps|CFastaOstream::fReverseStrand|CFastaOstream::fEnableGI);
+    }
+    else {
+    	m_fasta.SetAllFlags(CFastaOstream::fKeepGTSigns|CFastaOstream::fNoExpensiveOps|CFastaOstream::fEnableGI);
+    }
+
+    for (int i=0; m_BlastDb.CheckOrFindOID(i); i++) {
+    	Write( i, config);
+    }
+}
+
+CBlastDB_BioseqFormatter::CBlastDB_BioseqFormatter(CSeqDB& blastdb, CNcbiOstream& out)
+    :  m_BlastDb(blastdb), m_Out(out)
+{
+}
+
+int CBlastDB_BioseqFormatter::Write(CSeqDB::TOID oid, const CBlastDB_FormatterConfig & config, string target_id)
+{
+	int status = -1;
+	CRef<CBioseq> bioseq = m_BlastDb.GetBioseq(oid);
+	if(target_id != kEmptyStr) {
+		CSeq_id seq_id(target_id);
+		Int8 num_id;
+		string string_id;
+		bool simpler = false;
+		ESeqDBIdType  id_type = SeqDB_SimplifySeqid(seq_id, &target_id, num_id, string_id, simpler);
+		if (id_type == eGiId) {
+			bioseq = m_BlastDb.GetBioseq(oid, num_id);
+		}
+		else {
+			bioseq = m_BlastDb.GetBioseq(oid, ZERO_GI, &seq_id);
+		}
+	}
+	else {
+		bioseq = m_BlastDb.GetBioseq(oid);
+	}
+	if (bioseq.Empty()) {
+		return status;
+	}
+
+	m_Out << MSerial_AsnText << *bioseq;
+
+   return 0;
+}
+
+void CBlastDB_BioseqFormatter::DumpAll(const CBlastDB_FormatterConfig & config)
+{
+    for (int i=0; m_BlastDb.CheckOrFindOID(i); i++) {
+    	Write( i, config);
+    }
+}
+
+
+/// Auxiliary functor to compute the length of a string
+struct StrLenAdd : public binary_function<SIZE_TYPE, const string&, SIZE_TYPE>
+{
+    SIZE_TYPE operator() (SIZE_TYPE a, const string& b) const {
+        return a + b.size();
+    }
+};
+
+END_NCBI_SCOPE
diff --git a/c++/src/objtools/blast/blastdb_format/seq_writer.cpp b/c++/src/objtools/blast/blastdb_format/seq_writer.cpp
index a9e2381..cb452a6 100644
--- a/c++/src/objtools/blast/blastdb_format/seq_writer.cpp
+++ b/c++/src/objtools/blast/blastdb_format/seq_writer.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_writer.cpp 445606 2014-09-05 13:00:52Z madden $
+/*  $Id: seq_writer.cpp 520557 2016-11-29 19:16:57Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  *  Implementation of the CSeqFormatter class
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: seq_writer.cpp 445606 2014-09-05 13:00:52Z madden $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/blastdb_format/seq_writer.hpp>
 #include <objtools/blast/blastdb_format/blastdb_dataextract.hpp>
@@ -258,11 +253,32 @@ static void s_ReplaceCtrlAsInTitle(CRef<CBioseq> bioseq)
     }
 }
 
+string GetBareId(const CSeq_id& id)
+{
+    string retval; 
+
+    if (id.IsGi() || id.IsPrf() || id.IsPir()) {
+        retval = id.AsFastaString();
+    }
+    else {
+        retval = id.GetSeqIdString(true);
+    }
+
+    return retval;
+}
+
 void CSeqFormatter::DumpAll(CSeqDB& blastdb, CSeqFormatterConfig config)
 {
     CFastaOstream fasta(m_Out);
     fasta.SetWidth(config.m_LineWidth);
-    fasta.SetAllFlags(CFastaOstream::fKeepGTSigns|CFastaOstream::fNoExpensiveOps);
+    fasta.SetAllFlags(CFastaOstream::fKeepGTSigns|CFastaOstream::fNoExpensiveOps|CFastaOstream::fEnableGI);
+
+    bool long_seqids = false;
+    CNcbiApplication* app = CNcbiApplication::Instance();
+    if (app) {
+        const CNcbiRegistry& registry = app->GetConfig();
+        long_seqids = (registry.Get("BLAST", "LONG_SEQID") == "1");
+    }
 
     CRef<CBioseq> bioseq;
     for (int i=0; blastdb.CheckOrFindOID(i); i++) {
@@ -277,7 +293,6 @@ void CSeqFormatter::DumpAll(CSeqDB& blastdb, CSeqFormatterConfig config)
              m_Out << ">" << s_GetTitle(bioseq) << '\n';
              CScope scope(*CObjectManager::GetInstance());
              fasta.WriteSequence(scope.AddBioseq(*bioseq));
-             continue;
          }
          else if (id->IsLocal()) {
 	     string lcl_tmp = id->AsFastaString();
@@ -285,12 +300,59 @@ void CSeqFormatter::DumpAll(CSeqDB& blastdb, CSeqFormatterConfig config)
 	     m_Out << ">" << lcl_tmp << " " << s_GetTitle(bioseq) << '\n';
              CScope scope(*CObjectManager::GetInstance());
              fasta.WriteSequence(scope.AddBioseq(*bioseq));
-	     continue;
-	 }
-         if (config.m_UseCtrlA) {
-             s_ReplaceCtrlAsInTitle(bioseq);
          }
-         fasta.Write(*bioseq, 0, true);
+         else if (long_seqids) {
+
+             if (config.m_UseCtrlA) {
+                 s_ReplaceCtrlAsInTitle(bioseq);
+             }
+             fasta.Write(*bioseq, 0, true);
+         }
+         else {
+
+            string separator = config.m_UseCtrlA ? "\001" : " >";
+
+            m_Out << '>';
+            id = FindBestChoice(bioseq->GetId(), CSeq_id::Score);
+            m_Out << GetBareId(*id);
+
+            string title = s_GetTitle(bioseq);
+
+            if (!title.empty()) {
+                m_Out << ' ';
+
+                NStr::ReplaceInPlace(title, " >", "\001");
+
+                vector<string> tokens;
+                NStr::Split(title, "\001", tokens);
+                auto it = tokens.begin();
+                m_Out << *it;
+                ++it;
+                for (; it != tokens.end(); ++it) {
+                    size_t pos = it->find (" ");
+                    string str_id(*it, 0, pos != NPOS ? pos : it->length());
+                    list< CRef<CSeq_id> > seqids;
+                    CSeq_id::ParseFastaIds(seqids, str_id);
+
+                    // no valid sequence ids indicates that '>' was within the
+                    // defline text
+                    if (seqids.empty()) {
+                        m_Out << " >" << *it;
+                        continue;
+                    }
+                    m_Out << separator;
+                    id = FindBestChoice(seqids, CSeq_id::Score);
+                    m_Out << GetBareId(*id);
+                    if (pos != NPOS) {
+                        m_Out << it->substr(pos, it->length() - pos);
+                    }
+                }
+            }
+            m_Out << endl;
+
+            CScope scope(*CObjectManager::GetInstance());
+            fasta.WriteSequence(scope.AddBioseq(*bioseq));
+         }
     }
 }
 
diff --git a/c++/src/objtools/blast/blastdb_format/unit_test/Makefile.blastdb_format_unit_test.app b/c++/src/objtools/blast/blastdb_format/unit_test/Makefile.blastdb_format_unit_test.app
index 6b08fb2..52e373d 100644
--- a/c++/src/objtools/blast/blastdb_format/unit_test/Makefile.blastdb_format_unit_test.app
+++ b/c++/src/objtools/blast/blastdb_format/unit_test/Makefile.blastdb_format_unit_test.app
@@ -1,7 +1,7 @@
-# $Id: Makefile.blastdb_format_unit_test.app 294689 2011-05-25 20:37:36Z camacho $
+# $Id: Makefile.blastdb_format_unit_test.app 516391 2016-10-13 12:25:53Z ivanov $
 
 APP = blastdb_format_unit_test
-SRC = seq_writer_unit_test
+SRC = seq_writer_unit_test seq_formatter_unit_test
 
 CPPFLAGS = $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
 CXXFLAGS = $(FAST_CXXFLAGS)
@@ -19,4 +19,4 @@ CHECK_COPY = data
 REQUIRES = Boost.Test.Included
 
 
-WATCHERS = zaretska jianye madden camacho
+WATCHERS = zaretska jianye madden camacho fongah2
diff --git a/c++/src/objtools/blast/blastdb_format/unit_test/seq_formatter_unit_test.cpp b/c++/src/objtools/blast/blastdb_format/unit_test/seq_formatter_unit_test.cpp
new file mode 100644
index 0000000..1d1fdf8
--- /dev/null
+++ b/c++/src/objtools/blast/blastdb_format/unit_test/seq_formatter_unit_test.cpp
@@ -0,0 +1,386 @@
+/* 
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author: Amelia Fong 
+ *
+ * File Description:
+ *   Unit tests for the sequence formatting API for BLAST database apps
+ *
+ * ===========================================================================
+ */
+
+#include <ncbi_pch.hpp>
+#include <objtools/blast/blastdb_format/seq_formatter.hpp>
+#include <objtools/blast/blastdb_format/invalid_data_exception.hpp>
+#include <corelib/ncbifile.hpp>
+#define NCBI_BOOST_NO_AUTO_TEST_MAIN
+#include <corelib/test_boost.hpp>
+#include <boost/test/auto_unit_test.hpp>
+
+USING_NCBI_SCOPE;
+
+BOOST_AUTO_TEST_SUITE(seq_formatter)
+
+static const int kConvFlags = 
+    NStr::fConvErr_NoThrow |
+    NStr::fAllowLeadingSymbols | 
+    NStr::fAllowTrailingSymbols;
+
+BOOST_AUTO_TEST_CASE(TestNoFormatSpecifier)
+{
+    CSeqDB db("data/mask-data-db", CSeqDB::eProtein);
+    const string format_spec("hello world!");
+    BOOST_REQUIRE_THROW(CBlastDB_SeqFormatter f(format_spec, db, std::cout),
+                        CInvalidDataException);
+}
+
+BOOST_AUTO_TEST_CASE(TestInvalidFormatSpecifiers_Empty)
+{
+    CSeqDB db("data/mask-data-db", CSeqDB::eProtein);
+    BOOST_REQUIRE_THROW(CBlastDB_SeqFormatter f(kEmptyStr, db, std::cout),
+                        CInvalidDataException);
+}
+
+BOOST_AUTO_TEST_CASE(TestValidFormatSpecifiers)
+{
+    CSeqDB db("data/mask-data-db", CSeqDB::eProtein);
+    CBlastDB_FormatterConfig config;
+
+    vector<string> format_specs;
+    format_specs.push_back("%o print %% sign");   // escape '%'
+    format_specs.push_back("%s");
+    format_specs.push_back("%a");
+    format_specs.push_back("%g");
+    format_specs.push_back("%o");
+    format_specs.push_back("%t");
+    format_specs.push_back("%l");
+    format_specs.push_back("%T");
+    format_specs.push_back("%P");
+    format_specs.push_back("%m"); // should print all masks for algo ID 20
+
+    config.m_FiltAlgoId = 20;
+    ITERATE(vector<string>, itr, format_specs) {
+        CBlastDB_SeqFormatter f(*itr, db, std::cout);
+    }
+
+    config.m_FiltAlgoId = 40;
+    CBlastDB_SeqFormatter f("%m", db, std::cout);
+}
+
+BOOST_AUTO_TEST_CASE(TestRequestGiOidLength)
+{
+    const int kGi(43123516);
+    CTmpFile tmpfile;
+    const string& fname = tmpfile.GetFileName();
+    CSeqDB db("data/seqp", CSeqDB::eProtein);
+    const string format_spec("The GI %g has oid %o and length %l, 10%%");
+    ofstream out(fname.c_str());
+    CBlastDB_SeqFormatter f(format_spec, db, out);
+    int id = -1;
+    db.GiToOid(kGi, id);
+    CBlastDB_FormatterConfig config;
+    f.Write(id, config);
+    out.close();
+
+    ifstream in(fname.c_str());
+    char buffer[256] = { '\0' };
+    in.getline(buffer, sizeof(buffer));
+
+    vector<string> tokens;
+    NStr::Split(string(buffer), " ", tokens, NStr::fSplit_NoMergeDelims);
+
+    int gi = NStr::StringToInt(tokens[2], kConvFlags);
+    int oid = NStr::StringToInt(tokens[5], kConvFlags);
+    int length = NStr::StringToInt(tokens[8], kConvFlags);
+    string perc = tokens[9];
+    BOOST_REQUIRE_EQUAL(gi, kGi);
+    BOOST_REQUIRE_EQUAL(oid, 99);
+    BOOST_REQUIRE_EQUAL(length, 99);
+    BOOST_REQUIRE_EQUAL(perc, string("10%"));
+}
+
+BOOST_AUTO_TEST_CASE(TestRequestSeqId)
+{
+    CMetaRegistry::SEntry sentry =
+        CMetaRegistry::Load("ncbi", CMetaRegistry::eName_RcOrIni);
+
+    string old_value;
+    bool had_entry = sentry.registry->HasEntry("BLAST", "LONG_SEQID");
+    if (had_entry) {
+        old_value = sentry.registry->Get("BLAST", "LONG_SEQID");
+    }
+    sentry.registry->Unset("BLAST", "LONG_SEQID", IRWRegistry::fPersistent);
+    BOOST_REQUIRE(sentry.registry->HasEntry("BLAST", "LONG_SEQID") == false);
+
+    const int kGi(43123516);
+    const string kSeqId("gb|EAC27631.1|,EAC27631.1");
+    CTmpFile tmpfile;
+    const string& fname = tmpfile.GetFileName();
+    CSeqDB db("data/seqp", CSeqDB::eProtein);
+    const string format_spec("%i,%a");
+    ofstream out(fname.c_str());
+    CBlastDB_SeqFormatter f(format_spec, db, out);
+    int oid = -1;
+    db.GiToOid(kGi, oid);
+    CBlastDB_FormatterConfig config;
+    f.Write(oid, config);
+    out.close();
+
+    ifstream in(fname.c_str());
+    char buffer[256] = { '\0' };
+    in.getline(buffer, sizeof(buffer));
+
+    vector<string> tokens;
+    NStr::Split(string(buffer), " ", tokens);
+
+    BOOST_REQUIRE_EQUAL(tokens[0], kSeqId);
+
+    if (had_entry) {
+        sentry.registry->Set("BLAST", "LONG_SEQID", old_value,
+                             IRWRegistry::fPersistent);
+    }
+    else {
+        sentry.registry->Unset("BLAST", "LONG_SEQID", IRWRegistry::fPersistent);
+    }
+}
+
+
+BOOST_AUTO_TEST_CASE(TestRequestSeqIdLong)
+{
+    CMetaRegistry::SEntry sentry =
+        CMetaRegistry::Load("ncbi", CMetaRegistry::eName_RcOrIni);
+
+    string old_value;
+    bool had_entry = sentry.registry->HasEntry("BLAST", "LONG_SEQID");
+    if (had_entry) {
+        old_value = sentry.registry->Get("BLAST", "LONG_SEQID");
+    }
+    sentry.registry->Set("BLAST", "LONG_SEQID", "1", IRWRegistry::fPersistent);
+    BOOST_REQUIRE(sentry.registry->HasEntry("BLAST", "LONG_SEQID") == true);
+
+    const int kGi(43123516);
+    const string kSeqId("gb|EAC27631.1|");
+    CTmpFile tmpfile;
+    const string& fname = tmpfile.GetFileName();
+    CSeqDB db("data/seqp", CSeqDB::eProtein);
+    const string format_spec("%i");
+    ofstream out(fname.c_str());
+    CBlastDB_SeqFormatter f(format_spec, db, out);
+    int oid = -1;
+    db.GiToOid(kGi, oid);
+    CBlastDB_FormatterConfig config;
+    f.Write(oid, config);
+    out.close();
+
+    ifstream in(fname.c_str());
+    char buffer[256] = { '\0' };
+    in.getline(buffer, sizeof(buffer));
+
+    vector<string> tokens;
+    NStr::Split(string(buffer), " ", tokens);
+
+    BOOST_REQUIRE_EQUAL(tokens[0], kSeqId);
+
+    if (had_entry) {
+        sentry.registry->Set("BLAST", "LONG_SEQID", old_value,
+                             IRWRegistry::fPersistent);
+    }
+    else {
+        sentry.registry->Unset("BLAST", "LONG_SEQID", IRWRegistry::fPersistent);
+    }
+}
+
+
+BOOST_AUTO_TEST_CASE(TestRequestAccessionPIGTaxidTitle)
+{
+    const int kGi(43167137);
+    CTmpFile tmpfile;
+    const string& fname = tmpfile.GetFileName();
+    CSeqDB db("data/seqp", CSeqDB::eProtein);
+    string format_spec("GI %g has accession '%a', PIG %P, taxid %T and ");
+    format_spec += "title '%t'.";
+    ofstream out(fname.c_str());
+    CBlastDB_SeqFormatter f(format_spec, db, out);
+    int oid = -1;
+    db.GiToOid(kGi, oid);
+    CBlastDB_FormatterConfig config;
+    f.Write(oid, config);
+    out.close();
+
+    ifstream in(fname.c_str());
+    char buffer[256] = { '\0' };
+    in.getline(buffer, sizeof(buffer));
+
+    vector<string> tokens;
+    NStr::Split(string(buffer), " ", tokens, NStr::fSplit_NoMergeDelims);
+
+    int gi = NStr::StringToInt(tokens[1], kConvFlags);
+    string accession = tokens[4];
+    int pig = NStr::StringToInt(tokens[6], kConvFlags);
+    int taxid = NStr::StringToInt(tokens[8], kConvFlags);
+    string title = tokens[10];
+    BOOST_REQUIRE_EQUAL(gi, kGi);
+    BOOST_REQUIRE_EQUAL(pig, -1);   // unassigned PIG in database :(
+    BOOST_REQUIRE_EQUAL(taxid, 0);
+}
+
+BOOST_AUTO_TEST_CASE(TestRequestGiGivenPIG)
+{
+    const int kPig(1067150);
+    const int kGi(129295);
+    CTmpFile tmpfile;
+    const string& fname = tmpfile.GetFileName();
+    CSeqDB db("nr", CSeqDB::eProtein);
+    const string format_spec("%g");
+    ofstream out(fname.c_str());
+    CBlastDB_SeqFormatter f(format_spec, db, out);
+    int oid = -1;
+    db.PigToOid(kPig, oid);
+    CBlastDB_FormatterConfig config;
+    f.Write(oid, config);
+    out.close();
+
+    ifstream in(fname.c_str());
+    char buffer[256] = { '\0' };
+    in.getline(buffer, sizeof(buffer));
+
+    const int gi_read = NStr::StringToInt(buffer, kConvFlags);
+    BOOST_REQUIRE_EQUAL(kGi, gi_read);
+}
+
+BOOST_AUTO_TEST_CASE(TestRequestSequenceDataLength)
+{
+    const int kGi(43167137);
+    const int kLength = 101;
+    const string
+        kSeqData("MKALVYVGEEKLDFREVADPVVNSGEQLIKVDSAGICGSDMHAYLGHDERRPAPLILGHEASGVILGGDRNGERVAINPLVTCMKCQACNSRRENICSKRQ");
+
+    CTmpFile tmpfile;
+    const string& fname = tmpfile.GetFileName();
+    CSeqDB db("data/seqp", CSeqDB::eProtein);
+    const string format_spec("%g|%l|%s");
+    ofstream out(fname.c_str());
+    CBlastDB_SeqFormatter f(format_spec, db, out);
+    int oid = -1;
+    db.GiToOid(kGi, oid);
+    CBlastDB_FormatterConfig config;
+    f.Write(oid, config);
+    out.close();
+
+    ifstream in(fname.c_str());
+    char buffer[256] = { '\0' };
+    in.getline(buffer, sizeof(buffer));
+
+    vector<string> tokens;
+    NStr::Split(string(buffer), "|", tokens, NStr::fSplit_NoMergeDelims);
+
+    int gi = NStr::StringToInt(tokens[0], kConvFlags);
+    int len = NStr::StringToInt(tokens[1], kConvFlags);
+    string seq_data = tokens[2];
+    BOOST_REQUIRE_EQUAL(gi, kGi);
+    BOOST_REQUIRE_EQUAL(len, kLength);
+    BOOST_REQUIRE_EQUAL(kSeqData, seq_data);
+}
+
+BOOST_AUTO_TEST_CASE(TestMaskedFasta)
+{
+    const int kGi(15597722);
+    const TSeqPos kLength = 1036;
+
+    CTmpFile tmpfile;
+    const string& fname = tmpfile.GetFileName();
+    const string format_spec("%f");
+    CSeqDB db("data/mask-data-db", CSeqDB::eProtein);
+    ofstream out(fname.c_str());
+    CBlastDB_FormatterConfig config;
+    config.m_SeqRange = TSeqRange(0, 100);
+    config.m_FiltAlgoId = 40;
+    //config.m_FiltAlgoIds.push_back(40);
+    CBlastDB_FastaFormatter f(db, out, config.m_SeqRange.GetLength());
+    int oid = -1;
+    db.GiToOid(kGi, oid);
+    f.Write(oid, config);
+    out.close();
+
+    ifstream in(fname.c_str());
+    char buffer[kLength+1] = { '\0' };
+    while (in.getline(buffer, sizeof(buffer))) {
+        if (NStr::StartsWith(buffer, "MSLS")) {
+            // found the sequence data
+            break;
+        }
+    }
+
+    const TSeqRange masked_range(22,72);
+    for (TSeqPos i = 0; i < masked_range.GetFrom(); i++) {
+        BOOST_REQUIRE(isupper(buffer[i]));
+    }
+    for (TSeqPos i = masked_range.GetFrom(); i < masked_range.GetTo(); i++) {
+        BOOST_REQUIRE(islower(buffer[i]));
+    }
+    for (TSeqPos i = masked_range.GetTo()+1; i < config.m_SeqRange.GetTo(); i++)
+    {
+        ostringstream os;
+        os << "Failed at position " << i << ": " << buffer[i];
+        BOOST_REQUIRE_MESSAGE(isupper(buffer[i]), os.str());
+    }
+}
+
+BOOST_AUTO_TEST_CASE(TestMaskedSequenceData)
+{
+    const int kGi(15597722);
+    const TSeqPos kLength = 1036;
+
+    CTmpFile tmpfile;
+    const string& fname = tmpfile.GetFileName();
+    const string format_spec("%s");
+    CSeqDB db("data/mask-data-db", CSeqDB::eProtein);
+    ofstream out(fname.c_str());
+    CBlastDB_FormatterConfig config;
+    config.m_FiltAlgoId = 40;
+    //config.m_FiltAlgoIds.push_back(40);
+    CBlastDB_SeqFormatter f(format_spec, db, out);
+    int oid = -1;
+    db.GiToOid(kGi, oid);
+    f.Write(oid, config);
+    out.close();
+
+    ifstream in(fname.c_str());
+    char buffer[kLength+1] = { '\0' };
+    in.getline(buffer, sizeof(buffer));     // read the sequence data
+
+    const TSeqRange masked_range(22,72);
+    for (TSeqPos i = 0; i < masked_range.GetFrom(); i++) {
+        BOOST_REQUIRE(isupper(buffer[i]));
+    }
+    for (TSeqPos i = masked_range.GetFrom(); i < masked_range.GetTo(); i++) {
+        BOOST_REQUIRE(islower(buffer[i]));
+    }
+    for (TSeqPos i = masked_range.GetTo(); i < kLength; i++) {
+        BOOST_REQUIRE(isupper(buffer[i]));
+    }
+}
+
+BOOST_AUTO_TEST_SUITE_END();
diff --git a/c++/src/objtools/blast/blastdb_format/unit_test/seq_writer_unit_test.cpp b/c++/src/objtools/blast/blastdb_format/unit_test/seq_writer_unit_test.cpp
index f7b13ea..bb43386 100644
--- a/c++/src/objtools/blast/blastdb_format/unit_test/seq_writer_unit_test.cpp
+++ b/c++/src/objtools/blast/blastdb_format/unit_test/seq_writer_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_writer_unit_test.cpp 488259 2015-12-29 14:32:15Z camacho $
+/*  $Id: seq_writer_unit_test.cpp 509852 2016-08-09 16:58:45Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -130,6 +130,61 @@ BOOST_AUTO_TEST_CASE(TestRequestGiOidLength)
 
 BOOST_AUTO_TEST_CASE(TestRequestSeqId)
 {
+    CMetaRegistry::SEntry sentry =
+        CMetaRegistry::Load("ncbi", CMetaRegistry::eName_RcOrIni);
+
+    string old_value;
+    bool had_entry = sentry.registry->HasEntry("BLAST", "LONG_SEQID");
+    if (had_entry) {
+        old_value = sentry.registry->Get("BLAST", "LONG_SEQID");
+    }
+    sentry.registry->Unset("BLAST", "LONG_SEQID", IRWRegistry::fPersistent);
+    BOOST_REQUIRE(sentry.registry->HasEntry("BLAST", "LONG_SEQID") == false);
+
+    const int kGi(43123516);
+    const string kSeqId("EAC27631.1");
+    CTmpFile tmpfile;
+    const string& fname = tmpfile.GetFileName();
+    CSeqDB db("data/seqp", CSeqDB::eProtein);
+    const string format_spec("%i");
+    ofstream out(fname.c_str());
+    CSeqFormatter f(format_spec, db, out);
+    CBlastDBSeqId id(NStr::IntToString(kGi));
+    f.Write(id);
+    out.close();
+
+    ifstream in(fname.c_str());
+    char buffer[256] = { '\0' };
+    in.getline(buffer, sizeof(buffer));
+
+    vector<string> tokens;
+    NStr::Split(string(buffer), " ", tokens);
+
+    BOOST_REQUIRE_EQUAL(tokens[0], kSeqId);
+
+    if (had_entry) {
+        sentry.registry->Set("BLAST", "LONG_SEQID", old_value,
+                             IRWRegistry::fPersistent);
+    }
+    else {
+        sentry.registry->Unset("BLAST", "LONG_SEQID", IRWRegistry::fPersistent);
+    }
+}
+
+
+BOOST_AUTO_TEST_CASE(TestRequestSeqIdLong)
+{
+    CMetaRegistry::SEntry sentry =
+        CMetaRegistry::Load("ncbi", CMetaRegistry::eName_RcOrIni);
+
+    string old_value;
+    bool had_entry = sentry.registry->HasEntry("BLAST", "LONG_SEQID");
+    if (had_entry) {
+        old_value = sentry.registry->Get("BLAST", "LONG_SEQID");
+    }
+    sentry.registry->Set("BLAST", "LONG_SEQID", "1", IRWRegistry::fPersistent);
+    BOOST_REQUIRE(sentry.registry->HasEntry("BLAST", "LONG_SEQID") == true);
+
     const int kGi(43123516);
     const string kSeqId("gb|EAC27631.1|");
     CTmpFile tmpfile;
@@ -147,9 +202,17 @@ BOOST_AUTO_TEST_CASE(TestRequestSeqId)
     in.getline(buffer, sizeof(buffer));
 
     vector<string> tokens;
-    NStr::Tokenize(string(buffer), " ", tokens);
+    NStr::Split(string(buffer), " ", tokens);
 
     BOOST_REQUIRE_EQUAL(tokens[0], kSeqId);
+
+    if (had_entry) {
+        sentry.registry->Set("BLAST", "LONG_SEQID", old_value,
+                             IRWRegistry::fPersistent);
+    }
+    else {
+        sentry.registry->Unset("BLAST", "LONG_SEQID", IRWRegistry::fPersistent);
+    }
 }
 
 
diff --git a/c++/src/objtools/blast/gene_info_reader/demo/gene_info_reader_app.cpp b/c++/src/objtools/blast/gene_info_reader/demo/gene_info_reader_app.cpp
index 02043c4..b40a275 100644
--- a/c++/src/objtools/blast/gene_info_reader/demo/gene_info_reader_app.cpp
+++ b/c++/src/objtools/blast/gene_info_reader/demo/gene_info_reader_app.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gene_info_reader_app.cpp 473030 2015-07-15 19:29:59Z camacho $
+/*  $Id: gene_info_reader_app.cpp 492284 2016-02-16 16:55:37Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -254,6 +254,6 @@ void CReadFilesApp::Exit(void)
 int main(int argc, const char* argv[])
 {
     // Execute main application function
-    return CReadFilesApp().AppMain(argc, argv, 0, eDS_Default, "");
+    return CReadFilesApp().AppMain(argc, argv);
 }
 
diff --git a/c++/src/objtools/blast/gene_info_reader/file_utils.cpp b/c++/src/objtools/blast/gene_info_reader/file_utils.cpp
index 6dd43e2..ae838fd 100644
--- a/c++/src/objtools/blast/gene_info_reader/file_utils.cpp
+++ b/c++/src/objtools/blast/gene_info_reader/file_utils.cpp
@@ -1,4 +1,4 @@
-/*  $Id: file_utils.cpp 140909 2008-09-22 18:25:56Z ucko $
+/*  $Id: file_utils.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file file_utils.cpp
 /// Implementation of Gene info file processing routines.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: file_utils.cpp 140909 2008-09-22 18:25:56Z ucko $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 //==========================================================================//
 
 #include <ncbi_pch.hpp>
diff --git a/c++/src/objtools/blast/gene_info_reader/gene_info.cpp b/c++/src/objtools/blast/gene_info_reader/gene_info.cpp
index f196c37..d6a5406 100644
--- a/c++/src/objtools/blast/gene_info_reader/gene_info.cpp
+++ b/c++/src/objtools/blast/gene_info_reader/gene_info.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gene_info.cpp 140909 2008-09-22 18:25:56Z ucko $
+/*  $Id: gene_info.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file gene_info.cpp
 /// Implementation of the Gene information class.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: gene_info.cpp 140909 2008-09-22 18:25:56Z ucko $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 //==========================================================================//
 
 #include <ncbi_pch.hpp>
diff --git a/c++/src/objtools/blast/gene_info_reader/gene_info_reader.cpp b/c++/src/objtools/blast/gene_info_reader/gene_info_reader.cpp
index 00434de..1360f82 100644
--- a/c++/src/objtools/blast/gene_info_reader/gene_info_reader.cpp
+++ b/c++/src/objtools/blast/gene_info_reader/gene_info_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gene_info_reader.cpp 219583 2011-01-11 20:26:07Z camacho $
+/*  $Id: gene_info_reader.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file gene_info_reader.cpp
 /// Implementation of reading Gene information from files.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: gene_info_reader.cpp 219583 2011-01-11 20:26:07Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 //==========================================================================//
 
 #include <ncbi_pch.hpp>
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdb.cpp b/c++/src/objtools/blast/seqdb_reader/seqdb.cpp
index e7a14ac..665601f 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdb.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdb.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdb.cpp 488259 2015-12-29 14:32:15Z camacho $
+/*  $Id: seqdb.cpp 516402 2016-10-13 12:28:06Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file seqdb.cpp
 /// Implementation for the CSeqDB class, the top level class for SeqDB.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdb.cpp 488259 2015-12-29 14:32:15Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_reader/seqdb.hpp>
 #include <util/sequtil/sequtil_convert.hpp>
@@ -739,6 +734,15 @@ bool CSeqDB::GiToOid(TGi gi, int & oid) const
     return rv;
 }
 
+bool CSeqDB::GiToOidwFilterCheck(TGi gi, int & oid) const
+{
+    m_Impl->Verify();
+    bool rv = m_Impl->GiToOidwFilterCheck(gi, oid);
+    m_Impl->Verify();
+
+    return rv;
+}
+
 bool CSeqDB::OidToGi(int oid, TGi & gi) const
 {
     m_Impl->Verify();
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbalias.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbalias.cpp
index 175339b..c982d91 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbalias.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbalias.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbalias.cpp 500118 2016-05-02 16:12:05Z ivanov $
+/*  $Id: seqdbalias.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -41,11 +41,6 @@
 ///     CSeqDB_MembBitWalker 
 /// 
 /// Implemented for: UNIX, MS-Windows
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbalias.cpp 500118 2016-05-02 16:12:05Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbistr.hpp>
 #include <corelib/ncbifile.hpp>
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbatlas.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbatlas.cpp
index b1fca52..d6bc86a 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbatlas.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbatlas.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbatlas.cpp 463291 2015-03-26 14:57:38Z rackerst $
+/*  $Id: seqdbatlas.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file seqdbatlas.cpp
 /// Implementation for the CSeqDBAtlas class and several related
 /// classes, which provide control of a set of memory mappings.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbatlas.cpp 463291 2015-03-26 14:57:38Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 
 #include <objtools/blast/seqdb_reader/impl/seqdbatlas.hpp>
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbbitset.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbbitset.cpp
index 0f977b7..6b6c8ad 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbbitset.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbbitset.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbbitset.cpp 140187 2008-09-15 16:35:34Z camacho $
+/*  $Id: seqdbbitset.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file seqdbbitset.cpp
 /// Implementation for the CSeqDB_BitSet class, a bit vector.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbbitset.cpp 140187 2008-09-15 16:35:34Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "seqdbbitset.hpp"
 
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbblob.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbblob.cpp
index 076a4a6..5d5b5cf 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbblob.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbblob.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbblob.cpp 390580 2013-02-28 16:13:24Z maning $
+/*  $Id: seqdbblob.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file seqdbblob.cpp
 /// Defines BlastDb `Blob' class for SeqDB and WriteDB.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbblob.cpp 390580 2013-02-28 16:13:24Z maning $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_reader/seqdbblob.hpp>
 #include <objtools/blast/seqdb_reader/seqdbcommon.hpp>
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbcol.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbcol.cpp
index a0b811a..56a5615 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbcol.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbcol.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbcol.cpp 398157 2013-05-03 12:09:43Z camacho $
+/*  $Id: seqdbcol.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
 /// This is the implementation file for the CSeqDBColumnReader,
 /// CSeqDBColumn, CSeqDBColumnFlush, and CSeqDB_ColumnEntry classes,
 /// which support read operations on BlastDb format database columns.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbcol.cpp 398157 2013-05-03 12:09:43Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_reader/column_reader.hpp>
 #include <objtools/blast/seqdb_reader/impl/seqdbcol.hpp>
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbcommon.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbcommon.cpp
index ea382bd..a9f2f45 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbcommon.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbcommon.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbcommon.cpp 484109 2015-11-06 16:30:06Z rackerst $
+/*  $Id: seqdbcommon.cpp 519978 2016-11-21 18:10:37Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file seqdbcommon.cpp
 /// Definitions of various helper functions for SeqDB.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbcommon.cpp 484109 2015-11-06 16:30:06Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/metareg.hpp>
 #include <corelib/ncbienv.hpp>
@@ -2345,7 +2340,27 @@ ESeqDBIdType SeqDB_SimplifyAccession(const string & acc,
 
         result = SeqDB_SimplifySeqid(*bestid, & acc, num_id, str_id, simpler);
     } else {
-        str_id = acc;
+
+        // Check for bare pdb accession with underscore (such as 12AS_A). These
+        // are not in the isam index and need to be translated to the
+        // standard form (pdb|12AS|A).
+        list< CRef<CSeq_id> > seqids;
+        try {
+            CSeq_id::ParseFastaIds(seqids, acc, false);
+        }
+        catch (...) {
+            seqids.clear();
+        }
+
+        if (!seqids.empty() && seqids.front()->IsPdb() &&
+            acc.find("_") != string::npos) {
+
+            str_id = seqids.front()->AsFastaString();
+            str_id = NStr::ToLower(str_id);
+        }
+        else {
+            str_id = acc;
+        }
         result = eStringId;
         simpler = false;
     }
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbexpert.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbexpert.cpp
index c588c22..f2258ae 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbexpert.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbexpert.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbexpert.cpp 481389 2015-10-09 14:40:20Z rackerst $
+/*  $Id: seqdbexpert.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file seqdbexpert.cpp
 /// Implementation for the CSeqDBExpert class.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbexpert.cpp 481389 2015-10-09 14:40:20Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_reader/seqdbexpert.hpp>
 #include "seqdbimpl.hpp"
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbfile.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbfile.cpp
index f6acb90..d55559e 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbfile.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbfile.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbfile.cpp 351200 2012-01-26 19:01:24Z maning $
+/*  $Id: seqdbfile.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file seqdbfile.cpp
 /// Several classes providing access to the component files of a
 /// database volume.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbfile.cpp 351200 2012-01-26 19:01:24Z maning $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_reader/impl/seqdbfile.hpp>
 
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbfilter.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbfilter.cpp
index f63792e..4ed5afc 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbfilter.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbfilter.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbfilter.cpp 140187 2008-09-15 16:35:34Z camacho $
+/*  $Id: seqdbfilter.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file seqdbfilter.cpp
 /// Implementation for some assorted ID list filtering code.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbfilter.cpp 140187 2008-09-15 16:35:34Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "seqdbfilter.hpp"
 #include "seqdbbitset.hpp"
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbgilistset.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbgilistset.cpp
index 8579ab1..6845a03 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbgilistset.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbgilistset.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbgilistset.cpp 484410 2015-11-10 19:12:26Z rackerst $
+/*  $Id: seqdbgilistset.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file seqdbgilistset.cpp
 /// Implementation for the CSeqDBVol class, which provides an
 /// interface for all functionality of one database volume.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbgilistset.cpp 484410 2015-11-10 19:12:26Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "seqdbgilistset.hpp"
 #include <algorithm>
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbgimask.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbgimask.cpp
index 688ac2d..c3b3678 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbgimask.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbgimask.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbgimask.cpp 481389 2015-10-09 14:40:20Z rackerst $
+/*  $Id: seqdbgimask.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file seqdbgimask.cpp
 /// This is the implementation file for the CSeqDBGiMask class,
 /// which support read operations on Gi based BlastDB masks.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbgimask.cpp 481389 2015-10-09 14:40:20Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "seqdbgimask.hpp"
 #include <objtools/blast/seqdb_reader/impl/seqdbgeneral.hpp>
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbimpl.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbimpl.cpp
index 0e49871..5b17e02 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbimpl.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbimpl.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbimpl.cpp 483686 2015-11-03 16:05:45Z rackerst $
+/*  $Id: seqdbimpl.cpp 516293 2016-10-12 14:27:34Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file seqdbimpl.cpp
 /// Implementation for the CSeqDBImpl class, the top implementation
 /// layer for SeqDB.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbimpl.cpp 483686 2015-11-03 16:05:45Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "seqdbimpl.hpp"
 #include <iostream>
@@ -253,16 +248,31 @@ void CSeqDBImpl::x_GetOidList(CSeqDBLockHold & locked)
     if (! m_OidListSetup) {
         m_Atlas.Lock(locked);
 
+        CRef<CSeqDB_FilterTree> ft = m_Aliases.GetFilterTree();
         if (m_OIDList.Empty()) {
             m_OIDList.Reset( new CSeqDBOIDList(m_Atlas,
                                                m_VolSet,
-                                               *m_Aliases.GetFilterTree(),
+                                               *ft,
                                                m_UserGiList,
                                                m_NegativeList,
                                                locked) );
         }
 
         m_OidListSetup = true;
+        // Handle the case where FIRST_OID and LAST_OID is set on a top level
+        // alias file and that's the only alias file present
+        if (ft->HasFilter()) {
+            const vector< CRef<CSeqDB_FilterTree> >& nodes = ft->GetNodes();
+            if (nodes.size() == 1) {
+                const CSeqDB_FilterTree::TFilters& filters = nodes.front()->GetFilters();
+                if (filters.size() == 1 && filters.front()->GetType() == CSeqDB_AliasMask::eOidRange) {
+                    const CSeqDB_AliasMask& alias_mask = *filters.front();
+                    SetIterationRange(alias_mask.GetBegin(), alias_mask.GetEnd());
+                }
+            }
+        }
+        //DebugDumpText(cerr, "CSeqDBImpl after m_OIDList initialization", 10);
+        //ft->Print();
     }
 }
 
@@ -315,6 +325,10 @@ CSeqDBImpl::GetNextOIDChunk(int         & begin_chunk, // out
 
     m_Atlas.Lock(locked);
 
+    if (! m_OidListSetup) {
+        x_GetOidList(locked);
+    }
+
     if (! state_obj) {
         state_obj = & m_NextChunkOID;
     }
@@ -350,16 +364,13 @@ CSeqDBImpl::GetNextOIDChunk(int         & begin_chunk, // out
     }
     *state_obj = end_chunk;
 
-    if (! m_OidListSetup) {
-        x_GetOidList(locked);
-    }
-
     // Case 2: Return a range
 
     if (m_OIDList.Empty()) {
         return CSeqDB::eOidRange;
     }
 
+
     // Case 3: Ones and Zeros - The bitmap provides OIDs.
 
     int next_oid = begin_chunk;
@@ -720,7 +731,7 @@ void CSeqDBImpl::x_FillSeqBuffer(SSeqResBuffer  *buffer,
             res.address = seq;
             buffer->results.push_back(res);
             res.length = vol->GetSequence(vol_oid++, &seq, locked);
-        } while (res.length >= 0 && tot_length >= res.length);
+        } while (res.length >= 0 && tot_length >= res.length && vol_oid < m_RestrictEnd);
 
         if (res.length >= 0)  m_Atlas.RetRegion(seq);
         return;
@@ -1490,9 +1501,10 @@ void CSeqDBImpl::GetTaxInfo(int taxid, SSeqDBTaxInfo & info)
 
     CSeqDBTaxInfo taxinfo(atlas);
     if (! taxinfo.GetTaxNames(taxid, info, locked)) {
-        NCBI_THROW(CSeqDBException,
-                   eArgErr,
-                   "Specified taxid was not found.");
+        CNcbiOstrstream oss;
+        oss << "Taxid " << taxid << " not found";
+        string msg = CNcbiOstrstreamToString(oss);
+        NCBI_THROW(CSeqDBException, eArgErr, msg);
     }
 }
 
@@ -2205,8 +2217,8 @@ string CSeqDBImpl::GetAvailableMaskAlgorithmDescriptions()
            << "Available filtering algorithms applied to database sequences:"
            << endl << endl;
 
-    retval << setw(14) << left << "Algorithm ID"
-           << setw(20) << left << "Algorithm name"
+    retval << setw(13) << left << "Algorithm ID"
+           << setw(40) << left << "Algorithm name"
            << setw(40) << left << "Algorithm options" << endl;
     ITERATE(vector<int>, algo_id, algorithms) {
         string algo, algo_opts, algo_name;
@@ -2215,13 +2227,13 @@ string CSeqDBImpl::GetAvailableMaskAlgorithmDescriptions()
             algo_opts.assign("default options used");
         }
         if (s_IsNumericId(algo)) {
-            retval << setw(14) << left << (*algo_id)
-               << setw(20) << left << algo_name
-               << setw(40) << left << algo_opts << endl;
+            retval << setw(13) << left << (*algo_id)
+                   << setw(40) << left << algo_name
+                   << setw(40) << left << algo_opts << endl;
         } else {
-            retval << setw(14) << left << algo
-               << setw(20) << left << algo_name
-               << setw(40) << left << algo_opts << endl;
+            retval << setw(13) << left << (*algo_id)
+                   << setw(40) << left << algo
+                   << setw(40) << left << algo_opts << endl;
         }
     }
     return CNcbiOstrstreamToString(retval);
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbimpl.hpp b/c++/src/objtools/blast/seqdb_reader/seqdbimpl.hpp
index c316ebb..af38eeb 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbimpl.hpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbimpl.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_READERS_SEQDB__SEQDBIMPL_HPP
 #define OBJTOOLS_READERS_SEQDB__SEQDBIMPL_HPP
 
-/*  $Id: seqdbimpl.hpp 481389 2015-10-09 14:40:20Z rackerst $
+/*  $Id: seqdbimpl.hpp 491223 2016-02-03 15:19:38Z rackerst $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1102,6 +1102,24 @@ public:
     void GarbageCollect(void);
 
     /// Set number of threads
+    ///
+    /// Set number of threads which will share this object.  This
+    /// permits use of an internal mmap for the threads.
+    /// If the second parameter is 'false' (the default),
+    /// the internal mmap is not used if num_threads == 1.
+    /// For certain applications where there are multiple CSeqDB
+    /// objects, each one accessed by only a single thread,
+    /// setting num_threads to 1 (thread per CSeqDB) results in
+    /// a performance hit by not using the mmap.
+    /// In this case, force_mt ("force multithreading") should
+    /// be set to 'true' to allow use of the mmap when num_threads
+    /// == 1.  For num_threads > 1, force_mt has no effect.
+    ///
+    /// @param num_threads The number of threads which will share
+    ///                    access to this CSeqDB object. [in]
+    /// @param force_mt Defaults to false, setting to true when
+    ///                 num_threads == 1 forces multithread
+    ///                 internal mmap. [in]
     void SetNumberOfThreads(int num_threads, bool force_mt = false);
 
     /// Retrieve the slice size used in internal mmap
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbisam.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbisam.cpp
index b9c6898..bc17903 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbisam.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbisam.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbisam.cpp 484099 2015-11-06 15:23:03Z rackerst $
+/*  $Id: seqdbisam.cpp 500834 2016-05-09 15:12:58Z rackerst $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file seqdbisam.cpp
 /// Implementation for the CSeqDBIsam class, which manages an ISAM
 /// index of some particular kind of identifiers.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbisam.cpp 484099 2015-11-06 15:23:03Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_reader/impl/seqdbisam.hpp>
 #include <objects/seqloc/Seq_id.hpp>
@@ -483,10 +478,10 @@ int CSeqDBIsam::x_DiffCharLease(const string   & term_in,
                    ignore_case);
 
     if (dc_result != -1) {
-        result = dc_result;
+        return dc_result;
     }
 
-    return dc_result;
+    return result;
 }
 
 /// Return NUL for nulls or EOL characters
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbobj.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbobj.cpp
index 280ddc2..b4f9139 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbobj.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbobj.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbobj.cpp 140909 2008-09-22 18:25:56Z ucko $
+/*  $Id: seqdbobj.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file seqdbobj.cpp
 /// Definitions of various helper functions for SeqDB.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbobj.cpp 140909 2008-09-22 18:25:56Z ucko $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_reader/seqdbcommon.hpp>
 
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdboidlist.cpp b/c++/src/objtools/blast/seqdb_reader/seqdboidlist.cpp
index 198bdcd..e4ba723 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdboidlist.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdboidlist.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdboidlist.cpp 311249 2011-07-11 14:12:16Z camacho $
+/*  $Id: seqdboidlist.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file seqdboidlist.cpp
 /// Implementation for the CSeqDBOIDList class, an array of bits
 /// describing a subset of the virtual oid space.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdboidlist.cpp 311249 2011-07-11 14:12:16Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbistr.hpp>
 #include "seqdboidlist.hpp"
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbtax.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbtax.cpp
index db81f89..7e52331 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbtax.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbtax.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbtax.cpp 439674 2014-07-02 16:25:04Z vakatov $
+/*  $Id: seqdbtax.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file seqdbtax.cpp
 /// Implementation for the CSeqDBVol class, which provides an
 /// interface for all functionality of one database volume.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbtax.cpp 439674 2014-07-02 16:25:04Z vakatov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/error_codes.hpp>
 #include <objtools/blast/seqdb_reader/impl/seqdbtax.hpp>
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbvol.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbvol.cpp
index bedbe60..376072b 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbvol.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbvol.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbvol.cpp 484414 2015-11-10 19:24:28Z rackerst $
+/*  $Id: seqdbvol.cpp 516395 2016-10-13 12:26:34Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file seqdbvol.cpp
 /// Implementation for the CSeqDBVol class, which provides an
 /// interface for all functionality of one database volume.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbvol.cpp 484414 2015-11-10 19:24:28Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_reader/impl/seqdbvol.hpp>
 #include "seqdboidlist.hpp"
@@ -779,9 +774,12 @@ s_SeqDBRebuildDNA_NA8(char               * seq,
 
         if (new_format) ++i;
 
-        if (position + row_len <= region.begin || position >= region.end)
+        if (position + row_len <= region.begin)
             continue;
 
+        if(position >= region.end)
+        	break;
+
         for (int j = 0; j < row_len; ++j, ++position)
             if ( position >= region.begin  && position < region.end)
                 seq[position] = trans_ch;
@@ -1281,16 +1279,21 @@ CSeqDBVol::GetBioseq(int                    oid,
         defline_set.Reset(new CBlast_def_line_set);
 
         CRef<const CSeq_id > seqid;
+        CRef<const CSeq_id > seqid_lcl;
         if (target_gi != ZERO_GI) {
             seqid.Reset(new CSeq_id(CSeq_id::e_Gi, GI_TO(TIntId, target_gi)));
-        } else {
+            seqid_lcl.Reset(new CSeq_id(CSeq_id::e_Local, NStr::NumericToString(target_gi)));
+        }
+        else {
             seqid.Reset(target_seq_id);
+            seqid_lcl.Reset(new CSeq_id(CSeq_id::e_Local, seqid->GetSeqIdString(true)));
         }
 
         CRef<CBlast_def_line> filt_dl;
 
         ITERATE(TDeflines, iter, orig_deflines->Get()) {
-            if (s_SeqDB_SeqIdIn((**iter).GetSeqid(), *seqid)) {
+            if ((seqid.NotEmpty() && s_SeqDB_SeqIdIn((**iter).GetSeqid(), *seqid)) ||
+                (seqid_lcl.NotEmpty() && s_SeqDB_SeqIdIn((**iter).GetSeqid(), *seqid_lcl))) {
                 filt_dl = *iter;
                 break;
             }
diff --git a/c++/src/objtools/blast/seqdb_reader/seqdbvolset.cpp b/c++/src/objtools/blast/seqdb_reader/seqdbvolset.cpp
index a0d191d..359b85e 100644
--- a/c++/src/objtools/blast/seqdb_reader/seqdbvolset.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/seqdbvolset.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdbvolset.cpp 140187 2008-09-15 16:35:34Z camacho $
+/*  $Id: seqdbvolset.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file seqdbvolset.cpp
 /// Implementation for the CSeqDBVolSet class, which manages a list of volumes.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: seqdbvolset.cpp 140187 2008-09-15 16:35:34Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "seqdbvolset.hpp"
 
diff --git a/c++/src/objtools/blast/seqdb_reader/test/seqdb_perf.cpp b/c++/src/objtools/blast/seqdb_reader/test/seqdb_perf.cpp
index 9b36492..69f3780 100644
--- a/c++/src/objtools/blast/seqdb_reader/test/seqdb_perf.cpp
+++ b/c++/src/objtools/blast/seqdb_reader/test/seqdb_perf.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seqdb_perf.cpp 473030 2015-07-15 19:29:59Z camacho $
+/*  $Id: seqdb_perf.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  * Command line tool to measure the performance of CSeqDB.
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] =
-    "$Id: seqdb_perf.cpp 473030 2015-07-15 19:29:59Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiapp.hpp>
 #include <corelib/ncbi_system.hpp>
@@ -342,6 +337,6 @@ int CSeqDBPerfApp::Run(void)
 #ifndef SKIP_DOXYGEN_PROCESSING
 int main(int argc, const char* argv[] /*, const char* envp[]*/)
 {
-    return CSeqDBPerfApp().AppMain(argc, argv, 0, eDS_Default, "");
+    return CSeqDBPerfApp().AppMain(argc, argv);
 }
 #endif /* SKIP_DOXYGEN_PROCESSING */
diff --git a/c++/src/objtools/blast/seqdb_writer/build-alias-index b/c++/src/objtools/blast/seqdb_writer/build-alias-index
index 72a3643..2921085 100755
--- a/c++/src/objtools/blast/seqdb_writer/build-alias-index
+++ b/c++/src/objtools/blast/seqdb_writer/build-alias-index
@@ -3,7 +3,7 @@
 # subdirectory
 # Author: Kevin Bealer
 # Original date: 10/21/2005
-# $URL: https://svn.ncbi.nlm.nih.gov/repos/toolkit/release/blast/2.4.0/c++/src/objtools/blast/seqdb_writer/build-alias-index $
+# $URL: https://svn.ncbi.nlm.nih.gov/repos/toolkit/release/blast/2.6.0/c++/src/objtools/blast/seqdb_writer/build-alias-index $
 
 INDEX_NAME=index.alx
 OUTNAME=index.alx.new
diff --git a/c++/src/objtools/blast/seqdb_writer/build_db.cpp b/c++/src/objtools/blast/seqdb_writer/build_db.cpp
index 99ef4a3..b2fe68c 100644
--- a/c++/src/objtools/blast/seqdb_writer/build_db.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/build_db.cpp
@@ -1,4 +1,4 @@
-/*  $Id: build_db.cpp 485504 2015-11-23 14:41:02Z rackerst $
+/*  $Id: build_db.cpp 518102 2016-10-31 17:37:45Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -29,12 +29,9 @@
 
 /** @file build_db.cpp
   Code to build a database given various sources of sequence data.
-*/
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: build_db.cpp 485504 2015-11-23 14:41:02Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
+  */
 #include <ncbi_pch.hpp>
+#include <corelib/ncbienv.hpp>
 
 // Blast databases
 
@@ -470,7 +467,7 @@ bool CBuildDatabase::x_EditAndAddBioseq(CConstRef<objects::CBioseq>   bs,
                                         bool						  add_pig)
 {
     CRef<CBlast_def_line_set> headers =
-        CWriteDB::ExtractBioseqDeflines(*bs, m_ParseIDs);
+        CWriteDB::ExtractBioseqDeflines(*bs, m_ParseIDs, m_LongIDs);
 
     x_EditHeaders(headers);
 
@@ -684,7 +681,8 @@ class CFastaBioseqSource : public IBioseqSource {
 public:
     CFastaBioseqSource(CNcbiIstream & fasta_file,
                        bool is_protein,
-                       bool parse_ids);
+                       bool parse_ids,
+                       bool long_ids);
 
     ~CFastaBioseqSource();
 
@@ -697,11 +695,11 @@ private:
 
 CFastaBioseqSource::CFastaBioseqSource(CNcbiIstream & fasta_file,
                                        bool is_protein,
-                                       bool parse_ids)
+                                       bool parse_ids,
+                                       bool long_ids)
     : m_FastaReader(NULL)
 {
     m_LineReader.Reset(new CBufferedLineReader(fasta_file));
-
     typedef CFastaReader::EFlags TFlags;
 
     int iflags = CFastaReader::fAllSeqIds |
@@ -716,6 +714,10 @@ CFastaBioseqSource::CFastaBioseqSource(CNcbiIstream & fasta_file,
 
     if (parse_ids) {
         iflags |= CFastaReader::fAllSeqIds | CFastaReader::fRequireID;
+        // parse bare accessions
+        if (!long_ids) {
+            iflags |= CFastaReader::fParseRawID;
+        }
     } else {
         iflags |= CFastaReader::fNoParseID;
     }
@@ -793,6 +795,24 @@ bool CBuildDatabase::AddSequences(IBioseqSource & src, bool add_pig)
             if (! ids.empty() && ids.front().NotEmpty()) {
                 bioseq_id.assign(ids.front()->AsFastaString());
             }
+
+            if (!m_LongIDs) {
+
+                // If accession's molecule type is different than expected,
+                // change sequence id to local. CFastaReader cannot distingush
+                // between bare pir protein ids genbank nucleotide ids.
+                CBioseq* bss = const_cast<CBioseq*>(bs.GetNonNullPointer());
+                for (auto& it: bss->SetId()) {
+                    CSeq_id::EAccessionInfo info = it->IdentifyAccession();
+                    if (!it->IsLocal() && !it->IsGi() &&
+                        (info & (CSeq_id::fAcc_prot | CSeq_id::fAcc_nuc)) &&
+                        m_IsProtein == !!(info & CSeq_id::fAcc_nuc)) {
+
+                        string label = it->GetSeqIdString(true);
+                        it.Reset(new CSeq_id(CSeq_id::e_Local, label));
+                    }
+                }
+            }
         }
 
         if(bs->IsAa() != m_IsProtein ){
@@ -1007,7 +1027,8 @@ CBuildDatabase::CBuildDatabase(const string         & dbname,
                                bool                   is_protein,
                                CWriteDB::TIndexType   indexing,
                                bool                   use_gi_mask,
-                               ostream              * logfile)
+                               ostream              * logfile,
+                               bool                   long_seqids)
     : m_IsProtein    (is_protein),
       m_KeepLinks    (false),
       m_KeepMbits    (false),
@@ -1019,6 +1040,7 @@ CBuildDatabase::CBuildDatabase(const string         & dbname,
       m_OIDCount     (0),
       m_Verbose      (false),
       m_ParseIDs     (((indexing & CWriteDB::eFullIndex) != 0 ? true : false)),
+      m_LongIDs      (long_seqids),
       m_FoundMatchingMasks(false)
 {
     s_CreateDirectories(dbname);
@@ -1043,6 +1065,7 @@ CBuildDatabase::CBuildDatabase(const string         & dbname,
                                   title,
                                   indexing,
                                   m_ParseIDs,
+                                  m_LongIDs,
                                   use_gi_mask));
 
     // Standard 1 GB limit
@@ -1056,7 +1079,8 @@ CBuildDatabase::CBuildDatabase(const string & dbname,
                                bool           sparse,
                                bool           parse_seqids,
                                bool           use_gi_mask,
-                               ostream      * logfile)
+                               ostream      * logfile,
+                               bool           long_seqids)
     : m_IsProtein    (is_protein),
       m_KeepLinks    (false),
       m_KeepMbits    (false),
@@ -1068,6 +1092,7 @@ CBuildDatabase::CBuildDatabase(const string & dbname,
       m_OIDCount     (0),
       m_Verbose      (false),
       m_ParseIDs     (parse_seqids),
+      m_LongIDs      (long_seqids),
       m_FoundMatchingMasks(false)
 {
     s_CreateDirectories(dbname);
@@ -1203,7 +1228,7 @@ CBuildDatabase::Build(const vector<string> & ids,
 
     bool success2 = EndBuild();
 
-    success = success || success2;
+    success = success && success2;
 
     double t = sw.Elapsed();
 
@@ -1305,7 +1330,8 @@ bool CBuildDatabase::AddFasta(CNcbiIstream & fasta_file)
     if (fasta_file) {
         CFastaBioseqSource fbs(fasta_file,
                                m_IsProtein,
-                               m_ParseIDs);
+                               m_ParseIDs,
+                               m_LongIDs);
 
         try {
             success = AddSequences(fbs);
@@ -1339,7 +1365,7 @@ bool CBuildDatabase::EndBuild(bool erase)
 
 bool CBuildDatabase::x_EndBuild(bool erase, const CException * close_exception)
 {
-    bool success = false;
+    bool success = true;
 
     vector<string> vols;
     vector<string> files;
diff --git a/c++/src/objtools/blast/seqdb_writer/mask_info_registry.cpp b/c++/src/objtools/blast/seqdb_writer/mask_info_registry.cpp
index 807adfc..b5f46af 100644
--- a/c++/src/objtools/blast/seqdb_writer/mask_info_registry.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/mask_info_registry.cpp
@@ -29,11 +29,6 @@
 /** @file mask_info_registry.cpp
  * Implements CMaskInfoRegistry class
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: mask_info_registry.cpp 389699 2013-02-20 15:33:26Z maning $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "mask_info_registry.hpp"
 #include <objtools/blast/seqdb_writer/writedb_error.hpp>
diff --git a/c++/src/objtools/blast/seqdb_writer/multisource_util.cpp b/c++/src/objtools/blast/seqdb_writer/multisource_util.cpp
index 1ac2451..512b80b 100644
--- a/c++/src/objtools/blast/seqdb_writer/multisource_util.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/multisource_util.cpp
@@ -1,4 +1,4 @@
-/*  $Id: multisource_util.cpp 495728 2016-03-21 14:25:14Z ivanov $
+/*  $Id: multisource_util.cpp 500404 2016-05-04 14:59:01Z camacho $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /** @file multisource_util.cpp
 * Utility functions and classes for multisource app.
 */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: multisource_util.cpp 495728 2016-03-21 14:25:14Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <serial/typeinfo.hpp>
 #include <objects/seqloc/seqloc__.hpp>
diff --git a/c++/src/objtools/blast/seqdb_writer/taxid_set.cpp b/c++/src/objtools/blast/seqdb_writer/taxid_set.cpp
index 3bacb5d..25209a2 100644
--- a/c++/src/objtools/blast/seqdb_writer/taxid_set.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/taxid_set.cpp
@@ -1,4 +1,4 @@
-/*  $Id: taxid_set.cpp 495728 2016-03-21 14:25:14Z ivanov $
+/*  $Id: taxid_set.cpp 500404 2016-05-04 14:59:01Z camacho $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /** @file taxid_set.cpp
 *     Class which defines sequence id to taxid mapping.
 */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: taxid_set.cpp 495728 2016-03-21 14:25:14Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_writer/taxid_set.hpp>
 #include <objtools/blast/seqdb_writer/multisource_util.hpp>
diff --git a/c++/src/objtools/blast/seqdb_writer/unit_test/Makefile.writedb_unit_test.app b/c++/src/objtools/blast/seqdb_writer/unit_test/Makefile.writedb_unit_test.app
index 795cdd7..38aff80 100644
--- a/c++/src/objtools/blast/seqdb_writer/unit_test/Makefile.writedb_unit_test.app
+++ b/c++/src/objtools/blast/seqdb_writer/unit_test/Makefile.writedb_unit_test.app
@@ -1,4 +1,4 @@
-# $Id: Makefile.writedb_unit_test.app 428319 2014-03-03 14:03:48Z fongah2 $
+# $Id: Makefile.writedb_unit_test.app 507920 2016-07-22 15:11:05Z boratyng $
 
 APP = writedb_unit_test
 SRC = writedb_unit_test criteria_unit_test
@@ -16,4 +16,4 @@ CHECK_REQUIRES = in-house-resources
 CHECK_CMD = writedb_unit_test
 CHECK_COPY = writedb_unit_test.ini data
 
-WATCHERS = madden camacho fongah2
+WATCHERS = madden camacho fongah2 boratyng
diff --git a/c++/src/objtools/blast/seqdb_writer/unit_test/data/some_prots.fsa b/c++/src/objtools/blast/seqdb_writer/unit_test/data/some_prots.fsa
new file mode 100644
index 0000000..aee64df
--- /dev/null
+++ b/c++/src/objtools/blast/seqdb_writer/unit_test/data/some_prots.fsa
@@ -0,0 +1,142 @@
+>gi|75550147|sp|Q6WNV7.1|VP3_ROTEL RecName: Full=Protein VP3; Includes: RecName: Full=mRNA guanylyltransferase; Includes: RecName: Full=mRNA (guanine-N(7)-)-methyltransferase [Equine rotavirus L338/G13]
+MKVLALRHSVTQVYADTQTYLHDDMKDDYENAFLISNLTVHNILYLNYSLKTLEILNKSGIAAVEVQGIEELLALIRCNF
+TYDYLNNVVFLHDYSYYTNNEIRTDQHWITKTDIENYLLPGWKLTYVGYNGKSTRGHYNFSFTCQNAATDDDIIIEYIYS
+NELDFQNFMLSKIKERMTTALPIARLSNRVFRDKLFQSLSLNNDKIVNVGPRNESMFTFLKFPSIKQFSDGPYLVKDTIK
+LKQERWLGKRVSQFDIGQYKNMLNVITTIYYYYNLYAEKPIVYMLGSAPSYWIYDIKQYSEFVFETWDPLDTPYSNMHHK
+ELFFEKDTIKLKDNSILYIDIRTDRGDIDWKEWRKIVKEQTLSNLNIAYKYLSTGKSKVCCVKMTAMDIELPISAKLLHH
+PTTEIRSEFYMIVDLSDFKNIKRFVPKGVLYSFINNITTENVFIQHPFKLRKMKNEYIVALYALSNDFNNRENVIKLINE
+QEKSLITVRLNNTFKDEPKIGFKNIYDWTFLPTDFNTRNSIITSYDGCIGMFGLSISLSSKPTGNNHIFILNGTDKYEMI
+DQFANHMGISRRSHQIRFSESATSYSGYIFRDLSNNNFNLIGTNVENSVSGHVYNAIIYFRYNYSFDLKRWIHLHSVDKV
+KIEGGRYYEHAPIELIYACRSAKEFAKMQDDLTTLRYANEIERYINKVYSIVYADDPNYFIGIKFVSIPYKYDVKVPHLT
+FGVLHISDNMIPDVISILNQMKVELFKMNITTSYTYMLSDGIHVANVSGVLLTYFKIYNVFYKKQITFGQSRMFIPHITL
+SFKTNKTIRINITKLKIESIYLRKIKGETVFAMTE
+>gi|17369390|sp|Q9PFV5.1|RSMI_XYLFA RecName: Full=Ribosomal RNA small subunit methyltransferase I; AltName: Full=16S rRNA 2'-O-ribose C1402 methyltransferase; AltName: Full=rRNA (cytidine-2'-O-)-methyltransferase RsmI
+MSTPGTLHIVATPIGNLGDLSPRAQHILRTVTMICAEDTRHTRQLLAHFGIERPLLALHAHNEDTLAERIITRLISGASL
+ALVSDAGTPLISDPGFLLVRAARAAGIRVTPVPGPSALIAALSVSGLPSNRFTFEGFLPAKPTARRDRLTHLAHEPRTLI
+FYEASHRIAECLTDLATIFGSMRAAVVARELTKIFETVLDGTLATLQTQVANDDNQRKGEFVIIVQGAADQDAAKITEGR
+RVYALLKEHLPPSSAAKLAAEITGAPRKALYGG
+>gi|259647248|sp|C0QKZ6.1|GATC_DESAH RecName: Full=Aspartyl/glutamyl-tRNA(Asn/Gln) amidotransferase subunit C; Short=Asp/Glu-ADT subunit C
+MKISKQDVEHLAHLARLAVDGSQVESLTAQVSNILDYMDVLKEVDVDGVPLASGAALGTNVFRQDQVKPSPGPCVTLANA
+PERDDDFYTVPRIVG
+>gi|357580413|sp|D4GCB2.1|AAEB_PANAM RecName: Full=p-hydroxybenzoic acid efflux pump subunit AaeB; Short=pHBA efflux pump protein B
+MTEFLRFPIKLTFALVAALMIGFHLNLETPRWAVMTAGIVAGGTAFAAGGDPYSGALRYRGILRIIGTFIGCVAALVIMI
+ATVRAPVVMLLLCCIWAGFCVWLSSLIKVENSYALGLAGYTALIIVVTANASGGLTLVPQYAVERCSEIILGILCAILAD
+MIFSPRSIKKVIDAEVDSLLVAHYRLLQLCVAHEDKEEVDKAWGALVRRTTALSSMRSQLMMESSRWQNTSRRLQMLNTL
+SLTMITQAAETFLIQNSRPDYIATQYRVLMEKEAATAEDVHKRMKALRRLIAVSSKTVPETLESWVEAATEYQLLTHGIK
+SNGRITALEEGILQREVVIQARSAENHHAMINGVRTFVATALGSLFWLYTGWTSGSGCMVMLGVITALAMRMPNPLMMAK
+DFVYGMTVAVPLGALYFMYILPNTQQSAVLLCIAIGLLGFISGILIQRRQIGTLGAMVGTINVLVLDNPMQFNFTQFIDN
+ALGQWIGSFVALMVILLIRDKSKARTGRKLLNRFMYAAVSAMTTNQARRRENHLPALYQQLFLLLNLFPGDIDKYRIALT
+LIIGHQRLRAADVPVNADLSAYHRQLRHTADRIISVRSDEKRRYYFERLLKELDVYQHKLAHYDAPTSVTEPVTRLAEML
+KKYQNTLVQI
+>gi|81601547|sp|Q5WZJ9.1|RS14_LEGPL RecName: Full=30S ribosomal protein S14
+MAKKSMLMRESKRAKLVEKYRQRRNELKQLIKSSDDFQVIMESQEKLAKLPVNSNPVRYVTRCKQCGRPHAVYRKFNLCR
+ICLRQQLMVGNIPGGRKSSW
+>gi|75503293|sp|Q4ZXT0.1|RSMC_PSEU2 RecName: Full=Ribosomal RNA small subunit methyltransferase C; AltName: Full=16S rRNA m2G1207 methyltransferase; AltName: Full=rRNA (guanine-N(2)-)-methyltransferase RsmC
+MDPRSEVLLRQAELFQGSLLLVGLPADDLLGKLPDARGWCWHAGDQAALDARFEGRVDFGVEAPQTGFEAAVLFLPKARD
+LTDYLLNALASRLAGRELFLVGEKRGGIEAAAKQLSPFGRARKLDSARHCQLWQVTVEHAPQAVSLDSLARPYQIELQDG
+PLTVVSLPGVFSHGRLDRGSALLLENIDKLPSGNLLDFGCGAGVLGAAIKRRYPHNEVIMLDVDAFATASSRLTLAANGL
+QAQVLTGDGIDAAPMGLNTILSNPPFHVGVHTDYMATENLLRKARQHLKSGGELRLVANNFLRYQPLIEEHVGQCEVRAQ
+GNGFKIYSAKRP
+>gi|20454793|sp|Q9V8R9.1|41_DROME RecName: Full=Protein 4.1 homolog; AltName: Full=Protein coracle
+MPAEIKPSAPAEPETPTKSKPKSSSSSHGKPALARVTLLDGSLLDVSIDRKAIGRDVINSICAGLNLIEKDYFGLTYETP
+TDPRTWLDLEKPVSKFFRTDTWPLTFAVKFYPPEPSQLKEDITRYHLCLQVRNDILEGRLPCTFVTHALLGSYLVQSEMG
+DYDAEEMPTRAYLKDFKIAPNQTAELEDKVMDLHKTHKGQSPAEAELHYLENAKKLAMYGVDLHPAKDSEGVDIMLGVCA
+SGLLVYRDKLRINRFAWPKILKISYKRHHFYIKIRPGEFEQYESTIGFKLANHRAAKKLWKSCVEHHTFFRLMTPEPVSK
+SKMFPVFGSTYRYKGRTQAESTNTPVDRTPPKFNRTLSGARLTSRSMDALALAEKEKVARKSSTLDHRGDRNADGDAHSR
+SPIKNKKEKDADKEAKLREKKQKEKEEKERKEREKRELEEKKKAEKAAKAALAAGAAAGAAVNGNDELNDSNKSDKSSGR
+RGVGIFSSGRKSKSGSPSKDGKDKSGKDKDKEVGRLGLVVTSGLGDNQQDQNLDEAARNAAKNRGSTTPGVTRQYEYAVD
+NDGNTSPTRKSYTPGGFRYDQDPNSRKSGADGQEQLSPTSQQKKIGLAFNYAPGNENALKETAEKLKAGQLSPRTQDKLN
+RGQLSPKSRAKLLQDPLLSPTTRAKLQGSAVDAAAVPLSDSQKRSYSPTKGPQGYSSGAPGSYKPISDPTADFLESQRYN
+KEPGYVGPSKADVAAGLAGAAGSKKPGSPTKTGKGAPGAAAAAAAGAAGAAAAAAKPKKRRVKIMVITSKFDPSTKRIDA
+ENGSIEHSTGILDPATGLIDTKYGVIDPKKGTLEALNTKTGKKEVFQGDVDGKTGNLHLVSGVADPKTGRLDDTLGQIVC
+ITPQDNPVVELTVITSRIDPATGKIDTVNGDVERSLGVLNLDTGLLDTKYGEINTRTGELKAIDPKSGKIVVSKNVKVDP
+GTGQITILGIVDPKTNKIDPNQGRLIEVGQQIDPIVEVTSLAGKFDSKRNIIDPKTAQVETSGGQFDPKAGKIDTKYGQI
+DLVKHTITFNDPKSGKTVTRDIKIEPTTGQIVLKNQVNPKNNKPDKDYARIISLRIVQQRVDPATKAPITEVSASKDKDI
+VVDPKSNQIWVPTGATDPATKEQQYISSSVDPKTGYVITIYGYLDPKTNEIKKQTKLDPNTIKIEPTSGKIYTATGEVDQ
+ATGEPLYAATQVDPESGEVYTKLARVDPKTGKIVIVRILLISKTDERGRPEEIDPSTCEIDPVSGRVLKFFNKTVYVYNM
+IDPVTGEIVQVDPNDPRFAGARTTVTHTMTLTGEIDPVTGRIKSEYGDIDPNTGDIDPATAVTDPVTGKLILNYAQIDPS
+HFGKQAQVQTTTETVPITRQQFFDGVKHISKGALRRDSEGSSDDDMTAQYGADQVNEILIGSPAGQAGGKLGKPVSTPTV
+VKTTTKQVLTKNIDGVTHNVEEEVRNLGTGEVTYSTQEHKADATPTDLSGAYVTATAVTTRTATTHEDLGKNAKTEQLEE
+KTVATTRTHDPNKQQQRVVTQEVKTTATVTSGDQYQRRDSVSSTSSGDSGTPIDGPYDGASVVRTDNQKSPLFTTSATTG
+PHVESTRVVLGEDTPGFSGHGEIISTQTVSSKTRTVETITYKTERDGIVETRVEQKITIQSDGDPIDHDKALAEAIQEAT
+AMNPDMTVEKIEIQQQTQ
+>gi|67462843|sp|P0A8V6.2|FADR_ECOLI RecName: Full=Fatty acid metabolism regulator protein >gi|67462844|sp|P0A8V7.2|FADR_ECOL6 RecName: Full=Fatty acid metabolism regulator protein >gi|67462845|sp|P0A8V8.2|FADR_ECO57 RecName: Full=Fatty acid metabolism regulator protein >gi|67462846|sp|P0A8V9.2|FADR_SHIFL RecName: Full=Fatty acid metabolism regulator protein >gi|123049263|sp|Q0TII8.1|FADR_ECOL5 RecName: Full=Fatty acid metabolism regulator protein >gi|123266100|sp|Q1RCQ9.1|FADR_ECOUT RecN [...]
+MVIKAQSPAGFAEEYIIESIWNNRFPPGTILPAERELSELIGVTRTTLREVLQRLARDGWLTIQHGKPTKVNNFWETSGL
+NILETLARLDHESVPQLIDNLLSVRTNISTIFIRTAFRQHPDKAQEVLATANEVADHADAFAELDYNIFRGLAFASGNPI
+YGLILNGMKGLYTRIGRHYFANPEARSLALGFYHKLSALCSEGAHDQVYETVRRYGHESGEIWHRMQKNLPGDLAIQGR
+>gi|732006|sp|P39284.1|YJEO_ECOLI RecName: Full=Inner membrane protein YjeO
+MSARMFVLCCIWFIVAFLWITITSALDKEWMIDGRGINNVCDVLMYLEEDDTRDVGVIMTLPLFFPFLWFALWRKKRGWF
+MYATALAIFGYWLWQFFLRYQFCL
+>gi|122968794|sp|Q12NQ7.1|FADR_SHEDO RecName: Full=Fatty acid metabolism regulator protein
+MIINAKGPASFAEKYIVRSIWDNKFPPGSILPAERELSELIGVTRTTLREVLQRLARDGWLKIQHGKPTQVNNFWETSGL
+NILETIADLNPEGFPVLVDQLLSARTNVSAIYFRGALRNNPDQAVDVLAGIHQLENTAEAFAEFDYQLHHRLAFSSGNPL
+YVLILNGFKGLYSRVGRYYFSSSDARALALNFYVELEKLALAKNYIDVPAVMRSYGINSGKMWQRLRDDMPADIAQDKS
+>gi|226733118|sp|A1TA81.1|PYRG_MYCVP RecName: Full=CTP synthase; AltName: Full=CTP synthetase; AltName: Full=UTP--ammonia ligase
+MPALRKHPQTATKHLFVTGGVVSSLGKGLTASSLGQLLTARGLQVTMQKLDPYLNVDPGTMNPFQHGEVFVTEDGAETDL
+DVGHYERFLDRNLSGSANVTTGQVYSTVIAKERRGEYLGDTVQVIPHITDEIKRRILAMDAADSDGNRPDVIITEIGGTV
+GDIESLPFLEAARQVRHEVGRENCFFLHCSLVPYMAPSGELKTKPTQHSVAALRSIGITPDALILRCDRDVPEPLKNKIA
+LMCDVDIDGVISTPDAPSIYDIPKVLHREELDAYVVRRLNLPFRDVDWTQWNDLLRRVHEPRDTVRIALVGKYIDLSDAY
+LSVAEALRAGGFAQHAKVEMRWVASDDCETDASAAAALADVDGVLIPGGFGIRGIEGKIGAIHYARKRGLPVLGLCLGLQ
+CIVIEAARSVGLTEANSAEFDPATPDPVISTMADQRDAVAGEADLGGTMRLGAYPAVLEPNSLVAQAYGTIEVSERHRHR
+YEVNNTYRDRIAESGLRFSGTSPDGHLVEFVEYPPEVHPFLVGTQAHPELKSRPTRPHPLFAAFVGASLDYKNAERLPVE
+MPEIPEHEPNGAEHALEDAPARG
+>gi|259645868|sp|C3L0M1.1|DER_CLOB6 RecName: Full=GTPase Der; AltName: Full=GTP-binding protein EngA
+MGKPIVAIVGRPNVGKSTLFNKLAGKRISIVQDTPGVTRDRIYAEAEWLNYKFTMIDTGGIEPESEDIIVSQMRRQAQIA
+IEMANVIIFLVDGKEGLAPADKEVAQMLRKSKKPVVLVVNKIDKLKDENNAYEFYNLGIGDPVTISSSQALGLGDMLDRV
+VEHFKDDESDGEDDERINIAFIGKPNVGKSSLINKLLGEERLIVSDIPGTTRDSIDSYVNTDFGEFTLIDTAGLRRKSKV
+KEEIERYSVIRTYASIERADVCILMIDATEGISEQDQKIIGYAHDINKAILVIVNKWDLVEKDDKTMDKFKKELKVNLSF
+MPYAKYLFISAKTGQRVVKVLQTAKECYDNYTKRVKTGVLNDVISQAIMMKEPPIVGTKRLKIYYVTQIGTKPPTFIFFV
+NDPACIHFSYQRYLENQLRENFDFQGTGIKLEFRERKEK
+>gi|131193|sp|P20120.1|PSAG_PEA RecName: Full=Photosystem I reaction center subunit V; AltName: Full=PSI-G; AltName: Full=Photosystem I 9 kDa protein
+ELNPSLVISLSTGLSLFLGRFVFFNFQRENVAKQGLPEQ
+>gi|15213932|sp|Q9KNH1.1|ATPF_VIBCH RecName: Full=ATP synthase subunit b; AltName: Full=ATP synthase F(0) sector subunit b; AltName: Full=ATPase subunit I; AltName: Full=F-type ATPase subunit b; Short=F-ATPase subunit b >gi|226696197|sp|A5F475.1|ATPF_VIBC3 RecName: Full=ATP synthase subunit b; AltName: Full=ATP synthase F(0) sector subunit b; AltName: Full=ATPase subunit I; AltName: Full=F-type ATPase subunit b; Short=F-ATPase subunit b
+MNMNATLLGQAISFGMFVWFCMKYVWPPIIKAIEDRQKKIADGLQAAERAKKDLDLAQANASDQLKEAKRTATELIEQAN
+KRKAQIIDEAREEAQAERQKILTQAEAEIEAERNRARDELRKQVATLAIAGAEKILERSIDKDTHKDILDNITAKL
+>gi|27734482|sp|Q8S8V5.1|RR3_ATRBE RecName: Full=30S ribosomal protein S3, chloroplastic
+MGQKINPLGFRLGTTQGHHSLWFSQPKNYSEGLQEDQKIRDCIKNYVQKNMRTSSGVEGIARIEIQKRIDLIQVIIFMGF
+PKLLIESRPRGIEELQMTLQKELNCVNRKLNIAVTRIAKPYGNPNILAEFIAGQLKNRVSFRKAMKKAIELTEQADTKGI
+QIQIAGRIDGKEIARVEWIREGRVPLQTIRAKIDYCAYTVRTIYGVLGIKIWIFLDEE
+>gi|74996881|sp|Q54PJ1.1|PRS10_DICDI RecName: Full=26S protease regulatory subunit 10B; AltName: Full=26S proteasome AAA-ATPase subunit RPT4; AltName: Full=Proteasome 26S subunit ATPase 6
+MSTEETKKEQALQNYRDRLIEHKNAELRLNKAHELIKKLKKDFQKTEDHIKTIQYIGEIIGEVLRSLDEERFIVKACNGP
+RYVVRCANYQDKAHLLVPGARVTLDLTTLTILKILPREVDPIIFNMTAESPGSVSYGEIGGLSNQIRELREVVELPLMIP
+ELFIRVGIKAPKGVLLYGPPGTGKTLLARAIASNLEANFLKVVSSAIVDKYIGESARVIREMFGYARDHQPCVIFMDEID
+AIGGRRFSEGTSADREIQRTLMELLNQMDGFDTLSKVKIIMATNRPDVLDPALLRPGRLDRKIEIPLPNEAGRVDVLKIH
+AANITKHGDVDYEAIAKLADGFNAADLRNVCTEAGMFAIRAERDYVMEEDFMKAVRKCQEAKKLEGKLDYQKV
+>gi|73913732|sp|Q5WER0.1|Y2615_BACSK RecName: Full=UPF0758 protein ABC2615
+MTLLIRDVPQTERPRERFIREGAKALSNQEIVAILLRTGTKQSSALHVASTLLSQFPTLAMFSEAPLEEIQKVPGIGMAK
+AIELSAAIELGRRIQRETKLVRPVISSPEDAAELVSEDMRGLQQEHFVALYLNTKNHVIKQKTLFIGSLNASIVHPREVF
+KEALQSSSASVICLHNHPSGDPSPSPEDISVTKRLRQAGAILGIELLDHIIVGDGCFISLKERGFFATIS
+>gi|29428258|sp|Q9H944.1|MED20_HUMAN RecName: Full=Mediator of RNA polymerase II transcription subunit 20; AltName: Full=Mediator complex subunit 20; AltName: Full=TRF-proximal protein homolog; Short=hTRFP
+MGVTCVSQMPVAEGKSVQQTVELLTRKLEMLGAEKQGTFCVDCETYHTAASTLGSQGQTGKLMYVMHNSEYPLSCFALFE
+NGPCLIADTNFDVLMVKLKGFFQSAKASKIETRGTRYQYCDFLVKVGTVTMGPSARGISVEVEYGPCVVASDCWSLLLEF
+LQSFLGSHTPGAPAVFGNRHDAVYGPADTMVQYMELFNKIRKQQQVPVAGIR
+>gi|226699301|sp|B2V7K5.1|RL29_SULSY RecName: Full=50S ribosomal protein L29
+MKASELRKLSNEELKEKILELKKKLFNLRFQNKIGSISNTAEINQTKKDIARILTILRERELNKTNG
+>gi|109893645|sp|Q2JV82.1|RL4_SYNJA RecName: Full=50S ribosomal protein L4
+MASCVVKNWQGETVGSAELSLKVARPETASHILYLALRRQMTNARQGNAHTKTRAEVRGGGRKPWRQKGTGRARAGSIRS
+PLWRKGGVIFGPRKREYNLAMNRKERQLALRTALQSRVEDLIVVEDFQDQLNPPKTRAVAQALLRWGVMEDQSALLIVAE
+RSEAVERAVRNIARVKLIGLDQLNVFDLLNVDWVLITTSALEKLKARWGSGAAAAAPTQADRLEDQAQAAEREARPVEQA
+EGQSQEQEEQAEAQAQPEAPPAQADQANQVALANPQVQETQEEELAQAQEREVQGQAELAQEAEPLAQPPAGEEAETAAA
+EEEDND
+>gi|20137741|sp|P58704.1|CYNS_ECO57 RecName: Full=Cyanate hydratase; Short=Cyanase; AltName: Full=Cyanate hydrolase; AltName: Full=Cyanate lyase >gi|226722273|sp|B5Z2P3.1|CYNS_ECO5E RecName: Full=Cyanate hydratase; Short=Cyanase; AltName: Full=Cyanate hydrolase; AltName: Full=Cyanate lyase >gi|226722277|sp|B7N8P7.1|CYNS_ECOLU RecName: Full=Cyanate hydratase; Short=Cyanase; AltName: Full=Cyanate hydrolase; AltName: Full=Cyanate lyase
+MIQSQINRNIRLDLADAILLSKAKKDLSFAEIADGTGLAEAFVTAALLGQQALPADAARQVGAKLDLDEDAILLLQMIPL
+RGCIDDRIPTDPTMYRFYEMLQVYGTTLKALVHEKFGDGIISAINFKLDVKKVADPEGGERAVITLDGKYLPTKPF
+>gi|131932|sp|P12466.1|RBL_CHLVU RecName: Full=Ribulose bisphosphate carboxylase large chain; Short=RuBisCO large subunit; Flags: Precursor
+MSPQTETKARVGFKAGVKDYRLTYYTPDYQPKDTDILAAFRMTPQPGVPPEEAGAAVAAESSTGTWTTVWTDGLTSLDRY
+KGRCYDIEPVPGEENQYIAYIAYPLDLFEEGSVTNLFTSIVGNVFGFKALRALRLEDLRIPPAYVKTFQGPPHGIQVERD
+KLNKYGRGLLGCTIKPKLGLSAKNYGRAVYECLRGGLDFTKDDENVNSQPFMRWRDRFLFVAEAIYKSQAETGEIKGHYL
+NATAATAEAMMQRAECAKDLGVPIIMHDYLTGGFTANTSLSHYCRDNGLLLHIHRAMHAVIDRQRNHGITFRVLAKALRL
+SGGDHLHSGTVVGKLEGEREVTLGFVDLMRDDYIEKDRSRGIYFTQDWVSLPGTMPVASGGIHVWHMPALVEIFGDDACL
+QFGGGTLGHPWGNAPGAAANRVALEACTQARNEGRDLAREGGDVIRAACKWSPELAAACEVWKEIKFEFETIDTL
+>gi|75146721|sp|Q84JT6.1|MSRB9_ARATH RecName: Full=Peptide methionine sulfoxide reductase B9; Short=AtMSRB9; AltName: Full=Peptide-methionine (R)-S-oxide reductase
+MPTSATAVAPSTGSVQKKDQDWRAILSPEQFRVLREKGTENRGKGEYTKLFDDGIYSCAGCATPLYKSTTKFDSGCGWPS
+FFDAIPGAIKQTPEAGGRRMEITCAACDGHLGHVVKGEGFPTATDERHCVNSVSLKFSEISSQ
+>gi|38258693|sp|P59982.1|Y2104_MYCBO RecName: Full=Uncharacterized protein Mb2104 >gi|614089143|sp|P9WLK8.1|Y2078_MYCTO RecName: Full=Uncharacterized protein MT2139
+MFVDVGLLHSGANESHYAGEHAHGGADQLSRGPLLSGMFGTFPVAQTFHDAVGAAHAQQMRNLHAHRQALITVGEKARHA
+ATGFTDMDDGNAAELKAVVCSCAT
+>gi|3024094|sp|P72396.2|MALR_STRCO RecName: Full=HTH-type transcriptional regulator MalR; AltName: Full=Maltose operon transcriptional repressor
+MTTRLADIAAQAGVSEATVSRVLNGKPGVAATTRQSVLAALDVLGYERPVRLRQRSEGLVGLITPELENPIFPALAQVIG
+QALTRQGYTPVLATQTPGGSTEDELTEMLVDRGVAGIIYVSGLHADTTADMQRYERLRAQGVPFVLVDGFSSQVQAPFIS
+PDDRAAMSLAVTHLVSLGHTRIGLALGPKRFVPVQRKIEGFVRTVQDQLGLSAETVEKELVQHSLYTLEGGQAAASALIG
+RDCTAVVCASDMMALGAIRAARQLGLDVPKDVSVVGFDDSPLIAFTDPPLTTVRKPVPAMGQAAVRTLLEEIGGTPAPHS
+EFVFMPELVVRGSTASAPGERGRP
diff --git a/c++/src/objtools/blast/seqdb_writer/unit_test/writedb_unit_test.cpp b/c++/src/objtools/blast/seqdb_writer/unit_test/writedb_unit_test.cpp
index ab167a5..b1b0ebd 100644
--- a/c++/src/objtools/blast/seqdb_writer/unit_test/writedb_unit_test.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/unit_test/writedb_unit_test.cpp
@@ -1,4 +1,4 @@
-/*  $Id: writedb_unit_test.cpp 495728 2016-03-21 14:25:14Z ivanov $
+/*  $Id: writedb_unit_test.cpp 518254 2016-11-01 17:36:44Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -50,6 +50,8 @@
 #include <objtools/blast/seqdb_reader/impl/seqdbisam.hpp>
 #include <objects/seqset/Seq_entry.hpp>
 
+#include <unordered_map>
+
 #ifndef SKIP_DOXYGEN_PROCESSING
 
 USING_NCBI_SCOPE;
@@ -658,6 +660,7 @@ static void s_NuclBioseqDupSwitch(int cutpoint)
     BOOST_REQUIRE_CUTPOINT(14);
 }
 
+
 BOOST_AUTO_TEST_SUITE(writedb)
 
 #if 0
@@ -2662,6 +2665,82 @@ BOOST_AUTO_TEST_CASE(CBuildDatabase_TestBasicDatabaseCreation)
     BOOST_REQUIRE(f1.Exists() == false);
 }
 
+BOOST_AUTO_TEST_CASE(CBuildDatabase_TestQuickDatabaseCreation)
+{
+    CTmpFile tmpfile;
+    CNcbiOstream& log = tmpfile.AsOutputFile(CTmpFile::eIfExists_Reset);
+    const string kOutput("x");
+    const string title("fuwafuwa");     // it's Japanese...
+    CFileDeleteAtExit::Add("x.pin");
+    CFileDeleteAtExit::Add("x.phr");
+    CFileDeleteAtExit::Add("x.psq");
+
+    // FASTA file contains 25 sequences.
+    CNcbiIfstream fasta_file("data/some_prots.fsa");
+    CRef<CBuildDatabase> bd;
+    bd.Reset(new CBuildDatabase(
+            kOutput,
+            title,
+            true,               // is_protein
+            CWriteDB::eNoIndex, // indexing
+            false,              // use_gi_mask
+            &log
+    ));
+    bd->SetSourceDb("swissprot");
+
+    // These two IDs are NOT in the FASTA file.
+    vector<string> ids;
+    ids.push_back("166225656");
+    ids.push_back("259646160");
+
+    bool success = bd->Build(ids, &fasta_file);
+    // Created DB should now contain 27 sequences.
+    BOOST_REQUIRE(success);
+
+    CFile f1(kOutput + ".pin");
+    BOOST_REQUIRE(f1.Exists() == true);
+
+    bd->EndBuild(true);
+    BOOST_REQUIRE(f1.Exists() == false);
+}
+
+BOOST_AUTO_TEST_CASE(CBuildDatabase_TestQuickDatabaseCreation_NoIds)
+{
+    CTmpFile tmpfile;
+    CNcbiOstream& log = tmpfile.AsOutputFile(CTmpFile::eIfExists_Reset);
+    const string kOutput("x1");
+    const string title("fuwafuwa");
+    CFileDeleteAtExit::Add("x1.pin");
+    CFileDeleteAtExit::Add("x1.phr");
+    CFileDeleteAtExit::Add("x1.psq");
+
+    // FASTA file contains 25 sequences.
+    CNcbiIfstream fasta_file("data/some_prots.fsa");
+    CRef<CBuildDatabase> bd;
+    bd.Reset(new CBuildDatabase(
+            kOutput,
+            title,
+            true,               // is_protein
+            CWriteDB::eNoIndex, // indexing
+            false,              // use_gi_mask
+            &log
+    ));
+    bd->SetSourceDb("swissprot");
+
+    // Not adding any IDs.
+    vector<string> ids;     // empty
+
+    bool success = bd->Build(ids, &fasta_file);
+    // Created DB should now contain 25 sequences.
+    BOOST_REQUIRE(success);
+
+    CFile f1(kOutput + ".pin");
+    BOOST_REQUIRE(f1.Exists() == true);
+
+    bd->EndBuild(true);
+    BOOST_REQUIRE(f1.Exists() == false);
+}
+
 class CSeqEntryGetSource : public IBioseqSource {
 public:
 	CSeqEntryGetSource(CRef<CSeq_entry> seq_entry)
@@ -2709,7 +2788,7 @@ BOOST_AUTO_TEST_CASE(CBuildDatabase_WGS_gap)
 
     CRef<CBuildDatabase> bd;
     bd.Reset(new CBuildDatabase(kOutput, "foo", false,
-            CWriteDB::eNoIndex, false, &log));
+                                CWriteDB::eNoIndex, false, &log));
     bd->StartBuild();
 
     auto_ptr<CObjectIStream> ois
@@ -2819,6 +2898,377 @@ BOOST_AUTO_TEST_CASE(CSeqDBIsam_32bit_GI)
     }
 }
 
+BOOST_AUTO_TEST_CASE(ReadBareIDProtein)
+{
+    // create a FASTA file with bare and legacy IDs
+    CTmpFile tmpfile;
+    CNcbiOfstream ostr(tmpfile.GetFileName().c_str());
+    string sequence = "MASTQNIVEEVQKMLDTYDTNKDGEITKAEAVEYFKGKKAFNPER";
+
+    std::unordered_map<string, CSeq_id::E_Choice> fasta_ids = {
+        {"XP_642131.1", CSeq_id::e_Other},
+        {"ref|XP_642837.1", CSeq_id::e_Other},
+        {"BAA06266.1", CSeq_id::e_Ddbj},
+        {"dbj|GAE97797.1", CSeq_id::e_Ddbj},
+        {"320460102", CSeq_id::e_Local},
+        {"gi|716054866", CSeq_id::e_Gi},
+        {"Q02VU1.1", CSeq_id::e_Swissprot},
+        {"sp|Q6GIX1.1|CADA_STAAR", CSeq_id::e_Swissprot},
+        {"EQR80552.1", CSeq_id::e_Genbank},
+        {"gb|EQS08124.1", CSeq_id::e_Genbank},
+        {"Somestring", CSeq_id::e_Local},
+        {"lcl|anotherstring", CSeq_id::e_Local},
+        {"12AS_A", CSeq_id::e_Pdb},
+        {"pdb|1I4D|D", CSeq_id::e_Pdb},
+        {"2209341B", CSeq_id::e_Local},
+        {"prf||2209335A", CSeq_id::e_Prf},
+        {"T49736", CSeq_id::e_Local},
+        {"pir||AI1052", CSeq_id::e_Pir}};
+
+    for (auto it: fasta_ids) {
+        ostr << ">" << it.first << endl << sequence << endl;
+    }
+    ostr.close();
+
+    // create a database from the fasta file
+    CNcbiIstream& istr = tmpfile.AsInputFile(CTmpFile::eIfExists_Throw);
+    BOOST_REQUIRE(istr);
+    string dbname = "data/bare_id_test_prot";
+    string title = "Temporary unit test db";
+    ostringstream log;
+    CBuildDatabase db(dbname, title, true, false, true, false, &log);
+
+    db.StartBuild();
+    db.AddFasta(istr);
+    db.EndBuild();
+
+    CFileDeleteAtExit::Add(dbname + ".phr");
+    CFileDeleteAtExit::Add(dbname + ".pin");
+    CFileDeleteAtExit::Add(dbname + ".psq");
+    CFileDeleteAtExit::Add(dbname + ".pog");
+    CFileDeleteAtExit::Add(dbname + ".psd");
+    CFileDeleteAtExit::Add(dbname + ".psi");
+
+    int index = 0;
+    CSeqDB seqdb(dbname, CSeqDB::eProtein);
+
+    // check that each sequence id has a correct type
+    for (auto it: fasta_ids) {
+        list< CRef<CSeq_id> > ids = seqdb.GetSeqIDs(index++);
+        BOOST_REQUIRE_MESSAGE(ids.front()->Which() == it.second,
+                              (string)"Sequence id type for " +
+                              it.first + " is " +
+                              NStr::IntToString(ids.front()->Which()) +
+                              " (expected " + NStr::IntToString(it.second)
+                              + ")");
+    }
+    BOOST_REQUIRE_EQUAL(index, (int)fasta_ids.size());
+}
+
+
+BOOST_AUTO_TEST_CASE(ReadMultipleBareIDs)
+{
+    // create a FASTA file with bare and legacy IDs
+    CTmpFile tmpfile;
+    CNcbiOfstream ostr(tmpfile.GetFileName().c_str());
+    string sequence = "MASTQNIVEEVQKMLDTYDTNKDGEITKAEAVEYFKGKKAFNPER";
+
+    std::unordered_map<string, CSeq_id::E_Choice> fasta_ids = {
+        {"XP_642131.1", CSeq_id::e_Other},
+        {"ref|XP_642837.1", CSeq_id::e_Other},
+        {"BAA06266.1", CSeq_id::e_Ddbj},
+        {"dbj|GAE97797.1", CSeq_id::e_Ddbj},
+        {"320460102", CSeq_id::e_Local},
+        {"gi|716054866", CSeq_id::e_Gi}};
+
+    auto it = fasta_ids.begin();
+    ostr << ">" << it->first << " Some defline";
+    ++it;
+    for (; it != fasta_ids.end(); ++it) {
+        ostr << '\01' << it->first << " Some defline";
+    }
+    ostr << endl << sequence << endl;
+    ostr.close();
+
+    // create a database from the fasta file
+    CNcbiIstream& istr = tmpfile.AsInputFile(CTmpFile::eIfExists_Throw);
+    BOOST_REQUIRE(istr);
+    string dbname = "data/bare_id_test_prot2";
+    string title = "Temporary unit test db";
+    ostringstream log;
+    CBuildDatabase db(dbname, title, true, false, true, false, &log);
+
+    db.StartBuild();
+    db.AddFasta(istr);
+    db.EndBuild();
+
+    CFileDeleteAtExit::Add(dbname + ".phr");
+    CFileDeleteAtExit::Add(dbname + ".pin");
+    CFileDeleteAtExit::Add(dbname + ".psq");
+    CFileDeleteAtExit::Add(dbname + ".pog");
+    CFileDeleteAtExit::Add(dbname + ".psd");
+    CFileDeleteAtExit::Add(dbname + ".psi");
+
+    CSeqDB seqdb(dbname, CSeqDB::eProtein);
+
+    list< CRef<CSeq_id> > ids = seqdb.GetSeqIDs(0);
+    BOOST_REQUIRE_EQUAL(ids.size(), fasta_ids.size());
+
+    auto seqdb_id = ids.begin();
+    for (auto it: fasta_ids) {
+        BOOST_REQUIRE_MESSAGE((*seqdb_id)->Which() == it.second,
+                              (string)"Sequence id type for " +
+                              it.first + " is " +
+                              NStr::IntToString(ids.front()->Which()) +
+                              " (expected " + NStr::IntToString(it.second)
+                              + ")");
+        ++seqdb_id;
+    }
+    BOOST_REQUIRE(seqdb_id == ids.end());
+}
+
+
+BOOST_AUTO_TEST_CASE(ReadBareIDNucleotide)
+{
+    // create a FASTA file with bare and legacy IDs
+    CTmpFile tmpfile;
+    CNcbiOfstream ostr(tmpfile.GetFileName().c_str());
+    string sequence = "AACTAGTATTAGAGGCACTGCCTGCCCAGTGACAATCGTTAAACGGCCG";
+
+    std::unordered_map<string, CSeq_id::E_Choice> fasta_ids = {
+        {"U13103.1", CSeq_id::e_Genbank},
+        {"gb|U13080.1", CSeq_id::e_Genbank},
+        {"Z18633.1", CSeq_id::e_Embl},
+        {"emb|Z18632.1", CSeq_id::e_Embl},
+        {"NM_176670.2", CSeq_id::e_Other},
+        {"ref|NM_175822.2", CSeq_id::e_Other},
+        {"SRR1272186", CSeq_id::e_Local},
+        {"gnl|SRA|SRR342213.1", CSeq_id::e_General},
+        {"gi|971149218", CSeq_id::e_Gi},
+        {"emb|LO018508.1", CSeq_id::e_Embl}};
+
+    for (auto it: fasta_ids) {
+        ostr << ">" << it.first << endl << sequence << endl;
+    }
+    ostr.close();
+
+    // create a database from the fasta file
+    CNcbiIstream& istr = tmpfile.AsInputFile(CTmpFile::eIfExists_Throw);
+    BOOST_REQUIRE(istr);
+    string dbname = "data/bare_id_test_nucl";
+    string title = "Temporary unit test db";
+    ostringstream log;
+    CBuildDatabase db(dbname, title, false, false, true, false, &log);
+
+    db.StartBuild();
+    db.AddFasta(istr);
+    db.EndBuild();
+
+    CFileDeleteAtExit::Add(dbname + ".nhr");
+    CFileDeleteAtExit::Add(dbname + ".nin");
+    CFileDeleteAtExit::Add(dbname + ".nsq");
+    CFileDeleteAtExit::Add(dbname + ".nog");
+    CFileDeleteAtExit::Add(dbname + ".nsd");
+    CFileDeleteAtExit::Add(dbname + ".nsi");
+
+    int index = 0;
+    CSeqDB seqdb(dbname, CSeqDB::eNucleotide);
+
+    // check that each sequence id has a correct type
+    for (auto it: fasta_ids) {
+        list< CRef<CSeq_id> > ids = seqdb.GetSeqIDs(index++);
+        BOOST_REQUIRE_MESSAGE(ids.front()->Which() == it.second,
+                              (string)"Sequence id type for " +
+                              it.first + " is " +
+                              NStr::IntToString(ids.front()->Which()) +
+                              " (expected " + NStr::IntToString(it.second)
+                              + ")");
+    }
+    BOOST_REQUIRE_EQUAL(index, (int)fasta_ids.size());
+}
+
+
+BOOST_AUTO_TEST_CASE(ReadLongIDProtein)
+{
+    // create a FASTA file with bare and legacy IDs
+    CTmpFile tmpfile;
+    CNcbiOfstream ostr(tmpfile.GetFileName().c_str());
+    string sequence = "MASTQNIVEEVQKMLDTYDTNKDGEITKAEAVEYFKGKKAFNPER";
+
+    std::unordered_map<string, CSeq_id::E_Choice> fasta_ids = {
+        {"XP_642131.1", CSeq_id::e_Local},
+        {"ref|XP_642837.1", CSeq_id::e_Other},
+        {"BAA06266.1", CSeq_id::e_Local},
+        {"dbj|GAE97797.1", CSeq_id::e_Ddbj},
+        {"320460102", CSeq_id::e_Local},
+        {"gi|716054866", CSeq_id::e_Gi},
+        {"Q02VU1.1", CSeq_id::e_Local},
+        {"sp|Q6GIX1.1|CADA_STAAR", CSeq_id::e_Swissprot},
+        {"EQR80552.1", CSeq_id::e_Local},
+        {"gb|EQS08124.1", CSeq_id::e_Genbank},
+        {"Somestring", CSeq_id::e_Local},
+        {"lcl|anotherstring", CSeq_id::e_Local},
+        {"12AS_A", CSeq_id::e_Local},
+        {"pdb|1I4D|D", CSeq_id::e_Pdb},
+        {"2209341B", CSeq_id::e_Local},
+        {"prf||2209335A", CSeq_id::e_Prf},
+        {"T49736", CSeq_id::e_Local},
+        {"pir||AI1052", CSeq_id::e_Pir}};
+
+
+    for (auto it: fasta_ids) {
+        ostr << ">" << it.first << endl << sequence << endl;
+    }
+    ostr.close();
+
+    // create a database from the fasta file
+    CNcbiIstream& istr = tmpfile.AsInputFile(CTmpFile::eIfExists_Throw);
+    BOOST_REQUIRE(istr);
+    string dbname = "data/bare_id_test_prot_legacy";
+    string title = "Temporary unit test db";
+    ostringstream log;
+    CBuildDatabase db(dbname, title, true, false, true, false, &log, true);
+
+    db.StartBuild();
+    db.AddFasta(istr);
+    db.EndBuild();
+
+    CFileDeleteAtExit::Add(dbname + ".phr");
+    CFileDeleteAtExit::Add(dbname + ".pin");
+    CFileDeleteAtExit::Add(dbname + ".psq");
+    CFileDeleteAtExit::Add(dbname + ".pog");
+    CFileDeleteAtExit::Add(dbname + ".psd");
+    CFileDeleteAtExit::Add(dbname + ".psi");
+
+    int index = 0;
+    CSeqDB seqdb(dbname, CSeqDB::eProtein);
+
+    // check that each sequence id has a correct type
+    for (auto it: fasta_ids) {
+        list< CRef<CSeq_id> > ids = seqdb.GetSeqIDs(index++);
+        BOOST_REQUIRE_MESSAGE(ids.front()->Which() == it.second,
+                              (string)"Sequence id type for " +
+                              it.first + " is " +
+                              NStr::IntToString(ids.front()->Which()) +
+                              " (expected " + NStr::IntToString(it.second)
+                              + ")");
+    }
+    BOOST_REQUIRE_EQUAL(index, (int)fasta_ids.size());
+}
+
+
+BOOST_AUTO_TEST_CASE(ReadMultipleLongIDs)
+{
+    // create a FASTA file with bare and legacy IDs
+    CTmpFile tmpfile;
+    CNcbiOfstream ostr(tmpfile.GetFileName().c_str());
+    string sequence = "MASTQNIVEEVQKMLDTYDTNKDGEITKAEAVEYFKGKKAFNPER";
+
+    std::unordered_map<string, CSeq_id::E_Choice> fasta_ids = {
+        {"XP_642131.1", CSeq_id::e_Local},
+        {"ref|XP_642837.1", CSeq_id::e_Other},
+        {"BAA06266.1", CSeq_id::e_Local},
+        {"dbj|GAE97797.1", CSeq_id::e_Ddbj},
+        {"320460102", CSeq_id::e_Local},
+        {"gi|716054866", CSeq_id::e_Gi}};
+
+    auto it = fasta_ids.begin();
+    ostr << ">" << it->first << " Some defline";
+    ++it;
+    for (; it != fasta_ids.end(); ++it) {
+        ostr << '\01' << it->first << " Some defline";
+    }
+    ostr << endl << sequence << endl;
+    ostr.close();
+
+    // create a database from the fasta file
+    CNcbiIstream& istr = tmpfile.AsInputFile(CTmpFile::eIfExists_Throw);
+    BOOST_REQUIRE(istr);
+    string dbname = "data/bare_id_test_legacy_prot2";
+    string title = "Temporary unit test db";
+    ostringstream log;
+    CBuildDatabase db(dbname, title, true, false, true, false, &log, true);
+
+    db.StartBuild();
+    db.AddFasta(istr);
+    db.EndBuild();
+
+    CFileDeleteAtExit::Add(dbname + ".phr");
+    CFileDeleteAtExit::Add(dbname + ".pin");
+    CFileDeleteAtExit::Add(dbname + ".psq");
+    CFileDeleteAtExit::Add(dbname + ".pog");
+    CFileDeleteAtExit::Add(dbname + ".psd");
+    CFileDeleteAtExit::Add(dbname + ".psi");
+
+    CSeqDB seqdb(dbname, CSeqDB::eProtein);
+
+    list< CRef<CSeq_id> > ids = seqdb.GetSeqIDs(0);
+    BOOST_REQUIRE_EQUAL(ids.size(), fasta_ids.size());
+
+    auto seqdb_id = ids.begin();
+    for (auto it: fasta_ids) {
+        BOOST_REQUIRE_MESSAGE((*seqdb_id)->Which() == it.second,
+                              (string)"Sequence id type for " +
+                              it.first + " is " +
+                              NStr::IntToString(ids.front()->Which()) +
+                              " (expected " + NStr::IntToString(it.second)
+                              + ")");
+        ++seqdb_id;
+    }
+    BOOST_REQUIRE(seqdb_id == ids.end());
+}
+
+
+BOOST_AUTO_TEST_CASE(ReadLongIDNucleotide)
+{
+    // create a FASTA file with bare and legacy IDs
+    CTmpFile tmpfile;
+    CNcbiOfstream ostr(tmpfile.GetFileName().c_str());
+    string sequence = "AACTAGTATTAGAGGCACTGCCTGCCCAGTGACAATCGTTAAACGGCCG";
+
+    std::unordered_map<string, CSeq_id::E_Choice> fasta_ids = {
+        {"U13103.1", CSeq_id::e_Local},
+        {"gb|U13080.1", CSeq_id::e_Genbank},
+        {"Z18633.1", CSeq_id::e_Local},
+        {"emb|Z18632.1", CSeq_id::e_Embl},
+        {"NM_176670.2", CSeq_id::e_Local},
+        {"ref|NM_175822.2", CSeq_id::e_Other}};
+
+    for (auto it: fasta_ids) {
+        ostr << ">" << it.first << endl << sequence << endl;
+    }
+    ostr.close();
+
+    // create a database from the fasta file
+    CNcbiIstream& istr = tmpfile.AsInputFile(CTmpFile::eIfExists_Throw);
+    BOOST_REQUIRE(istr);
+    string dbname = "data/bare_id_test_nucl_legacy";
+    string title = "Temporary unit test db";
+    ostringstream log;
+    CBuildDatabase db(dbname, title, false, false, true, false, &log, true);
+
+    db.StartBuild();
+    db.AddFasta(istr);
+    db.EndBuild();
+
+    CFileDeleteAtExit::Add(dbname + ".nhr");
+    CFileDeleteAtExit::Add(dbname + ".nin");
+    CFileDeleteAtExit::Add(dbname + ".nsq");
+    CFileDeleteAtExit::Add(dbname + ".nog");
+    CFileDeleteAtExit::Add(dbname + ".nsd");
+    CFileDeleteAtExit::Add(dbname + ".nsi");
+
+    int index = 0;
+    CSeqDB seqdb(dbname, CSeqDB::eNucleotide);
+
+    // check that each sequence id has a correct type
+    for (auto it: fasta_ids) {
+        list< CRef<CSeq_id> > ids = seqdb.GetSeqIDs(index++);
+        BOOST_REQUIRE_EQUAL(ids.front()->Which(), it.second);
+    }
+    BOOST_REQUIRE_EQUAL(index, (int)fasta_ids.size());
+}
+
 BOOST_AUTO_TEST_SUITE_END()
 
 #endif /* SKIP_DOXYGEN_PROCESSING */
diff --git a/c++/src/objtools/blast/seqdb_writer/writedb.cpp b/c++/src/objtools/blast/seqdb_writer/writedb.cpp
index d60399f..c13618f 100644
--- a/c++/src/objtools/blast/seqdb_writer/writedb.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/writedb.cpp
@@ -1,4 +1,4 @@
-/*  $Id: writedb.cpp 480531 2015-10-01 15:03:55Z rackerst $
+/*  $Id: writedb.cpp 513849 2016-09-15 17:36:45Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file writedb.cpp
 /// Implementation for the CWriteDB class, the top level class for WriteDB.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: writedb.cpp 480531 2015-10-01 15:03:55Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_writer/writedb.hpp>
 #include <objtools/blast/seqdb_reader/seqdb.hpp>
@@ -55,6 +50,7 @@ CWriteDB::CWriteDB(const string       & dbname,
                    const string       & title,
                    int                  indices,
                    bool                 parse_ids,
+                   bool                 long_ids,
                    bool                 use_gi_mask)
     : m_Impl(0)
 {
@@ -63,6 +59,7 @@ CWriteDB::CWriteDB(const string       & dbname,
                                title,
                                (EIndexType)indices,
                                parse_ids,
+                               long_ids,
                                use_gi_mask);
 }
 
@@ -121,9 +118,10 @@ void CWriteDB::SetMaxVolumeLetters(Uint8 sz)
 }
 
 CRef<CBlast_def_line_set>
-CWriteDB::ExtractBioseqDeflines(const CBioseq & bs, bool parse_ids)
+CWriteDB::ExtractBioseqDeflines(const CBioseq & bs, bool parse_ids,
+                                bool long_ids)
 {
-    return CWriteDB_Impl::ExtractBioseqDeflines(bs, parse_ids);
+    return CWriteDB_Impl::ExtractBioseqDeflines(bs, parse_ids, long_ids);
 }
 
 void CWriteDB::SetMaskedLetters(const string & masked)
diff --git a/c++/src/objtools/blast/seqdb_writer/writedb_column.cpp b/c++/src/objtools/blast/seqdb_writer/writedb_column.cpp
index a60c91c..a322d3f 100644
--- a/c++/src/objtools/blast/seqdb_writer/writedb_column.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/writedb_column.cpp
@@ -1,4 +1,4 @@
-/*  $Id: writedb_column.cpp 154436 2009-03-11 16:27:17Z camacho $
+/*  $Id: writedb_column.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file writedb_column.cpp
 /// Implementation for the CWriteDB_Column and related classes.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: writedb_column.cpp 154436 2009-03-11 16:27:17Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_writer/writedb.hpp>
 #include "writedb_column.hpp"
diff --git a/c++/src/objtools/blast/seqdb_writer/writedb_convert.cpp b/c++/src/objtools/blast/seqdb_writer/writedb_convert.cpp
index 9d6b039..b1fee3a 100644
--- a/c++/src/objtools/blast/seqdb_writer/writedb_convert.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/writedb_convert.cpp
@@ -1,4 +1,4 @@
-/*  $Id: writedb_convert.cpp 495293 2016-03-16 14:53:07Z ivanov $
+/*  $Id: writedb_convert.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file writedb_convert.cpp
 /// Data conversion tools for CWriteDB and associated code.
 /// class for WriteDB.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: writedb_convert.cpp 495293 2016-03-16 14:53:07Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <util/sequtil/sequtil_convert.hpp>
 #include <util/random_gen.hpp>
diff --git a/c++/src/objtools/blast/seqdb_writer/writedb_files.cpp b/c++/src/objtools/blast/seqdb_writer/writedb_files.cpp
index b5241fd..c39fe80 100644
--- a/c++/src/objtools/blast/seqdb_writer/writedb_files.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/writedb_files.cpp
@@ -1,4 +1,4 @@
-/*  $Id: writedb_files.cpp 446663 2014-09-17 14:36:30Z rackerst $
+/*  $Id: writedb_files.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file writedb_files.cpp
 /// Implementation for the CWriteDB_Files class.
 /// class for WriteDB.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: writedb_files.cpp 446663 2014-09-17 14:36:30Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_writer/writedb_files.hpp>
 #include <objtools/blast/seqdb_writer/writedb_convert.hpp>
diff --git a/c++/src/objtools/blast/seqdb_writer/writedb_general.cpp b/c++/src/objtools/blast/seqdb_writer/writedb_general.cpp
index 5d463d7..de3cbaa 100644
--- a/c++/src/objtools/blast/seqdb_writer/writedb_general.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/writedb_general.cpp
@@ -1,4 +1,4 @@
-/*  $Id: writedb_general.cpp 214595 2010-12-06 20:24:17Z maning $
+/*  $Id: writedb_general.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file writedb_general.cpp
 /// Implementation for general purpose utilities for WriteDB.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: writedb_general.cpp 214595 2010-12-06 20:24:17Z maning $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_writer/writedb_general.hpp>
 
diff --git a/c++/src/objtools/blast/seqdb_writer/writedb_gimask.cpp b/c++/src/objtools/blast/seqdb_writer/writedb_gimask.cpp
index db0204d..efd4b83 100644
--- a/c++/src/objtools/blast/seqdb_writer/writedb_gimask.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/writedb_gimask.cpp
@@ -1,4 +1,4 @@
-/*  $Id: writedb_gimask.cpp 480398 2015-09-30 12:57:29Z rackerst $
+/*  $Id: writedb_gimask.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file writedb_gimask.cpp
 /// Implementation for the CWriteDB_GiMask and related classes.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: writedb_gimask.cpp 480398 2015-09-30 12:57:29Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_writer/writedb.hpp>
 #include "writedb_gimask.hpp"
diff --git a/c++/src/objtools/blast/seqdb_writer/writedb_impl.cpp b/c++/src/objtools/blast/seqdb_writer/writedb_impl.cpp
index 9ddce4b..e561b0a 100644
--- a/c++/src/objtools/blast/seqdb_writer/writedb_impl.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/writedb_impl.cpp
@@ -1,4 +1,4 @@
-/*  $Id: writedb_impl.cpp 495464 2016-03-17 16:30:45Z ivanov $
+/*  $Id: writedb_impl.cpp 518254 2016-11-01 17:36:44Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file writedb_impl.cpp
 /// Implementation for the CWriteDB_Impl class.
 /// class for WriteDB.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: writedb_impl.cpp 495464 2016-03-17 16:30:45Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/blast/seqdb_writer/writedb_error.hpp>
 #include <objtools/blast/seqdb_reader/seqdbexpert.hpp>
@@ -62,6 +57,7 @@ CWriteDB_Impl::CWriteDB_Impl(const string & dbname,
                              const string & title,
                              EIndexType     indices,
                              bool           parse_ids,
+                             bool           long_ids,
                              bool           use_gi_mask)
     : m_Dbname           (dbname),
       m_Protein          (protein),
@@ -76,7 +72,8 @@ CWriteDB_Impl::CWriteDB_Impl(const string & dbname,
       m_Pig              (0),
       m_Hash             (0),
       m_SeqLength        (0),
-      m_HaveSequence     (false)
+      m_HaveSequence     (false),
+      m_LongSeqId        (long_ids)
 {
     CTime now(CTime::eCurrent);
 
@@ -646,15 +643,21 @@ x_SetDeflinesFromBinary(const string                   & bin_hdr,
 }
 
 
-static bool s_UseFastaReaderDeflines(CConstRef<CBioseq> & bioseq, CConstRef<CBlast_def_line_set> & deflines)
+static bool s_UseFastaReaderDeflines(CConstRef<CBioseq> & bioseq, CConstRef<CBlast_def_line_set> & deflines, bool long_seqid)
 {
 	if(deflines.Empty())
 		return false;
 
 	const CSeq_id * bioseq_id = bioseq->GetNonLocalId();
 
-	if(bioseq_id == NULL)
-		return true;
+	if(bioseq_id == NULL ||
+       // For bare pir and prf ids go with the one from defline.
+       // This is to parse bare ids as local ones. The bare pdb ids are pdb in
+       // bioseq (parsed by CFastaReader), but local in deflines (parsed by
+       // CSeq_id).
+       (!long_seqid && (bioseq_id->IsPrf() || bioseq_id->IsPir()))) {
+        return true;
+       }
 
 	// Bioseq has non-local id, make sure at least one id is non-local from CFastaReader
 	// defline
@@ -676,7 +679,8 @@ CWriteDB_Impl::x_ExtractDeflines(CConstRef<CBioseq>             & bioseq,
                                  const vector< vector<int> >    & linkouts,
                                  int                              pig,
                                  int                              OID,
-                                 bool                             parse_ids)
+                                 bool                             parse_ids,
+                                 bool                             long_ids)
 {
     bool use_bin = (deflines.Empty() && pig == 0);
 
@@ -709,10 +713,11 @@ CWriteDB_Impl::x_ExtractDeflines(CConstRef<CBioseq>             & bioseq,
                                      linkouts,
                                      pig,
                                      false,
-                                     parse_ids);
+                                     parse_ids,
+                                     long_ids);
         }
 
-        if(!s_UseFastaReaderDeflines(bioseq, deflines)) {
+        if(!s_UseFastaReaderDeflines(bioseq, deflines, long_ids)) {
         	deflines.Reset();
         }
 
@@ -799,7 +804,8 @@ void CWriteDB_Impl::x_CookHeader()
                       m_Linkouts,
                       m_Pig,
                       OID,
-                      m_ParseIDs);
+                      m_ParseIDs,
+                      m_LongSeqId);
 }
 
 void CWriteDB_Impl::x_CookIds()
@@ -1415,7 +1421,8 @@ void CWriteDB_Impl::SetMaxVolumeLetters(Uint8 sz)
 }
 
 CRef<CBlast_def_line_set>
-CWriteDB_Impl::ExtractBioseqDeflines(const CBioseq & bs, bool parse_ids)
+CWriteDB_Impl::ExtractBioseqDeflines(const CBioseq & bs, bool parse_ids,
+                                     bool long_seqids)
 {
     // Get information
 
@@ -1424,7 +1431,8 @@ CWriteDB_Impl::ExtractBioseqDeflines(const CBioseq & bs, bool parse_ids)
     vector< vector<int> > v1, v2;
 
     CConstRef<CBioseq> bsref(& bs);
-    x_ExtractDeflines(bsref, deflines, binary_header, v2, v2, 0, -1, parse_ids);
+    x_ExtractDeflines(bsref, deflines, binary_header, v2, v2, 0, -1, parse_ids,
+                      long_seqids);
 
     // Convert to return type
 
@@ -1556,7 +1564,8 @@ x_GetFastaReaderDeflines(const CBioseq                  & bioseq,
                          const vector< vector<int> >    & linkout,
                          int                              pig,
                          bool                             accept_gt,
-                         bool                             parse_ids)
+                         bool                             parse_ids,
+                         bool                             long_seqids)
 {
     if (! bioseq.CanGetDescr()) {
         return;
@@ -1681,11 +1690,30 @@ x_GetFastaReaderDeflines(const CBioseq                  & bioseq,
 
             // Parse '|' seperated ids.
             list< CRef<CSeq_id> > seqids;
-            if ( ids.find('|') == NPOS
-              || !isalpha((unsigned char)(ids[0]))) {
+            if ( (ids.find('|') == NPOS && long_seqids)
+                 || !isalpha((unsigned char)(ids[0]))) {
+
                  seqids.push_back(CRef<CSeq_id> (new CSeq_id(CSeq_id::e_Local, ids)));
             } else {
                  CSeq_id::ParseFastaIds(seqids, ids);
+
+                 if (!long_seqids) {
+
+                     // If accession's molecule type is different than
+                     // expected, change sequence id to local. CFastaReader
+                     // cannot distingush between bare pir protein ids genbank
+                     // nucleotide ids.
+                     for (auto& it: seqids) {
+                         CSeq_id::EAccessionInfo info = it->IdentifyAccession();
+                         if (!it->IsLocal() && !it->IsGi() &&
+                             (info & (CSeq_id::fAcc_prot | CSeq_id::fAcc_nuc)) &&
+                             bioseq.IsAa() == !!(info & CSeq_id::fAcc_nuc)) {
+
+                             string label = it->GetSeqIdString(true);
+                             it.Reset(new CSeq_id(CSeq_id::e_Local, label));
+                         }
+                     }
+                 }
             }
 
             // Build the actual defline.
diff --git a/c++/src/objtools/blast/seqdb_writer/writedb_impl.hpp b/c++/src/objtools/blast/seqdb_writer/writedb_impl.hpp
index 72743a7..18d8cec 100644
--- a/c++/src/objtools/blast/seqdb_writer/writedb_impl.hpp
+++ b/c++/src/objtools/blast/seqdb_writer/writedb_impl.hpp
@@ -1,7 +1,7 @@
 #ifndef OBJTOOLS_WRITERS_WRITEDB__WRITEDB_IMPL_HPP
 #define OBJTOOLS_WRITERS_WRITEDB__WRITEDB_IMPL_HPP
 
-/*  $Id: writedb_impl.hpp 480531 2015-10-01 15:03:55Z rackerst $
+/*  $Id: writedb_impl.hpp 513849 2016-09-15 17:36:45Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -72,12 +72,15 @@ public:
     /// @param title Title string for volumes and alias file.
     /// @param indices Type of indexing to do for string IDs.
     /// @param parse_ids If true generate ISAM files
+    /// @param long_ids If true, assume long sequence ids (database|accession)
+    /// when parsing strings ids
     /// @param use_gi_mask If true generate GI-based mask files.
     CWriteDB_Impl(const string     & dbname,
                   bool               protein,
                   const string     & title,
                   EIndexType         indices,
                   bool               parse_ids,
+                  bool               long_ids,
                   bool               use_gi_mask);
 
     /// Destructor.
@@ -213,9 +216,10 @@ public:
     ///
     /// @param bs Bioseq from which to construct the defline set.
     /// @param parse_ids If we should parse seq_ids.
+    /// @param long_seqids If true use long sequence ids (database|accession)
     /// @return The blast defline set.
     static CRef<CBlast_def_line_set>
-    ExtractBioseqDeflines(const CBioseq & bs, bool parse_ids);
+    ExtractBioseqDeflines(const CBioseq & bs, bool parse_ids, bool long_seqids);
 
     /// Set bases that should not be used in sequences.
     ///
@@ -478,6 +482,8 @@ private:
     /// @param pig PIG to attach to a protein sequence. [in]
     /// @param accept_gt Whether greater-than is a delimiter. [in]
     /// @param parse_ids Whether seq_id should not be parsed. [in]
+    /// @param long_seqids If true, use long sequence ids (database|accession)
+    /// [in]
     static void
     x_GetFastaReaderDeflines(const CBioseq                  & bioseq,
                              CConstRef<CBlast_def_line_set> & deflines,
@@ -485,7 +491,8 @@ private:
                              const vector< vector<int> >    & linkout,
                              int                              pig,
                              bool                             accept_gt,
-                             bool                             parse_ids);
+                             bool                             parse_ids,
+                             bool                             long_seqids);
 
     /// Returns true if we have unwritten sequence data.
     bool x_HaveSequence() const;
@@ -520,7 +527,8 @@ private:
                                   const vector< vector<int> >    & linkouts,
                                   int                              pig,
                                   int                              OID=-1,
-                                  bool                             parse_ids=true);
+                                  bool                             parse_ids=true,
+                                  bool                             long_seqid=false);
 
     /// Compute the hash of a (raw) sequence.
     ///
@@ -612,6 +620,10 @@ private:
 
     /// Registry for masking algorithms in this database.
     CMaskInfoRegistry m_MaskAlgoRegistry;
+
+    /// If true, use long sequence id format (database|accession) for all
+    /// acessions
+    bool m_LongSeqId;
 };
 
 END_NCBI_SCOPE
diff --git a/c++/src/objtools/blast/seqdb_writer/writedb_isam.cpp b/c++/src/objtools/blast/seqdb_writer/writedb_isam.cpp
index f1c6f16..9837466 100644
--- a/c++/src/objtools/blast/seqdb_writer/writedb_isam.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/writedb_isam.cpp
@@ -1,4 +1,4 @@
-/*  $Id: writedb_isam.cpp 481389 2015-10-09 14:40:20Z rackerst $
+/*  $Id: writedb_isam.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
 
 /// @file writedb_isam.cpp
 /// Implementation for the CWriteDB_Isam and related classes.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: writedb_isam.cpp 481389 2015-10-09 14:40:20Z rackerst $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/tempstr.hpp>
 #include <objtools/blast/seqdb_writer/writedb_error.hpp>
diff --git a/c++/src/objtools/blast/seqdb_writer/writedb_volume.cpp b/c++/src/objtools/blast/seqdb_writer/writedb_volume.cpp
index f11c538..12b9c5f 100644
--- a/c++/src/objtools/blast/seqdb_writer/writedb_volume.cpp
+++ b/c++/src/objtools/blast/seqdb_writer/writedb_volume.cpp
@@ -1,4 +1,4 @@
-/*  $Id: writedb_volume.cpp 500116 2016-05-02 16:11:10Z ivanov $
+/*  $Id: writedb_volume.cpp 500957 2016-05-10 13:45:41Z fongah2 $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
 /// @file writedb_volume.cpp
 /// Implementation for the CWriteDB_Volume class.
 /// class for WriteDB.
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: writedb_volume.cpp 500116 2016-05-02 16:11:10Z ivanov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "writedb_volume.hpp"
 #include <objtools/blast/seqdb_writer/writedb_error.hpp>
@@ -222,7 +217,8 @@ bool CWriteDB_Volume::WriteSequence(const string      & seq,
     	string id_u;
     	pair<set<string>::iterator, bool > rv;
         ITERATE(TIdList, iter, idlist) {
-            string id = (*iter)->GetSeqIdString(true);
+            string id = kEmptyStr;
+            (*iter)->GetLabel(&id);
             id_u = NStr::ToUpper(id);
             rv = m_IdSet.insert(id_u);
             if((rv.second == false) && (!(*iter)->IsLocal())) {
diff --git a/c++/src/objtools/blast/services/Makefile.blast_services.lib b/c++/src/objtools/blast/services/Makefile.blast_services.lib
index b598c92..8d2fee2 100644
--- a/c++/src/objtools/blast/services/Makefile.blast_services.lib
+++ b/c++/src/objtools/blast/services/Makefile.blast_services.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.blast_services.lib 468535 2015-05-26 13:23:32Z ucko $
+# $Id: Makefile.blast_services.lib 498594 2016-04-18 14:09:11Z camacho $
 
 WATCHERS = madden camacho
 
@@ -11,7 +11,8 @@ LIB = blast_services
 DLL_LIB = xnetblastcli xnetblast
 
 CFLAGS   = $(FAST_CFLAGS)
-CPPFLAGS = -DNCBI_MODULE=NETBLAST $(ORIG_CPPFLAGS)
+# -DNCBI_MODULE=NETBLAST moved to blast_services.*pp to avoid misnamed modules in DLL configurations
+CPPFLAGS = $(ORIG_CPPFLAGS)
 CXXFLAGS = $(FAST_CXXFLAGS)
 LDFLAGS  = $(FAST_LDFLAGS)
 
diff --git a/c++/src/objtools/blast/services/blast_services.cpp b/c++/src/objtools/blast/services/blast_services.cpp
index ed63345..1078d4b 100644
--- a/c++/src/objtools/blast/services/blast_services.cpp
+++ b/c++/src/objtools/blast/services/blast_services.cpp
@@ -1,4 +1,4 @@
-/*  $Id: blast_services.cpp 464987 2015-04-15 19:29:32Z merezhuk $
+/*  $Id: blast_services.cpp 498594 2016-04-18 14:09:11Z camacho $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -54,6 +54,8 @@
 BEGIN_NCBI_SCOPE
 USING_SCOPE(objects);
 
+#define NCBI_MODULE NETBLAST
+
 /// Process error messages from a reply object.
 ///
 /// Every reply object from blast4 has a space for error and warning
@@ -439,7 +441,7 @@ CBlastServices::GetDatabaseInfoLegacy(const string& dbname, bool is_protein,
 {
     vector<CRef<objects::CBlast4_database_info> > retval;
     vector<string> dbs;
-    NStr::Tokenize(dbname, " \n\t", dbs);
+    NStr::Split(dbname, " \n\t", dbs);
 
     if (dbs.empty())
       *found_all = false; // Loop did not run.
@@ -484,7 +486,7 @@ CBlastServices::GetDatabaseInfo(const string& dbname, bool is_protein,
     if( found_all ){
 	*found_all = false;
     }
-    NStr::Tokenize(local_db_name, " \n\t", all_db_names);
+    NStr::Split(local_db_name, " \n\t", all_db_names);
     l_multiple_db = ( all_db_names.size() > 1 );
 
     request.Reset(new CBlast4_request);
@@ -671,6 +673,8 @@ CBlastServices::GetTaxIdWithWindowMaskerSupport()
     return m_WindowMaskedTaxIds;
 }
 
+#undef NCBI_MODULE
+
 END_NCBI_SCOPE
 
 /* @} */
diff --git a/c++/src/objtools/cleanup/Makefile.cleanup.lib b/c++/src/objtools/cleanup/Makefile.cleanup.lib
index bcb2975..7a04a5f 100644
--- a/c++/src/objtools/cleanup/Makefile.cleanup.lib
+++ b/c++/src/objtools/cleanup/Makefile.cleanup.lib
@@ -1,11 +1,11 @@
-# $Id: Makefile.cleanup.lib 485437 2015-11-20 20:47:45Z bollin $
+# $Id: Makefile.cleanup.lib 515770 2016-10-05 17:31:33Z ivanov $
 
 # Build library "xcleanup"
 ###############################
 
-WATCHERS = bollin kans kornbluh
+WATCHERS = bollin kans
 
-ASN_DEP = general biblio seq pub seqset submit valid valerr
+ASN_DEP = submit valid
 SRC = autogenerated_cleanup autogenerated_extended_cleanup cleanup \
       cleanup_utils \
       newcleanupp
diff --git a/c++/src/objtools/cleanup/autogenerated_cleanup.cpp b/c++/src/objtools/cleanup/autogenerated_cleanup.cpp
index 7d6b030..31b83a5 100644
--- a/c++/src/objtools/cleanup/autogenerated_cleanup.cpp
+++ b/c++/src/objtools/cleanup/autogenerated_cleanup.cpp
@@ -1,4 +1,4 @@
-/* $Id: autogenerated_cleanup.cpp 499507 2016-04-26 17:32:39Z ivanov $
+/* $Id: autogenerated_cleanup.cpp 518682 2016-11-07 15:44:00Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -39,16 +39,6 @@
 BEGIN_SCOPE(ncbi)
 BEGIN_SCOPE(objects)
 
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_E_ETC( CDbtag & arg0 )
-{ // type Sequence
-  m_NewCleanup.DbtagBC( arg0 );
-} // end of x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_E_ETC
-
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( CDbtag & arg0 )
-{ // type Reference
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_E_ETC( arg0 );
-} // end of x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC
-
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_identification_identification_pdb_pdb_rel_rel_std_std_ETC( CDate_std & arg0 )
 { // type Sequence
   m_NewCleanup.x_DateStdBC( arg0 );
@@ -91,9 +81,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_support_support_model_evidence
 { // type Choice
   m_NewCleanup.SeqIdBC( arg0 );
   switch( arg0.Which() ) {
-  case CSeq_id::e_General:
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetGeneral() );
-    break;
   case CSeq_id::e_Pdb:
     x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_identification_identification_pdb_ETC( arg0.SetPdb() );
     break;
@@ -154,22 +141,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_v
   }
 } // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_location_equiv
 
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_ids_E_E_ETC( CFeat_id & arg0 )
-{ // type Choice
-  switch( arg0.Which() ) {
-  case CFeat_id::e_General:
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetGeneral() );
-    break;
-  default:
-    break;
-  }
-} // end of x_BasicCleanupSeqFeat_ids_E_E_ETC
-
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_ids_E_ETC( CFeat_id & arg0 )
-{ // type Reference
-    x_BasicCleanupSeqFeat_ids_E_E_ETC( arg0 );
-} // end of x_BasicCleanupSeqFeat_ids_E_ETC
-
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_location_packed_int_packed_int_E_E_ETC( CSeq_interval & arg0 )
 { // type Sequence
   if( arg0.IsSetId() ) {
@@ -244,9 +215,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_v
   case CSeq_loc::e_Equiv:
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_location_equiv( arg0.SetEquiv() );
     break;
-  case CSeq_loc::e_Feat:
-    x_BasicCleanupSeqFeat_ids_E_ETC( arg0.SetFeat() );
-    break;
   case CSeq_loc::e_Int:
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_location_packed_int_packed_int_E_ETC( arg0.SetInt() );
     break;
@@ -670,30 +638,11 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_v
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_imp_imp_pub_pub_ETC( arg0 );
 } // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_imp_imp_pub_ETC
 
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_E_name_name_ETC( CPerson_id & arg0 )
-{ // type Choice
-  switch( arg0.Which() ) {
-  case CPerson_id::e_Dbtag:
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetDbtag() );
-    break;
-  default:
-    break;
-  }
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_E_name_name_ETC
-
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_E_name_ETC( CPerson_id & arg0 )
-{ // type Reference
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_E_name_name_ETC( arg0 );
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_E_name_ETC
-
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_E_ETC( CAuthor & arg0 )
 { // type Sequence
   if( arg0.IsSetAffil() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_imp_imp_pub_ETC( arg0.SetAffil() );
   }
-  if( arg0.IsSetName() ) {
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_E_name_ETC( arg0.SetName() );
-  }
 } // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_E_ETC
 
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_ETC( CAuthor & arg0 )
@@ -864,37 +813,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_v
   }
 } // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_from_ETC
 
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ids_E_E_ETC( CArticleId & arg0 )
-{ // type Choice
-  switch( arg0.Which() ) {
-  case CArticleId::e_Other:
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetOther() );
-    break;
-  default:
-    break;
-  }
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ids_E_E_ETC
-
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ids_E_ETC( CArticleId & arg0 )
-{ // type Reference
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ids_E_E_ETC( arg0 );
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ids_E_ETC
-
-template< typename Tcontainer_ncbi_cref_carticleid_ >
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ids_ETC( Tcontainer_ncbi_cref_carticleid_ & arg0 )
-{ // type UniSequence
-  NON_CONST_ITERATE( typename Tcontainer_ncbi_cref_carticleid_, iter, arg0 ) { 
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ids_E_ETC( **iter );
-  }
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ids_ETC
-
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ETC( CArticleIdSet & arg0 )
-{ // type Reference
-  if( arg0.IsSet() ) {
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ids_ETC( arg0.Set() );
-  }
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ETC
-
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_title_title_E_name_ETC( std::string & arg0 )
 { // type Primitive
   m_NewCleanup.x_StripSpacesMarkChanged( arg0 );
@@ -935,9 +853,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_v
   if( arg0.IsSetFrom() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_from_ETC( arg0.SetFrom() );
   }
-  if( arg0.IsSetIds() ) {
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ETC( arg0.SetIds() );
-  }
   if( arg0.IsSetTitle() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_title_ETC( arg0.SetTitle() );
   }
@@ -1237,13 +1152,23 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_bios
   m_NewCleanup.x_TrimInternalSemicolonsMarkChanged( arg0 );
 } // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_common_ETC
 
+void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_dbxref_E_E_ETC( CDbtag & arg0 )
+{ // type Sequence
+  m_NewCleanup.DbtagBC( arg0 );
+} // end of x_BasicCleanupSeqFeat_dbxref_E_E_ETC
+
+void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_dbxref_E_ETC( CDbtag & arg0 )
+{ // type Reference
+    x_BasicCleanupSeqFeat_dbxref_E_E_ETC( arg0 );
+} // end of x_BasicCleanupSeqFeat_dbxref_E_ETC
+
 template< typename Tcontainer_ncbi_cref_cdbtag_ >
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( Tcontainer_ncbi_cref_cdbtag_ & arg0 )
+void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_dbxref_ETC( Tcontainer_ncbi_cref_cdbtag_ & arg0 )
 { // type UniSequence
   NON_CONST_ITERATE( typename Tcontainer_ncbi_cref_cdbtag_, iter, arg0 ) { 
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( **iter );
+    x_BasicCleanupSeqFeat_dbxref_E_ETC( **iter );
   }
-} // end of x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC
+} // end of x_BasicCleanupSeqFeat_dbxref_ETC
 
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_mod_E_ETC( std::string & arg0 )
 { // type Primitive
@@ -1382,7 +1307,7 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_data_data_biosrc_biosrc_org_or
     x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_common_ETC( arg0.SetCommon() );
   }
   if( arg0.IsSetDb() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetDb() );
+    x_BasicCleanupSeqFeat_dbxref_ETC( arg0.SetDb() );
   }
   if( arg0.IsSetMod() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_mod_ETC( arg0.SetMod() );
@@ -1462,9 +1387,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_v
   case CSeq_loc::e_Equiv:
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_location_equiv( arg0.SetEquiv() );
     break;
-  case CSeq_loc::e_Feat:
-    x_BasicCleanupSeqFeat_ids_E_ETC( arg0.SetFeat() );
-    break;
   case CSeq_loc::e_Int:
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_location_packed_int_packed_int_E_ETC( arg0.SetInt() );
     break;
@@ -1528,9 +1450,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_data_data_cdregion( CCdregion
 
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_clone_clone_clone_seq_clone_seq_E_E_ETC( CClone_seq & arg0 )
 { // type Sequence
-  if( arg0.IsSetAlign_id() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetAlign_id() );
-  }
   if( arg0.IsSetLocation() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_ETC( arg0.SetLocation() );
   }
@@ -1582,18 +1501,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txin
   m_NewCleanup.x_ConvertDoubleQuotesMarkChanged( arg0 );
 } // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_desc_ETC
 
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_formal_name_formal_name_ETC( CGene_nomenclature & arg0 )
-{ // type Sequence
-  if( arg0.IsSetSource() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetSource() );
-  }
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_formal_name_formal_name_ETC
-
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_formal_name_ETC( CGene_nomenclature & arg0 )
-{ // type Reference
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_formal_name_formal_name_ETC( arg0 );
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_formal_name_ETC
-
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_locus_ETC( std::string & arg0 )
 { // type Primitive
   m_NewCleanup.x_DecodeXMLMarkChanged( arg0 );
@@ -1627,15 +1534,9 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_data_data_gene_gene( CGene_ref
   if( arg0.IsSetAllele() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_locus_tag_ETC( arg0.SetAllele() );
   }
-  if( arg0.IsSetDb() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetDb() );
-  }
   if( arg0.IsSetDesc() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_desc_ETC( arg0.SetDesc() );
   }
-  if( arg0.IsSetFormal_name() ) {
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_formal_name_ETC( arg0.SetFormal_name() );
-  }
   if( arg0.IsSetLocus() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_locus_ETC( arg0.SetLocus() );
   }
@@ -1743,7 +1644,7 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_data_data_org_org( COrg_ref &
     x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_common_ETC( arg0.SetCommon() );
   }
   if( arg0.IsSetDb() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetDb() );
+    x_BasicCleanupSeqFeat_dbxref_ETC( arg0.SetDb() );
   }
   if( arg0.IsSetMod() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_mod_ETC( arg0.SetMod() );
@@ -1809,9 +1710,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_data_data_prot_prot( CProt_ref
   if( arg0.IsSetActivity() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_protein_E_E_activity_ETC( arg0.SetActivity() );
   }
-  if( arg0.IsSetDb() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetDb() );
-  }
   if( arg0.IsSetDesc() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_protein_E_E_desc_ETC( arg0.SetDesc() );
   }
@@ -2047,22 +1945,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_data_data_rna( CRNA_ref & arg0
     x_BasicCleanupSeqFeat_data_data_rna_rna( arg0 );
 } // end of x_BasicCleanupSeqFeat_data_data_rna
 
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_rsite_rsite_ETC( CRsite_ref & arg0 )
-{ // type Choice
-  switch( arg0.Which() ) {
-  case CRsite_ref::e_Db:
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetDb() );
-    break;
-  default:
-    break;
-  }
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_rsite_rsite_ETC
-
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_rsite_ETC( CRsite_ref & arg0 )
-{ // type Reference
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_rsite_rsite_ETC( arg0 );
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_rsite_ETC
-
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_data_data_site( CSeqFeatData::ESite & arg0 )
 { // type Enum
   m_NewCleanup.SiteFeatBC( arg0, *m_LastArg_BasicCleanupSeqFeat );
@@ -2079,15 +1961,9 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txin
   if( arg0.IsSetAllele() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_locus_tag_ETC( arg0.SetAllele() );
   }
-  if( arg0.IsSetDb() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetDb() );
-  }
   if( arg0.IsSetDesc() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_desc_ETC( arg0.SetDesc() );
   }
-  if( arg0.IsSetFormal_name() ) {
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_formal_name_ETC( arg0.SetFormal_name() );
-  }
   if( arg0.IsSetLocus() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_locus_ETC( arg0.SetLocus() );
   }
@@ -2123,9 +1999,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txin
   if( arg0.IsSetActivity() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_protein_E_E_activity_ETC( arg0.SetActivity() );
   }
-  if( arg0.IsSetDb() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetDb() );
-  }
   if( arg0.IsSetDesc() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_protein_E_E_desc_ETC( arg0.SetDesc() );
   }
@@ -2160,7 +2033,7 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txin
     x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_common_ETC( arg0.SetCommon() );
   }
   if( arg0.IsSetDb() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetDb() );
+    x_BasicCleanupSeqFeat_dbxref_ETC( arg0.SetDb() );
   }
   if( arg0.IsSetMod() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_mod_ETC( arg0.SetMod() );
@@ -2276,40 +2149,9 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_v
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_data_instance_instance_ETC( arg0 );
 } // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_data_instance_ETC
 
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_E_E_ETC( CPhenotype & arg0 )
-{ // type Sequence
-  if( arg0.IsSetXref() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetXref() );
-  }
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_E_E_ETC
-
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_E_ETC( CPhenotype & arg0 )
-{ // type Reference
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_E_E_ETC( arg0 );
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_E_ETC
-
-template< typename Tcontainer_ncbi_cref_cphenotype_ >
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_ETC( Tcontainer_ncbi_cref_cphenotype_ & arg0 )
-{ // type UniSequence
-  NON_CONST_ITERATE( typename Tcontainer_ncbi_cref_cphenotype_, iter, arg0 ) { 
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_E_ETC( **iter );
-  }
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_ETC
-
-template< typename Tcvariation_ref_container_ncbi_cref_c_e_somatic_origin_c_e_somatic_origin_c_condition >
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_somatic_origin_E_condition_ETC( Tcvariation_ref_container_ncbi_cref_c_e_somatic_origin_c_e_somatic_origin_c_condition & arg0 )
-{ // type Sequence
-  if( arg0.IsSetObject_id() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetObject_id() );
-  }
-} // end of x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_somatic_origin_E_condition_ETC
-
 template< typename Tcvariation_ref_container_ncbi_cref_c_e_somatic_origin_c_e_somatic_origin >
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_somatic_origin_E_ETC( Tcvariation_ref_container_ncbi_cref_c_e_somatic_origin_c_e_somatic_origin & arg0 )
 { // type Sequence
-  if( arg0.IsSetCondition() ) {
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_somatic_origin_E_condition_ETC( arg0.SetCondition() );
-  }
   if( arg0.IsSetSource() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_somatic_origin_E_source_ETC( arg0.SetSource() );
   }
@@ -2331,18 +2173,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_E
   if( arg0.IsSetData() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_data( arg0.SetData() );
   }
-  if( arg0.IsSetId() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetId() );
-  }
-  if( arg0.IsSetOther_ids() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetOther_ids() );
-  }
-  if( arg0.IsSetParent_id() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetParent_id() );
-  }
-  if( arg0.IsSetPhenotype() ) {
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_ETC( arg0.SetPhenotype() );
-  }
   if( arg0.IsSetSomatic_origin() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_somatic_origin_ETC( arg0.SetSomatic_origin() );
   }
@@ -2390,18 +2220,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_v
   if( arg0.IsSetData() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_data( arg0.SetData() );
   }
-  if( arg0.IsSetId() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetId() );
-  }
-  if( arg0.IsSetOther_ids() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetOther_ids() );
-  }
-  if( arg0.IsSetParent_id() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetParent_id() );
-  }
-  if( arg0.IsSetPhenotype() ) {
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_ETC( arg0.SetPhenotype() );
-  }
   if( arg0.IsSetSomatic_origin() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_somatic_origin_ETC( arg0.SetSomatic_origin() );
   }
@@ -2448,9 +2266,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_data_data( CSeqFeatData & arg0
   case CSeqFeatData::e_Rna:
     x_BasicCleanupSeqFeat_data_data_rna( arg0.SetRna() );
     break;
-  case CSeqFeatData::e_Rsite:
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_rsite_ETC( arg0.SetRsite() );
-    break;
   case CSeqFeatData::e_Seq:
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_ETC( arg0.SetSeq() );
     break;
@@ -2489,14 +2304,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_exts( Tcontainer_ncbi_cref_cus
   }
 } // end of x_BasicCleanupSeqFeat_exts
 
-template< typename Tcontainer_ncbi_cref_cfeat_id_ >
-void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_ids_ETC( Tcontainer_ncbi_cref_cfeat_id_ & arg0 )
-{ // type UniSequence
-  NON_CONST_ITERATE( typename Tcontainer_ncbi_cref_cfeat_id_, iter, arg0 ) { 
-    x_BasicCleanupSeqFeat_ids_E_ETC( **iter );
-  }
-} // end of x_BasicCleanupSeqFeat_ids_ETC
-
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_location_location_equiv_ETC( CSeq_loc_equiv & arg0 )
 { // type Reference
   if( arg0.IsSet() ) {
@@ -2518,9 +2325,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_location_location1767_ETC( CSe
   case CSeq_loc::e_Equiv:
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_location_location_equiv_ETC( arg0.SetEquiv() );
     break;
-  case CSeq_loc::e_Feat:
-    x_BasicCleanupSeqFeat_ids_E_ETC( arg0.SetFeat() );
-    break;
   case CSeq_loc::e_Int:
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_location_packed_int_packed_int_E_ETC( arg0.SetInt() );
     break;
@@ -2609,9 +2413,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_support_support_model_evidence
 
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_ETC( CModelEvidenceSupport & arg0 )
 { // type Sequence
-  if( arg0.IsSetDbxref() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetDbxref() );
-  }
   if( arg0.IsSetEst() ) {
     x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_protein_ETC( arg0.SetEst() );
   }
@@ -2687,7 +2488,7 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_bios
     x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_common_ETC( arg0.SetCommon() );
   }
   if( arg0.IsSetDb() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetDb() );
+    x_BasicCleanupSeqFeat_dbxref_ETC( arg0.SetDb() );
   }
   if( arg0.IsSetMod() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_mod_ETC( arg0.SetMod() );
@@ -2813,9 +2614,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_data_data_ETC( CSeqFe
   case CSeqFeatData::e_Rna:
     x_BasicCleanupSeqFeat_xref_E_E_data_data_rna_ETC( arg0.SetRna() );
     break;
-  case CSeqFeatData::e_Rsite:
-    x_BasicCleanupSeqFeat_xref_E_E_data_data_rsite_ETC( arg0.SetRsite() );
-    break;
   case CSeqFeatData::e_Seq:
     x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_ETC( arg0.SetSeq() );
     break;
@@ -2843,9 +2641,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_E_ETC( CSeqFeatXref & a
   if( arg0.IsSetData() ) {
     x_BasicCleanupSeqFeat_xref_E_E_data_ETC( arg0.SetData() );
   }
-  if( arg0.IsSetId() ) {
-    x_BasicCleanupSeqFeat_ids_E_ETC( arg0.SetId() );
-  }
 } // end of x_BasicCleanupSeqFeat_xref_E_E_ETC
 
 void CAutogeneratedCleanup::x_BasicCleanupSeqFeat_xref_E_ETC( CSeqFeatXref & arg0 )
@@ -2897,7 +2692,7 @@ void CAutogeneratedCleanup::BasicCleanupSeqFeat( CSeq_feat & arg0_raw )
     x_BasicCleanupSeqFeat_data( arg0.SetData() );
   }
   if( arg0.IsSetDbxref() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetDbxref() );
+    x_BasicCleanupSeqFeat_dbxref_ETC( arg0.SetDbxref() );
   }
   if( arg0.IsSetExt() ) {
     x_BasicCleanupSeqFeat_ext_ETC( arg0.SetExt() );
@@ -2905,12 +2700,6 @@ void CAutogeneratedCleanup::BasicCleanupSeqFeat( CSeq_feat & arg0_raw )
   if( arg0.IsSetExts() ) {
     x_BasicCleanupSeqFeat_exts( arg0.SetExts() );
   }
-  if( arg0.IsSetId() ) {
-    x_BasicCleanupSeqFeat_ids_E_ETC( arg0.SetId() );
-  }
-  if( arg0.IsSetIds() ) {
-    x_BasicCleanupSeqFeat_ids_ETC( arg0.SetIds() );
-  }
   if( arg0.IsSetLocation() ) {
     x_BasicCleanupSeqFeat_location_ETC( arg0.SetLocation() );
   }
@@ -3216,30 +3005,6 @@ void CAutogeneratedCleanup::x_BasicCleanupBioseqSet_annot_E_E_desc_ETC( CAnnot_d
   }
 } // end of x_BasicCleanupBioseqSet_annot_E_E_desc_ETC
 
-void CAutogeneratedCleanup::x_BasicCleanupBioseqSet_annot_E_E_id_E_E_ETC( CAnnot_id & arg0 )
-{ // type Choice
-  switch( arg0.Which() ) {
-  case CAnnot_id::e_General:
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetGeneral() );
-    break;
-  default:
-    break;
-  }
-} // end of x_BasicCleanupBioseqSet_annot_E_E_id_E_E_ETC
-
-void CAutogeneratedCleanup::x_BasicCleanupBioseqSet_annot_E_E_id_E_ETC( CAnnot_id & arg0 )
-{ // type Reference
-    x_BasicCleanupBioseqSet_annot_E_E_id_E_E_ETC( arg0 );
-} // end of x_BasicCleanupBioseqSet_annot_E_E_id_E_ETC
-
-template< typename Tcontainer_ncbi_cref_cannot_id_ >
-void CAutogeneratedCleanup::x_BasicCleanupBioseqSet_annot_E_E_id_ETC( Tcontainer_ncbi_cref_cannot_id_ & arg0 )
-{ // type UniSequence
-  NON_CONST_ITERATE( typename Tcontainer_ncbi_cref_cannot_id_, iter, arg0 ) { 
-    x_BasicCleanupBioseqSet_annot_E_E_id_E_ETC( **iter );
-  }
-} // end of x_BasicCleanupBioseqSet_annot_E_E_id_ETC
-
 void CAutogeneratedCleanup::x_BasicCleanupBioseq_annot_E_E( CSeq_annot & arg0 )
 { // type Sequence
   if( arg0.IsSetData() ) {
@@ -3248,9 +3013,6 @@ void CAutogeneratedCleanup::x_BasicCleanupBioseq_annot_E_E( CSeq_annot & arg0 )
   if( arg0.IsSetDesc() ) {
     x_BasicCleanupBioseqSet_annot_E_E_desc_ETC( arg0.SetDesc() );
   }
-  if( arg0.IsSetId() ) {
-    x_BasicCleanupBioseqSet_annot_E_E_id_ETC( arg0.SetId() );
-  }
 } // end of x_BasicCleanupBioseq_annot_E_E
 
 void CAutogeneratedCleanup::x_BasicCleanupBioseq_annot_E( CSeq_annot & arg0 )
@@ -3380,9 +3142,6 @@ void CAutogeneratedCleanup::x_BasicCleanupBioseqSet_seq_set_E_E_seq_seq_descr_de
   if( arg0.IsSetCreated() ) {
     x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_identification_identification_pdb_pdb_rel_ETC( arg0.SetCreated() );
   }
-  if( arg0.IsSetDbref() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( arg0.SetDbref() );
-  }
   if( arg0.IsSetSeqref() ) {
     x_BasicCleanupSeqFeat_support_support_inference_E_E_basis_basis_accessions_ETC( arg0.SetSeqref() );
   }
@@ -3412,18 +3171,12 @@ void CAutogeneratedCleanup::x_BasicCleanupBioseq_descr_descr_E_E( CSeqdesc & arg
   case CSeqdesc::e_Create_date:
     x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_identification_identification_pdb_pdb_rel_ETC( arg0.SetCreate_date() );
     break;
-  case CSeqdesc::e_Dbxref:
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetDbxref() );
-    break;
   case CSeqdesc::e_Embl:
     x_BasicCleanupBioseqSet_seq_set_E_E_seq_seq_descr_descr_E_E_embl_ETC( arg0.SetEmbl() );
     break;
   case CSeqdesc::e_Genbank:
     x_BasicCleanupBioseqSet_seq_set_E_E_seq_seq_descr_descr_E_E_genbank_ETC( arg0.SetGenbank() );
     break;
-  case CSeqdesc::e_Maploc:
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetMaploc() );
-    break;
   case CSeqdesc::e_Modelev:
     x_BasicCleanupSeqFeat_support_support_model_evidence_E_ETC( arg0.SetModelev() );
     break;
@@ -3721,9 +3474,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqEntry_set_set_annot_E_E( CSeq_annot
   if( arg0.IsSetDesc() ) {
     x_BasicCleanupBioseqSet_annot_E_E_desc_ETC( arg0.SetDesc() );
   }
-  if( arg0.IsSetId() ) {
-    x_BasicCleanupBioseqSet_annot_E_E_id_ETC( arg0.SetId() );
-  }
 } // end of x_BasicCleanupSeqEntry_set_set_annot_E_E
 
 void CAutogeneratedCleanup::x_BasicCleanupSeqEntry_set_set_annot_E( CSeq_annot & arg0 )
@@ -3758,18 +3508,12 @@ void CAutogeneratedCleanup::x_BasicCleanupBioseqSet_descr_descr_E_E_ETC( CSeqdes
   case CSeqdesc::e_Create_date:
     x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_identification_identification_pdb_pdb_rel_ETC( arg0.SetCreate_date() );
     break;
-  case CSeqdesc::e_Dbxref:
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetDbxref() );
-    break;
   case CSeqdesc::e_Embl:
     x_BasicCleanupBioseqSet_seq_set_E_E_seq_seq_descr_descr_E_E_embl_ETC( arg0.SetEmbl() );
     break;
   case CSeqdesc::e_Genbank:
     x_BasicCleanupBioseqSet_seq_set_E_E_seq_seq_descr_descr_E_E_genbank_ETC( arg0.SetGenbank() );
     break;
-  case CSeqdesc::e_Maploc:
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetMaploc() );
-    break;
   case CSeqdesc::e_Modelev:
     x_BasicCleanupSeqFeat_support_support_model_evidence_E_ETC( arg0.SetModelev() );
     break;
@@ -3856,9 +3600,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqEntry_set_set_ETC( CBioseq_set & ar
   if( arg0.IsSetAnnot() ) {
     x_BasicCleanupSeqEntry_set_set_annot( arg0.SetAnnot() );
   }
-  if( arg0.IsSetColl() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetColl() );
-  }
   if( arg0.IsSetDate() ) {
     x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_identification_identification_pdb_pdb_rel_ETC( arg0.SetDate() );
   }
@@ -3940,9 +3681,6 @@ void CAutogeneratedCleanup::x_BasicCleanupSeqSubmit_data_annots_E_E( CSeq_annot
   if( arg0.IsSetDesc() ) {
     x_BasicCleanupBioseqSet_annot_E_E_desc_ETC( arg0.SetDesc() );
   }
-  if( arg0.IsSetId() ) {
-    x_BasicCleanupBioseqSet_annot_E_E_id_ETC( arg0.SetId() );
-  }
 } // end of x_BasicCleanupSeqSubmit_data_annots_E_E
 
 void CAutogeneratedCleanup::x_BasicCleanupSeqSubmit_data_annots_E( CSeq_annot & arg0 )
@@ -4109,9 +3847,6 @@ void CAutogeneratedCleanup::BasicCleanupSeqAnnot( CSeq_annot & arg0 )
   if( arg0.IsSetDesc() ) {
     x_BasicCleanupBioseqSet_annot_E_E_desc_ETC( arg0.SetDesc() );
   }
-  if( arg0.IsSetId() ) {
-    x_BasicCleanupBioseqSet_annot_E_E_id_ETC( arg0.SetId() );
-  }
 } // end of BasicCleanupSeqAnnot
 
 void CAutogeneratedCleanup::x_BasicCleanupBioseqSet_annot_E_E_data_ftable_E( CSeq_feat & arg0 )
@@ -4161,9 +3896,6 @@ void CAutogeneratedCleanup::x_BasicCleanupBioseqSet_annot_E_E( CSeq_annot & arg0
   if( arg0.IsSetDesc() ) {
     x_BasicCleanupBioseqSet_annot_E_E_desc_ETC( arg0.SetDesc() );
   }
-  if( arg0.IsSetId() ) {
-    x_BasicCleanupBioseqSet_annot_E_E_id_ETC( arg0.SetId() );
-  }
 } // end of x_BasicCleanupBioseqSet_annot_E_E
 
 void CAutogeneratedCleanup::x_BasicCleanupBioseqSet_annot_E( CSeq_annot & arg0 )
@@ -4225,9 +3957,6 @@ void CAutogeneratedCleanup::BasicCleanupBioseqSet( CBioseq_set & arg0 )
   if( arg0.IsSetAnnot() ) {
     x_BasicCleanupBioseqSet_annot( arg0.SetAnnot() );
   }
-  if( arg0.IsSetColl() ) {
-    x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( arg0.SetColl() );
-  }
   if( arg0.IsSetDate() ) {
     x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_identification_identification_pdb_pdb_rel_ETC( arg0.SetDate() );
   }
diff --git a/c++/src/objtools/cleanup/autogenerated_cleanup.hpp b/c++/src/objtools/cleanup/autogenerated_cleanup.hpp
index 7a8e7a9..8e61575 100644
--- a/c++/src/objtools/cleanup/autogenerated_cleanup.hpp
+++ b/c++/src/objtools/cleanup/autogenerated_cleanup.hpp
@@ -1,7 +1,7 @@
 #ifndef AUTOGENERATEDCLEANUP__HPP
 #define AUTOGENERATEDCLEANUP__HPP
 
-/* $Id: autogenerated_cleanup.hpp 499507 2016-04-26 17:32:39Z ivanov $
+/* $Id: autogenerated_cleanup.hpp 518682 2016-11-07 15:44:00Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -41,12 +41,10 @@
 #include <objects/seqloc/Seq_bond.hpp>
 #include <objects/seqloc/Seq_point.hpp>
 #include <objects/seqloc/Seq_id.hpp>
-#include <objects/general/Dbtag.hpp>
 #include <objects/seqloc/PDB_seq_id.hpp>
 #include <objects/general/Date.hpp>
 #include <objects/general/Date_std.hpp>
 #include <objects/seqloc/Seq_loc_equiv.hpp>
-#include <objects/seqfeat/Feat_id.hpp>
 #include <objects/seqloc/Seq_interval.hpp>
 #include <objects/seqloc/Seq_loc_mix.hpp>
 #include <objects/seqloc/Packed_seqint.hpp>
@@ -68,7 +66,6 @@
 #include <objects/biblio/Auth_list.hpp>
 #include <objects/biblio/Affil.hpp>
 #include <objects/biblio/Author.hpp>
-#include <objects/general/Person_id.hpp>
 #include <objects/biblio/Cit_book.hpp>
 #include <objects/biblio/Imprint.hpp>
 #include <objects/biblio/PubStatusDateSet.hpp>
@@ -76,8 +73,6 @@
 #include <objects/biblio/Cit_jour.hpp>
 #include <objects/biblio/Cit_proc.hpp>
 #include <objects/biblio/Meeting.hpp>
-#include <objects/biblio/ArticleIdSet.hpp>
-#include <objects/biblio/ArticleId.hpp>
 #include <objects/biblio/Title.hpp>
 #include <objects/medline/Medline_entry.hpp>
 #include <objects/biblio/Cit_pat.hpp>
@@ -90,6 +85,7 @@
 #include <objects/seqfeat/SeqFeatData.hpp>
 #include <objects/seqfeat/BioSource.hpp>
 #include <objects/seqfeat/Org_ref.hpp>
+#include <objects/general/Dbtag.hpp>
 #include <objects/seqfeat/OrgName.hpp>
 #include <objects/seqfeat/OrgMod.hpp>
 #include <objects/seqfeat/MultiOrgName.hpp>
@@ -100,7 +96,6 @@
 #include <objects/seqfeat/Clone_seq_set.hpp>
 #include <objects/seqfeat/Clone_seq.hpp>
 #include <objects/seqfeat/Gene_ref.hpp>
-#include <objects/seqfeat/Gene_nomenclature.hpp>
 #include <objects/seqfeat/Imp_feat.hpp>
 #include <objects/seq/Numbering.hpp>
 #include <objects/seq/Num_ref.hpp>
@@ -111,12 +106,10 @@
 #include <objects/seqfeat/RNA_qual_set.hpp>
 #include <objects/seqfeat/RNA_qual.hpp>
 #include <objects/seqfeat/Trna_ext.hpp>
-#include <objects/seqfeat/Rsite_ref.hpp>
 #include <objects/seqfeat/Txinit.hpp>
 #include <objects/seqfeat/Variation_ref.hpp>
 #include <objects/seqfeat/Variation_inst.hpp>
 #include <objects/seqfeat/Delta_item.hpp>
-#include <objects/seqfeat/Phenotype.hpp>
 #include <objects/seqfeat/SeqFeatSupport.hpp>
 #include <objects/seqfeat/InferenceSupport.hpp>
 #include <objects/seqfeat/EvidenceBasis.hpp>
@@ -133,7 +126,6 @@
 #include <objects/seq/Annot_descr.hpp>
 #include <objects/seq/Annotdesc.hpp>
 #include <objects/seq/Align_def.hpp>
-#include <objects/seq/Annot_id.hpp>
 #include <objects/seq/Seq_descr.hpp>
 #include <objects/seq/Seqdesc.hpp>
 #include <objects/seqblock/EMBL_block.hpp>
@@ -187,8 +179,6 @@ public:
   void BasicCleanupSeqFeat( CSeq_feat & arg0_raw );
 
 private: 
-  void x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_E_ETC( CDbtag & arg0 );
-  void x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_E_ETC( CDbtag & arg0 );
   void x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_identification_identification_pdb_pdb_rel_rel_std_std_ETC( CDate_std & arg0 );
   void x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_identification_identification_pdb_pdb_rel_rel_std_ETC( CDate_std & arg0 );
   void x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_identification_identification_pdb_pdb_rel_rel_ETC( CDate & arg0 );
@@ -205,8 +195,6 @@ private:
   template< typename Tcontainer_ncbi_cref_cseq_loc_ >
 void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_location_equiv_equiv( Tcontainer_ncbi_cref_cseq_loc_ & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_location_equiv( CSeq_loc_equiv & arg0 );
-  void x_BasicCleanupSeqFeat_ids_E_E_ETC( CFeat_id & arg0 );
-  void x_BasicCleanupSeqFeat_ids_E_ETC( CFeat_id & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_location_packed_int_packed_int_E_E_ETC( CSeq_interval & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_location_packed_int_packed_int_E_ETC( CSeq_interval & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_ext_locs_E_E_location_location_mix_mix_E( CSeq_loc & arg0 );
@@ -282,8 +270,6 @@ void x_BasicCleanupSeqFeat_xref_E_E_data_data_pub_pub_num_num_ref_ref_aligns_ali
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_imp_imp_pub_pub_str_ETC( std::string & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_imp_imp_pub_pub_ETC( CAffil & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_imp_imp_pub_ETC( CAffil & arg0 );
-  void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_E_name_name_ETC( CPerson_id & arg0 );
-  void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_E_name_ETC( CPerson_id & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_E_ETC( CAuthor & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_man_cit_cit_authors_authors_names_std_E_ETC( CAuthor & arg0 );
   template< typename Tcontainer_ncbi_cref_cauthor_ >
@@ -307,11 +293,6 @@ void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_man_ma
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_proc_proc_ETC( CCit_proc & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_proc_ETC( CCit_proc & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_from_ETC( CCit_art::C_From & arg0 );
-  void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ids_E_E_ETC( CArticleId & arg0 );
-  void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ids_E_ETC( CArticleId & arg0 );
-  template< typename Tcontainer_ncbi_cref_carticleid_ >
-void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ids_ETC( Tcontainer_ncbi_cref_carticleid_ & arg0 );
-  void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_ids_ETC( CArticleIdSet & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_title_title_E_name_ETC( std::string & arg0 );
   template< typename Tcontainer_ncbi_cref_c_e_c_e >
 void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_pub_pub_article_article_title_title_E_ETC( Tcontainer_ncbi_cref_c_e_c_e & arg0 );
@@ -359,8 +340,10 @@ void x_BasicCleanupSeqFeat_cit_cit_pub_ETC( Tcontainer_ncbi_cref_cpub_ & arg0 );
   void x_BasicCleanupSeqFeat_cit_ETC( CPub_set & arg0 );
   void x_BasicCleanupSeqFeat_comment_ETC( std::string & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_common_ETC( std::string & arg0 );
+  void x_BasicCleanupSeqFeat_dbxref_E_E_ETC( CDbtag & arg0 );
+  void x_BasicCleanupSeqFeat_dbxref_E_ETC( CDbtag & arg0 );
   template< typename Tcontainer_ncbi_cref_cdbtag_ >
-void x_BasicCleanupSeqFeat_support_support_model_evidence_E_E_dbxref_ETC( Tcontainer_ncbi_cref_cdbtag_ & arg0 );
+void x_BasicCleanupSeqFeat_dbxref_ETC( Tcontainer_ncbi_cref_cdbtag_ & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_mod_E_ETC( std::string & arg0 );
   template< typename Tcontainer_std_string_ >
 void x_BasicCleanupSeqFeat_xref_E_E_data_data_biosrc_biosrc_org_org_mod_ETC( Tcontainer_std_string_ & arg0 );
@@ -407,8 +390,6 @@ void x_BasicCleanupSeqFeat_xref_E_E_data_data_clone_clone_clone_seq_clone_seq_ET
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_clone_ETC( CClone_ref & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_locus_tag_ETC( std::string & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_desc_ETC( std::string & arg0 );
-  void x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_formal_name_formal_name_ETC( CGene_nomenclature & arg0 );
-  void x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_formal_name_ETC( CGene_nomenclature & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_locus_ETC( std::string & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_syn_E_ETC( std::string & arg0 );
   template< typename Tcontainer_std_string_ >
@@ -464,8 +445,6 @@ void x_BasicCleanupSeqFeat_xref_E_E_data_data_rna_rna_ext_gen_gen_quals_quals_ET
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_rna_rna_ext_ETC( CRNA_ref::C_Ext & arg0 );
   void x_BasicCleanupSeqFeat_data_data_rna_rna( CRNA_ref & arg0 );
   void x_BasicCleanupSeqFeat_data_data_rna( CRNA_ref & arg0 );
-  void x_BasicCleanupSeqFeat_xref_E_E_data_data_rsite_rsite_ETC( CRsite_ref & arg0 );
-  void x_BasicCleanupSeqFeat_xref_E_E_data_data_rsite_ETC( CRsite_ref & arg0 );
   void x_BasicCleanupSeqFeat_data_data_site( CSeqFeatData::ESite & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_E_ETC( CGene_ref & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_txinit_txinit_gene_E_ETC( CGene_ref & arg0 );
@@ -493,12 +472,6 @@ void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_consequence( T
 void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_data_instance_instance_delta_ETC( Tcontainer_ncbi_cref_cdelta_item_ & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_data_instance_instance_ETC( CVariation_inst & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_data_instance_ETC( CVariation_inst & arg0 );
-  void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_E_E_ETC( CPhenotype & arg0 );
-  void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_E_ETC( CPhenotype & arg0 );
-  template< typename Tcontainer_ncbi_cref_cphenotype_ >
-void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_phenotype_ETC( Tcontainer_ncbi_cref_cphenotype_ & arg0 );
-  template< typename Tcvariation_ref_container_ncbi_cref_c_e_somatic_origin_c_e_somatic_origin_c_condition >
-void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_somatic_origin_E_condition_ETC( Tcvariation_ref_container_ncbi_cref_c_e_somatic_origin_c_e_somatic_origin_c_condition & arg0 );
   template< typename Tcvariation_ref_container_ncbi_cref_c_e_somatic_origin_c_e_somatic_origin >
 void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_somatic_origin_E_ETC( Tcvariation_ref_container_ncbi_cref_c_e_somatic_origin_c_e_somatic_origin & arg0 );
   template< typename Tcontainer_ncbi_cref_c_e_somatic_origin_ >
@@ -516,8 +489,6 @@ void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_data_set_varia
   void x_BasicCleanupSeqFeat_exts_E( CUser_object & arg0 );
   template< typename Tcontainer_ncbi_cref_cuser_object_ >
 void x_BasicCleanupSeqFeat_exts( Tcontainer_ncbi_cref_cuser_object_ & arg0 );
-  template< typename Tcontainer_ncbi_cref_cfeat_id_ >
-void x_BasicCleanupSeqFeat_ids_ETC( Tcontainer_ncbi_cref_cfeat_id_ & arg0 );
   void x_BasicCleanupSeqFeat_xref_E_E_data_data_variation_variation_location_location_equiv_ETC( CSeq_loc_equiv & arg0 );
   void x_BasicCleanupSeqFeat_location_location1767_ETC( CSeq_loc & arg0 );
   void x_BasicCleanupSeqFeat_location_ETC( CSeq_loc & arg0 );
@@ -592,10 +563,6 @@ void x_BasicCleanupBioseqSet_annot_E_E_data_seq_table_seq_table_columns_ETC( Tco
   template< typename Tcontainer_ncbi_cref_cannotdesc_ >
 void x_BasicCleanupBioseqSet_annot_E_E_desc_desc_ETC( Tcontainer_ncbi_cref_cannotdesc_ & arg0 );
   void x_BasicCleanupBioseqSet_annot_E_E_desc_ETC( CAnnot_descr & arg0 );
-  void x_BasicCleanupBioseqSet_annot_E_E_id_E_E_ETC( CAnnot_id & arg0 );
-  void x_BasicCleanupBioseqSet_annot_E_E_id_E_ETC( CAnnot_id & arg0 );
-  template< typename Tcontainer_ncbi_cref_cannot_id_ >
-void x_BasicCleanupBioseqSet_annot_E_E_id_ETC( Tcontainer_ncbi_cref_cannot_id_ & arg0 );
   void x_BasicCleanupBioseq_annot_E_E( CSeq_annot & arg0 );
   void x_BasicCleanupBioseq_annot_E( CSeq_annot & arg0 );
   template< typename Tcontainer_ncbi_cref_cseq_annot_ >
diff --git a/c++/src/objtools/cleanup/autogenerated_cleanup.txt b/c++/src/objtools/cleanup/autogenerated_cleanup.txt
index cd33d4e..045ba4d 100644
--- a/c++/src/objtools/cleanup/autogenerated_cleanup.txt
+++ b/c++/src/objtools/cleanup/autogenerated_cleanup.txt
@@ -276,7 +276,7 @@ use m_NewCleanup.x_GBQualToOrgRef {
 
 use m_NewCleanup.x_DateStdBC { Date-std }
 
-use m_NewCleanup.DbtagBC { Dbtag }
+use m_NewCleanup.DbtagBC { Seq-feat.dbxref.E, Org-ref.db.E }
 
 use m_NewCleanup.DeltaExtBC { Seq-inst.ext.delta AND Seq-inst }
 
diff --git a/c++/src/objtools/cleanup/autogenerated_extended_cleanup.cpp b/c++/src/objtools/cleanup/autogenerated_extended_cleanup.cpp
index 2e378b9..adca855 100644
--- a/c++/src/objtools/cleanup/autogenerated_extended_cleanup.cpp
+++ b/c++/src/objtools/cleanup/autogenerated_extended_cleanup.cpp
@@ -1,4 +1,4 @@
-/* $Id: autogenerated_extended_cleanup.cpp 499601 2016-04-26 18:10:02Z ivanov $
+/* $Id: autogenerated_extended_cleanup.cpp 520823 2016-12-01 18:52:54Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -354,7 +354,6 @@ void CAutogeneratedExtendedCleanup::ExtendedCleanupSeqFeat( CSeq_feat & arg0_raw
   m_NewCleanup.MoveStandardName( arg0 );
   m_NewCleanup.CreatePubFromFeat( arg0 );
   m_NewCleanup.ResynchProteinPartials( arg0 );
-  m_NewCleanup.x_RemoveUnnecessaryGeneXrefs( arg0 );
   m_NewCleanup.x_MoveSeqfeatOrgToSourceOrg( arg0 );
   if( arg0.IsSetData() ) {
     x_ExtendedCleanupSeqFeat_data( arg0.SetData() );
diff --git a/c++/src/objtools/cleanup/autogenerated_extended_cleanup.hpp b/c++/src/objtools/cleanup/autogenerated_extended_cleanup.hpp
index f1bb41c..f34d90f 100644
--- a/c++/src/objtools/cleanup/autogenerated_extended_cleanup.hpp
+++ b/c++/src/objtools/cleanup/autogenerated_extended_cleanup.hpp
@@ -1,7 +1,7 @@
 #ifndef AUTOGENERATEDEXTENDEDCLEANUP__HPP
 #define AUTOGENERATEDEXTENDEDCLEANUP__HPP
 
-/* $Id: autogenerated_extended_cleanup.hpp 499555 2016-04-26 17:51:03Z ivanov $
+/* $Id: autogenerated_extended_cleanup.hpp 497140 2016-04-04 18:31:44Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/cleanup/autogenerated_extended_cleanup.txt b/c++/src/objtools/cleanup/autogenerated_extended_cleanup.txt
index 5fe11e1..dade406 100644
--- a/c++/src/objtools/cleanup/autogenerated_extended_cleanup.txt
+++ b/c++/src/objtools/cleanup/autogenerated_extended_cleanup.txt
@@ -164,8 +164,6 @@ use m_NewCleanup.AddProteinTitles { POST Bioseq }
 
 use m_NewCleanup.x_RemoveUnseenTitles { Bioseq, Bioseq-set }
 
-use m_NewCleanup.x_RemoveUnnecessaryGeneXrefs { Seq-feat }
-
 use m_NewCleanup.x_MoveSeqdescOrgToSourceOrg { Seqdesc }
 use m_NewCleanup.x_MoveSeqfeatOrgToSourceOrg { Seq-feat }
 
diff --git a/c++/src/objtools/cleanup/cleanup.cpp b/c++/src/objtools/cleanup/cleanup.cpp
index 9f2be4c..579f5ac 100644
--- a/c++/src/objtools/cleanup/cleanup.cpp
+++ b/c++/src/objtools/cleanup/cleanup.cpp
@@ -1,4 +1,4 @@
-/* $Id: cleanup.cpp 500231 2016-05-03 14:59:56Z ivanov $
+/* $Id: cleanup.cpp 520817 2016-12-01 18:50:34Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -64,7 +64,8 @@
 #include <objmgr/seq_vector_ci.hpp>
 #include <objtools/cleanup/cleanup.hpp>
 #include "cleanup_utils.hpp"
-#include <objtools/edit/cds_fix.hpp>
+
+#include <util/strsearch.hpp>
 
 #include "newcleanupp.hpp"
 
@@ -78,11 +79,16 @@ enum EChangeType {
 // *********************** CCleanup implementation **********************
 
 
-CCleanup::CCleanup(CScope* scope) 
+CCleanup::CCleanup(CScope* scope, EScopeOptions scope_handling)
 {
-    m_Scope = new CScope(*(CObjectManager::GetInstance()));
-    if (scope) {
-        m_Scope->AddScope(*scope);
+    if (scope && scope_handling == eScope_UseInPlace) {
+        m_Scope = scope;
+    }
+    else {
+        m_Scope = new CScope(*(CObjectManager::GetInstance()));
+        if (scope) {
+            m_Scope->AddScope(*scope);
+        }
     }
 }
 
@@ -429,6 +435,7 @@ const char* const CCleanupChange::sm_ChangeDesc[eNumberofChangeTypes + 1] = {
     "Remove Dup BioSource",
     "Clean Org-ref",
     "Trim Internal Semicolons",
+    "Add SeqFeatXref",
 
     // set when any other change is made.
     "Change Other", 
@@ -446,6 +453,8 @@ CProt_ref::EProcessed s_ProcessedFromKey(const string& key)
         return CProt_ref::eProcessed_transit_peptide;
     } else if (NStr::Equal(key, "preprotein") || NStr::Equal(key, "proprotein")) {
         return CProt_ref::eProcessed_preprotein;
+    } else if (NStr::Equal(key, "propeptide")) {
+        return CProt_ref::eProcessed_propeptide;
     } else {
         return CProt_ref::eProcessed_not_set;
     }
@@ -466,6 +475,9 @@ string s_KeyFromProcessed(CProt_ref::EProcessed processed)
     case CProt_ref::eProcessed_transit_peptide:
         return "transit_peptide";
         break;
+    case CProt_ref::eProcessed_propeptide:
+        return "propeptide";
+        break;
     case CProt_ref::eProcessed_not_set:
         return kEmptyStr;
         break;
@@ -515,6 +527,33 @@ bool s_IsPreprotein(CSeq_feat_Handle fh)
 }
 
 
+void RescueProtProductQual(CSeq_feat& feat)
+{
+    if (!feat.IsSetQual() ||
+        !feat.IsSetData() || 
+        !feat.GetData().IsProt() ||
+        feat.GetData().GetProt().IsSetName()) {
+        return;
+    }
+    CSeq_feat::TQual::iterator it = feat.SetQual().begin();
+    while (it != feat.SetQual().end()) {
+        if ((*it)->IsSetQual() &&
+            NStr::Equal((*it)->GetQual(), "product")) {
+            if ((*it)->IsSetVal() && !NStr::IsBlank((*it)->GetVal())) {
+                feat.SetData().SetProt().SetName().push_back((*it)->GetVal());
+            }
+            it = feat.SetQual().erase(it);
+        } else {
+            ++it;
+        }
+    }
+
+    if (feat.SetQual().empty()) {
+        feat.ResetQual();
+    }
+}
+
+
 bool CCleanup::MoveFeatToProtein(CSeq_feat_Handle fh)
 {
     CProt_ref::EProcessed processed = CProt_ref::eProcessed_not_set;
@@ -548,9 +587,16 @@ bool CCleanup::MoveFeatToProtein(CSeq_feat_Handle fh)
         return ConvertProteinToImp(fh);
     }
 
-    CSeq_feat_Handle cds_h = fh.GetScope().GetSeq_featHandle(*cds);
-    if (!cds_h) {
-        // can't get handle
+    bool require_frame = false;
+    ITERATE(CBioseq::TId, id_it, parent_bsh.GetBioseqCore()->GetId()) {
+        if ((*id_it)->IsEmbl() || (*id_it)->IsDdbj()) {
+            require_frame = true;
+            break;
+        }
+    }
+    CRef<CSeq_loc> prot_loc = GetProteinLocationFromNucleotideLocation(fh.GetLocation(), *cds, fh.GetScope(), require_frame);
+
+    if (!prot_loc) {
         return false;
     }
 
@@ -559,40 +605,23 @@ bool CCleanup::MoveFeatToProtein(CSeq_feat_Handle fh)
     new_feat->Assign(*orig_feat);
     if (new_feat->GetData().Which() == CSeqFeatData::e_Imp) {
         new_feat->SetData().SetProt().SetProcessed(processed);
-        if (processed == CProt_ref::eProcessed_mature) {
-            new_feat->SetData().SetProt().SetName().push_back("unnamed");
-        }
-    }
-
-    CRef<CSeq_loc> new_loc;
-    CRef<CSeq_loc_Mapper> nuc2prot_mapper(
-        new CSeq_loc_Mapper(*cds, CSeq_loc_Mapper::eLocationToProduct, &fh.GetScope()));
-    new_loc = nuc2prot_mapper->Map(orig_feat->GetLocation());
-    if (!new_loc) {
-        return false;
-    }
-    const CSeq_id* sid = new_loc->GetId();
-    const CSeq_id* orig_id = orig_feat->GetLocation().GetId();
-    if (!sid || (orig_id && sid->Equals(*orig_id))) {
-        // unable to map to protein location
-        return false;
-    }
-    if (!cds_h.GetLocation().IsPartialStart(eExtreme_Biological)) {
-        if (new_loc->IsPartialStart(eExtreme_Biological)) {
-            new_loc->SetPartialStart(false, eExtreme_Biological);
-        }
-    }
-    if (!cds_h.GetLocation().IsPartialStop(eExtreme_Biological)) {
-        if (new_loc->IsPartialStop(eExtreme_Biological)) {
-            new_loc->SetPartialStop(false, eExtreme_Biological);
+        // if possible, rescue product qual
+        RescueProtProductQual(*new_feat);
+        if (processed == CProt_ref::eProcessed_mature &&
+            !new_feat->GetData().GetProt().IsSetName()) {
+            if (orig_feat->IsSetComment() && !NStr::IsBlank(orig_feat->GetComment())) {
+                new_feat->SetData().SetProt().SetName().push_back(orig_feat->GetComment());
+                new_feat->ResetComment();
+            } else {
+                new_feat->SetData().SetProt().SetName().push_back("unnamed");
+            }
         }
     }
 
-    new_loc->ResetStrand();
     // change location to protein
     new_feat->ResetLocation();
-    new_feat->SetLocation(*new_loc);
-
+    new_feat->SetLocation(*prot_loc);
+    SetFeaturePartial(*new_feat);
 
     CSeq_feat_EditHandle edh(fh);
     edh.Replace(*new_feat);
@@ -683,7 +712,7 @@ bool CCleanup::IsGeneXrefUnnecessary(const CSeq_feat& sf, CScope& scope, const C
 
     ITERATE(sequence::TFeatScores, g, scores) {
         if (g->second.GetPointer() != gene.GetPointer() && 
-            sequence::Compare(g->second->GetLocation(), gene->GetLocation(), &scope) == sequence::eSame) {
+            sequence::Compare(g->second->GetLocation(), gene->GetLocation(), &scope, sequence::fCompareOverlapping) == sequence::eSame) {
             return false;
         }
     }
@@ -761,6 +790,92 @@ bool CCleanup::RemoveNonsuppressingGeneXrefs(CSeq_feat& f)
     return any_removed;
 }
 
+
+bool CCleanup::RepairXrefs(const CSeq_feat& src, CSeq_feat_Handle& dst, const CTSE_Handle& tse)
+{
+    if (!src.IsSetId() || !src.GetId().IsLocal()) {
+        // can't create xref if no ID
+        return false;
+    }
+    if (!CSeqFeatData::AllowXref(src.GetData().GetSubtype(), dst.GetData().GetSubtype())) {
+        // only create reciprocal xrefs if permitted
+        return false;
+    }
+    // don't create xref if already have xref to feature of same type as src
+    bool has_xref = false;
+    if (dst.IsSetXref()) {
+        ITERATE(CSeq_feat::TXref, xit, dst.GetXref()) {
+            if ((*xit)->IsSetId() && (*xit)->GetId().IsLocal()) {
+                if ((*xit)->GetId().Equals(src.GetId())) {
+                    // already have xref
+                    has_xref = true;
+                    break;
+                } else {
+                    const CTSE_Handle::TFeatureId& feat_id = (*xit)->GetId().GetLocal();
+                    CTSE_Handle::TSeq_feat_Handles far_feats = tse.GetFeaturesWithId(CSeqFeatData::e_not_set, feat_id);
+                    ITERATE(CTSE_Handle::TSeq_feat_Handles, fit, far_feats) {
+                        if (fit->GetData().GetSubtype() == src.GetData().GetSubtype()) {
+                            has_xref = true;
+                            break;
+                        }
+                    }
+                    if (has_xref) {
+                        break;
+                    }
+                }
+            }
+        }
+    }
+    bool rval = false;
+    if (!has_xref) {
+        // to put into "editing mode"
+        dst.GetAnnot().GetEditHandle();
+        CSeq_feat_EditHandle eh(dst);
+        CRef<CSeq_feat> cpy(new CSeq_feat());
+        cpy->Assign(*(dst.GetSeq_feat()));
+        cpy->AddSeqFeatXref(src.GetId());
+        eh.Replace(*cpy);
+        rval = true;
+    }
+    return rval;
+}
+
+
+bool CCleanup::RepairXrefs(const CSeq_feat& f, const CTSE_Handle& tse)
+{
+    bool rval = false;
+
+    if (!f.IsSetId() || !f.IsSetXref()) {
+        return rval;
+    }
+
+    ITERATE(CSeq_feat::TXref, xit, f.GetXref()) {
+        if ((*xit)->IsSetId() && (*xit)->GetId().IsLocal()) {            
+            const CTSE_Handle::TFeatureId& x_id = (*xit)->GetId().GetLocal();
+            CTSE_Handle::TSeq_feat_Handles far_feats = tse.GetFeaturesWithId(CSeqFeatData::e_not_set, x_id);
+            if (far_feats.size() == 1) {
+                rval |= RepairXrefs(f, far_feats[0], tse);
+            }
+        }
+    }
+    return rval;
+}
+
+
+bool CCleanup::RepairXrefs(CSeq_entry_Handle seh)
+{
+    bool rval = false;
+    const CTSE_Handle& tse = seh.GetTSE_Handle();
+
+    CFeat_CI fi(seh);
+    while (fi) {
+        rval |= RepairXrefs(*(fi->GetSeq_feat()), tse);
+        ++fi;
+    }
+    return rval;
+}
+
+
 bool CCleanup::FindMatchingLocusGene(CSeq_feat& f, const CGene_ref& gene_xref, CBioseq_Handle bsh)
 {
     bool match = false;
@@ -856,7 +971,7 @@ bool CCleanup::RemoveOrphanLocus_tagGeneXrefs(CSeq_feat& f, CBioseq_Handle bsh)
 }
 
 
-bool SeqLocExtend(CSeq_loc& loc, size_t pos, CScope& scope)
+bool CCleanup::SeqLocExtend(CSeq_loc& loc, size_t pos, CScope& scope)
 {
     size_t loc_start = loc.GetStart(eExtreme_Positional);
     size_t loc_stop = loc.GetStop(eExtreme_Positional);
@@ -888,25 +1003,66 @@ bool SeqLocExtend(CSeq_loc& loc, size_t pos, CScope& scope)
 }
 
 
-bool CCleanup::ExtendToStopCodon(CSeq_feat& f, CBioseq_Handle bsh, size_t limit, CCdregion::TFrame frame)
+bool CCleanup::ExtendStopPosition(CSeq_feat& f, const CSeq_feat* cdregion, size_t extension)
+{
+    CRef<CSeq_loc> new_loc(&f.SetLocation());
+
+    CRef<CSeq_loc> last_interval;
+    if (new_loc->IsMix()) {
+        last_interval = new_loc->SetMix().SetLastLoc();
+    }
+    else
+    {
+        last_interval = new_loc;
+    }
+
+    CConstRef<CSeq_id> id(last_interval->GetId());
+
+    TSeqPos new_start;
+    TSeqPos new_stop;
+
+    // the last element of the mix or the single location MUST be converted into interval
+    // whethe it's whole or point, etc
+    if (last_interval->IsSetStrand() && last_interval->GetStrand() == eNa_strand_minus) {
+        new_start = (cdregion ? cdregion->GetLocation().GetStart(eExtreme_Positional) :          
+              last_interval->GetStart(eExtreme_Positional)) - extension;
+
+        new_stop = last_interval->GetStop(eExtreme_Positional);
+    }
+    else {
+        new_start = last_interval->GetStart(eExtreme_Positional);
+        new_stop = (cdregion ? cdregion->GetLocation().GetStop(eExtreme_Positional) :
+            last_interval->GetStop(eExtreme_Positional)) + extension;
+    }
+    last_interval->SetInt().SetFrom(new_start);
+    last_interval->SetInt().SetTo(new_stop);
+    last_interval->SetInt().SetId().Assign(*id);
+
+    new_loc->SetPartialStop(false, eExtreme_Biological);
+
+    return true;
+}
+
+bool CCleanup::ExtendToStopCodon(CSeq_feat& f, CBioseq_Handle bsh, size_t limit)
 {
     const CSeq_loc& loc = f.GetLocation();
-    CRef<CSeq_loc> new_loc;
 
+    CCdregion::TFrame frame = CCdregion::eFrame_not_set;
     const CGenetic_code* code = NULL;
-    if (f.IsSetData() && f.GetData().IsCdregion() && f.GetData().GetCdregion().IsSetCode()) {
-        code = &(f.GetData().GetCdregion().GetCode());
+    // we need to extract frame and cd_region from linked cd_region
+    if (f.IsSetData() && f.GetData().IsCdregion())
+    {
+        if (f.GetData().GetCdregion().IsSetCode())
+           code = &(f.GetData().GetCdregion().GetCode());
+        if (f.GetData().GetCdregion().IsSetFrame())
+           frame = f.GetData().GetCdregion().GetFrame();
     }
 
     size_t stop = loc.GetStop(eExtreme_Biological);
     // figure out if we have a partial codon at the end
     size_t orig_len = sequence::GetLength(loc, &(bsh.GetScope()));
     size_t len = orig_len;
-    if (frame == CCdregion::eFrame_not_set &&
-        f.IsSetData() && f.GetData().IsCdregion() &&
-        f.GetData().GetCdregion().IsSetFrame()) {
-        frame = f.GetData().GetCdregion().GetFrame();
-    }
+
     if (frame == CCdregion::eFrame_two) {
         len -= 1;
     } else if (frame == CCdregion::eFrame_three) {
@@ -915,7 +1071,7 @@ bool CCleanup::ExtendToStopCodon(CSeq_feat& f, CBioseq_Handle bsh, size_t limit,
     
     size_t mod = len % 3;
     CRef<CSeq_loc> vector_loc(new CSeq_loc());
-    vector_loc->SetInt().SetId().Assign(*(loc.GetId()));
+    vector_loc->SetInt().SetId().Assign(*(bsh.GetId().front().GetSeqId()));
 
     if (loc.IsSetStrand() && loc.GetStrand() == eNa_strand_minus) {
         vector_loc->SetInt().SetFrom(0);
@@ -954,44 +1110,8 @@ bool CCleanup::ExtendToStopCodon(CSeq_feat& f, CBioseq_Handle bsh, size_t limit,
         }
 
         if (tbl.GetCodonResidue(state) == '*') {
-            CSeq_loc_CI it(loc);
-            CSeq_loc_CI it_next = it;
-            ++it_next;
-            while (it_next) {
-                CConstRef<CSeq_loc> this_loc = it.GetRangeAsSeq_loc();
-                if (new_loc) {
-                    new_loc->Add(*this_loc);
-                } else {
-                    new_loc.Reset(new CSeq_loc());
-                    new_loc->Assign(*this_loc);
-                }
-                it = it_next;
-                ++it_next;
-            }
-            CRef<CSeq_loc> last_interval(new CSeq_loc());
-            CConstRef<CSeq_loc> this_loc = it.GetRangeAsSeq_loc();
-            size_t this_start = this_loc->GetStart(eExtreme_Positional);
-            size_t this_stop = this_loc->GetStop(eExtreme_Positional);
             size_t extension = ((i + 1) * 3) - mod;
-            last_interval->SetInt().SetId().Assign(*(this_loc->GetId()));
-            if (this_loc->IsSetStrand() && this_loc->GetStrand() == eNa_strand_minus) {
-                last_interval->SetStrand(eNa_strand_minus);
-                last_interval->SetInt().SetFrom(this_start - extension);
-                last_interval->SetInt().SetTo(this_stop);
-            } else {
-                last_interval->SetInt().SetFrom(this_start);
-                last_interval->SetInt().SetTo(this_stop + extension);
-            }
-
-            if (new_loc) {
-                new_loc->Add(*last_interval);
-            } else {
-                new_loc.Reset(new CSeq_loc());
-                new_loc->Assign(*last_interval);
-            }
-            new_loc->SetPartialStart(loc.IsPartialStart(eExtreme_Biological), eExtreme_Biological);
-            new_loc->SetPartialStop(false, eExtreme_Biological);
-            f.SetLocation().Assign(*new_loc);
+            ExtendStopPosition(f, 0, extension);
             return true;
         }
     }
@@ -1084,77 +1204,13 @@ bool CCleanup::SetFrameFromLoc(CCdregion &cdregion, const CSeq_loc& loc, CScope&
 }
 
 
-CConstRef <CSeq_feat> CCleanup::GetGeneForFeature(const CSeq_feat& feat, CScope& scope)
+bool IsTransSpliced(const CSeq_feat& feat)
 {
-    const CGene_ref* gene = feat.GetGeneXref();
-    if (gene && gene->IsSuppressed()) {
-        return (CConstRef <CSeq_feat>());
-    }
-
-    if (gene) {
-        CBioseq_Handle
-            bioseq_hl = sequence::GetBioseqFromSeqLoc(feat.GetLocation(), scope);
-        if (!bioseq_hl) {
-            return (CConstRef <CSeq_feat>());
-        }
-        CTSE_Handle tse_hl = bioseq_hl.GetTSE_Handle();
-        if (gene->CanGetLocus_tag() && !(gene->GetLocus_tag().empty())) {
-            CSeq_feat_Handle
-                seq_feat_hl = tse_hl.GetGeneWithLocus(gene->GetLocus_tag(), true);
-            if (seq_feat_hl) {
-                return (seq_feat_hl.GetOriginalSeq_feat());
-            }
-        } else if (gene->CanGetLocus() && !(gene->GetLocus().empty())) {
-            CSeq_feat_Handle
-                seq_feat_hl = tse_hl.GetGeneWithLocus(gene->GetLocus(), false);
-            if (seq_feat_hl) {
-                return (seq_feat_hl.GetOriginalSeq_feat());
-            }
-        } else return (CConstRef <CSeq_feat>());
-    } else {
-        return(
-            CConstRef <CSeq_feat>(sequence::GetBestOverlappingFeat(feat.GetLocation(),
-            CSeqFeatData::e_Gene,
-            sequence::eOverlap_Contained,
-            scope)));
-    }
-
-    return (CConstRef <CSeq_feat>());
-};
-
-
-bool CCleanup::IsPseudo(const CSeq_feat& feat, CScope& scope)
-{
-    if (feat.IsSetPseudo() && feat.GetPseudo()) {
+    if (feat.IsSetExcept_text() && NStr::Find(feat.GetExcept_text(), "trans-splicing") != string::npos) {
         return true;
-    }
-    if (feat.IsSetQual()) {
-        ITERATE(CSeq_feat::TQual, it, feat.GetQual()) {
-            if ((*it)->IsSetQual() && NStr::EqualNocase((*it)->GetQual(), "pseudogene")) {
-                return true;
-            }
-        }
-    }
-    if (feat.GetData().IsGene()) {
-        if (feat.GetData().GetGene().IsSetPseudo() && feat.GetData().GetGene().GetPseudo()) {
-            return true;
-        }
     } else {
-        if (feat.IsSetXref()) {
-            ITERATE(CSeq_feat::TXref, it, feat.GetXref()) {
-                if ((*it)->IsSetData() && (*it)->GetData().IsGene() &&
-                    (*it)->GetData().GetGene().IsSetPseudo() &&
-                    (*it)->GetData().GetGene().GetPseudo()) {
-                    return true;
-                }
-            }
-        }
-        CConstRef<CSeq_feat> gene = GetGeneForFeature(feat, scope);
-        if (gene && IsPseudo(*gene, scope)) {
-            return true;
-        }
+        return false;
     }
-    return false;
 }
 
 
@@ -1164,7 +1220,7 @@ bool CCleanup::ExtendToStopIfShortAndNotPartial(CSeq_feat& f, CBioseq_Handle bsh
         // not coding region
         return false;
     }
-    if (IsPseudo(f, bsh.GetScope())) {
+    if (sequence::IsPseudo(f, bsh.GetScope())) {
         return false;
     }
     if (f.GetLocation().IsPartialStop(eExtreme_Biological)) {
@@ -1319,6 +1375,116 @@ bool CCleanup::SetCDSPartialsByFrameAndTranslation(CSeq_feat& cds, CScope& scope
 }
 
 
+bool CCleanup::ClearInternalPartials(CSeq_loc& loc, bool is_first, bool is_last)
+{
+    bool rval = false;
+    switch (loc.Which()) {
+        case CSeq_loc::e_Mix:
+            rval |= ClearInternalPartials(loc.SetMix(), is_first, is_last);
+            break;
+        case CSeq_loc::e_Packed_int:
+            rval |= ClearInternalPartials(loc.SetPacked_int(), is_first, is_last);
+            break;
+        default:
+            break;
+    }
+    return rval;
+}
+
+
+bool CCleanup::ClearInternalPartials(CSeq_loc_mix& mix, bool is_first, bool is_last)
+{
+    bool rval = false;
+    NON_CONST_ITERATE(CSeq_loc::TMix::Tdata, it, mix.Set()) {
+        bool this_is_last = is_last && (*it == mix.Set().back());
+        if ((*it)->IsMix() || (*it)->IsPacked_int()) {
+            rval |= ClearInternalPartials(**it, is_first, this_is_last);
+        } else {
+            if (!is_first &&
+                (*it)->IsPartialStart(eExtreme_Biological)) {
+                (*it)->SetPartialStart(false, eExtreme_Biological);
+                rval = true;
+            }
+            if (!this_is_last &&
+                (*it)->IsPartialStop(eExtreme_Biological)) {
+                (*it)->SetPartialStop(false, eExtreme_Biological);
+                rval = true;
+            }
+        }
+        is_first = false;
+    }
+    return rval;
+}
+
+
+bool CCleanup::ClearInternalPartials(CPacked_seqint& pint, bool is_first, bool is_last)
+{
+    bool rval = false;
+
+    NON_CONST_ITERATE(CSeq_loc::TPacked_int::Tdata, it, pint.Set()) {
+        bool this_is_last = is_last && (*it == pint.Set().back());
+        if (!is_first && (*it)->IsPartialStart(eExtreme_Biological)) {
+            (*it)->SetPartialStart(false, eExtreme_Biological);
+            rval = true;
+        }
+        if (!this_is_last && (*it)->IsPartialStop(eExtreme_Biological)) {
+            (*it)->SetPartialStop(false, eExtreme_Biological);
+            rval = true;
+        }
+        is_first = false;
+    }
+    return rval;
+}
+
+
+bool CCleanup::ClearInternalPartials(CSeq_entry_Handle seh)
+{
+    bool rval = false;
+    CFeat_CI f(seh);
+    while (f) {
+        CRef<CSeq_feat> new_feat(new CSeq_feat());
+        new_feat->Assign(*(f->GetSeq_feat()));
+        if (ClearInternalPartials(new_feat->SetLocation())) {
+            CSeq_feat_EditHandle eh(f->GetSeq_feat_Handle());
+            eh.Replace(*new_feat);
+        }
+        ++f;
+    }
+
+    return rval;
+}
+
+
+bool CCleanup::SetFeaturePartial(CSeq_feat& f)
+{
+    if (!f.IsSetLocation()) {
+        return false;
+    }
+    bool partial = false;
+    CSeq_loc_CI li(f.GetLocation());
+    while (li && !partial) {
+        if (li.GetFuzzFrom() || li.GetFuzzTo()) {
+            partial = true;
+            break;
+        }
+        ++li;
+    }
+    bool changed = false;
+    if (f.IsSetPartial() && f.GetPartial()) {
+        if (!partial) {
+            f.ResetPartial();
+            changed = true;
+        }
+    } else {
+        if (partial) {
+            f.SetPartial(true);
+            changed = true;
+        }
+    }
+    return changed;
+}
+
+
 bool CCleanup::UpdateECNumbers(CProt_ref::TEc & ec_num_list)
 {
     bool changed = false;
@@ -1344,6 +1510,57 @@ bool CCleanup::UpdateECNumbers(CProt_ref::TEc & ec_num_list)
     return changed;
 }
 
+
+bool CCleanup::RemoveBadECNumbers(CProt_ref::TEc & ec_num_list)
+{
+    bool changed = false;
+    CProt_ref::TEc::iterator ec_num_iter = ec_num_list.begin();
+    while (ec_num_iter != ec_num_list.end()) {
+        string & ec_num = *ec_num_iter;
+        size_t tlen = ec_num.length();
+        CleanVisStringJunk(ec_num);
+        if (tlen != ec_num.length()) {
+            changed = true;
+        }
+        CProt_ref::EECNumberStatus ec_status = CProt_ref::GetECNumberStatus(ec_num);
+        if (ec_status == CProt_ref::eEC_deleted || ec_status == CProt_ref::eEC_unknown || CProt_ref::IsECNumberSplit(ec_num)) {
+            ec_num_iter = ec_num_list.erase(ec_num_iter);
+            changed = true;
+        } else {
+            ++ec_num_iter;
+        }
+
+    }
+    return changed;
+}
+
+
+bool CCleanup::FixECNumbers(CSeq_entry_Handle entry)
+{
+    bool any_change = false;
+    CFeat_CI f(entry, CSeqFeatData::e_Prot);
+    while (f) {
+        if (f->GetData().GetProt().IsSetEc()) {
+            bool this_change = false;
+            CRef<CSeq_feat> new_feat(new CSeq_feat());
+            new_feat->Assign(*(f->GetSeq_feat()));
+            this_change = UpdateECNumbers(new_feat->SetData().SetProt().SetEc());
+            this_change |= RemoveBadECNumbers(new_feat->SetData().SetProt().SetEc());
+            if (new_feat->GetData().GetProt().GetEc().empty()) {
+                new_feat->SetData().SetProt().ResetEc();
+                this_change = true;
+            }
+            if (this_change) {
+                CSeq_feat_EditHandle efh(*f);
+                efh.Replace(*new_feat);
+            }
+        }
+        ++f;
+    }
+    return any_change;
+}
+
+
 bool CCleanup::SetGenePartialByLongestContainedFeature(CSeq_feat& gene, CScope& scope)
 {
     CBioseq_Handle bh = scope.GetBioseqHandle(gene.GetLocation());
@@ -1488,25 +1705,13 @@ bool CCleanup::AddProteinTitle(CBioseq_Handle bsh)
     }
 
     string new_defline = sequence::CDeflineGenerator().GenerateDefline(bsh, sequence::CDeflineGenerator::fIgnoreExisting);
-    if (bsh.IsSetDescr()) {
-        ITERATE(CBioseq_set::TDescr::Tdata, title_d, bsh.GetDescr().Get()) {
-            if ((*title_d)->IsTitle()) {
-                if (!NStr::Equal((*title_d)->GetTitle(), new_defline)) {
-                    CSeqdesc* d = const_cast<CSeqdesc*>(title_d->GetPointer());
-                    d->SetTitle(new_defline);
-                    return true;
-                } else {
-                    return false;
-                }
-            }
-        }
-    }
 
-    CRef<CSeqdesc> t(new CSeqdesc());
-    t->SetTitle(new_defline);
-    CBioseq_EditHandle eh = bsh.GetEditHandle();
-    eh.AddSeqdesc(*t);
-    return true;
+    CAutoAddDesc title_desc(bsh.GetEditHandle().SetDescr(), CSeqdesc::e_Title);
+
+    bool modified = title_desc.Set().SetTitle() != new_defline; // get or create a title
+    if (modified)
+      title_desc.Set().SetTitle().swap(new_defline);
+    return modified;
 }
 
 
@@ -1704,7 +1909,7 @@ CRef<CSeq_entry> AddProtein(const CSeq_feat& cds, CScope& scope)
 }
 
 
-CRef<objects::CSeq_id> GetNewProteinId(objects::CSeq_entry_Handle seh, objects::CBioseq_Handle bsh)
+CRef<objects::CSeq_id> GetNewProteinId(size_t& offset, objects::CSeq_entry_Handle seh, objects::CBioseq_Handle bsh)
 {
     string id_base;
     objects::CSeq_id_Handle hid;
@@ -1717,17 +1922,15 @@ CRef<objects::CSeq_id> GetNewProteinId(objects::CSeq_entry_Handle seh, objects::
 
     hid.GetSeqId()->GetLabel(&id_base, objects::CSeq_id::eContent);
 
-    int offset = 1;
-    string id_label = id_base + "_" + NStr::NumericToString(offset);
     CRef<objects::CSeq_id> id(new objects::CSeq_id());
-    id->SetLocal().SetStr(id_label);
-    objects::CBioseq_Handle b_found = seh.GetBioseqHandle(*id);
-    while (b_found) {
-        offset++;
-        id_label = id_base + "_" + NStr::NumericToString(offset);
-        id->SetLocal().SetStr(id_label);
+    string& id_label = id->SetLocal().SetStr();
+    objects::CBioseq_Handle b_found;
+    do
+    {
+        id_label = id_base + "_" + NStr::NumericToString(offset++);
         b_found = seh.GetBioseqHandle(*id);
-    }
+    } while (b_found);
+
     return id;
 }
 
@@ -2057,7 +2260,7 @@ bool CCleanup::AddPartialToProteinTitle(CBioseq &bioseq)
 
 bool CCleanup::RemovePseudoProduct(CSeq_feat& cds, CScope& scope)
 {
-    if (!IsPseudo(cds, scope) ||
+    if (!sequence::IsPseudo(cds, scope) ||
         !cds.IsSetData() || !cds.GetData().IsCdregion() ||
         !cds.IsSetProduct()) {
         return false;
@@ -2093,12 +2296,13 @@ bool CCleanup::WGSCleanup(CSeq_entry_Handle entry)
 {
     bool any_changes = false;
 
+    size_t protein_id_counter = 1;
     SAnnotSelector sel(CSeqFeatData::e_Cdregion);
     for (CFeat_CI cds_it(entry, sel); cds_it; ++cds_it) {
         bool change_this_cds = false;
         CRef<CSeq_feat> new_cds(new CSeq_feat());
         new_cds->Assign(*(cds_it->GetSeq_feat()));
-        if (IsPseudo(*(cds_it->GetSeq_feat()), entry.GetScope())) {
+        if (sequence::IsPseudo(*(cds_it->GetSeq_feat()), entry.GetScope())) {
             change_this_cds = RemovePseudoProduct(*new_cds, entry.GetScope());
         } else {
             change_this_cds |= SetBestFrame(*new_cds, entry.GetScope());
@@ -2110,8 +2314,8 @@ bool CCleanup::WGSCleanup(CSeq_entry_Handle entry)
                 any_changes |= feature::RetranslateCDS(*new_cds, entry.GetScope());
             } else {
                 // need to set product if not set
-                if (!new_cds->IsSetProduct() && !IsPseudo(*new_cds, entry.GetScope())) {
-                    CRef<CSeq_id> new_id = GetNewProteinId(entry, entry.GetScope().GetBioseqHandle(new_cds->GetLocation()));
+                if (!new_cds->IsSetProduct() && !sequence::IsPseudo(*new_cds, entry.GetScope())) {
+                    CRef<CSeq_id> new_id = GetNewProteinId(protein_id_counter, entry, entry.GetScope().GetBioseqHandle(new_cds->GetLocation()));
                     if (new_id) {
                         new_cds->SetProduct().SetWhole().Assign(*new_id);
                         change_this_cds = true;
@@ -2237,6 +2441,8 @@ static const TSeqdescOrderElem sc_seqdesc_order_map[] = {
         { CSeqdesc::e_Prf, 19 },
         { CSeqdesc::e_Pdb, 20 },
         { CSeqdesc::e_Het, 4 },
+        
+        
         { CSeqdesc::e_Source, 2 },
         { CSeqdesc::e_Molinfo, 3 },
         { CSeqdesc::e_Modelev, 23 }
@@ -2245,11 +2451,11 @@ typedef CStaticPairArrayMap<CSeqdesc::E_Choice, int> TSeqdescOrderMap;
 DEFINE_STATIC_ARRAY_MAP(TSeqdescOrderMap, sc_SeqdescOrderMap, sc_seqdesc_order_map);
 
 static
-int s_SeqDescToOrdering(const CRef<CSeqdesc> &desc) {
+int s_SeqDescToOrdering(CSeqdesc::E_Choice chs) {
     // ordering assigned to unknown
     const int unknown_seqdesc = (1 + sc_SeqdescOrderMap.size());
 
-    TSeqdescOrderMap::const_iterator find_iter = sc_SeqdescOrderMap.find(desc->Which());
+    TSeqdescOrderMap::const_iterator find_iter = sc_SeqdescOrderMap.find(chs);
     if (find_iter == sc_SeqdescOrderMap.end()) {
         return unknown_seqdesc;
     }
@@ -2260,7 +2466,12 @@ int s_SeqDescToOrdering(const CRef<CSeqdesc> &desc) {
 static
 bool s_SeqDescLessThan(const CRef<CSeqdesc> &desc1, const CRef<CSeqdesc> &desc2)
 {
-    return (s_SeqDescToOrdering(desc1) < s_SeqDescToOrdering(desc2));
+    CSeqdesc::E_Choice chs1, chs2;
+
+    chs1 = desc1->Which();
+    chs2 = desc2->Which();
+
+    return (s_SeqDescToOrdering(chs1) < s_SeqDescToOrdering(chs2));
 }
 
 bool CCleanup::NormalizeDescriptorOrder(CSeq_descr& descr)
@@ -2277,7 +2488,7 @@ bool CCleanup::NormalizeDescriptorOrder(CSeq_entry_Handle seh)
 {
     bool rval = false;
 
-    CSeq_entry_CI ci(seh);
+    CSeq_entry_CI ci(seh, CSeq_entry_CI::fRecursive);
     while (ci) {
         CSeq_entry_EditHandle edit(*ci);
         if (edit.IsSetDescr()) {
@@ -2689,13 +2900,43 @@ bool IsSiteRef(const CSeq_feat& sf)
 }
 
 
+bool CCleanup::IsMinPub(const CPubdesc& pd, bool is_refseq_prot)
+{
+    if (!pd.IsSetPub()) {
+        return true;
+    }
+    bool found_non_minimal = false;
+    ITERATE(CPubdesc::TPub::Tdata, it, pd.GetPub().Get()) {
+        if ((*it)->IsMuid() || (*it)->IsPmid()) {
+            if (is_refseq_prot) {
+                found_non_minimal = true;
+                break;
+            }
+        } else if ((*it)->IsGen()) {
+            const CCit_gen& gen = (*it)->GetGen();
+            if (gen.IsSetCit() && !gen.IsSetJournal() &&
+                !gen.IsSetAuthors() && !gen.IsSetVolume() &&
+                !gen.IsSetPages()) {
+                //minimalish, keep looking
+            } else {
+                found_non_minimal = true;
+            }
+        } else {
+            found_non_minimal = true;
+            break;
+        }
+    }
+    
+    return !found_non_minimal;
+}
+
+
 bool CCleanup::RescueSiteRefPubs(CSeq_entry_Handle seh)
 {
     bool found_site_ref = false;
     CFeat_CI f(seh, CSeqFeatData::e_Imp);
     while (f && !found_site_ref) {
-        if (f->GetData().GetImp().IsSetKey() && 
-            NStr::Equal(f->GetData().GetImp().GetKey(), "Site-ref")) {
+        if (IsSiteRef(*(f->GetSeq_feat()))) {
             found_site_ref = true;
         }
         ++f;
@@ -2706,13 +2947,23 @@ bool CCleanup::RescueSiteRefPubs(CSeq_entry_Handle seh)
 
     bool any_change = false;
     for (CBioseq_CI b(seh); b; ++b) {
+        bool is_refseq_prot = false;
+        if (b->IsAa()) {
+            ITERATE(CBioseq::TId, id_it, b->GetCompleteBioseq()->GetId()) {
+                if ((*id_it)->IsOther()) {
+                    is_refseq_prot = true;
+                    break;
+                }
+            }
+        }
+
         for (CFeat_CI p(*b); p; ++p) {
             if (!p->IsSetCit() || p->GetCit().Which() != CPub_set::e_Pub) {
                 continue;
             }            
 
             bool is_site_ref = IsSiteRef(*(p->GetSeq_feat()));
-            ITERATE(CSeq_feat::TCit::TPub, c, p->GetCit().GetPub()) { 
+            ITERATE(CSeq_feat::TCit::TPub, c, p->GetCit().GetPub()) {
                 CRef<CSeqdesc> d(new CSeqdesc());
                 if ((*c)->IsEquiv()) {
                     ITERATE(CPub_equiv::Tdata, t, (*c)->GetEquiv().Get()) {
@@ -2734,7 +2985,9 @@ bool CCleanup::RescueSiteRefPubs(CSeq_entry_Handle seh)
                 CRef<CCleanupChange> changes(makeCleanupChange(0));
                 CNewCleanup_imp pubclean(changes, 0);
                 pubclean.BasicCleanup(d->SetPub(), ShouldStripPubSerial(*(b->GetCompleteBioseq())));
-                MoveOneFeatToPubdesc(*p, d, *b, false);
+                if (!IsMinPub(d->SetPub(), is_refseq_prot)) {
+                    MoveOneFeatToPubdesc(*p, d, *b, false);
+                }
             }
             if (is_site_ref) {
                 CSeq_feat_EditHandle feh(*p);
@@ -2987,6 +3240,18 @@ bool CCleanup::ConvertSrcFeatsToSrcDescs(CSeq_entry_Handle seh)
 {
     bool any_change = false;
     for (CBioseq_CI b(seh); b; ++b) {
+        bool transgenic_or_focus = false;
+        CSeqdesc_CI existing_src(*b, CSeqdesc::e_Source);
+        while (existing_src && !transgenic_or_focus) {
+            if (existing_src->GetSource().IsSetIs_focus() ||
+                existing_src->GetSource().HasSubtype(CSubSource::eSubtype_transgenic)) {
+                transgenic_or_focus = true;
+            }
+            ++existing_src;
+        }
+        if (transgenic_or_focus) {
+            continue;
+        }
         for (CFeat_CI p(*b, CSeqFeatData::e_Biosrc); p; ++p) {
             if (p->GetLocation().IsInt() &&
                 p->GetLocation().GetStart(eExtreme_Biological) == 0 &&
@@ -3207,5 +3472,333 @@ bool CCleanup::RenormalizeNucProtSets(CSeq_entry_Handle seh)
     return change_made;
 }
 
+
+bool CCleanup::DecodeXMLMarkChanged(std::string & str)
+{
+// return false;
+    bool change_made = false;
+
+    // This is more complex than you might initially think is necessary
+    // because this needs to be as efficient as possible since it's
+    // called on every single string in an object.
+
+    SIZE_TYPE amp = str.find('&');
+    if( NPOS == amp ) {
+        // Check for the common case of no replacements required
+        return change_made;
+    }
+
+    // transformations done by this function:
+    const static struct {
+        string src_word;
+        string result_word;
+    } transformations[] = {
+        // all start with an implicit ampersand
+        // and end with an implicit semi-colon
+        { "amp",      "&"      },
+        { "apos",     "\'"     },
+        { "gt",       ">"      },
+        { "lt",       "<"      },
+        { "quot",     "\""     },
+        { "#13&#10",  ""       },
+        { "#13;&#10", ""       },
+        { "#916",     "Delta"  },
+        { "#945",     "alpha"  },
+        { "#946",     "beta"   },
+        { "#947",     "gamma"  },
+        { "#952",     "theta"  },
+        { "#955",     "lambda" },
+        { "#956",     "mu"     },
+        { "#957",     "nu"     },
+        { "#8201",    ""       },
+        { "#8206",    ""       },
+        { "#8242",    "'"      },
+        { "#8594",    "->"     },
+        { "#8722",    "-"      },
+        { "#8710",    "delta"  },
+        { "#64257",   "fi"     },
+        { "#64258",   "fl"     },
+        { "#65292",   ","      }
+    };
+
+    // Collisions should be rare enough that the CFastMutex is
+    // faster than recreating the searcher each time this function is called
+    static CTextFsm<int> searcher;
+    // set searcher's state, if not already done
+    {
+        // just in case of the tiny chance that two threads try to prime
+        // the searcher at the same time.
+        static CFastMutex searcher_mtx;
+        CFastMutexGuard searcher_mtx_guard( searcher_mtx );
+        if( ! searcher.IsPrimed() ) {
+            for( size_t idx = 0;
+                idx < sizeof(transformations)/sizeof(transformations[0]); 
+                ++idx ) 
+            {
+                // match type is index into transformations array
+                searcher.AddWord( transformations[idx].src_word, idx );
+            }
+            searcher.Prime();
+        }
+    }
+
+    // a smart compiler probably won't need this manual optimization,
+    // but just in case.
+    const SIZE_TYPE str_len = str.length();
+
+    // fill result up to the first '&'
+    string result;
+    result.reserve( str_len ); 
+    copy( str.begin(), str.begin() + amp,
+        back_inserter(result) );
+
+    // at the start of each loop, the result is filled in
+    // up to the ampersand (amp)
+    while( amp != NPOS && amp < str_len ) {
+
+        // find out what the ampersand code represents
+        // (if it represents anything)
+        int state = searcher.GetInitialState();
+        SIZE_TYPE search_pos = (amp + 1);
+        if (str[search_pos] == ' ') {
+            break;
+        }
+        for( ; search_pos < str_len ; ++search_pos ) {
+            const char ch = str[search_pos];
+            if( ch == ';' ) {
+                break;
+            }
+            if( ch == '&' && state == 0 ) {
+                --search_pos; // so we don't skip over the '&'
+                state = searcher.GetInitialState(); // force "no-match"
+                break;
+            }
+            state = searcher.GetNextState(state, ch);
+        }
+
+        if( search_pos == str_len && searcher.IsMatchFound(state) ) {
+            // copy the translation of the XML code:
+            _ASSERT( searcher.GetMatches(state).size() == 1 );
+            const int match_idx = searcher.GetMatches(state)[0];
+            const string & result_word = transformations[match_idx].result_word;
+            copy( result_word.begin(), result_word.end(),
+                back_inserter(result) );
+            change_made = true;
+            break;
+        }
+
+        if( search_pos >= str_len ) {
+            // we reached the end without finding anything, so
+            // copy the rest and break
+            copy( str.begin() + amp, str.end(),
+                back_inserter(result) );
+            break;
+        }
+
+        if( searcher.IsMatchFound(state) ) {
+            // copy the translation of the XML code:
+            _ASSERT( searcher.GetMatches(state).size() == 1 );
+            const int match_idx = searcher.GetMatches(state)[0];
+            const string & result_word = transformations[match_idx].result_word;
+            copy( result_word.begin(), result_word.end(),
+                back_inserter(result) );
+            change_made = true;
+        } else {
+            // no match found, so copy the text we looked at
+            // as-is
+            copy( str.begin() + amp, str.begin() + search_pos + 1,
+                back_inserter(result) );
+        }
+
+        // find next_amp
+        if( str[search_pos] == '&' ) {
+            // special case that occurs when there are multiple '&' together
+            ++search_pos;
+            result += '&';
+        }
+        SIZE_TYPE next_amp = str.find('&', search_pos );
+        if( NPOS == next_amp ) {
+            // no more amps; copy the rest and break
+            copy( str.begin() + search_pos + 1, str.end(),
+                back_inserter(result) );
+            break;
+        }
+
+        // copy up to the next amp
+        if( (search_pos + 1) < next_amp ) {
+            copy( str.begin() + search_pos + 1, str.begin() + next_amp,
+                back_inserter(result) );
+        }
+        amp = next_amp;
+    }
+
+    if (change_made) {
+      str = result;
+    }
+
+    return change_made;
+}
+
+
+CRef<CSeq_loc> CCleanup::GetProteinLocationFromNucleotideLocation(const CSeq_loc& nuc_loc, const CSeq_feat& cds, CScope& scope, bool require_inframe)
+{
+    if (require_inframe) {
+        feature::ELocationInFrame is_in_frame = feature::IsLocationInFrame(scope.GetSeq_featHandle(cds), nuc_loc);
+        bool is_ok = false;
+        switch (is_in_frame) {
+            case feature::eLocationInFrame_InFrame:
+                is_ok = true;
+                break;
+            case feature::eLocationInFrame_BadStart:
+                if (cds.GetLocation().GetStart(eExtreme_Biological) == nuc_loc.GetStart(eExtreme_Biological)) {
+                    is_ok = true;
+                }
+                break;
+            case feature::eLocationInFrame_BadStop:
+                if (cds.GetLocation().GetStop(eExtreme_Biological) == nuc_loc.GetStop(eExtreme_Biological)) {
+                    is_ok = true;
+                }
+                break;
+            case feature::eLocationInFrame_BadStartAndStop:
+                if (cds.GetLocation().GetStart(eExtreme_Biological) == nuc_loc.GetStart(eExtreme_Biological) &&
+                    cds.GetLocation().GetStop(eExtreme_Biological) == nuc_loc.GetStop(eExtreme_Biological)) {
+                    is_ok = true;
+                }
+                break;
+            case feature::eLocationInFrame_NotIn:
+                break;
+        }
+        if (!is_ok) {
+            return CRef<CSeq_loc>(NULL);
+        }
+    }
+    CRef<CSeq_loc> new_loc;
+    CRef<CSeq_loc_Mapper> nuc2prot_mapper(
+        new CSeq_loc_Mapper(cds, CSeq_loc_Mapper::eLocationToProduct, &scope));
+    new_loc = nuc2prot_mapper->Map(nuc_loc);
+    if (!new_loc) {
+        return CRef<CSeq_loc>(NULL);
+    }
+
+    const CSeq_id* sid = new_loc->GetId();
+    const CSeq_id* orig_id = nuc_loc.GetId();
+    if (!sid || (orig_id && sid->Equals(*orig_id))) {
+        // unable to map to protein location
+        return CRef<CSeq_loc>(NULL);
+    }
+
+    new_loc->ResetStrand();
+
+    // if location includes stop codon, remove it
+    CBioseq_Handle prot = scope.GetBioseqHandle(*sid);
+    if (prot && new_loc->GetStop(objects::eExtreme_Positional) >= prot.GetBioseqLength())
+    {
+        CRef<CSeq_id> sub_id(new CSeq_id());
+        sub_id->Assign(*sid);
+        CSeq_loc sub(*sub_id, prot.GetBioseqLength(), new_loc->GetStop(objects::eExtreme_Positional), new_loc->GetStrand());
+        new_loc = sequence::Seq_loc_Subtract(*new_loc, sub, CSeq_loc::fMerge_All | CSeq_loc::fSort, &scope);
+        if (nuc_loc.IsPartialStop(eExtreme_Biological)) {
+            new_loc->SetPartialStop(true, eExtreme_Biological);
+        }
+    }
+
+    if (!new_loc->IsInt() && !new_loc->IsPnt()) {
+        CRef<CSeq_loc> tmp = sequence::Seq_loc_Merge(*new_loc, CSeq_loc::fMerge_All, &scope);
+        new_loc = tmp;
+    }
+
+    if (!cds.GetLocation().IsPartialStart(eExtreme_Biological)) {
+        if (new_loc->IsPartialStart(eExtreme_Biological)) {
+            new_loc->SetPartialStart(false, eExtreme_Biological);
+        }
+    }
+    if (!cds.GetLocation().IsPartialStop(eExtreme_Biological)) {
+        if (new_loc->IsPartialStop(eExtreme_Biological)) {
+            new_loc->SetPartialStop(false, eExtreme_Biological);
+        }
+    }
+
+
+
+    return new_loc;
+}
+
+
+CRef<CSeq_loc> CCleanup::GetProteinLocationFromNucleotideLocation(const CSeq_loc& nuc_loc, CScope& scope)
+{
+    CConstRef<CSeq_feat> cds = sequence::GetOverlappingCDS(nuc_loc, scope);
+    if (!cds || !cds->IsSetProduct()) {
+        // there is no overlapping coding region feature, so there is no appropriate
+        // protein sequence to move to
+        return CRef<CSeq_loc>(NULL);
+    }
+
+    return GetProteinLocationFromNucleotideLocation(nuc_loc, *cds, scope);
+}
+
+
+
+bool CCleanup::RepackageProteins(const CSeq_feat& cds, CBioseq_set_Handle np)
+{
+    if (!cds.IsSetProduct() || !cds.GetProduct().IsWhole()) {
+        // no product, or product is specified weirdly
+        return false;
+    }
+    CBioseq_Handle protein = np.GetTSE_Handle().GetBioseqHandle(cds.GetProduct().GetWhole());
+    if (!protein) {
+        // protein is not in the same TSE
+        return false;
+    }
+    if (protein.GetParentBioseq_set() == np) {
+        // already in the right set
+        return false;
+    }
+    CBioseq_set_EditHandle eh(np);
+    CSeq_entry_Handle ph = protein.GetSeq_entry_Handle();
+    CSeq_entry_EditHandle peh(ph);
+    eh.TakeEntry(peh);
+    return true;
+}
+
+
+bool CCleanup::RepackageProteins(CSeq_entry_Handle seh)
+{
+    bool changed = false;
+    CSeq_entry_CI si(seh, CSeq_entry_CI::fRecursive | CSeq_entry_CI::fIncludeGivenEntry, CSeq_entry::e_Set);
+    while (si) {
+        CBioseq_set_Handle set = si->GetSet();
+        if (set.IsSetClass() && set.GetClass() == CBioseq_set::eClass_nuc_prot && set.HasAnnots()) {
+            ITERATE(CBioseq_set::TAnnot, annot_it, set.GetCompleteBioseq_set()->GetAnnot()) {
+                if ((*annot_it)->IsSetData() && (*annot_it)->IsFtable()) {
+                    ITERATE(CSeq_annot::TData::TFtable, feat_it, (*annot_it)->GetData().GetFtable()) {
+                        if ((*feat_it)->IsSetData() && (*feat_it)->GetData().IsCdregion()) {
+                            changed |= RepackageProteins(**feat_it, set);
+                        }
+                    }
+                }
+            }
+        }
+        ++si;
+    }
+    return changed;
+}
+
+
+bool CCleanup::ConvertDeltaSeqToRaw(CSeq_entry_Handle seh, CSeq_inst::EMol filter)
+{
+    bool any_change = false;
+    for (CBioseq_CI bi(seh, filter); bi; ++bi) {
+        CBioseq_Handle bsh = *bi;
+        CRef<CSeq_inst> inst(new CSeq_inst());
+        inst->Assign(bsh.GetInst());
+        if (inst->ConvertDeltaToRaw()) {
+            CBioseq_EditHandle beh(bsh);
+            beh.SetInst(*inst);
+            any_change = true;
+        }
+    }
+    return any_change;
+}
+
 END_SCOPE(objects)
 END_NCBI_SCOPE
diff --git a/c++/src/objtools/cleanup/cleanup_utils.cpp b/c++/src/objtools/cleanup/cleanup_utils.cpp
index 68a1648..ea0f23c 100644
--- a/c++/src/objtools/cleanup/cleanup_utils.cpp
+++ b/c++/src/objtools/cleanup/cleanup_utils.cpp
@@ -1,4 +1,4 @@
-/* $Id: cleanup_utils.cpp 493625 2016-03-01 13:42:44Z ivanov $
+/* $Id: cleanup_utils.cpp 518092 2016-10-31 17:33:59Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -508,6 +508,7 @@ bool Asn2gnbkCompressSpaces(string& val)
         if (two_chars == twocommas) {
             *out++ = curr;
             next = ' ';
+            two_chars = next;
         }
         else if (two_chars == twospaces) {
         }
diff --git a/c++/src/objtools/cleanup/newcleanupp.cpp b/c++/src/objtools/cleanup/newcleanupp.cpp
index e8880fc..065bb29 100644
--- a/c++/src/objtools/cleanup/newcleanupp.cpp
+++ b/c++/src/objtools/cleanup/newcleanupp.cpp
@@ -59,10 +59,8 @@
 #include <objmgr/scope.hpp>
 
 #include <objects/medline/Medline_entry.hpp>
-#include <objtools/edit/struc_comm_field.hpp>
-#include <objtools/edit/gb_block_field.hpp>
-#include <objtools/edit/seq_entry_edit.hpp>
 #include <objects/valid/Comment_rule.hpp>
+#include <objects/valid/Comment_set.hpp>
 
 #include <util/ncbi_cache.hpp>
 #include <util/sequtil/sequtil_convert.hpp>
@@ -173,7 +171,8 @@ CNewCleanup_imp::CNewCleanup_imp (CRef<CCleanupChange> changes, Uint4 options)
       m_IsGpipe(false),
       m_SyncGenCodes(false),
       m_StripSerial(true),
-      m_IsEmblOrDdbj(false)
+      m_IsEmblOrDdbj(false),
+      m_KeepTopNestedSet(false)
 {
     if (options & CCleanup::eClean_GpipeMode) {
         m_IsGpipe = true;
@@ -183,6 +182,10 @@ CNewCleanup_imp::CNewCleanup_imp (CRef<CCleanupChange> changes, Uint4 options)
         m_SyncGenCodes = true;
     }
 
+    if (options & CCleanup::eClean_KeepTopSet) {
+        m_KeepTopNestedSet = true;
+    }
+
     m_Objmgr = CObjectManager::GetInstance ();
     m_Scope.Reset (new CScope (*m_Objmgr));
 
@@ -864,7 +867,7 @@ bool s_RegexpReplace( string &target,
     CRegexp::ECompile compile_flags = CRegexp::fCompile_default )
 {
     CRegexpUtil replacer( target );
-    int num_replacements = replacer.Replace( search_pattern, replacement, 
+    size_t num_replacements = replacer.Replace( search_pattern, replacement, 
         compile_flags, CRegexp::fMatch_default, max_replace );
     // swap is faster than assignment
     replacer.GetResult().swap( target ); 
@@ -1096,7 +1099,7 @@ void CNewCleanup_imp::GBblockBC (
         CGB_block::TKeywords::iterator it = gbk.SetKeywords().begin();
         while (it != gbk.SetKeywords().end()) {
             vector<string> tokens;
-            NStr::Tokenize(*it, ";", tokens);
+            NStr::Split(*it, ";", tokens);
             if (tokens.size() > 1) {
                 it = gbk.SetKeywords().erase(it);
                 gbk.SetKeywords().insert(it, tokens.begin(), tokens.end());
@@ -1753,6 +1756,16 @@ void CNewCleanup_imp::BiosourceBC (
         }
     }
 
+    if (biosrc.FixEnvironmentalSample()) {
+        ChangeMade(CCleanupChange::eChangeSubsource);
+    }
+    if (biosrc.RemoveNullTerms()) {
+        ChangeMade(CCleanupChange::eChangeBioSourceOther);
+    }
+    if (biosrc.FixGenomeForQualifiers()) {
+        ChangeMade(CCleanupChange::eChangeBioSourceGenome);
+    }
+
     x_PostBiosource(biosrc);
     if (biosrc.IsSetOrg()) {
         x_PostOrgRef(biosrc.SetOrg());
@@ -2166,6 +2179,10 @@ void CNewCleanup_imp::OrgmodBC (
             }
         }
     }
+
+    if (omd.RemoveAbbreviation()) {
+        ChangeMade(CCleanupChange::eCleanOrgmod);
+    }
 }
 
 bool s_IsAllDigits(const string& str)
@@ -2257,7 +2274,7 @@ void CNewCleanup_imp::DbtagBC (
 
     if (FIELD_IS (oid, Id)) {
         const string& db = dbtag.GetDb();
-        if (NStr::EqualNocase (db, "HGNC") || NStr::EqualNocase (db, "MGI") ) {
+        if (NStr::EqualNocase (db, "HGNC") || NStr::EqualNocase (db, "VGNC") || NStr::EqualNocase (db, "MGI") ) {
             int val = dbtag.GetTag().GetId();
             string str = db + ":" + NStr::IntToString(val);
             dbtag.SetTag().SetStr(str);
@@ -2304,6 +2321,16 @@ void CNewCleanup_imp::DbtagBC (
             ChangeMade(CCleanupChange::eChangeDbxrefs);
             */
         }
+    } else if (NStr::EqualNocase (db, "VGNC") ) {
+        if(! NStr::StartsWith (str, "VGNC:")) {
+            string newstr = "VGNC:" + str;
+            dbtag.SetTag().SetStr(newstr);
+            ChangeMade(CCleanupChange::eChangeDbxrefs);
+            /*
+            dbtag.SetTag().SetStr (dbtag.GetTag().GetStr().substr (5));
+            ChangeMade(CCleanupChange::eChangeDbxrefs);
+            */
+        }
     } else if (NStr::EqualNocase (db, "RGD") ) {
         if(NStr::StartsWith (str, "RGD:")) {
             dbtag.SetTag().SetStr (str.substr (4));
@@ -2316,7 +2343,7 @@ void CNewCleanup_imp::DbtagBC (
         try {
             // extract the part before the first space for conversion
             string::size_type pos_of_first_space = 0;
-            while( pos_of_first_space < str.length() && ! isspace(str[pos_of_first_space]) ) {
+            while (pos_of_first_space < str.length() && !isspace(str[pos_of_first_space])) {
                 ++pos_of_first_space;
             }
             CTempString sStrOfNum(str, 0, pos_of_first_space);
@@ -2324,9 +2351,9 @@ void CNewCleanup_imp::DbtagBC (
             // only convert str to int if it fits into the non-negative side
             // of an int.
             int value = NStr::StringToInt(sStrOfNum, NStr::fConvErr_NoThrow);
-            if( value > 0) {
-                SET_FIELD ( oid, Id, NStr::StringToUInt(sStrOfNum) );
-                ChangeMade (CCleanupChange::eChangeDbxrefs);
+            if (value > 0) {
+                dbtag.SetTag().SetId(NStr::StringToUInt(sStrOfNum));
+                ChangeMade(CCleanupChange::eChangeDbxrefs);
             }
         } catch (CStringException&) {
             // just leave things as are
@@ -2334,6 +2361,7 @@ void CNewCleanup_imp::DbtagBC (
     }
 }
 
+
 void CNewCleanup_imp::PubdescBC (
     CPubdesc& pubdesc
 )
@@ -2475,7 +2503,7 @@ void CNewCleanup_imp::PubEquivBC (CPub_equiv& pub_equiv)
     if (last_pmid == 0 && last_article_pubmed_id > 0) {
         CRef<CPub> new_pub( new CPub );
         new_pub->SetPmid().Set( last_article_pubmed_id );
-        pub_equiv.Set().push_back( new_pub );
+        pub_equiv.Set().insert(pub_equiv.Set().begin(), new_pub);
         ChangeMade(CCleanupChange::eChangePublication);
     } else if (last_pmid > 0 && last_article_pubmed_id == 0 && last_article ) {
         CRef<CArticleId> new_article_id(new CArticleId);
@@ -2484,6 +2512,7 @@ void CNewCleanup_imp::PubEquivBC (CPub_equiv& pub_equiv)
         ChangeMade(CCleanupChange::eChangePublication);
     }
 
+
 }
 
 CNewCleanup_imp::EAction CNewCleanup_imp::PubBC(CPub& pub, bool fix_initials)
@@ -3166,6 +3195,8 @@ void CNewCleanup_imp::ImpFeatBC( CSeq_feat& feat )
                 processed = NCBI_PROTREF(signal_peptide);
             } else if ( key == "transit_peptide" ) {
                 processed = NCBI_PROTREF(transit_peptide);
+            } else if ( key == "propeptide" ) {
+                processed = NCBI_PROTREF(propeptide);
             }
             if (processed != NCBI_PROTREF(not_set) || key == "Protein" ) {
                 const CSeq_id* location_seq_id = ( feat.IsSetLocation() ? feat.GetLocation().GetId() : NULL );
@@ -3174,6 +3205,10 @@ void CNewCleanup_imp::ImpFeatBC( CSeq_feat& feat )
                     if ( bioseq_handle && bioseq_handle.IsAa() ) {
                         CRef<CProt_ref> new_prot_ref( new CProt_ref );
                         new_prot_ref->SetProcessed( processed );
+                        if (feat.IsSetComment() && !NStr::IsBlank(feat.GetComment())) {
+                            new_prot_ref->SetName().push_back(feat.GetComment());
+                            feat.ResetComment();
+                        }
                         feat.SetData().SetProt( *new_prot_ref );
                         ChangeMade(CCleanupChange::eAddProtFeat);
                         x_CleanSeqFeatQuals(feat);
@@ -3616,6 +3651,8 @@ const char *s_FindKeyFromFeatDefType( const CSeq_feat &feat )
                     return "sig_peptide";
                 case NCBI_PROTREF(transit_peptide):
                     return "transit_peptide";
+                case NCBI_PROTREF(propeptide):
+                    return "propeptide";
                 default:
                     return kFeatBad;
                 }
@@ -4151,7 +4188,7 @@ void s_ExpandThisQual(
     //    
     vector< string > newValues;
     string valueList = val.substr(1, val.length() - 2);
-    NStr::Tokenize(valueList, ",", newValues);
+    NStr::Split(valueList, ",", newValues);
     
     qual.SetVal( newValues[0] );
    
@@ -4423,6 +4460,7 @@ static const TTrnaKey trna_key_to_subtype [] = {
     {  "His",            'H'  },
     {  "Histidine",      'H'  },
     {  "Ile",            'I'  },
+    {  "iMet",           'M'  },
     {  "Isoleucine",     'I'  },
     {  "Leu",            'L'  },
     {  "Leu or Ile",     'J'  },
@@ -4601,7 +4639,7 @@ void s_TokenizeTRnaString (const string &tRNA_string, list<string> &out_string_l
     vector<string> tRNA_tokens;
     // " \t\n\v\f\r" are the standard whitespace chars
     // ( source: http://www.cplusplus.com/reference/clibrary/cctype/isspace/ )
-    NStr::Tokenize( tRNA_string_copy, " \t\n\v\f\r", tRNA_tokens, NStr::eMergeDelims );
+    NStr::Split(tRNA_string_copy, " \t\n\v\f\r", tRNA_tokens, NStr::fSplit_MergeDelimiters | NStr::fSplit_Truncate);
 
     EDIT_EACH_STRING_IN_VECTOR( tRNA_token_iter, tRNA_tokens ) {
         string &tRNA_token = *tRNA_token_iter;
@@ -4708,6 +4746,7 @@ CNewCleanup_imp::x_HandleTrnaProductGBQual(CSeq_feat& feat, CRNA_ref& rna, const
         char aa = s_ParseSeqFeatTRnaString(name, &justTrnaText, codon, false);
         if (aa != '\0') {
             const bool is_fMet = (NStr::Find(name, "fMet") != NPOS);
+            const bool is_iMet = (NStr::Find(name, "iMet") != NPOS);
             CRNA_ref_Base::C_Ext::TTRNA &trp = rna.SetExt().SetTRNA();
             trp.SetAa().SetNcbieaa(aa);
             if (justTrnaText) {
@@ -4716,6 +4755,8 @@ CNewCleanup_imp::x_HandleTrnaProductGBQual(CSeq_feat& feat, CRNA_ref& rna, const
             if (aa == 'M') {
                 if (is_fMet) {
                     x_AddToComment(feat, "fMet");
+                } else if (is_iMet) {
+                    x_AddToComment(feat, "iMet");
                 }
             }
             x_SeqFeatTRNABC(feat, trp);
@@ -4743,6 +4784,9 @@ CNewCleanup_imp::x_HandleTrnaProductGBQual(CSeq_feat& feat, CRNA_ref& rna, const
                 if (NStr::Find(product, "fMet") != NPOS &&
                     (!feat.IsSetComment() || NStr::Find(feat.GetComment(), "fMet") == NPOS)) {
                     x_AddToComment(feat, "fMet");
+                } else if (NStr::Find(product, "iMet") != NPOS &&
+                    (!feat.IsSetComment() || NStr::Find(feat.GetComment(), "iMet") == NPOS)) {
+                    x_AddToComment(feat, "iMet");
                 }
             }
 
@@ -4760,11 +4804,15 @@ CNewCleanup_imp::x_HandleTrnaProductGBQual(CSeq_feat& feat, CRNA_ref& rna, const
             if (trp.GetAa().GetNcbieaa() == s_ParseSeqFeatTRnaString(product, NULL, ignored, false) &&
                 NStr::IsBlank(ignored)) {
             } else {
-                x_AddToComment(feat, product);
+                return eAction_Nothing;
+//                x_AddToComment(feat, product);
             }
             if (NStr::CompareNocase (product, "tRNA-fMet") == 0 || NStr::CompareNocase (product, "iRNA-fMet") == 0) {
                 return eAction_Nothing;
             }
+            if (NStr::CompareNocase (product, "tRNA-iMet") == 0 || NStr::CompareNocase (product, "iRNA-iMet") == 0) {
+                return eAction_Nothing;
+            }
             return eAction_Erase;
         }
     }
@@ -5106,11 +5154,7 @@ CNewCleanup_imp::x_ProtGBQualBC(CProt_ref& prot, const CGb_qual& gb_qual, EGBQua
 
     if (NStr::EqualNocase(qual, "product")  ||  NStr::EqualNocase(qual, "standard_name")) {
         if ( opt == eGBQualOpt_CDSMode || !prot.IsSetName()  ||  NStr::IsBlank(prot.GetName().front())) {
-            if( opt == eGBQualOpt_normal ) {
-                prot.SetName().push_back(val);
-            } else {
-                prot.SetName().push_front(val);
-            }
+            CCleanup::SetProteinName(prot, val, false);
             ChangeMade(CCleanupChange::eChangeQualifiers);
         } else {
             return eAction_Nothing;
@@ -5265,7 +5309,7 @@ void CNewCleanup_imp::x_CleanupOrgModNoteEC(COrg_ref& org)
             (*it)->GetSubtype() == COrgMod::eSubtype_other &&
             (*it)->IsSetSubname() &&
             (s_HasMatchingGBMod(org.GetOrgname(), (*it)->GetSubname()) ||
-             org.IsSetTaxname() && NStr::Equal(org.GetTaxname(), (*it)->GetSubname()))) {
+             (org.IsSetTaxname() && NStr::Equal(org.GetTaxname(), (*it)->GetSubname())))) {
             ChangeMade(CCleanupChange::eRemoveOrgmod);
             it = org.SetOrgname().SetMod().erase(it);
         } else {
@@ -5367,6 +5411,7 @@ void CNewCleanup_imp::x_PersonIdBC( CPerson_id& pid, bool fix_initials )
     }
 }
 
+
 void CNewCleanup_imp::x_NameStdBC ( CName_std& name, bool fix_initials )
 {
     // there's a lot of shuffling around (e.g. adding and removing
@@ -5415,7 +5460,7 @@ void CNewCleanup_imp::x_NameStdBC ( CName_std& name, bool fix_initials )
                     next_pos = first.find_first_not_of(" -", next_pos);
                     if( string::npos == next_pos ) break;
                     // if we hit an letter after that, copy the letter to inits
-                    if( isalpha( first[next_pos] ) ) {\
+                    if( isalpha( first[next_pos] ) ) {
                         first_initials += first[next_pos];
                     }
                     // find next space or hyphen
@@ -5428,10 +5473,30 @@ void CNewCleanup_imp::x_NameStdBC ( CName_std& name, bool fix_initials )
                 }
             }
         }
-
-        if( FIELD_IS_SET(name, First) ) {
-            NStr::ReplaceInPlace( GET_MUTABLE(name, First), sDot, kEmptyStr);
-            NStr::TruncateSpacesInPlace( GET_MUTABLE(name, First), NStr::eTrunc_Begin );
+        // continue extracting initials from middle name, but only if existing Initials field is empty
+        {
+            if (RAW_FIELD_IS_EMPTY_OR_UNSET(name, Initials)) {
+                if ( FIELD_IS_SET(name, Middle) ) {
+                    const string &middle = GET_FIELD(name, Middle);
+                    string::size_type next_pos = 0;
+                    while ( next_pos < middle.length() ) {
+                        // skip initial spaces and hyphens
+                        next_pos = middle.find_first_not_of(" -", next_pos);
+                        if( string::npos == next_pos ) break;
+                        // if we hit an letter after that, copy the  to inits
+                        if( isalpha( middle[next_pos] ) ) {
+                            first_initials += middle[next_pos];
+                        }
+                        // find next space or hyphen
+                        next_pos = middle.find_first_of(" -", next_pos);
+                        if( string::npos == next_pos ) break;
+                        // if it's a hyphen, copy it
+                        if( middle[next_pos] == '-' ) {
+                            first_initials += '-';
+                        }
+                    }
+                }
+            }
         }
 
         if (fix_initials) {
@@ -5519,28 +5584,7 @@ void CNewCleanup_imp::x_NameStdBC ( CName_std& name, bool fix_initials )
         }
 
         if( FIELD_IS_SET(name, Suffix) ) {
-            string &suffix = GET_MUTABLE(name, Suffix);
-            // remove spaces
-            NStr::ReplaceInPlace( suffix, " ", "" );
-
-            if ( ! suffix.empty() ) {
-                // remove any period, if any, on the end
-                if( NStr::EndsWith(suffix, ".") ) {
-                    suffix.resize( suffix.length() - 1 );
-                }
-
-                if( NStr::EqualNocase(suffix, "1d") ) {
-                     suffix = "1st";
-                } else if( NStr::EqualNocase(suffix, "2d") ) {
-                     suffix = "2nd";
-                } else if( NStr::EqualNocase(suffix, "3d") ) {
-                     suffix = "3rd";
-                } else if( NStr::EqualNocase(suffix, "Sr") ) {
-                     suffix = "Sr.";
-                } else if( NStr::EqualNocase(suffix, "Jr") ) {
-                     suffix = "Jr.";
-                }
-            }
+            name.FixSuffix(name.SetSuffix());
         }
 
         // add dot to "et al"
@@ -5585,14 +5629,8 @@ void CNewCleanup_imp::x_NameStdBC ( CName_std& name, bool fix_initials )
     if( ! FIELD_IS_SET(name, Last) ) {
         SET_FIELD(name, Last, kEmptyCStr );
     }
-    string &last = GET_MUTABLE(name, Last);
-    if( RAW_FIELD_IS_EMPTY_OR_UNSET(name, Suffix) &&
-        ( NStr::EndsWith(last, " Jr.") || NStr::EndsWith(last, " Sr.") ) ) 
-    {
-        SET_FIELD(name, Suffix, last.substr( last.length() - 3 ) );
-        last.resize( last.length() - 4 );
-        NStr::TruncateSpacesInPlace( last );
-    }
+
+    name.ExtractSuffixFromLastName();
 
     if( FIELD_IS_SET(name, Initials) && RAW_FIELD_IS_EMPTY_OR_UNSET(name, Suffix) ) {
         string & initials = GET_MUTABLE(name, Initials);
@@ -5774,7 +5812,7 @@ void CNewCleanup_imp::x_SplitDbtag( CDbtag &dbt, vector< CRef< CDbtag > > & out_
     // check if we're trying to split something we shouldn't
     if (dbt.IsSetDb()) {
         string db = dbt.GetDb();
-        if (NStr::Equal(db, "MGD") || NStr::Equal(db, "MGI") || NStr::Equal(db, "HGNC")) {
+        if (NStr::Equal(db, "MGD") || NStr::Equal(db, "MGI") || NStr::Equal(db, "HGNC") || NStr::Equal(db, "VGNC")) {
             return;
         }
     }
@@ -5785,7 +5823,7 @@ void CNewCleanup_imp::x_SplitDbtag( CDbtag &dbt, vector< CRef< CDbtag > > & out_
 
     // split by colon and generate new tags
     vector<string> tags;
-    NStr::Tokenize( dbt.GetTag().GetStr(), ":", tags );
+    NStr::Split(dbt.GetTag().GetStr(), ":", tags);
     _ASSERT( tags.size() >= 2 );
 
     // treat the CDbtag argument as the first of the new CDbtags
@@ -5818,7 +5856,7 @@ char s_ConvertTrnaAaToLetter( const CTrna_ext::C_Aa &trna_aa, CSeqUtil::ECoding
 {
     char temp_aa = '\0';
 
-    int num_converted = 0;
+    size_t num_converted = 0;
     char new_aa = '\0';
     switch( trna_aa.Which() ) {
     case CTrna_ext::C_Aa::e_Iupacaa:
@@ -5888,7 +5926,7 @@ void s_ParsePCRComponent(vector<string> &out_list, const string *component)
         component_copy = component_copy.substr( 1, component_copy.length() - 2 );
     }
 
-    NStr::Tokenize( component_copy, string(","), out_list );
+    NStr::Split(component_copy, string(","), out_list);
     EDIT_EACH_STRING_IN_VECTOR( str_iter, out_list ) {
         NStr::TruncateSpacesInPlace( *str_iter );
     }
@@ -6002,7 +6040,7 @@ void s_ParsePCRSet( const CBioSource &biosrc, list<CPCRParsedSet> &out_pcr_set )
 static
 void s_ParsePCRColonString( vector<string> &out_list, const string &str ) 
 {
-    NStr::Tokenize( str, ":", out_list );
+    NStr::Split(str, ":", out_list);
     EDIT_EACH_STRING_IN_VECTOR(str_iter, out_list ) {
         NStr::TruncateSpacesInPlace( *str_iter );
         if( str_iter->empty() ) {
@@ -6888,7 +6926,7 @@ void CNewCleanup_imp::x_CleanStructuredComment( CUser_object &user_object )
                         if (!ambiguous && coll_date->GetStd().IsSetMonth()) {
                             coll_date->GetDate(&month, "%N");
                             month = month.substr(0, 3);
-                            NStr::ToUpper(month);
+                            month = NStr::ToUpper(month);
                         }
                         coll_date->GetDate(&year, "%Y");
                         if (!NStr::IsBlank(day)) {
@@ -6960,7 +6998,7 @@ void CNewCleanup_imp::x_RemoveFlankingQuotes( string &val )
     // holds the first and last pos that we will keep
     // (have to use "ints" since might be negative)
     int first_pos = 0;
-    int last_pos = ( val.length() - 1 );
+    size_t last_pos = ( val.length() - 1 );
 
     // move inwards until there are no more quotes to trim
     for( ; first_pos <= last_pos ; ++first_pos, --last_pos ) {
@@ -7096,7 +7134,7 @@ void CNewCleanup_imp::Except_textBC (
     }
 
     vector<string> exceptions;
-    NStr::Tokenize (except_text, ",", exceptions);
+    NStr::Split(except_text, ",", exceptions);
 
     EDIT_EACH_STRING_IN_VECTOR (it, exceptions) {
         string& text = *it;
@@ -7142,6 +7180,64 @@ bool s_SeqLocAnyNull( const CSeq_loc & loc )
     return false;
 }
 
+
+bool SortGBQuals(CSeq_feat& sf)
+{
+    if (!sf.IsSetQual()) {
+        return false;
+    }
+    if (sf.IsSetQual() && sf.GetQual().size() == 0) {
+        sf.ResetQual();
+        return true;
+    }
+
+    CRef<CSeq_feat> orig(new CSeq_feat());
+    orig->Assign(sf);
+
+    // first, extract product qualifier values, because order must be
+    // preserved
+    vector<string> products;
+    CSeq_feat::TQual::iterator it = sf.SetQual().begin();
+    while (it != sf.SetQual().end()) {
+        if ((*it)->IsSetQual() && NStr::EqualNocase((*it)->GetQual(), "product")) {
+            if ((*it)->IsSetVal() && !NStr::IsBlank((*it)->GetVal())) {
+                products.push_back((*it)->GetVal());
+            }
+            it = sf.SetQual().erase(it);
+        } else {
+            ++it;
+        }
+    }
+
+    if (sf.GetQual().size() > 1) {
+        SORT_GBQUAL_ON_SEQFEAT(sf, s_GbQualCompareLegalFirst);
+    }
+
+    // insert product qualifiers back in list
+    it = sf.SetQual().begin();
+    while (it != sf.SetQual().end()) {
+        if (!(*it)->IsSetQual() ||            
+            s_CompareNoCaseCStyle("product", (*it)->GetQual()) < 0 ||
+            s_IsIllegalQual((*it)->GetQual())) {
+            break;
+        }
+        ++it;
+    }
+    if (it == sf.SetQual().end()) {
+        ITERATE(vector<string>, s, products) {
+            CRef<CGb_qual> pq(new CGb_qual("product", *s));
+            sf.SetQual().push_back(pq);
+        }
+    } else {
+        ITERATE(vector<string>, s, products) {
+            CRef<CGb_qual> pq(new CGb_qual("product", *s));
+            it = sf.SetQual().insert(it, pq);
+        }
+    }
+    return !(orig->Equals(sf));          
+}
+
+
 void CNewCleanup_imp::x_CleanSeqFeatQuals(CSeq_feat& sf)
 {
     // clean before uniquing
@@ -7151,8 +7247,7 @@ void CNewCleanup_imp::x_CleanSeqFeatQuals(CSeq_feat& sf)
     }
 
     // sort/unique gbquals, just alphabetically
-    if (!GBQUAL_ON_SEQFEAT_IS_SORTED(sf, s_GbQualCompare)) {
-        SORT_GBQUAL_ON_SEQFEAT(sf, s_GbQualCompare);
+    if (SortGBQuals(sf)) {
         ChangeMade(CCleanupChange::eCleanQualifiers);
     }
 
@@ -7171,12 +7266,6 @@ void CNewCleanup_imp::x_CleanSeqFeatQuals(CSeq_feat& sf)
         }
     }
 
-    // sort again, putting legal qualifiers first
-    if (!GBQUAL_ON_SEQFEAT_IS_SORTED(sf, s_GbQualCompareLegalFirst)) {
-        SORT_GBQUAL_ON_SEQFEAT(sf, s_GbQualCompareLegalFirst);
-        ChangeMade(CCleanupChange::eCleanQualifiers);
-    }
-
     REMOVE_IF_EMPTY_GBQUAL_ON_SEQFEAT(sf);
 }
 
@@ -7343,12 +7432,12 @@ bool s_SplitGeneSyn( const string &syn, vector<string> &gene_syns_to_add)
 
     // split by comma
     vector<string> pieces_split_by_comma;
-    NStr::Tokenize( syn, ",", pieces_split_by_comma );
+    NStr::Split(syn, ",", pieces_split_by_comma);
 
     // now split each of those pieces by "; "
     vector<string> pieces_split_by_semicolon;
     FOR_EACH_STRING_IN_VECTOR( piece_iter, pieces_split_by_comma ) {
-        NStr::TokenizePattern( *piece_iter, "; ", pieces_split_by_semicolon );
+        NStr::SplitByPattern(*piece_iter, "; ", pieces_split_by_semicolon);
     }
 
     if( pieces_split_by_semicolon.size() > 1 ) {
@@ -8409,9 +8498,12 @@ void CNewCleanup_imp::x_MoveCDSFromNucAnnotToSetAnnot( CBioseq_set &set )
         SAnnotSelector sel(CSeqFeatData::e_Cdregion);
         CFeat_CI fi(seh, sel);
         while (fi) {
-            CSeq_feat_Handle fh = fi->GetSeq_feat_Handle();
-            if (feature::PromoteCDSToNucProtSet(fh)) {
-                ChangeMade (CCleanupChange::eMoveFeat);
+            if ((fi->IsSetProduct() || sequence::GetLength(fi->GetLocation(), m_Scope) >= 6) && 
+                (!fi->IsSetPseudo() || !fi->GetPseudo())) {
+                CSeq_feat_Handle fh = fi->GetSeq_feat_Handle();
+                if (feature::PromoteCDSToNucProtSet(fh)) {
+                    ChangeMade(CCleanupChange::eMoveFeat);
+                }
             }
             ++fi;
         }
@@ -8852,7 +8944,7 @@ void CNewCleanup_imp::RnaFeatBC (
         STRING_FIELD_NOT_EMPTY(seq_feat, Comment) &&
         FIELD_EQUALS( rna, Type, NCBI_RNAREF(rRNA) ) ) 
     {
-        const int comment_len = GET_FIELD(seq_feat, Comment).length();
+        const size_t comment_len = GET_FIELD(seq_feat, Comment).length();
         if (comment_len > 15 && comment_len < 20) {
             if ( NStr::EndsWith(GET_FIELD(seq_feat, Comment), "S ribosomal RNA", NStr::eNocase) ) {
                 rna.SetExt().SetName( GET_FIELD(seq_feat, Comment) );
@@ -8941,7 +9033,7 @@ void CNewCleanup_imp::RnaFeatBC (
             CAminoAcidCharToSymbol::const_iterator aa_end  = sm_TrnaInverseKeys.upper_bound(aa);
             for( ; aa_iter != aa_end ; ++aa_iter ) {
                 const string &a_name = aa_iter->second;
-                if( comment == a_name && ( aa != 'M' || ! NStr::EqualNocase(a_name, "fMet") ) ) {
+                if( comment == a_name && ( aa != 'M' || ! NStr::EqualNocase(a_name, "fMet") || ! NStr::EqualNocase(a_name, "iMet") ) ) {
                     RESET_FIELD(seq_feat, Comment);
                     ChangeMade(CCleanupChange::eChangeComment);
                     break;
@@ -9773,151 +9865,7 @@ void CNewCleanup_imp::x_RememberSeqFeatCitPubs( CPub &pub )
 
 void CNewCleanup_imp::x_DecodeXMLMarkChanged( std::string & str )
 {
-    // This is more complex than you might initially think is necessary
-    // because this needs to be as efficient as possible since it's
-    // called on every single string in an object.
-
-    SIZE_TYPE amp = str.find('&');
-    if( NPOS == amp ) {
-        // Check for the common case of no replacements required
-        return;
-    }
-
-    // transformations done by this function:
-    const static struct {
-        string src_word;
-        string result_word;
-    } transformations[] = {
-        // all start with an implicit ampersand
-        // and end with an implicit semi-colon
-        { "amp",      "&"      },
-        { "apos",     "\'"     },
-        { "gt",       ">"      },
-        { "lt",       "<"      },
-        { "quot",     "\""     },
-        { "#13;&#10", ""       },
-        { "#916",     "Delta"  },
-        { "#945",     "alpha"  },
-        { "#946",     "beta"   },
-        { "#947",     "gamma"  },
-        { "#952",     "theta"  },
-        { "#955",     "lambda" },
-        { "#956",     "mu"     },
-        { "#957",     "nu"     },
-        { "#8201",    ""       },
-        { "#8206",    ""       },
-        { "#8242",    "'"      },
-        { "#8594",    "->"     },
-        { "#8722",    "-"      },
-        { "#8710",    "delta"  },
-        { "#64257",   "fi"     },
-        { "#64258",   "fl"     },
-        { "#65292",   ","      }
-    };
-
-    // Collisions should be rare enough that the CFastMutex is
-    // faster than recreating the searcher each time this function is called
-    static CTextFsm<int> searcher;
-    // set searcher's state, if not already done
-    {
-        // just in case of the tiny chance that two threads try to prime
-        // the searcher at the same time.
-        static CFastMutex searcher_mtx;
-        CFastMutexGuard searcher_mtx_guard( searcher_mtx );
-        if( ! searcher.IsPrimed() ) {
-            for( size_t idx = 0;
-                idx < sizeof(transformations)/sizeof(transformations[0]); 
-                ++idx ) 
-            {
-                // match type is index into transformations array
-                searcher.AddWord( transformations[idx].src_word, idx );
-            }
-            searcher.Prime();
-        }
-    }
-
-    // a smart compiler probably won't need this manual optimization,
-    // but just in case.
-    const SIZE_TYPE str_len = str.length();
-
-    // fill result up to the first '&'
-    string result;
-    result.reserve( str_len ); 
-    copy( str.begin(), str.begin() + amp,
-        back_inserter(result) );
-
-    bool change_made = false;
-
-    // at the start of each loop, the result is filled in
-    // up to the ampersand (amp)
-    while( amp != NPOS && amp < str_len ) {
-
-        // find out what the ampersand code represents
-        // (if it represents anything)
-        int state = searcher.GetInitialState();
-        SIZE_TYPE search_pos = (amp + 1);
-        for( ; search_pos < str_len ; ++search_pos ) {
-            const char ch = str[search_pos];
-            if( ch == ';' ) {
-                break;
-            }
-            if( ch == '&' ) {
-                --search_pos; // so we don't skip over the '&'
-                state = searcher.GetInitialState(); // force "no-match"
-                break;
-            }
-            state = searcher.GetNextState(state, ch);
-        }
-
-        if( search_pos >= str_len ) {
-            // we reached the end without finding anything, so
-            // copy the rest and break
-            copy( str.begin() + amp, str.end(),
-                back_inserter(result) );
-            break;
-        }
-
-        if( searcher.IsMatchFound(state) ) {
-            // copy the translation of the XML code:
-            _ASSERT( searcher.GetMatches(state).size() == 1 );
-            const int match_idx = searcher.GetMatches(state)[0];
-            const string & result_word = transformations[match_idx].result_word;
-            copy( result_word.begin(), result_word.end(),
-                back_inserter(result) );
-            change_made = true;
-        } else {
-            // no match found, so copy the text we looked at
-            // as-is
-            copy( str.begin() + amp, str.begin() + search_pos + 1,
-                back_inserter(result) );
-        }
-
-        // find next_amp
-        if( str[search_pos] == '&' ) {
-            // special case that occurs when there are multiple '&' together
-            ++search_pos;
-            result += '&';
-        }
-        SIZE_TYPE next_amp = str.find('&', search_pos );
-        if( NPOS == next_amp ) {
-            // no more amps; copy the rest and break
-            copy( str.begin() + search_pos + 1, str.end(),
-                back_inserter(result) );
-            break;
-        }
-
-        // copy up to the next amp
-        if( (search_pos + 1) < next_amp ) {
-            copy( str.begin() + search_pos + 1, str.begin() + next_amp,
-                back_inserter(result) );
-        }
-        amp = next_amp;
-    }
-
-    // mark changes, if any
-    if( change_made ) {
-        // swap should be faster than assignment ( amortized O(1) )
-        str.swap( result );
+    if (CCleanup::DecodeXMLMarkChanged(str)) {
         ChangeMade(CCleanupChange::eDecodeXML);
     }
 }
@@ -10550,6 +10498,36 @@ string s_GetDiv(const CBioSource& src)
 }
 
 
+void RemoveStrain(string& src, const CBioSource& biosrc)
+{
+    if (!biosrc.IsSetOrg() || !biosrc.GetOrg().IsSetOrgname() ||
+        !biosrc.GetOrg().GetOrgname().IsSetMod()) {
+        return;
+    }
+    size_t pos = NStr::Find(src, "(strain ");
+    if (pos == string::npos) {
+        return;
+    }
+
+    ITERATE(COrgName::TMod, it, biosrc.GetOrg().GetOrgname().GetMod()) {
+        if ((*it)->IsSetSubtype() &&
+            (*it)->GetSubtype() == COrgMod::eSubtype_strain &&
+            (*it)->IsSetSubname()) {
+            const string& strain = (*it)->GetSubname();
+            size_t expected_len = 9 + strain.length();
+            if (src.length() >= pos + expected_len) {
+                string compare = src.substr(pos, expected_len);
+                string expected = "(strain " + strain + ")";
+                if (NStr::Equal(compare, expected)) {
+                    src = src.substr(0, pos - 1) + src.substr(pos + expected_len);
+                    NStr::ReplaceInPlace(src, "  ", " ");
+                }
+            }
+        }
+    }
+}
+
+
 bool CNewCleanup_imp::x_CanRemoveGenbankBlockSource(const string& src, const CBioSource& biosrc)
 {
     string compare = src;
@@ -10562,6 +10540,7 @@ bool CNewCleanup_imp::x_CanRemoveGenbankBlockSource(const string& src, const CBi
         compare = compare.substr(0, compare.length() - 1);
         NStr::TruncateSpacesInPlace(compare);
     }
+    RemoveStrain(compare, biosrc);
 
     if (biosrc.IsSetOrg()) {
         if (biosrc.GetOrg().IsSetTaxname() &&
@@ -11130,7 +11109,6 @@ bool HasAuthor(const CPubdesc& pub, bool strict)
         return false;
     }
     
-    bool is_patent = false;
     bool any_authors = false;
     ITERATE(CPubdesc::TPub::Tdata, it, pub.GetPub().Get()) {
         if ((*it)->IsPatent()) {
@@ -11410,8 +11388,8 @@ bool s_RetainEmptyAnnot(const CSeq_annot& annot)
 bool CNewCleanup_imp::ShouldRemoveAnnot(const CSeq_annot& annot)
 {
     if (!s_RetainEmptyAnnot(annot) &&
-        (annot.IsFtable() && annot.GetData().GetFtable().empty()) ||
-        !annot.IsSetData()) {
+        ((annot.IsFtable() && annot.GetData().GetFtable().empty()) ||
+         !annot.IsSetData())) {
         return true;
     } else {
         return false;
@@ -12066,6 +12044,7 @@ void CNewCleanup_imp::x_RemoveNestedGenBankSet(CBioseq_set & bioseq_set)
         bioseq_set.GetSeq_set().front()->IsSet() &&
         bioseq_set.GetSeq_set().front()->GetSet().IsSetClass() &&
         bioseq_set.GetSeq_set().front()->GetSet().GetClass() == CBioseq_set::eClass_genbank) {
+        if (bioseq_set.GetParentSet() != NULL || !m_KeepTopNestedSet) 
         x_CollapseSet(bioseq_set);
     }
     
@@ -12499,55 +12478,64 @@ void CNewCleanup_imp::CdRegionEC(CSeq_feat& sf)
     if (cdr.IsSetConflict() && 
         cdr.GetConflict() &&
         sf.IsSetProduct()) {
-        CBioseq_Handle nuc = m_Scope->GetBioseqHandle(sf.GetLocation());
-        if (nuc) {
-            CSeqdesc_CI src(nuc, CSeqdesc::e_Source);
-            if (src && src->GetSource().IsSetGcode()) {
-                CBioseq_Handle prot = m_Scope->GetBioseqHandle(sf.GetProduct());
-                string expected;
-                CSeqTranslator::Translate(sf, *m_Scope, expected, false);
-                CSeqVector vec(prot, CBioseq_Handle::eCoding_Iupac);
-                CSeqVector_CI vi = vec.begin();
-                string::iterator si = expected.begin();
-                while (vi != vec.end() && si != expected.end() && *vi == *si) {
-                    ++vi;
-                    ++si;
-                }
-                if (vi != vec.end() || si != expected.end()) {
-                    if (CCleanup::SetMolinfoTech(prot, CMolInfo::eTech_concept_trans_a)) {
-                        ChangeMade(CCleanupChange::eChangeMolInfo);
+        try {
+            CBioseq_Handle nuc = m_Scope->GetBioseqHandle(sf.GetLocation());
+            if (nuc) {
+                CSeqdesc_CI src(nuc, CSeqdesc::e_Source);
+                if (src && src->GetSource().IsSetGcode()) {
+                    CBioseq_Handle prot = m_Scope->GetBioseqHandle(sf.GetProduct());
+                    string expected;
+                    CSeqTranslator::Translate(sf, *m_Scope, expected, false);
+                    CSeqVector vec(prot, CBioseq_Handle::eCoding_Iupac);
+                    CSeqVector_CI vi = vec.begin();
+                    string::iterator si = expected.begin();
+                    while (vi != vec.end() && si != expected.end() && *vi == *si) {
+                        ++vi;
+                        ++si;
+                    }
+                    if (vi != vec.end() || si != expected.end()) {
+                        if (CCleanup::SetMolinfoTech(prot, CMolInfo::eTech_concept_trans_a)) {
+                            ChangeMade(CCleanupChange::eChangeMolInfo);
+                        }
+                    } else {
+                        cdr.ResetConflict();
+                        ChangeMade(CCleanupChange::eChangeOther);
                     }
-                } else {
-                    cdr.ResetConflict();
-                    ChangeMade(CCleanupChange::eChangeOther);
                 }
             }
+        } catch (CException& ex) {
+            // unable to get bioseq handle when loc is on multiple sequences
         }
     }
 
     CConstRef<CSeq_feat> mrna = sequence::GetmRNAforCDS(sf, *m_Scope);
-    CConstRef<CSeq_feat> gene = CCleanup::GetGeneForFeature(sf, *m_Scope);
+    CConstRef<CSeq_feat> gene = sequence::GetGeneForFeature(sf, *m_Scope);
 
-    CBioseq_Handle bsh = m_Scope->GetBioseqHandle(sf.GetLocation());
-    if (bsh && CCleanup::ExtendToStopIfShortAndNotPartial(sf, bsh)) {
-        CCdregion::TFrame frame = cdr.IsSetFrame() ? cdr.GetFrame() : CCdregion::eFrame_not_set;
-        if (gene && s_LocationShouldBeExtendedToMatch(gene->GetLocation(), sf.GetLocation())) {
-            CRef<CSeq_feat> new_gene(new CSeq_feat());
-            new_gene->Assign(*gene);
-            if (CCleanup::ExtendToStopCodon(*new_gene, bsh, 3, frame)) {
-                CSeq_feat_EditHandle efh = CSeq_feat_EditHandle(m_Scope->GetSeq_featHandle(*gene));
-                efh.Replace(*new_gene);
-            }
-        }
-        if (mrna && s_LocationShouldBeExtendedToMatch(mrna->GetLocation(), sf.GetLocation())) {
-            CRef<CSeq_feat> new_mrna(new CSeq_feat());
-            new_mrna->Assign(*mrna);
-            if (CCleanup::ExtendToStopCodon(*new_mrna, bsh, 3, frame)) {
-                CSeq_feat_EditHandle efh = CSeq_feat_EditHandle(m_Scope->GetSeq_featHandle(*mrna));
-                efh.Replace(*new_mrna);
+    if (!m_IsEmblOrDdbj) {
+        try {
+            CBioseq_Handle bsh = m_Scope->GetBioseqHandle(sf.GetLocation());
+            if (bsh && CCleanup::ExtendToStopIfShortAndNotPartial(sf, bsh)) {
+                if (gene && s_LocationShouldBeExtendedToMatch(gene->GetLocation(), sf.GetLocation())) {
+                    CRef<CSeq_feat> new_gene(new CSeq_feat());
+                    new_gene->Assign(*gene);
+                    if (CCleanup::ExtendStopPosition(*new_gene, &sf)) {
+                        CSeq_feat_EditHandle efh = CSeq_feat_EditHandle(m_Scope->GetSeq_featHandle(*gene));
+                        efh.Replace(*new_gene);
+                    }
+                }
+                if (mrna && s_LocationShouldBeExtendedToMatch(mrna->GetLocation(), sf.GetLocation())) {
+                    CRef<CSeq_feat> new_mrna(new CSeq_feat());
+                    new_mrna->Assign(*mrna);
+                    if (CCleanup::ExtendStopPosition(*new_mrna, &sf)) {
+                        CSeq_feat_EditHandle efh = CSeq_feat_EditHandle(m_Scope->GetSeq_featHandle(*mrna));
+                        efh.Replace(*new_mrna);
+                    }
+                }
+                ChangeMade(CCleanupChange::eChangeFeatureLocation);
             }
+        } catch (CException& ex) {
+            // unable to get bioseq handle when loc is on multiple sequences
         }
-        ChangeMade(CCleanupChange::eChangeFeatureLocation);
     }
 
     if (sf.IsSetPseudo() && sf.GetPseudo() && sf.IsSetProduct()) {
@@ -12763,6 +12751,13 @@ void CNewCleanup_imp::MoveStandardName(CSeq_feat& sf)
     if (!sf.GetData().GetRna().IsSetType() || sf.GetData().GetRna().GetType() == CRNA_ref::eType_tmRNA) {
         return;
     }
+    if (sf.GetData().GetRna().GetType() == CRNA_ref::eType_tRNA &&
+        sf.GetData().GetRna().IsSetExt() &&
+        sf.GetData().GetRna().GetExt().IsTRNA() &&
+        !s_IsEmpty(sf.GetData().GetRna().GetExt().GetTRNA())) {
+        return;
+    }
+
     // not for EMBL or DDBJ
     if (m_IsEmblOrDdbj) {
         return;
@@ -12771,6 +12766,7 @@ void CNewCleanup_imp::MoveStandardName(CSeq_feat& sf)
     if (!sf.IsSetQual()) {
         return;
     }
+
     CSeq_feat::TQual::iterator it = sf.SetQual().begin();
     while (it != sf.SetQual().end()) {
         if ((*it)->IsSetQual() && (*it)->IsSetVal() && NStr::Equal((*it)->GetQual(), "standard_name")) {
@@ -13182,6 +13178,12 @@ void CNewCleanup_imp::x_ExtendedCleanupExtra(CSeq_entry_Handle seh)
     if (CCleanup::RenormalizeNucProtSets(seh)) {
         ChangeMade(CCleanupChange::eCollapseSet);
     }
+    if (CCleanup::RepairXrefs(seh)) {
+        ChangeMade(CCleanupChange::eAddSeqFeatXref);
+    }
+    if (CCleanup::RepackageProteins(seh)) {
+        ChangeMade(CCleanupChange::eChangeOther);
+    }
 }
 
 
diff --git a/c++/src/objtools/cleanup/newcleanupp.hpp b/c++/src/objtools/cleanup/newcleanupp.hpp
index c859651..344be6b 100644
--- a/c++/src/objtools/cleanup/newcleanupp.hpp
+++ b/c++/src/objtools/cleanup/newcleanupp.hpp
@@ -141,7 +141,6 @@ public:
     
     void SetScope(CScope& scope) { m_Scope.Reset(&scope); }
 
-
     /// Basic Cleanup methods
 
     void BasicCleanupSeqEntry (
@@ -642,6 +641,8 @@ protected:
     /// tells if any Seq-id on any Bioseq in the blob being cleaned is embl or ddbj.
     bool m_IsEmblOrDdbj;
 
+    bool m_KeepTopNestedSet;
+
     friend class CAutogeneratedCleanup;
     friend class CAutogeneratedExtendedCleanup;
 };
diff --git a/c++/src/objtools/data_loaders/Makefile.in b/c++/src/objtools/data_loaders/Makefile.in
index 9bc6107..9e7505b 100644
--- a/c++/src/objtools/data_loaders/Makefile.in
+++ b/c++/src/objtools/data_loaders/Makefile.in
@@ -1,6 +1,6 @@
-# $Id: Makefile.in 481220 2015-10-07 18:23:37Z grichenk $
+# $Id: Makefile.in 501731 2016-05-18 15:58:33Z gouriano $
 
-SUB_PROJ = genbank lds2 blastdb patcher
+SUB_PROJ = genbank lds2 blastdb patcher asn_cache
 
 srcdir = @srcdir@
 include @builddir@/Makefile.meta
diff --git a/c++/src/objtools/data_loaders/blastdb/bdbloader.cpp b/c++/src/objtools/data_loaders/blastdb/bdbloader.cpp
index 631c64f..00e58d4 100644
--- a/c++/src/objtools/data_loaders/blastdb/bdbloader.cpp
+++ b/c++/src/objtools/data_loaders/blastdb/bdbloader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: bdbloader.cpp 443376 2014-08-13 17:03:05Z vakatov $
+/*  $Id: bdbloader.cpp 500404 2016-05-04 14:59:01Z camacho $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -30,10 +30,6 @@
 *
 * ===========================================================================
 */
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: bdbloader.cpp 443376 2014-08-13 17:03:05Z vakatov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/data_loaders/blastdb/bdbloader.hpp>
 #include <objmgr/impl/tse_loadlock.hpp>
diff --git a/c++/src/objtools/data_loaders/blastdb/bdbloader_rmt.cpp b/c++/src/objtools/data_loaders/blastdb/bdbloader_rmt.cpp
index c0bc6c9..bbefd07 100644
--- a/c++/src/objtools/data_loaders/blastdb/bdbloader_rmt.cpp
+++ b/c++/src/objtools/data_loaders/blastdb/bdbloader_rmt.cpp
@@ -1,4 +1,4 @@
-/*  $Id: bdbloader_rmt.cpp 443376 2014-08-13 17:03:05Z vakatov $
+/*  $Id: bdbloader_rmt.cpp 500404 2016-05-04 14:59:01Z camacho $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -30,10 +30,6 @@
 *
 * ===========================================================================
 */
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: bdbloader_rmt.cpp 443376 2014-08-13 17:03:05Z vakatov $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/data_loaders/blastdb/bdbloader_rmt.hpp>
 #include <objmgr/impl/tse_loadlock.hpp>
diff --git a/c++/src/objtools/data_loaders/blastdb/cached_sequence.cpp b/c++/src/objtools/data_loaders/blastdb/cached_sequence.cpp
index 145a68d..aa2a530 100644
--- a/c++/src/objtools/data_loaders/blastdb/cached_sequence.cpp
+++ b/c++/src/objtools/data_loaders/blastdb/cached_sequence.cpp
@@ -1,4 +1,4 @@
-/*  $Id: cached_sequence.cpp 468783 2015-05-28 13:00:08Z vasilche $
+/*  $Id: cached_sequence.cpp 500404 2016-05-04 14:59:01Z camacho $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -31,10 +31,6 @@
 /** @file cached_sequence.cpp
  * Defines the CCachedSequence class
  */
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: cached_sequence.cpp 468783 2015-05-28 13:00:08Z vasilche $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "cached_sequence.hpp"
 #include <objects/seq/Seq_inst.hpp>
diff --git a/c++/src/objtools/data_loaders/blastdb/local_blastdb_adapter.cpp b/c++/src/objtools/data_loaders/blastdb/local_blastdb_adapter.cpp
index aeeefa2..7fdee71 100644
--- a/c++/src/objtools/data_loaders/blastdb/local_blastdb_adapter.cpp
+++ b/c++/src/objtools/data_loaders/blastdb/local_blastdb_adapter.cpp
@@ -1,4 +1,4 @@
-/*  $Id: local_blastdb_adapter.cpp 468783 2015-05-28 13:00:08Z vasilche $
+/*  $Id: local_blastdb_adapter.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,10 +31,6 @@
 /** @file local_blastdb_adapter.cpp
  * Defines the CLocalBlastDbAdapter class
  */
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: local_blastdb_adapter.cpp 468783 2015-05-28 13:00:08Z vasilche $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "local_blastdb_adapter.hpp"
 #include <objects/seq/Seq_inst.hpp>
diff --git a/c++/src/objtools/data_loaders/blastdb/remote_blastdb_adapter.cpp b/c++/src/objtools/data_loaders/blastdb/remote_blastdb_adapter.cpp
index c2e6dad..9033354 100644
--- a/c++/src/objtools/data_loaders/blastdb/remote_blastdb_adapter.cpp
+++ b/c++/src/objtools/data_loaders/blastdb/remote_blastdb_adapter.cpp
@@ -1,4 +1,4 @@
-/*  $Id: remote_blastdb_adapter.cpp 468783 2015-05-28 13:00:08Z vasilche $
+/*  $Id: remote_blastdb_adapter.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,10 +31,6 @@
 /** @file remote_blastdb_adapter.cpp
  * Defines the CRemoteBlastDbAdapter class
  */
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: remote_blastdb_adapter.cpp 468783 2015-05-28 13:00:08Z vasilche $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include "remote_blastdb_adapter.hpp"
 #include <objtools/blast/services/blast_services.hpp>
diff --git a/c++/src/objtools/data_loaders/genbank/Makefile.ncbi_xreader.lib b/c++/src/objtools/data_loaders/genbank/Makefile.ncbi_xreader.lib
index 29cf9f0..45557c4 100644
--- a/c++/src/objtools/data_loaders/genbank/Makefile.ncbi_xreader.lib
+++ b/c++/src/objtools/data_loaders/genbank/Makefile.ncbi_xreader.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.ncbi_xreader.lib 490251 2016-01-22 15:40:54Z vasilche $
+# $Id: Makefile.ncbi_xreader.lib 501939 2016-05-19 18:58:38Z ucko $
 
 SRC = dispatcher reader writer processors \
     reader_snp seqref blob_id request_result \
@@ -14,6 +14,8 @@ LIB_OR_DLL = both
 # Dependencies for shared library
 DLL_LIB = $(GENBANK_READER_LDEP)
 
+LIBS = $(CMPRS_LIBS) $(NETWORK_LIBS) $(DL_LIBS) $(ORIG_LIBS)
+
 WATCHERS = vasilche
 
 
diff --git a/c++/src/objtools/data_loaders/genbank/cache/reader_cache.cpp b/c++/src/objtools/data_loaders/genbank/cache/reader_cache.cpp
index e09c24f..1ac6351 100644
--- a/c++/src/objtools/data_loaders/genbank/cache/reader_cache.cpp
+++ b/c++/src/objtools/data_loaders/genbank/cache/reader_cache.cpp
@@ -1,4 +1,4 @@
-/*  $Id: reader_cache.cpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: reader_cache.cpp 493171 2016-02-24 19:31:13Z vasilche $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
diff --git a/c++/src/objtools/data_loaders/genbank/cache/writer_cache.cpp b/c++/src/objtools/data_loaders/genbank/cache/writer_cache.cpp
index ffe2430..7a2eee9 100644
--- a/c++/src/objtools/data_loaders/genbank/cache/writer_cache.cpp
+++ b/c++/src/objtools/data_loaders/genbank/cache/writer_cache.cpp
@@ -1,4 +1,4 @@
-/*  $Id: writer_cache.cpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: writer_cache.cpp 493171 2016-02-24 19:31:13Z vasilche $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
diff --git a/c++/src/objtools/data_loaders/genbank/dispatcher.cpp b/c++/src/objtools/data_loaders/genbank/dispatcher.cpp
index 7000a40..a836d02 100644
--- a/c++/src/objtools/data_loaders/genbank/dispatcher.cpp
+++ b/c++/src/objtools/data_loaders/genbank/dispatcher.cpp
@@ -1,4 +1,4 @@
-/*  $Id: dispatcher.cpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: dispatcher.cpp 493171 2016-02-24 19:31:13Z vasilche $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
diff --git a/c++/src/objtools/data_loaders/genbank/gbloader.cpp b/c++/src/objtools/data_loaders/genbank/gbloader.cpp
index 2d77d9d..0400d27 100644
--- a/c++/src/objtools/data_loaders/genbank/gbloader.cpp
+++ b/c++/src/objtools/data_loaders/genbank/gbloader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gbloader.cpp 499792 2016-04-28 14:15:13Z ivanov $
+/*  $Id: gbloader.cpp 499679 2016-04-27 16:42:09Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -122,7 +122,7 @@ public:
 
     CInitMutexPool& GetMutexPool(void) { return m_Loader->m_MutexPool; }
 
-    virtual TExpirationTime GetIdExpirationTimeout(void) const;
+    virtual TExpirationTime GetIdExpirationTimeout(GBL::EExpirationType type) const;
 
     virtual bool GetAddWGSMasterDescr(void) const;
 
@@ -633,7 +633,7 @@ bool CGBDataLoader::x_CreateReaders(const string& str,
                                     CGBLoaderParams::EPreopenConnection preopen)
 {
     vector<string> str_list;
-    NStr::Tokenize(str, ";", str_list, NStr::eNoMergeDelims);
+    NStr::Split(str, ";", str_list);
     size_t reader_count = 0;
     for ( size_t i = 0; i < str_list.size(); ++i ) {
         CRef<CReader> reader(x_CreateReader(str_list[i], params));
@@ -657,7 +657,7 @@ void CGBDataLoader::x_CreateWriters(const string& str,
                                     const TParamTree* params)
 {
     vector<string> str_list;
-    NStr::Tokenize(str, ";", str_list, NStr::eNoMergeDelims);
+    NStr::Split(str, ";", str_list);
     for ( size_t i = 0; i < str_list.size(); ++i ) {
         CRef<CWriter> writer(x_CreateWriter(str_list[i], params));
         if( writer ) {
@@ -1812,9 +1812,14 @@ void CGBReaderRequestResult::GetLoadedBlob_ids(const CSeq_id_Handle& idh,
 
 
 CGBDataLoader::TExpirationTimeout
-CGBReaderRequestResult::GetIdExpirationTimeout(void) const
+CGBReaderRequestResult::GetIdExpirationTimeout(GBL::EExpirationType type) const
 {
-    return m_Loader->GetIdExpirationTimeout();
+    if ( type == GBL::eExpire_normal ) {
+        return m_Loader->GetIdExpirationTimeout();
+    }
+    else {
+        return CReaderRequestResult::GetIdExpirationTimeout(type);
+    }
 }
 
 
diff --git a/c++/src/objtools/data_loaders/genbank/gicache/Makefile.in b/c++/src/objtools/data_loaders/genbank/gicache/Makefile.in
index 0f62e52..acda129 100644
--- a/c++/src/objtools/data_loaders/genbank/gicache/Makefile.in
+++ b/c++/src/objtools/data_loaders/genbank/gicache/Makefile.in
@@ -1,6 +1,8 @@
-# $Id: Makefile.in 182287 2010-01-28 16:15:58Z vasilche $
+# $Id: Makefile.in 514589 2016-09-22 17:28:21Z ivanov $
 
 LIB_PROJ = ncbi_xreader_gicache
 
+REQUIRES = LMDB
+
 srcdir = @srcdir@
 include @builddir@/Makefile.meta
diff --git a/c++/src/objtools/data_loaders/genbank/gicache/Makefile.ncbi_xreader_gicache.lib b/c++/src/objtools/data_loaders/genbank/gicache/Makefile.ncbi_xreader_gicache.lib
index c16a177..7ad030e 100644
--- a/c++/src/objtools/data_loaders/genbank/gicache/Makefile.ncbi_xreader_gicache.lib
+++ b/c++/src/objtools/data_loaders/genbank/gicache/Makefile.ncbi_xreader_gicache.lib
@@ -1,16 +1,19 @@
-# $Id: Makefile.ncbi_xreader_gicache.lib 484420 2015-11-10 19:50:38Z ucko $
+# $Id: Makefile.ncbi_xreader_gicache.lib 514596 2016-09-22 17:29:50Z ivanov $
 
 REQUIRES = unix
 
-SRC = reader_gicache gicache_cxx
+SRC = reader_gicache gicache
 
 LIB = ncbi_xreader_gicache
 
 # Build shared version when possible
 LIB_OR_DLL = both
 
+CPPFLAGS = $(LMDB_INCLUDE) -I$(srcdir) $(ORIG_CPPFLAGS)
+
 # Dependencies for shared library
 DLL_LIB = ncbi_xreader$(DLL)
+LIBS = $(LMDB_LIBS)
 
 WATCHERS = vasilche
 
diff --git a/c++/src/objtools/data_loaders/genbank/gicache/gicache.c b/c++/src/objtools/data_loaders/genbank/gicache/gicache.c
index f06e178..5c93942 100644
--- a/c++/src/objtools/data_loaders/genbank/gicache/gicache.c
+++ b/c++/src/objtools/data_loaders/genbank/gicache/gicache.c
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* $Id: gicache.c 487414 2015-12-17 16:42:03Z syncbot $
+* $Id: gicache.c 514594 2016-09-22 17:29:29Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -29,6 +29,7 @@
 *
 *****************************************************************************/
 
+#include <inttypes.h>
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -38,20 +39,11 @@
 #include <assert.h>
 #include <poll.h>
 #include <errno.h>
+#include <time.h>
+
+#include <lmdb.h>
 #include "gicache.h"
 #include "ncbi_toolkit.h"
-#ifdef NCBI_CXX_TOOLKIT
-#include "connect/ncbi_core_cxx.hpp"
-#else
-#include "connect/ncbi_core_c.h"
-#endif
-#include "connect/ncbi_core.h"
-
-/****************************************************************************
- *
- * gi_data_index.h 
- *
- ****************************************************************************/
 
 #ifdef TEST_RUN
 #  ifdef NDEBUG
@@ -59,1865 +51,935 @@
 #  endif
 #endif
 
-#define MAX_ACCESSION_LENGTH 64
-
-#define kPageSize            8
-#define kPageMask            0xff
-
-#define kLocalOffsetMask     0x0000ffff
-#define kFullOffsetMask      0x7fffffff
-#define kTopBit              0x80000000
-#define kUint4Mask           0xffffffff
-#define kTopPageMask         0x0000007f
-
-#define INDEX_CACHE_SIZE     32768
-#define DATA_CACHE_SIZE      8192
-
-// Each top-level page correponds to a range of 2^25 gis (because 2 gis are
-// packed in each slot on leaf pages). Since gi is a signed integer, there are
-// a total of 2^31/2^25 = 2^6 = 64 top level pages.
-// The offset header contains 8-byte starting offsets for each top-level page,
-// but size is measured in 4-byte units of the m_GiIndex array, so it's
-// sufficient to have header size = 64 * 8 / 4 = 128.
-// However page size for the index file is 256, and it's inconvenient to use
-// fraction of a page for the header. Hence use one whole page.
-#define kOffsetHeaderSize    256
-
-// Given a Uint4* p
-#define GET_INT8(p) (((Int8)(*(p) & kUint4Mask))<<32) | ((Int8)(*((p)+1)))
-
-// If offset for top-level page corresponding to a given gi is not set ( = 0),
-// go back to previous top-level pages until a non-zero offset is found.
-#define GET_TOP_PAGE_OFFSET(gi) GET_INT8(&data_index->m_GiIndex[2*((((Uint4)gi)>>25)&kTopPageMask)])
-
-
-#define SET_TOP_PAGE_OFFSET(gi,off) \
-    data_index->m_GiIndex[2*((((Uint4)gi)>>25)&kTopPageMask)] = (Uint4)((off)>>32);\
-    data_index->m_GiIndex[2*((((Uint4)gi)>>25)&kTopPageMask)+1] = (Uint4)((off)&kUint4Mask);
+#define MAX_ACCESSION_LENGTH	64
+#define MAX_DBS					16
+#define MAX_READERS				1024
+#define MAP_SIZE_INIT		(256L * 1024 * 1024 * 1024)
+#define MAP_SIZE_DELTA		(16L * 1024 * 1024 * 1024)
+#define GI_DBI					"#GI_DBI"
+#define META_DBI				"#META_DBI"
+#define MAX_ROWS_PER_TRANSACTION	32
 
 typedef struct {
-    Uint4*  m_GiIndex;
-    char*   m_Data;
-    int     m_GiIndexFile;
-    int     m_DataFile;
-    Uint4   m_GiIndexLen;
-    Int8    m_DataLen;
-    Int8    m_MappedDataLen;
-    Uint4   m_MappedIndexLen;
     Uint1   m_ReadOnlyMode;
-    Uint4   m_IndexCacheLen;
-    Uint4   m_DataCacheLen;
-    char    m_FileNamePrefix[256];
-    Uint4   m_DataUnitSize;
-    Uint4   m_IndexCacheSize;
-    Uint4*  m_IndexCache;
-    Uint4   m_DataCacheSize;
-    char*   m_DataCache;
-    Uint1   m_SequentialData;
-    Uint1   m_FreeOnDrop;
-    MT_LOCK m_RemapLock; /* Remapper is WRITER, others are READERs */
-    volatile Uint1 m_NeedRemap; /* Is remap needed? */
-    Uint1   m_RemapOnRead; /* Is remap allowed when reading data? */
-    Uint4   m_OffsetHeaderSize; /* 0 for 32-bit version, 256 for 64-bit */
-    char*   m_OldDataPtr;
-    Int8    m_OldMappedDataLen;
-    ino_t   m_IndexInode;
-    ino_t   m_DataInode;
+    char    m_FileName[PATH_MAX];
+	MDB_env *m_env;
+	MDB_dbi m_gi_dbi;
+	MDB_dbi m_meta_dbi;
+	MDB_txn *m_txn;
+	int		m_txn_rowcount;
 } SGiDataIndex;
 
-static void (*LogFunc)(char*) = NULL;
+static SGiDataIndex *gi_cache = NULL;
 
-/****************************************************************************
- *
- * gi_data_index.c
- *
- ****************************************************************************/
-
-static void x_DumpIndexCache(SGiDataIndex* data_index)
-{
-    int bytes_written = 0;
-    if (data_index->m_GiIndexFile >= 0 && data_index->m_IndexCacheLen > 0) {
-        assert(data_index->m_GiIndexLen*sizeof(Uint4) ==
-               lseek(data_index->m_GiIndexFile, 0, SEEK_CUR));
-        assert(data_index->m_GiIndexLen*sizeof(Uint4) ==
-               lseek(data_index->m_GiIndexFile, 0, SEEK_END));
-        /* Write to the index file whatever is still left in cache. */
-        bytes_written =
-            write(data_index->m_GiIndexFile, data_index->m_IndexCache,
-                  data_index->m_IndexCacheLen*sizeof(int));
-		if (bytes_written != data_index->m_IndexCacheLen*sizeof(int) && LogFunc) {
-			char logmsg[256];
-			sprintf(logmsg, "GI_CACHE: Possible index corruption: failed to write: tried to write %lu, written: %d, err: %d\n", data_index->m_IndexCacheLen*sizeof(int), bytes_written, errno);
-			LogFunc(logmsg);
-		}
-        assert(bytes_written == data_index->m_IndexCacheLen*sizeof(int));
-        data_index->m_GiIndexLen += data_index->m_IndexCacheLen;
-        assert(data_index->m_GiIndexLen*sizeof(Uint4) ==
-               lseek(data_index->m_GiIndexFile, 0, SEEK_CUR));
-        assert(data_index->m_GiIndexLen*sizeof(Uint4) ==
-               lseek(data_index->m_GiIndexFile, 0, SEEK_END));
-        data_index->m_IndexCacheLen = 0;
-    }
-}
+static void (*LogFunc)(char*) = NULL;
 
-static void x_DumpDataCache(SGiDataIndex* data_index)
-{
-    int bytes_written = 0;
-    if (data_index->m_DataFile >= 0 && data_index->m_DataCacheLen > 0) {
-        assert(data_index->m_DataLen ==
-               lseek(data_index->m_DataFile, 0, SEEK_CUR));
-        assert(data_index->m_DataLen ==
-               lseek(data_index->m_DataFile, 0, SEEK_END));
-        /* Write to the data file whatever is still left in cache. */
-        bytes_written = 
-            write(data_index->m_DataFile, data_index->m_DataCache,
-                  data_index->m_DataCacheLen);
-		if (bytes_written != data_index->m_DataCacheLen && LogFunc) {
+int x_Commit(SGiDataIndex* data_index) {
+	int rv = 0;
+	if (data_index && data_index->m_txn) {
+		int rc;
+		rc = mdb_txn_commit(data_index->m_txn);
+		data_index->m_txn = NULL;
+		data_index->m_txn_rowcount = 0;
+		if (rc) {
 			char logmsg[256];
-			sprintf(logmsg, "GI_CACHE: Possible data corruption: failed to write: tried to write %u, written: %d, err: %d\n", data_index->m_DataCacheLen, bytes_written, errno);
-			LogFunc(logmsg);
+			snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to commit transaction: %s\n", mdb_strerror(rc));
+			if (LogFunc)
+				LogFunc(logmsg);
+			rv = -1;
 		}
-        assert(bytes_written == data_index->m_DataCacheLen);
-        data_index->m_DataLen += data_index->m_DataCacheLen;
-        assert(data_index->m_DataLen == 
-               lseek(data_index->m_DataFile, 0, SEEK_CUR));
-        assert(data_index->m_DataLen == 
-               lseek(data_index->m_DataFile, 0, SEEK_END));
-        data_index->m_DataCacheLen = 0;
-    }
-}
-
-static void x_CloseIndexFile(SGiDataIndex* data_index)
-{
-    if (data_index->m_GiIndexFile >= 0) {
-        close(data_index->m_GiIndexFile);
-        data_index->m_GiIndexFile = -1;
-        data_index->m_GiIndexLen = 0;
-        data_index->m_MappedIndexLen = 0;
-    }
-}
-
-static void x_CloseDataFile(SGiDataIndex* data_index)
-{
-    if (data_index->m_DataFile >= 0) {
-        close(data_index->m_DataFile);
-        data_index->m_DataFile = -1;
-        data_index->m_DataLen = 0;
-        data_index->m_MappedDataLen = 0;
-    }
-}
-
-/* Closes all files */
-static void x_CloseFiles(SGiDataIndex* data_index)
-{
-    x_CloseIndexFile(data_index);
-    x_CloseDataFile(data_index);
-}
-
-static void x_UnMapIndex(SGiDataIndex* data_index)
-{
-    if (data_index->m_GiIndex != MAP_FAILED) {
-        if (LogFunc) {
-            char logmsg[256];
-            sprintf(logmsg,
-                    "GI_CACHE: Unmapping index file, filedes %d, map length %u, path %s\n",
-                    data_index->m_GiIndexFile, data_index->m_MappedIndexLen,
-                    data_index->m_FileNamePrefix);
-            LogFunc(logmsg);
-        }
-        munmap((char*)data_index->m_GiIndex,
-               data_index->m_MappedIndexLen*sizeof(Uint4));
-        data_index->m_GiIndex = (Uint4*)MAP_FAILED;
-        data_index->m_MappedIndexLen = 0;
-    }
-}
-
-static void x_UnMapData(SGiDataIndex* data_index)
-{
-    if (data_index->m_Data != MAP_FAILED) {
-        if (LogFunc) {
-            char logmsg[256];
-            sprintf(logmsg,
-                    "GI_CACHE: Unmapping data file, filedes %d, map length %lld, path %s\n",
-                    data_index->m_DataFile, data_index->m_MappedDataLen,
-                    data_index->m_FileNamePrefix);
-            LogFunc(logmsg);
-        }
-        data_index->m_OldDataPtr = data_index->m_Data;
-        data_index->m_OldMappedDataLen = data_index->m_MappedDataLen;
-        munmap((char*)data_index->m_Data, data_index->m_MappedDataLen);
-        data_index->m_Data = (char*)MAP_FAILED;
-        data_index->m_MappedDataLen = 0;
-    }
+	}
+	return rv;
 }
 
-/* Unmaps data and index files */
-static void x_UnMap(SGiDataIndex* data_index)
-{
-    x_UnMapIndex(data_index);
-    x_UnMapData(data_index);
+int GiDataIndex_Commit(void) {
+	return x_Commit(gi_cache);
 }
 
-static Uint1 x_OpenIndexFile(SGiDataIndex* data_index)
-{
-    char buf[256];
-    int flags;
-	int open_err;
-
-    if (data_index->m_GiIndexFile >= 0)
-        return 1;
-    
-    flags = (data_index->m_ReadOnlyMode?O_RDONLY:O_RDWR|O_APPEND|O_CREAT);
-    
-    x_UnMapIndex(data_index);
-    
-    strcpy(buf, data_index->m_FileNamePrefix);
-
-    strcat(buf, "idx");
-    data_index->m_GiIndexFile = open(buf,flags,0644);
-	open_err = data_index->m_GiIndexFile < 0 ? errno : 0;
-    data_index->m_GiIndexLen = 
-        (data_index->m_GiIndexFile >= 0 ? 
-         lseek(data_index->m_GiIndexFile, 0, SEEK_END)/sizeof(Uint4) : 0);
-
-    /* Save inode number */
-    struct stat stat_buf;
-    memset(&stat_buf, 0, sizeof(stat_buf));
-    if (data_index->m_GiIndexFile >= 0) {
-        fstat(data_index->m_GiIndexFile, &stat_buf);
-	}
-    data_index->m_IndexInode = stat_buf.st_ino;
-
-    if (LogFunc) {
-        char logmsg[256];
-        sprintf(logmsg,
-                "GI_CACHE: Opened index file %s; filedes %d, inode %lx, length %u, path %s, err: %d\n",
-                buf, data_index->m_GiIndexFile, (unsigned long)data_index->m_IndexInode,
-                data_index->m_GiIndexLen, data_index->m_FileNamePrefix, open_err);
-        LogFunc(logmsg);
-    }
-
-    if (data_index->m_GiIndexLen == 0 && !data_index->m_ReadOnlyMode &&
-        data_index->m_GiIndexFile) {
-        Uint4* b;
-        int bytes_written = 0;
-        /* For 64-bit version only, the first page of the index is reserved to
-           store 8-byte starting offsets for data corresponding to the 64 top
-           level pages.
-           The next (first for 32-bit version, second for 64-bit) page of the
-           index is reserved for the pointers to other pages.
-        */
-        data_index->m_GiIndexLen = data_index->m_OffsetHeaderSize + (1<<kPageSize);
-        
-        b = (Uint4*) calloc(data_index->m_GiIndexLen, sizeof(Uint4));
-        assert(0 == lseek(data_index->m_GiIndexFile, 0, SEEK_END));
-        bytes_written = write(data_index->m_GiIndexFile, b,
-                              data_index->m_GiIndexLen*sizeof(Uint4));
-		if (bytes_written != data_index->m_GiIndexLen*sizeof(Uint4) && LogFunc) {
-			char logmsg[256];
-			sprintf(logmsg, "GI_CACHE: Possible index corruption: failed to write: tried to write %lu, written: %d, err: %d\n", data_index->m_GiIndexLen*sizeof(Uint4), bytes_written, errno);
-			LogFunc(logmsg);
-		}
-        assert(bytes_written == data_index->m_GiIndexLen*sizeof(Uint4));
-        free(b);
-        assert(data_index->m_GiIndexLen*sizeof(Uint4) ==
-               lseek(data_index->m_GiIndexFile, 0, SEEK_CUR));
-        assert(data_index->m_GiIndexLen*sizeof(Uint4) ==
-               lseek(data_index->m_GiIndexFile, 0, SEEK_END));
-    }
-    
-    return (data_index->m_GiIndexFile >= 0);
-}
-
-/* Opens data file, including check if they are already open. */
-static Uint1 x_OpenDataFile(SGiDataIndex* data_index)
-{
-    char buf[256];
-    int flags;
-	int open_err;
-
-    if (data_index->m_DataFile >= 0)
-        return 1;
-    
-    flags = (data_index->m_ReadOnlyMode?O_RDONLY:O_RDWR|O_APPEND|O_CREAT);
-    
-    strcpy(buf, data_index->m_FileNamePrefix);
-    strcat(buf, "dat");
-    data_index->m_DataFile = open(buf,flags,0644);
-	open_err = data_index->m_GiIndexFile < 0 ? errno : 0;
-    data_index->m_DataLen = (data_index->m_DataFile >= 0 ? 
-                             lseek(data_index->m_DataFile, 0, SEEK_END) : 0);
-    /* Save inode number */
-    struct stat stat_buf;
-    memset(&stat_buf, 0, sizeof(stat_buf));
-    if (data_index->m_DataFile >= 0) {
-        fstat(data_index->m_DataFile, &stat_buf);
-    }
-    data_index->m_DataInode = stat_buf.st_ino;
-
-    if (LogFunc) {
-        char logmsg[256];
-        sprintf(logmsg,
-                "GI_CACHE: Opened data file %s; filedes %d, inode %lx, length %lld, path %s, err: %d\n",
-                buf, data_index->m_DataFile, (unsigned long)data_index->m_DataInode,
-                data_index->m_DataLen, data_index->m_FileNamePrefix, open_err);
-        LogFunc(logmsg);
-    }
-
-    if (data_index->m_DataLen == 0 && !data_index->m_ReadOnlyMode &&
-        data_index->m_DataFile) {
-        /* Fill first 2*sizeof(int) bytes with 0: this guarantees that all 
-         * offsets into data file will be > 0, allowing 0 to mean absense of
-         * data. There reason to write 2 integers can be helpful in case of
-         * binary data, making sure that data is aligned.
-         */
-        int  b[2];
-        int bytes_written = 0;
-        memset(b, 0, sizeof(b));
-        assert(0 == lseek(data_index->m_DataFile, 0, SEEK_END));
-        bytes_written = write(data_index->m_DataFile, b, sizeof(b));
-		if (bytes_written != sizeof(b) && LogFunc) {
-			char logmsg[256];
-			sprintf(logmsg, "GI_CACHE: Possible file corruption: failed to write: tried to write %lu, written: %d, err: %d\n", sizeof(b), bytes_written, errno);
-			LogFunc(logmsg);
+/* Destructor */
+static void GiDataIndex_Free(SGiDataIndex* data_index) {
+	if (data_index) {
+		if (data_index->m_txn)
+			x_Commit(data_index);
+		if (data_index->m_env) {
+			if (data_index->m_gi_dbi) {
+				mdb_dbi_close(data_index->m_env, data_index->m_gi_dbi);
+				data_index->m_gi_dbi = 0;
+			}
+			if (data_index->m_meta_dbi) {
+				mdb_dbi_close(data_index->m_env, data_index->m_meta_dbi);
+				data_index->m_meta_dbi = 0;
+			}
+			mdb_env_close(data_index->m_env);
+			data_index->m_env = NULL;
 		}
-        assert(bytes_written == sizeof(b));
-        data_index->m_DataLen = sizeof(b);
-        assert(data_index->m_DataLen ==
-               lseek(data_index->m_DataFile, 0, SEEK_CUR));
-        assert(data_index->m_DataLen ==
-               lseek(data_index->m_DataFile, 0, SEEK_END));
-    }
-    
-    return (data_index->m_DataFile >= 0);
+		free(data_index);
+		data_index = NULL;
+	}
 }
 
-/* hack needed for SGI IRIX where MAP_NORESERVE isn't defined. Dima */
-#ifndef MAP_NORESERVE
-#define MAP_NORESERVE (0)
-#endif
-
-static Uint1 x_MapIndex(SGiDataIndex* data_index)
-{
-    int prot;
-    Uint4 map_size;
-
-    if (!x_OpenIndexFile(data_index)) return 0;
-
-    if (data_index->m_GiIndex != MAP_FAILED) return 1;
-    
-    if (data_index->m_ReadOnlyMode) {
-        map_size = lseek(data_index->m_GiIndexFile, 0, SEEK_END);
-        data_index->m_GiIndexLen = map_size / sizeof(Uint4);
-        prot = PROT_READ;
-    } else {
-        /* If there's anything in local memory cache, write it to disk. */
-        x_DumpIndexCache(data_index);
-        map_size = data_index->m_GiIndexLen*sizeof(Uint4);
-        assert(map_size == lseek(data_index->m_GiIndexFile, 0, SEEK_CUR));
-        assert(map_size == lseek(data_index->m_GiIndexFile, 0, SEEK_END));
-        prot = PROT_READ | PROT_WRITE;
-    }
-    data_index->m_GiIndex =
-        (Uint4*)mmap(0, map_size, prot, MAP_SHARED|MAP_NORESERVE, 
-                     data_index->m_GiIndexFile, 0);
-    data_index->m_MappedIndexLen = data_index->m_GiIndexLen;
-
-    if (LogFunc) {
-        char logmsg[256];
-        sprintf(logmsg,
-                "GI_CACHE: Memory mapped index file, filedes %d, map length %u, path %s\n",
-                data_index->m_GiIndexFile, data_index->m_MappedIndexLen,
-                data_index->m_FileNamePrefix);
-        LogFunc(logmsg);
-    }
-
-    return (data_index->m_GiIndex != MAP_FAILED);
-}
+/* Constructor */
+static SGiDataIndex*
+GiDataIndex_New(const char* prefix, Uint1 readonly, Uint1 enablesync) { 
+	int rc;
+	char logmsg[256];
+	SGiDataIndex*  data_index;
+	struct stat fstat;
+	MDB_txn *txn = 0;
+	int strc;
+	int64_t mapsize;
+
+    data_index = (SGiDataIndex*) malloc(sizeof(SGiDataIndex));
+    memset(data_index, 0, sizeof(SGiDataIndex));
+
+	rc = mdb_env_create(&data_index->m_env);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to init LMDB environment: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-#define MAP_EXTRA_DATA_LEN 1000000
-
-static Uint1 x_MapData(SGiDataIndex* data_index)
-{
-    if (!x_OpenDataFile(data_index)) return 0;
-
-    if (data_index->m_Data == MAP_FAILED) {
-        int prot;
-        Int8 map_size;
-
-        if (data_index->m_ReadOnlyMode) {
-            data_index->m_DataLen = lseek(data_index->m_DataFile, 0, SEEK_END);
-            map_size = 
-                (data_index->m_DataLen < data_index->m_OldMappedDataLen ?
-                 data_index->m_OldMappedDataLen :
-                 data_index->m_DataLen + MAP_EXTRA_DATA_LEN);
-            prot = PROT_READ;
-        } else {
-            /* If there's anything in local memory cache, write it to disk. */
-            x_DumpDataCache(data_index);
-            map_size = data_index->m_DataLen;
-            assert(map_size == lseek(data_index->m_DataFile, 0, SEEK_CUR));
-            assert(map_size == lseek(data_index->m_DataFile, 0, SEEK_END));
-            prot = PROT_READ | PROT_WRITE;
-        }
-        
-        data_index->m_Data =
-            (char*) mmap(data_index->m_OldDataPtr, map_size, prot,
-                         MAP_SHARED|MAP_NORESERVE, data_index->m_DataFile, 0);
-        data_index->m_MappedDataLen = map_size;
-
-        if (LogFunc) {
-            char logmsg[256];
-            sprintf(logmsg,
-                    "GI_CACHE: Memory mapped data file, filedes %d, map length %lld, path %s\n",
-                    data_index->m_DataFile, (long long)data_index->m_MappedDataLen,
-                    data_index->m_FileNamePrefix);
-            LogFunc(logmsg);
-        }
-    }
+	rc = mdb_env_set_maxdbs(data_index->m_env, MAX_DBS);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to update max dbs to %d: %s\n", MAX_DBS, mdb_strerror(rc));
+		goto ERROR;
+	}
 
-    return (data_index->m_Data != MAP_FAILED);
-}
+	rc = mdb_env_set_maxreaders(data_index->m_env, MAX_READERS);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to update max readers to %d: %s\n", MAX_READERS, mdb_strerror(rc));
+		goto ERROR;
+	}
 
-static void x_FlushData(SGiDataIndex* data_index)
-{
-    if (data_index->m_DataFile >= 0 && !data_index->m_ReadOnlyMode) {
-        if (data_index->m_DataCacheLen > 0)
-            x_DumpDataCache(data_index);
-        /* Synchronize memory mapped data with the file on disk. */
-        msync(data_index->m_Data, data_index->m_DataLen, MS_SYNC);
-    }
-}
+    data_index->m_ReadOnlyMode = readonly;
+    assert(strlen(prefix) < PATH_MAX);
+    snprintf(data_index->m_FileName, sizeof(data_index->m_FileName), "%s.db", prefix);
 
-static void x_FlushIndex(SGiDataIndex* data_index)
-{
-    /* Flush index file */
-    if (data_index->m_GiIndexFile >= 0 && !data_index->m_ReadOnlyMode) {
-        if (data_index->m_IndexCacheLen > 0)
-            x_DumpIndexCache(data_index);
-        /* Synchronize memory mapped data with the file on disk. */
-        msync((char*)data_index->m_GiIndex, data_index->m_GiIndexLen, MS_SYNC);
-    }
-}
+	strc = stat(data_index->m_FileName, &fstat);
 
-static void x_Flush(SGiDataIndex* data_index)
-{
-    x_FlushIndex(data_index);
-    x_FlushData(data_index);
-}
+	if (readonly && (strc  != 0 || fstat.st_size == 0)) {
+		rc = errno;
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to access file (%s): %s\n", data_index->m_FileName, strerror(rc));
+		goto ERROR;
+	}
 
-static Uint1 x_ReMapIndex(SGiDataIndex* data_index)
-{
-    x_FlushIndex(data_index);
-    x_UnMapIndex(data_index);
-    if (!x_MapIndex(data_index)) return 0;
-    
-    return 1;
-}
+	mapsize = MAP_SIZE_INIT;
+	if (strc == 0 && fstat.st_size + MAP_SIZE_DELTA >  mapsize)
+		mapsize = fstat.st_size + MAP_SIZE_DELTA;
 
-static Uint1 x_ReMapData(SGiDataIndex* data_index)
-{
-    x_FlushData(data_index);
-    x_UnMapData(data_index);
-    if (!x_MapData(data_index)) return 0;
-    
-    return 1;
-}
+	rc = mdb_env_set_mapsize(data_index->m_env, mapsize);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to set map size of %" PRId64 ": %s\n", mapsize, mdb_strerror(rc));
+		goto ERROR;
+	}
 
-static Uint1 GiDataIndex_ReMap(SGiDataIndex* data_index, int delay)
-{
-	int err;
-    /* If some other thread has already done the remapping or is in the process
-       of doing it, there is nothing to do here. */
-    if (!data_index->m_NeedRemap)
-        return 1;
-
-	/* MT_LOCK_Do return -1 - compiled with no locks, 0 -- failed, >0 -- aquired */
-	if ((err = MT_LOCK_Do(data_index->m_RemapLock, eMT_Lock)) == 0) {
-		if (LogFunc) {
-			char logmsg[256];
-			sprintf(logmsg, "GI_CACHE: failed to aquire WR lock, err: %d\n", err);
-			LogFunc(logmsg);
-		}
-		return 0;
+	rc = mdb_env_open(data_index->m_env, data_index->m_FileName, MDB_NOSUBDIR | (readonly ? MDB_RDONLY : 0) | (enablesync ? MDB_MAPASYNC : (MDB_NOSYNC | MDB_NOMETASYNC)), 0644);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to open LMDB db (%s): %s\n", data_index->m_FileName, mdb_strerror(rc));
+		goto ERROR;
 	}
 
-	/* remapping might have been done by somebody else while we were waiting for wr lock */
-	if (!data_index->m_NeedRemap)
-        return 1;
-
-    /* In read-only mode, check if inode numbers for underlying files have
-     * changed. If so, close and reopen the file descriptors.
-     * NB: both index and data file inodes must change before file descriptors
-     * are closed, otherwise it is possible to end up with mismatched files. 
-     */
-    if (data_index->m_ReadOnlyMode) {
-        int index_inode_changed = 0;
-        int data_inode_changed = 0;
-        struct stat stat_buf;
-        char buf[256];
-
-        memset(&stat_buf, 0, sizeof(stat_buf));
-        sprintf(buf, "%sidx", data_index->m_FileNamePrefix);
-        stat(buf, &stat_buf);
-        if (stat_buf.st_ino != data_index->m_IndexInode)
-            index_inode_changed = 1;
-        sprintf(buf, "%sdat", data_index->m_FileNamePrefix);
-        stat(buf, &stat_buf);
-        if (stat_buf.st_ino != data_index->m_DataInode)
-            data_inode_changed = 1;
-        
-        if (index_inode_changed && data_inode_changed)
-            x_CloseFiles(data_index);
-    }
+	rc = mdb_txn_begin(data_index->m_env, NULL, readonly ? MDB_RDONLY : 0, &txn);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to start transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-    if (!x_ReMapIndex(data_index)) {
-		MT_LOCK_Do(data_index->m_RemapLock, eMT_Unlock);
-        return 0;
+	rc = mdb_dbi_open(txn, GI_DBI, MDB_INTEGERKEY | (readonly ? 0 : MDB_CREATE), &data_index->m_gi_dbi);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to open dbi (%s): %s\n", GI_DBI, mdb_strerror(rc));
+		goto ERROR;
 	}
-    if (!x_ReMapData(data_index)) {
-		MT_LOCK_Do(data_index->m_RemapLock, eMT_Unlock);
-        return 0;
+	rc = mdb_dbi_open(txn, META_DBI, (readonly ? 0 : MDB_CREATE), &data_index->m_meta_dbi);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to open dbi (%s): %s\n", META_DBI, mdb_strerror(rc));
+		goto ERROR;
 	}
 
-    /* Inform any other threads that may want remapped data that remapping has
-       already finished. */
-    data_index->m_NeedRemap = 0;
-	MT_LOCK_Do(data_index->m_RemapLock, eMT_Unlock);
-
-    return 1;
-}
-
-/* For each page of 256 2-byte index array slots, the first 2 slots (0 and 1)
- * contain the full 4-byte offset for page element 0.
- * To catch up with the array index, the relative offsets for page elements
- * 1 and 2 are encoded in the 1-byte parts of slot 2. 
- * All other relative 2-byte offsets are encoded in slots corresponding to 
- * the page element with the same index.
- * To distinguish presence of element 0 in the index, the 4-byte offsets for 
- * leaf pages are encoded in the first 31 bits, and top bit is only set when
- * 0th element exists.
- * On error condition this function returns -1
- */
-static int
-x_GetIndexOffset(SGiDataIndex* data_index, int gi, Uint4 page, int level)
-{
-    int base = 0;
-    Uint4 base_page;
-    Uint4 remainder = page & kPageMask;
-    Uint4* gi_index = NULL;
-    Uint1 remap_done = 0;
-
-    if (page >= data_index->m_GiIndexLen + data_index->m_IndexCacheLen) {
-        /* Try remapping and check again */
-        data_index->m_NeedRemap = 1;
-        if (!data_index->m_RemapOnRead || !x_ReMapIndex(data_index))
-            return -1;
-        
-        /* If page is still outside of the index range after remapping, it's an
-           error condition */
-        if (page >= data_index->m_GiIndexLen + data_index->m_IndexCacheLen)
-            return -1;
-        remap_done = 1;
-    }
-
-    if (page < data_index->m_GiIndexLen) {
-        /* If page is outside of the mapped part of the index, try remapping,
-           unless remapping has already been done. */
-        if (page >= data_index->m_MappedIndexLen) {
-            if (remap_done)
-                return -1;
-            data_index->m_NeedRemap = 1;
-            if (!data_index->m_RemapOnRead || !x_ReMapIndex(data_index))
-                return -1;
-        }
-        gi_index = data_index->m_GiIndex;
-    } else {
-        page -= data_index->m_GiIndexLen;
-        gi_index = data_index->m_IndexCache;
-    }
-
-    /* Non-leaf pages contain direct offsets to other index pages.
-     * When data is added to index sequentially, the leaf offsets can be
-     * encoded in 2 bytes as increment to the offset on the beginning of the
-     * page, i.e. 2 gis can be encoded in the same 4-byte index array
-     * element.
-     */
-    if (level > 0 || !data_index->m_SequentialData) {
-        base = (int) gi_index[page];
-    } else if (remainder == 0 && (gi&1) == 0) {
-        if ((gi_index[page] & kTopBit) == kTopBit)
-            base = gi_index[page] & kFullOffsetMask;
-        else
-            base = -1;
-    } else {
-        Uint4 mask;
-        Uint4 base_offset;
-        
-        base_page = page - remainder;
-        if (remainder == 0 && (gi&1) == 1) {
-            base = (gi_index[base_page+1]>>24);
-            mask = kPageMask;
-        } else if (remainder == 1 && (gi&1) == 0) {
-            base = ((gi_index[page]>>16) & kPageMask);
-            mask = kPageMask;
-        } else if ((gi&1) == 0) {
-            base = (gi_index[page]>>16);
-            mask = kLocalOffsetMask;
-        } else { /* (gi&1) == 1 */
-            base = (gi_index[page]&kLocalOffsetMask);
-            mask = kLocalOffsetMask;
-        }
-        
-        if (base == 0) {
-            base = -1;
-        } else {
-            base_offset = (gi_index[base_page] == kFullOffsetMask ? 0 :
-                           gi_index[base_page]);
-            if ((Uint4)base == mask)
-                base = (Uint4) base_offset & kFullOffsetMask;
-            else
-                base += (Uint4) base_offset & kFullOffsetMask;
-        }
-    }
-
-    return base;
-}
-
-static int
-x_SetIndexOffset(SGiDataIndex* data_index, int gi, Uint4 page, int level,
-                 Uint4 offset)
-{
-    Uint4 base_page;
-    Uint4 remainder = page & kPageMask;
-    Uint4* gi_index = NULL;
-    Uint1 remap_done = 0;
-
-    if (page >= data_index->m_GiIndexLen + data_index->m_IndexCacheLen) {
-        /* Try remapping and check again */
-        data_index->m_NeedRemap = 1;
-        if (!x_ReMapIndex(data_index))
-            return -1;
-        
-        /* If page is still outside of the index range after remapping, it's an
-           error condition */
-        if (page >= data_index->m_GiIndexLen + data_index->m_IndexCacheLen)
-            return -1;
-        remap_done = 1;
-    } else {
-        if (page < data_index->m_GiIndexLen) {
-            if (remap_done)
-                return -1;
-            data_index->m_NeedRemap = 1;
-            if (page >= data_index->m_MappedIndexLen && !x_ReMapIndex(data_index))
-                return -1;
-            gi_index = data_index->m_GiIndex;
-        } else {
-            page -= data_index->m_GiIndexLen;
-            gi_index = data_index->m_IndexCache;
-        }
+	rc = mdb_txn_commit(txn);
+	txn = NULL;
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to commit transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
+	
 
-        if (level > 0 || !data_index->m_SequentialData) {
-            gi_index[page] = offset;
-        } else if (remainder == 0 && (gi&1) == 0) {
-            /* For gi which starts the leaf page, set the top bit, in order to 
-               distinguish absent vs present starting gi. */
-            gi_index[page] = offset | kTopBit;
-        } else {
-            Uint4 base_offset;
-            Uint4 local_offset;
-
-            base_page = page - remainder;
-            base_offset = gi_index[base_page];
-
-            /* If base offset is not yet available, it must be set now.
-               NB: For 64-bit version, the base page offset is relative to the
-               base top-level page offset, hence it may be = 0. To distinguish 0
-               value from "not-set", use a special mask value. In 32-bit version
-               this is never necessary.
-            */
-            if (base_offset == 0) {
-                base_offset = offset;
-                gi_index[base_page] = (offset > 0 ? offset : kFullOffsetMask);
-            } else {
-                // Get rid of the top bit if it's set (indicating availability
-                // of the first gi on the page).
-                base_offset &= kFullOffsetMask;
-                // Check for the special value indicating relative offset = 0.
-                if (base_offset == kFullOffsetMask)
-                    base_offset = 0;
-            }
-
-            local_offset = offset - base_offset;
-            /* If base offset was not previously set, use a special value for
-               the relative offset to distinguish a 0 offset from absence of 
-               data. */
-            if (local_offset == 0)
-               local_offset = kLocalOffsetMask;
-            if (remainder == 0 && (gi&1) == 1) {
-                gi_index[page+1] |= (local_offset<<24);
-            } else if (remainder == 1 && ((gi&1) == 0)) {
-                gi_index[page] |= ((local_offset&kPageMask)<<16);
-            } else if ((gi&1) == 0) {
-                gi_index[page] |= (local_offset<<16);
-            } else { /* (gi&1) == 1 */
-                gi_index[page] |= local_offset;
-            }
-        }
-    }
-    return 0;
-}
+    return data_index;
 
-static int x_GetGiData(SGiDataIndex* data_index, int gi, const char **buf)
-{
-    Uint4 page = 0;
-    int base = data_index->m_OffsetHeaderSize;
-    int shift = (data_index->m_SequentialData ? 1 : 0);
-    int level;
-	int err;
-    Uint1 is_64bit = (data_index->m_OffsetHeaderSize > 0);
-	*buf = NULL;
-
-    /* If some thread is currently remapping, the data is in an inconsistent
-       state, therefore return NULL. */
-
-	if ((err = MT_LOCK_Do(data_index->m_RemapLock, eMT_LockRead)) == 0) {
-		if (LogFunc) {
-			char logmsg[256];
-			sprintf(logmsg, "GI_CACHE: failed to aquire RD lock, err: %d\n", err);
+ERROR:
+	if (txn) {
+		mdb_txn_abort(txn);
+		txn = NULL;
+	}
+	GiDataIndex_Free(data_index);
+	data_index = NULL;
+	if (LogFunc)
+		LogFunc(logmsg);	
+	return NULL;
+}
+
+static int x_DataToGiData(int64_t gi, MDB_val *data, char *acc_buf, int acc_buf_len, int64_t* gi_len) {
+	char logmsg[256];
+	uint8_t flags = *(uint8_t*)data->mv_data;
+	int gi_len_bytes = flags & 0x7;
+	int gi_len_neg = flags & 0x8;
+	uint8_t acclen = *((uint8_t*)data->mv_data + gi_len_bytes + 1);
+	char* pacc = (char*)data->mv_data + gi_len_bytes + 2;
+	
+	if (acclen >= MAX_ACCESSION_LENGTH) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: accession length (%d) exceeded limit (%d) for gi: %" PRId64 "\n", acclen, MAX_ACCESSION_LENGTH, gi);
+		if (LogFunc)
 			LogFunc(logmsg);
-		}
-		return 0;
+		return 1;
 	}
 
-	if ((data_index->m_GiIndex == MAP_FAILED ||
-		 data_index->m_Data == MAP_FAILED)) {
-		data_index->m_NeedRemap = 1;
-		/* we can't remap while RD lock is aquired, so drop it first */
-		MT_LOCK_Do(data_index->m_RemapLock, eMT_Unlock);
-
-		if (!data_index->m_RemapOnRead || !GiDataIndex_ReMap(data_index, 0)) {
-			return 0;
+	if (gi_len) {
+		int64_t val = 0;
+		memcpy(&val, ((uint8_t*)data->mv_data + 1), gi_len_bytes);
+		if (gi_len_neg) {
+			if (val == 0)
+				val = -1;
+			else
+				val = -val;
 		}
-		/* re-aquire RD lock */
-		if ((err = MT_LOCK_Do(data_index->m_RemapLock, eMT_LockRead)) == 0) {
-			if (LogFunc) {
-				char logmsg[256];
-				sprintf(logmsg, "GI_CACHE: failed to aquire RD lock, err: %d\n", err);
+		*gi_len = val;
+	}
+	if (acc_buf) {
+		if (acc_buf_len <= acclen) {
+			snprintf(logmsg, sizeof(logmsg), "GI_CACHE: accession length buffer length (%d) is too small, actual accession length is %d for gi: %" PRId64 "\n", acc_buf_len, acclen, gi);
+			if (LogFunc)
 				LogFunc(logmsg);
-			}
-			return 0;
+			return 1;
 		}
-
+		memcpy(acc_buf, pacc, acclen);
+		acc_buf[acclen] = 0;
 	}
-	/* we've tried to remap and if still we have MAP_FAILED there, bailout */
-	if ((data_index->m_GiIndex == MAP_FAILED ||
-         data_index->m_Data == MAP_FAILED)) 
-	{
-		MT_LOCK_Do(data_index->m_RemapLock, eMT_Unlock);
-		return 0;
+	return 0;
+}
+
+static int x_GetGiData(SGiDataIndex* data_index, int64_t gi, char *acc_buf, int acc_buf_len, int64_t* gi_len) {
+	char logmsg[256];
+	int rc;
+	MDB_txn *txn = NULL;
+	MDB_val key;
+	MDB_val data = {0};
+	int64_t gi64;
+
+	logmsg[0] = 0;
+	if (gi_len)
+		*gi_len = 0;
+	if (acc_buf && acc_buf_len > 0)
+		acc_buf[0] = 0;
+
+	if (!data_index || !data_index->m_env) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: DB is not open\n");
+		goto ERROR;
 	}
 
-    assert((data_index->m_GiIndex != MAP_FAILED) && 
-           (data_index->m_Data != MAP_FAILED));
-
-    for (level = 3; level >= 0; --level) {
-
-        /* Get this gi's page number and find the starting offset for that page's 
-           information in the index file. */
-        page = (Uint4)base + ((gi>>(level*kPageSize+shift)) & kPageMask);
-
-        /* The page can never point beyond the length of the index. If that 
-         * happens, bail out.
-         * If we got to a page that has been written, but not yet mapped, 
-         * remapping must be done here.
-         */
-        base = x_GetIndexOffset(data_index, gi, page, level);
-        
-        /* 
-         * If base wasn't found, bail out, but set flag for remapping - maybe
-         * the data on disk has gone further...
-        */
-        if (base == -1) {
-            data_index->m_NeedRemap = 1;
-			MT_LOCK_Do(data_index->m_RemapLock, eMT_Unlock);
-			return 0;
-        }
-    }
-    
-    Int8 gi_offset = 0;
-
-    if (is_64bit) {
-        gi_offset = GET_TOP_PAGE_OFFSET(gi);
-        /* If top page offset is not set, it means no gis from this whole top page
-           have been saved in cache so far. */
-        if (gi_offset == 0) {
-			MT_LOCK_Do(data_index->m_RemapLock, eMT_Unlock);
-			return 0;
-		}
-    }
-    
-    gi_offset += base;
-
-    /* If offset points beyond the combined length of the mapped data and cache,
-       try to remap data. If that still doesn't help, bail out. */
-    if (gi_offset >= data_index->m_DataLen + data_index->m_DataCacheLen) {
-        data_index->m_NeedRemap = 1;
-        if (!data_index->m_RemapOnRead || !x_ReMapData(data_index) ||
-            gi_offset >= data_index->m_DataLen + data_index->m_DataCacheLen) 
-		{
-			MT_LOCK_Do(data_index->m_RemapLock, eMT_Unlock);
-            return 0;
-		}
-    }
-
-    /* If offset is beyond the mapped data, get the data from cache, otherwise
-       from the memory mapped location. */
-    if (gi_offset >= data_index->m_DataLen) {
-		*buf = data_index->m_DataCache + (gi_offset - data_index->m_DataLen);		
-        return 1;
-    } 
-	else {
-        /* If offset points to data that has been written to disk but not yet
-           mapped, remap now. */
-        if (gi_offset >= data_index->m_MappedDataLen) {
-            data_index->m_NeedRemap = 1;
-			MT_LOCK_Do(data_index->m_RemapLock, eMT_Unlock);
-            if (!data_index->m_RemapOnRead || !x_ReMapData(data_index))
-                return 0;
-
-			/* re-aquire RD lock */
-			if ((err = MT_LOCK_Do(data_index->m_RemapLock, eMT_LockRead)) == 0) {
-				if (LogFunc) {
-					char logmsg[256];
-					sprintf(logmsg, "GI_CACHE: failed to aquire RD lock, err: %d\n", err);
-					LogFunc(logmsg);
-				}
-				return 0;
-			}
-			/* still problem with offset? -> log it */
-			if (gi_offset >= data_index->m_MappedDataLen) {
-				MT_LOCK_Do(data_index->m_RemapLock, eMT_Unlock);
-				if (LogFunc) {
-					char logmsg[256];
-					sprintf(logmsg, "GI_CACHE: Possible corruption: gi_offset: %lld, gi: %d\n", gi_offset, gi);
-					LogFunc(logmsg);
-				}
-				return 0;
-			}
-        }
-		*buf = data_index->m_Data + gi_offset;
-		return 1;
-    }
-}
-
-/* Constructor */
-static SGiDataIndex*
-GiDataIndex_New(SGiDataIndex* data_index, int unit_size, const char* name,
-                Uint1 readonly, Uint1 sequential, Uint1 is_64bit)
-{
-    if (!data_index) {
-        data_index = (SGiDataIndex*) malloc(sizeof(SGiDataIndex));
-        memset( data_index, 0, sizeof(SGiDataIndex));
-        data_index->m_FreeOnDrop = 1;
-    } else {
-        data_index->m_FreeOnDrop = 0;
-    }
-
-    data_index->m_ReadOnlyMode = readonly;
-    assert(strlen(name) < 256);
-    strncpy(data_index->m_FileNamePrefix, name, 256);
-    data_index->m_DataUnitSize = unit_size;
-    data_index->m_SequentialData = sequential;
-    data_index->m_GiIndex = ((Uint4*)MAP_FAILED);
-    data_index->m_Data = ((char*)MAP_FAILED);
-    data_index->m_GiIndexFile = -1;
-    data_index->m_DataFile = -1;
-    data_index->m_GiIndexLen = 0;
-    data_index->m_DataLen = 0;
-    data_index->m_MappedDataLen = 0;
-    data_index->m_MappedIndexLen = 0;
-    data_index->m_IndexCacheLen = 0;
-    data_index->m_IndexCacheSize = INDEX_CACHE_SIZE;
-    data_index->m_IndexCache =
-        (Uint4*) malloc(data_index->m_IndexCacheSize*sizeof(Uint4));
-    data_index->m_DataCacheLen = 0;
-    data_index->m_DataCacheSize = unit_size*DATA_CACHE_SIZE;
-    data_index->m_DataCache = (char*) malloc(data_index->m_DataCacheSize);
-#ifdef NCBI_CXX_TOOLKIT
-    data_index->m_RemapLock = MT_LOCK_cxx2c(NULL, true);
-#else
-    data_index->m_RemapLock = MT_LOCK_c2c(0, 1);
-#endif
-    data_index->m_NeedRemap = 1;
-    data_index->m_RemapOnRead = 1;
-    data_index->m_OffsetHeaderSize = (is_64bit ? kOffsetHeaderSize : 0);
-    data_index->m_OldDataPtr = ((char*)MAP_FAILED);
-    data_index->m_OldMappedDataLen = 0;
-
-    return data_index;
-}
-
-/* Destructor */
-static SGiDataIndex* GiDataIndex_Free(SGiDataIndex* data_index)
-{
-    if (!data_index)
-        return NULL;
-
-    x_Flush(data_index);
-    x_UnMap(data_index);
-    x_CloseFiles(data_index);
-    free(data_index->m_IndexCache);
-    free(data_index->m_DataCache);
-	MT_LOCK_Delete(data_index->m_RemapLock);
-	memset(&data_index->m_RemapLock, 0, sizeof(data_index->m_RemapLock));
-    if (data_index->m_FreeOnDrop) {
-      free(data_index);
-      data_index=NULL;
-    }
-    return data_index;
-}
+	rc = mdb_txn_begin(data_index->m_env, NULL, MDB_RDONLY, &txn);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to start transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-/* Returns data corresponding to a given gi for reading only. */
-static const int GiDataIndex_GetData(SGiDataIndex* data_index, int gi, const char **buf)
-{
-    return x_GetGiData(data_index, gi, buf);
-}
+	gi64 = gi;
+	key.mv_size = sizeof(gi64);
+	key.mv_data = &gi64;
+	rc = mdb_get(txn, data_index->m_gi_dbi, &key, &data);
+	if (rc == MDB_NOTFOUND) // silent error
+		goto ERROR;
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to get data for gi=%" PRId64 ": %s\n", gi, mdb_strerror(rc));
+		goto ERROR;
+	}
 
-/* Writes data for a gi. */
-static Uint1
-GiDataIndex_PutData(SGiDataIndex* data_index, int gi, const char* data,
-                    Uint1 overwrite, Uint4 data_size)
-{
-    Uint4 page = 0;  
-    Int8 base = (Int8) data_index->m_OffsetHeaderSize;
-    Int8 top_page_offset = 0;
-    int shift = (data_index->m_SequentialData ? 1 : 0);
-    int level;
-    Uint1 is_64bit = (data_index->m_OffsetHeaderSize > 0);
-
-    /* No writing can occur in read-only mode. */
-    if (data_index->m_ReadOnlyMode)
-        return 0;
-
-    /* Check if index and data memory maps are open. */
-    if (data_index->m_GiIndex == MAP_FAILED && !x_MapIndex(data_index))
-        return 0;
-
-    if (data_index->m_Data == MAP_FAILED && !x_MapData(data_index))
-        return 0;
-
-    if ((data_index->m_GiIndexLen + (1<<kPageSize))*sizeof(Uint4) >= kFullOffsetMask)
-        return 0; /* can not map this amount of data anyway */
-    
-    /* For 32-bit version check the data file length too, and return error if
-       that file has reached maximal size. */
-    if (!is_64bit &&  
-        data_index->m_DataLen + sizeof(Uint4)*(1<<kPageSize) >= kFullOffsetMask)
-        return 0;
-
-    for (level = 3; level >= 0; --level) {
-        if (base < 0)
-            return 0;
-
-        page = (Uint4)base + ((gi>>(level*kPageSize+shift)) & kPageMask);
-
-        /* Find next level page offset for this gi. On the leaf level,
-         * if offset is not found, base will be set to -1, to distinguish from a
-         * 0 relative offset.
-         * NB: in particular, page can never point beyond the length of the
-         * index. If that happens, set next base to -1, so new page could be
-         * allocated for this data.
-         * NB2: If we got to a page that has been written, but not yet mapped, 
-         * remapping must be done here. If remapping fails, the error is
-         * unrecoverable within the current process.
-         */
-        base = x_GetIndexOffset(data_index, gi, page, level);
-
-        /* If there are no gis from the same page in the index yet, assign a new
-           page in the index for this gi's page. */
-        if (level > 0 && base == 0) {
-            const Uint4 kPageBitSize = 1<<kPageSize;
-            Uint4* b = (Uint4*) calloc(kPageBitSize, sizeof(Uint4));
-
-            /* Assign pointer to the new page. */
-            base = (int) (data_index->m_GiIndexLen + data_index->m_IndexCacheLen);
-
-            x_SetIndexOffset(data_index, gi, page, level, base);
-
-            /* Add the new page. */
-            if ((data_index->m_IndexCacheLen + kPageBitSize) >
-                data_index->m_IndexCacheSize) {
-                x_DumpIndexCache(data_index);
-            }
-            assert(data_index->m_GiIndexLen*sizeof(Uint4) == 
-                    lseek(data_index->m_GiIndexFile, 0, SEEK_END));
-            memcpy((void*)(&data_index->m_IndexCache[data_index->m_IndexCacheLen]),
-                   b, kPageBitSize*sizeof(Uint4));
-            data_index->m_IndexCacheLen += kPageBitSize;
-            free(b);
-        }
-    }
+	rc = x_DataToGiData(gi64, &data, acc_buf, acc_buf_len, gi_len);
+	if (rc)
+		goto ERROR;
 
-    if (data_size== 0)
-        data_size = data_index->m_DataUnitSize;
-
-    if (is_64bit)
-        top_page_offset = GET_TOP_PAGE_OFFSET(gi);
-
-    /* Check if data is already present. If it is, and overwrite is not 
-     * requested, just return, otherwise write new data in place of the old one.
-     * If previous data for this gi is not available, write the new data at the
-     * end of the data file.
-     */
-    if (base >= 0 && (!is_64bit || top_page_offset > 0)) {
-        if (!overwrite)
-            return 0;
-        
-        base += top_page_offset;
-
-        if (base >= (Int8)data_index->m_DataLen) {
-            /* The previous data for this gi is currently in cache. */
-            if (base + data_size <=
-                data_index->m_DataLen + data_index->m_DataCacheLen) {
-                memcpy(data_index->m_DataCache + base - data_index->m_DataLen,
-                       data, data_size);
-            } else {
-                /* The index got corrupted, and previous data cannot be found. */
-                base = 0;
-            }
-        } else {
-            /* If this base is in the part that has already been written to 
-               disk, but not yet mapped, remap now. */
-            if (base >= (int)data_index->m_MappedDataLen)
-                x_ReMapData(data_index);
-            memcpy(data_index->m_Data + base, data, data_size);
-        }
-    } else {
-        if (is_64bit && top_page_offset == 0) {
-            top_page_offset = data_index->m_DataLen + data_index->m_DataCacheLen;
-            SET_TOP_PAGE_OFFSET(gi, top_page_offset);
-        }
-        
-        x_SetIndexOffset(data_index, gi, page, 0,
-                         data_index->m_DataLen + data_index->m_DataCacheLen -
-                         top_page_offset);
-
-        /* This should already be valid, but in case of corruption, make sure
-         * that value data_index->m_DataLen reflects what is actually available
-         * on disk.
-         */
-        data_index->m_DataLen = (Int8) lseek(data_index->m_DataFile, 0, SEEK_END);
-        /* Check if there is space for current data in cache. If not, flush the 
-           cache. */
-        if (data_index->m_DataCacheLen + data_size >=
-            data_index->m_DataCacheSize)
-            x_DumpDataCache(data_index);
-    
-        assert(data_index->m_DataCacheLen + data_size <=
-               data_index->m_DataCacheSize);
-        /* Write the current data into cache. */
-        memcpy(data_index->m_DataCache + data_index->m_DataCacheLen, data,
-               data_size);
-        data_index->m_DataCacheLen += data_size;
-    }
+	rc = mdb_txn_commit(txn);
+	txn = NULL;
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to close transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-    return 1;
-}
+	return 1;
+ERROR:
+	if (txn) {
+		mdb_txn_abort(txn);
+		txn = NULL;
+	}
+	if (LogFunc && logmsg[0]) {
+		LogFunc(logmsg);
+	}
+	return 0;
+}
+
+static int64_t x_GetMaxGi(SGiDataIndex* data_index) {
+	char logmsg[256];
+	int rc;
+	MDB_txn *txn = NULL;
+	MDB_cursor *cur = NULL;
+	MDB_val key;
+	MDB_val data = {0};
+	int64_t gi64 = 0;
+
+	rc = mdb_txn_begin(data_index->m_env, NULL, MDB_RDONLY, &txn);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to start transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-#ifdef ALLOW_IN_PLACE_MODIFICATION
-/* Returns data corresponding to a given gi, for possible modification. */
-/* !WARNING: it's caller responsibility to unlock buffer by calling MT_LOCK_Do(data_index->m_RemapLock, eMT_Unlock); in case if returned value is NOT null */
-static char* GiDataIndex_SetData(SGiDataIndex* data_index, int gi)
-{
-	const char *buf = NULL;
-	int rv;
-    if (data_index->m_ReadOnlyMode)
-        return NULL;
+	rc = mdb_cursor_open(txn, data_index->m_gi_dbi, &cur);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to open cursor: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-	rv = x_GetGiData(data_index, gi, &buf);
-    return rv ? buf : NULL;
-}
+	key.mv_size = 0;
+	key.mv_data = NULL;
+	rc = mdb_cursor_get(cur, &key, &data, MDB_LAST);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to position cursor to last record: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-/* Deletes data for a gi. */
-static Uint1 GiDataIndex_DeleteData(SGiDataIndex* data_index, int gi)
-{
-    int page = 0; 
-    int base = 0;
-    int index;
-    
-    /* No writing can occur in read-only mode. */
-    if (data_index->m_ReadOnlyMode)
-        return 0;
+	if (!key.mv_data || key.mv_size != sizeof(gi64)) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: last record contains no valid gi\n");
+		goto ERROR;
+	}
+	gi64 = *(int64_t*)key.mv_data;
 
-    /* Check if index and data memory maps are open. */
-    if (data_index->m_GiIndex == MAP_FAILED && !x_MapIndex(data_index))
-        return 0;
+	mdb_cursor_close(cur);
+	cur = NULL;
 
-    if (data_index->m_Data == MAP_FAILED && !x_MapData(data_index))
-        return 0;
+	rc = mdb_txn_commit(txn);
+	txn = NULL;
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to close transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-    for (index = 3; index >= 0; --index) {
+    return gi64;
 
-        page = base + ((gi>>(index*kPageSize)) & kPageMask);
+ERROR:
+	if (cur) {
+		mdb_cursor_close(cur);
+		cur = NULL;
+	}
+	if (txn) {
+		mdb_txn_abort(txn);
+		txn = NULL;
+	}
+	if (LogFunc) {
+		LogFunc(logmsg);
+	}
+	return -1;
+}
+
+static int x_PutData(SGiDataIndex* data_index, int64_t gi, int64_t gi_len, const char *acc, int overwrite, int is_incremental) {
+	char logmsg[256];
+	int rc;
+	MDB_val key;
+	MDB_val data = {0};
+	int64_t gi64 = 0;
+	int acclen, datalen;
+	uint8_t *gidata = NULL;
+	int gi_len_bytes = 0;
+	int gi_len_neg;
+	uint8_t flags;
+
+	logmsg[0] = 0;
+	acclen = strlen(acc);
+	if (acclen > MAX_ACCESSION_LENGTH) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to put, provided accession is too long: %d (max supported length is %d)\n", acclen, MAX_ACCESSION_LENGTH);
+		goto ERROR;
+	}
 
-        /* The page can never point beyond the length of the index. If that 
-         * happens, bail out.
-         * If we got to a page that has been written, but not yet mapped, 
-         * remapping must be done here.
-         */
-        if (page >= (int)data_index->m_GiIndexLen) {
-            return 0;
-        } else if (page < (int)data_index->m_GiIndexLen) {
-            if (page >= (int)data_index->m_MappedIndexLen) {
-                if (!x_ReMapIndex(data_index))
-                    return 0;
-            }
-            base = data_index->m_GiIndex[page + data_index->m_OffsetHeaderSize];
-        } else {
-            base = (int) data_index->m_IndexCache[page-data_index->m_GiIndexLen];
-        }
+	if (is_incremental) {
+		char lacc[MAX_ACCESSION_LENGTH + 1];
+		int64_t lgi_len = 0;
+		rc = x_GetGiData(data_index, gi, lacc, sizeof(lacc), &lgi_len);
+		if (rc == 1) {
+			int changed_acc = 0;
+			int changed_len = 0;
+			changed_acc = strcmp(lacc, acc) != 0;
+			changed_len = lgi_len != gi_len;
+			if (!changed_acc && !changed_len)
+				return RC_ALREADY_EXISTS;
+			if (changed_acc)
+				snprintf(logmsg, sizeof(logmsg), "GI_CACHE: gi %" PRId64 " changed accession from %s to %s\n", gi, lacc, acc);
+			if (changed_len)
+				snprintf(logmsg, sizeof(logmsg), "GI_CACHE: gi %" PRId64 " changed len from %" PRId64 " to %" PRId64 "\n", gi, lgi_len, gi_len);
+		}
+	}
 
-        /* If there are no gis from this page in the index, there is nothing to
-           delete. Return success. */
-        if (base == 0)
-            return 1;
-    }
-     
-    /* Check if data is already present. If it is not, there is nothing to 
-       delete. */
-    if (base) {
-        if (page < (int)data_index->m_GiIndexLen)
-            data_index->m_GiIndex[page] = 0;
-        else
-            data_index->m_IndexCache[page-data_index->m_GiIndexLen] = 0;
-
-        if (base >= (int)data_index->m_DataLen) {
-            /* The previous data for this gi is currently in cache. */
-            assert(base + data_index->m_DataUnitSize <=
-                   data_index->m_DataLen + data_index->m_DataCacheLen);
-            memset(data_index->m_DataCache + base - data_index->m_DataLen, 0,
-                   data_index->m_DataUnitSize);
-        } else {
-            /* If this base is in the part that has already been written to 
-               disk, but not yet remapped, remap now. */
-            if (base >= (int)data_index->m_MappedDataLen) {
-                data_index->m_NeedRemap = 1;
-                if (!GiDataIndex_ReMap(data_index, 0))
-                    return 0;
-            }
-            memset(data_index->m_Data + base, 0, data_index->m_DataUnitSize);
-        }
-    }
-    return 1;
-}
+	if (!data_index->m_txn) {
+		rc = mdb_txn_begin(data_index->m_env, NULL, 0, &data_index->m_txn);
+		if (rc) {
+			data_index->m_txn = NULL;
+			snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to start transaction: %s\n", mdb_strerror(rc));
+			goto ERROR;
+		}
+	}
 
-/* Returns pointer to the start of data in the data file. Needed when
- * the whole data file needs to be read sequentially.
- * NB: This may involve remapping, hence no 'const' qualifier
- * for the object!
- */
-static void
-GiDataIndex_GetAllData(SGiDataIndex* data_index, const char* *data_ptr,
-                       Uint4* data_size)
-{
-    if (!data_ptr)
-        return;
-    
-    *data_ptr = NULL;
-    *data_size = 0;
-        
-    if (data_index->m_Data == MAP_FAILED) {
-        if (!x_MapData(data_index))
-            return;
-    } else if (data_index->m_DataCacheLen > 0) {
-        if (!x_ReMapData(data_index))
-            return;
-    }
+	gi64 = gi;	
+	key.mv_size = sizeof(gi64);
+	key.mv_data = &gi64;
+	gi_len_neg = gi_len < 0;
+	if (gi_len != 0 && gi_len != -1) {
+		if (gi_len_neg)
+			gi_len = -gi_len;
+		int64_t v = gi_len;
+		while (v != 0) {
+			gi_len_bytes++;
+			v >>= 8;
+		}
+	}
+	
+	flags = (gi_len_bytes & 0x7) | ((gi_len_neg ? 1 : 0) << 3);
+
+	datalen =	1 + 			// flags
+				gi_len_bytes +	// gi_len
+				1 +				// acclen
+				acclen;			// acc
+	gidata = (uint8_t*)malloc(datalen);
+	gidata[0] = flags;
+	memcpy(gidata + 1, &gi_len, gi_len_bytes);
+	gidata[1 + gi_len_bytes] = acclen;
+	memcpy(gidata + 1 + gi_len_bytes + 1, acc, acclen);
+	data.mv_size = datalen;
+	data.mv_data = gidata;
+	rc = mdb_put(data_index->m_txn, data_index->m_gi_dbi, &key, &data, overwrite ? 0 : MDB_NOOVERWRITE);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to start transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-    /* The first 2*sizeof(int) bytes are filled with 0's for convenience, the
-       actual data starts immediately after. */
-    *data_ptr = data_index->m_Data + 2*sizeof(int);
-    *data_size = data_index->m_DataLen + data_index->m_DataCacheLen - 2*sizeof(int);
-}
+	if (data_index->m_txn_rowcount++ > MAX_ROWS_PER_TRANSACTION) {
+		int rv = x_Commit(gi_cache);
+		if (rv != 0)
+			goto ERROR;
+	}
+	free(gidata);
+	return 1;
 
-static int GiDataIndex_GetMappedSize(SGiDataIndex* data_index)
-{
-    return data_index->m_MappedDataLen + data_index->m_MappedIndexLen;
+ERROR:
+	if (gidata) {
+		free(gidata);
+		gidata = NULL;
+	}
+	if (data_index->m_txn) {
+		mdb_txn_abort(data_index->m_txn);
+		data_index->m_txn = NULL;
+	}
+	if (LogFunc && logmsg[0]) {
+		LogFunc(logmsg);
+	}
+	return 0;
 }
-#endif
 
-static int GiDataIndex_GetMaxGi(SGiDataIndex* data_index)
-{
-    int base = data_index->m_OffsetHeaderSize;
-    int page = 0;
-    int gi = 0;
-    int index;
-    int shift = (data_index->m_SequentialData ? 1 : 0);
-    int remainder = 0;
-    Uint4* gi_index;
+static int x_GICacheInit(const char* prefix, Uint1 readonly, Uint1 enablesync) {
+    char prefix_str[PATH_MAX];
 
-    x_Flush(data_index);
-
-    if (data_index->m_GiIndex == MAP_FAILED && !x_MapIndex(data_index))
-        return -1;
+    // First try local files
+    snprintf(prefix_str, sizeof(prefix_str), "%s", (prefix ? prefix : DEFAULT_GI_CACHE_PREFIX));
 
-    gi_index = data_index->m_GiIndex;
+    /* When reading data, use readonly mode. */
+    if (gi_cache) {
+		GiDataIndex_Free(gi_cache);
+		gi_cache = NULL;
+	}
+    gi_cache = GiDataIndex_New(prefix_str, readonly, !readonly && enablesync);
 
-    for (index = 3; index >=0; --index) {
-        /* Find largest page present in the gi index.
-         * Check if referenced page points beyond index size. If invalid page is
-         * found, fix the index by resetting it to 0 (unless it's a read-only
-         * mode).
+    if (readonly) {
+        /* Check whether gi cache is available at this location, by trying to
+         * map it right away. If local cache isn't found, use default path and
+         * try again.
+         * NB: This is only done if nothing was provided in the input argument.
          */
-        for (page = base + kPageMask; page >= 0; --page) {
-            if (gi_index[page] == 0)
-                continue;
-            if (index > 0 && gi_index[page] >= data_index->m_GiIndexLen) {
-                if (!data_index->m_ReadOnlyMode)
-                    gi_index[page] = 0;
-                continue;
-            } else {
-                break;
-            }
-        }
-        if(page<0)
-          return -1;
-        if (gi_index[page] != 0) {
-            remainder = page - base;
-            gi |= (remainder<<(index*kPageSize+shift));
-            base = (int) gi_index[page];
-        }
-    }
+        Uint1 cache_found = gi_cache != NULL;
 
-    if (data_index->m_SequentialData) {
-        /* Because of the 2-gi per page slot encoding of data offsets, check
-           which exact gi is the maximal. */
-        int max_gi;
-        int min_gi;
-        if (remainder == 0) {
-            return gi;
-        } else if (remainder > 1) {
-            max_gi = gi + 1;
-            min_gi = gi;
-        } else {
-            max_gi = gi + 1;
-            min_gi = gi - 1;
-        }
-
-        for (gi = max_gi; gi >= min_gi; --gi) {
-            if (x_GetIndexOffset(data_index, gi, page, 0) > 0)
-                break;
+        if (!cache_found && !prefix) {
+            snprintf(prefix_str, sizeof(prefix_str), "%s/%s.", DEFAULT_GI_CACHE_PATH, DEFAULT_GI_CACHE_PREFIX);            
+            gi_cache = GiDataIndex_New(prefix_str, readonly, 0);
         }
     }
 
-    return gi;
+    return (gi_cache ? 0 : 1);    
 }
 
-/* When encoding in 4 bytes, top bit serves as control */
-static INLINE int s_EncodeInt4(char* buf, Uint4 val)
-{
-    int bytes = (val > 0x7fff ? 4 : 2);
-    char* ptr = buf;
-    int i;
-    for (i = bytes - 1; i >= 0; --i, ++ptr) {
-        *ptr = ((val>>(8*i)) & 0xff);
-    }
-
-    if (bytes == 4)
-        buf[0] |= 0x80;
-
-    return bytes;
+int GICache_ReadData(const char *prefix) {
+    int rc;
+    rc = x_GICacheInit(prefix, 1, 0);
+    return rc;
 }
 
-static INLINE int s_EncodeInt2(char* buf, Uint2 val)
-{
-    if (val <= 0x7f) {
-        *buf = (char) (val & 0x7f);
-        return 1;
-    } else {
-        *buf = 0x80 | (((val)>>8) & 0x7f);
-        *(buf+1) = (val) & 0xff;
-        return 2;
-    }
+int GICache_GetAccession(int64_t gi, char* acc, int buf_len) {
+	int retval = 0;
+	int rv;
+	if (acc && buf_len > 0)
+		acc[0] = NULLB;
+	if (!gi_cache) {
+		if (LogFunc)
+			LogFunc("GICache_GetAccession: GI Cache is not initialized, call GICache_ReadData() first");
+		return 0;
+	}
+	rv = x_GetGiData(gi_cache, gi, acc, buf_len, NULL);
+	if (rv)
+		retval = 1;
+	return retval;
 }
 
-static INLINE int s_DecodeInt4(const char* buf, int* val)
-{
-    if ((buf[0] & 0x80) != 0) {
-        *val = ((buf[0]&0x7f)<<24) | ((buf[1]&0xff)<<16) |
-               ((buf[2]&0xff)<<8)  | (buf[3]&0xff);
-        return 4;
-    } else {
-        *val = ((buf[0]&0x7f)<<8) | (buf[1]&0xff);
-        return 2;
-    }
-}
+int64_t GICache_GetLength(int64_t gi) {
+	int rv;
+	int64_t gi_len = 0;
+    if(!gi_cache) 
+		return 0;
+    rv = x_GetGiData(gi_cache, gi, NULL, 0, &gi_len);
 
-static INLINE int s_DecodeInt2(const char* buf, int* val)
-{
-    if ((buf[0] & 0x80) != 0) {
-        *val = ((buf[0]&0x7f)<<8) | (buf[1]&0xff);
-        return 2;
-    } else {
-        *val = buf[0] & 0x7f;
-        return 1;
-    }
-}
+    if(!rv) 
+		return 0;
 
-static INLINE
-int s_Encode3Plus5Accession(char* buf, const char* accession, int suffix,
-                            char* *buf_ptr)
-{
-    if (!(accession[0] >= 'A' && accession[0] <= 'Z' &&
-           accession[1] >= 'A' && accession[1] <= 'Z' &&
-           accession[2] >= 'A' && accession[2] <= 'Z' &&
-          ((suffix>>17) == 0))) {
-        return 0;
-    }
-    /* 1st prefix character + top 3 bits of 2nd prefix character */
-    buf[0] = ((accession[0] - 'A' + 1)<<3) | ((accession[1] - 'A' + 1)>>2);
-    /* bottom 2 bits of 2nd prefix character + 3rd prefix character + top 1 bit
-       of integer suffix */
-    buf[1] = ((accession[1] - 'A' + 1)<<6) | ((accession[2] - 'A' + 1)<<1) |
-        ((suffix>>16) & 0xff);
-    /* Bits 8-15 of integer suffix */
-    buf[2] = (suffix>>8) & 0xff;
-    /* Bits 0-7 of integer suffix */
-    buf[3] = (suffix & 0xff); 
-
-    *buf_ptr += 4;
-
-    return 1;
+    return gi_len;
 }
 
-static INLINE
-int s_Decode3Plus5Accession(const char* buf, char* prefix, 
-                             int* prefix_length, int* suffix)
-{
-    if ((prefix[0] = ((buf[0]&0xff)>>3) + 'A' - 1) > 'Z')
-        return -1;
-    if ((prefix[1] = (((buf[0]&0x07)<<2) | ((buf[1]&0xff)>>6)) + 'A' - 1) > 'Z')
-        return -1;
-    if ((prefix[2] = (((buf[1]&0xff)>>1) & 0x1f) + 'A' - 1) > 'Z')
-        return -1;
-    *prefix_length = 3;
-    *suffix = ((int)(buf[1] & 0x01)<<16) | (((int)(buf[2]&0xff)<<8) & 0xff00) |
-               ((int)(buf[3] & 0xff));
-    if (*suffix >= 100000)
-        return -1;
-
-    return 1;
+int64_t GICache_GetMaxGi(void) {
+    if(!gi_cache) return 0;
+    return x_GetMaxGi(gi_cache);
 }
 
-static INLINE
-int s_Encode2LetterAccession(char* buf, const char* accession, int suffix,
-                             int prefix_length, char* *buf_ptr)
-{
-    if (accession[0] < 'A' || accession[0] > 'Z')
-        return 0;
-
-    /* 1st prefix character */
-    buf[0] = (accession[0] - 'A' + 1)<<3;
-    if (prefix_length == 2) {
-        /* top 3 bits of 2nd prefix character */
-        buf[0] |= (accession[1] - 'A' + 1)>>2;
-        /* bottom 2 bits of 2nd prefix character */
-        buf[1] = ((accession[1] - 'A' + 1)<<6);
-    } else {
-        buf[1] = 0;
-    }
-    /* If integer suffix fits into 22 bits, we need only 2 extra bytes, otherwise
-       use 3 extra bytes. */
-    if (suffix>>22 != 0) {
-        /* Bits 24-28 of the integer suffix (currently always 0) */
-        buf[1] |= ((suffix>>24) & 0x1f);
-        /* Bits 16-23 of the integer suffix */
-        buf[2] = (suffix>>16) & 0xff;
-        /* Bits 8-15 of the integer suffix */
-        buf[3] = (suffix>>8) & 0xff;
-        /* Bits 0-7 of the integer suffix */
-        buf[4] = (suffix & 0xff);
-        *buf_ptr += 5;
-    } else {
-        /* Bits 16-21 of the integer suffix (and control bit = 0) */
-        buf[1] |= ((suffix>>16) & 0x3f);
-        /* Bits 8-15 of the integer suffix */
-        buf[2] = (suffix>>8) & 0xff;
-        /* Bits 0-7 of the integer suffix */
-        buf[3] = (suffix & 0xff);
-        *buf_ptr += 4;
-    }
-
-    return 1;
+int GICache_LoadStart(const char* cache_prefix, int enablesync) {
+    int rc;
+    rc = x_GICacheInit(cache_prefix, 0, enablesync);
+    return rc;
 }
 
-static INLINE
-int s_Decode2LetterAccession(const char* buf, Uint1 control_byte, char* prefix,
-                             int* prefix_length, int* suffix)
-{
-    Uint1 is_refseq = ((control_byte & (1<<5)) != 0);
-    Uint1 large_suffix = ((control_byte & (1<<6)) != 0);
-    Uint1 byte;
-
-    if ((prefix[0] = ((buf[0]&0xff)>>3) + 'A' - 1) > 'Z')
-        return -1;
-
-    byte = ((buf[0]&0x07)<<2) | ((buf[1]&0xff)>>6);
-    if (byte == 0) {
-        *prefix_length = 1;
-    } else {
-        if ((prefix[1] = byte + 'A' - 1) > 'Z')
-            return -1;
-        if (is_refseq) {
-            prefix[2] = '_';
-            *prefix_length = 3;
-        } else {
-            *prefix_length = 2;
-        } 
-    }
-
-    if (large_suffix) {
-        *suffix = (((int)(buf[1] & 0x1f)<<24) | (((int)(buf[2]) & 0xff)<<16) |
-                  ((int)(buf[3] & 0xff)<<8) | ((int)(buf[4] & 0xff)));
-    } else {
-        *suffix = (((int)(buf[1] & 0x3f)<<16) | (((int)(buf[2]) & 0xff)<<8) |
-                  ((int)(buf[3] & 0xff)));
-    }
-    return 1;
+void GICache_ReadEnd() {
+	if (gi_cache) {
+		GiDataIndex_Free(gi_cache);
+		gi_cache = NULL;
+	}
 }
 
-static INLINE
-int s_Encode4Plus9Accession(char* buf, const char* accession, int suffix,
-                            char* *buf_ptr)
-{
-    if (!(accession[0] >= 'A' && accession[0] <= 'Z' &&
-           accession[1] >= 'A' && accession[1] <= 'Z' &&
-           accession[2] >= 'A' && accession[2] <= 'Z' &&
-           accession[3] >= 'A' && accession[3] <= '_' &&
-          ((suffix>>27) == 0)))
-        return 0;
-    
-    /* 1st prefix character + top 3 bits of 2nd prefix character */
-    buf[0] = ((accession[0] - 'A' + 1)<<3) | ((accession[1] - 'A' + 1)>>2);
-    /* bottom 2 bits of 2nd prefix character + 3rd prefix character + top 1 bit
-       of 4th prefix character */
-    buf[1] = ((accession[1] - 'A' + 1)<<6) | ((accession[2] - 'A' + 1)<<1) | 
-        ((accession[3] - 'A' + 1)>>4);
-    /* Bottom 4 bits of 4th prefix character + bits 24-27 of integer suffix */
-    buf[2] = ((accession[3] - 'A' + 1)<<4) | ((suffix>>24) & 0x0f); 
-    /* Bits 16-23 of the integer suffix */
-    buf[3] = (suffix>>16) & 0xff;
-    /* Bits 8-15 of the integer suffix */
-    buf[4] = (suffix>>8) & 0xff;
-    /* Bits 0-7 of the integer suffix */
-    buf[5] = (suffix & 0xff);
-
-    *buf_ptr += 6;
-
-    return 1;
-}
+int GICache_LoadAdd(int64_t gi, int64_t gi_len, const char* acc, int version, int is_incremental) {
+    int acc_len;
 
-static INLINE
-int s_Decode4Plus9Accession(const char* buf, Uint1 control_byte, char* prefix,
-                            int* prefix_length, int* suffix)
-{
-    int pos = 0;
-    if ((control_byte & (1<<5)) != 0) {
-        /* NZ_-type Refseq */
-        sprintf(prefix, "NZ_");
-        pos = 3;
-    }
+    static char accbuf[MAX_ACCESSION_LENGTH];
+    if(!gi_cache) return 0;
 
-    if ((prefix[pos] = ((buf[0]&0xff)>>3) + 'A' - 1) > 'Z')
-        return -1; 
-    if ((prefix[pos+1] = (((buf[0]&0x07)<<2) | ((buf[1]&0xff)>>6)) + 'A' - 1) > 'Z')
-        return -1;
-    if ((prefix[pos+2] = (((buf[1]&0xff)>>1) & 0x1f) + 'A' - 1) > 'Z')
-        return -1;
-    if ((prefix[pos+3] = (((buf[1]&0x01)<<4) | ((buf[2]&0xff)>>4)) + 'A' - 1) > 'Z')
-        return -1;
-    *prefix_length = pos + 4;
-    *suffix = ((int)(buf[2]&0x0f)<<24) | ((int)(buf[3] & 0xff)<<16) | 
-        ((int)(buf[4]&0xff)<<8) | ((int)(buf[5]&0xff));
-
-    return 1;
+	if (version > 0)
+		snprintf(accbuf, sizeof(accbuf), "%s.%d", acc, version);
+	else 
+		snprintf(accbuf, sizeof(accbuf), "%s", acc);
+    
+    return x_PutData(gi_cache, gi, gi_len, accbuf, 1, is_incremental);
 }
 
-static int
-s_EncodeGiData(const char* accession, int version, int seq_length,
-               char* outbuf, int* encoded_length)
-{
-    int acc_length = strlen(accession);
-    Uint1 suffix_length = 0;
-    /* Control byte structure:
-     * Bits 0-2: Length of the integer suffix: 
-     *           0 means no suffix, like for PDB, otherwise (length-2), because
-     *           suffixes with length <= 2 are not worth encoding!
-     * Bit    3: Is version byte present in the encoding?
-     * NB: No version byte for version = 1; version byte = 0 if no version 
-     * Bits 4-7: Various special cases
-     * 1...: 2+N type accession 
-     * 11..: Refseq (i.e. AB_ prefix)
-     * 1.1.: integer suffix fits into 22 bits
-     * NB: only combinations 1000, 1100 and 1110 are possible, but not 1010!
-     * Compressed in 4-5 bytes:
-     *     Byte 1, Byte 2, bits 0-1: prefix compressed 5 bits per letter
-     *     If only 1 letter, second is 00000.
-     *     If suffix fits in 22 bits, then 
-     *        Byte 2, bits 2-7, Bytes 3,4: 22-bit integer suffix
-     *     else
-     *        Byte 2, bits 2-7, Bytes 3-5: 30-bit integer suffix
-     * 0100: 3+5 type accession (ABC12345)
-     * Compressed in 4 bytes:
-     *     15 top bits for the prefix;
-     *     17 bottom bits for the integer suffix.
-     * 0010: 4+[8|9] accession (ABCD0[0-2]1234567)
-     * Compressed in 6 bytes:
-     *     Byte 1, bit 0: is there an NZ_ pre-prefix?
-     *     Byte 1, bit 1 - Byte 3, bit 4: 4 letters encoded 5 bits per letter
-     *     Byte 3, bit 5-7, Bytes 4-6: integer suffix.
-     *     This gives a total of 27 bits for the integer suffix, more than enough
-     *     for any combination of 8 digits (i.e. 1st of 9 digits must be 0!).
-     * The above covers all cases with integer suffix length > 2. In all other
-     * cases there is no compression - just plain accession with no suffix and an
-     * extra null byte.
-     *
-     * Is accession prefix encoded in compressed form in 2 bytes? 
-     * NB: This means that prefix consists of <=3 capital letters or a 2 capital
-     * letters + '_'. Then top bit of Byte 1 is set when '_' is present, and
-     * remaining 15 bits encode prefix 5 bits per letter (char_val - 'A' + 1).
-     * If < 3 letters, the bits corresponding to missing letters are 00000;
-     */
-    int suffix = 0;
-    char* buf_ptr;
-    int acc_pos;
-    Uint1 no_encoding = 0;
-
-    outbuf[0] = 0;
-
-    buf_ptr = &outbuf[1];
-
-    buf_ptr += s_EncodeInt4(buf_ptr, seq_length);
-
-    if (version != 1) {
-        outbuf[0] |= (1<<3);
-        buf_ptr += s_EncodeInt2(buf_ptr, version);
-    }
-
-    acc_pos = acc_length - 1;
-
-    for ( ; acc_pos >= 0; --acc_pos) {
-        if (isdigit(accession[acc_pos]))
-            ++suffix_length;
-        else
-            break;
-    }
-
-    ++acc_pos;
-
-    /* Only encode suffix as integer if it is > 2 bytes long.
-     * NB: if suffix length is <= 4, it is certain that integer suffix will fit
-     * in 2 bytes, so it's still worth encoding!
-     */
-    if (suffix_length > 3) {
-        Uint1 is_refseq = (acc_pos >= 3 && accession[2] == '_');
-        suffix = atol(&accession[acc_pos]);
-        if (acc_pos == 2 || (is_refseq && acc_pos == 3)) {
-            outbuf[0] |= (1<<4);
-            if (is_refseq) {
-                outbuf[0] |= (1<<5);
-                --acc_pos;
-            }
-            if (suffix>>22 != 0)
-                outbuf[0] |= (1<<6);
-            if (!s_Encode2LetterAccession(buf_ptr, accession, suffix, acc_pos, &buf_ptr))
-                return 0;
-        } else if (suffix_length == 5 && acc_pos == 3) {
-            outbuf[0] |= (1<<5);
-            if (!s_Encode3Plus5Accession(buf_ptr, accession, suffix, &buf_ptr))
-                return 0;
-        } else if (suffix_length >= 8 && acc_pos >= 4) {
-            const char* acc_ptr = accession;
-            outbuf[0] |= (1<<6);
-            if (is_refseq) {
-                outbuf[0] |= (1<<5);
-                acc_ptr += 3;
-            }
-            if (!s_Encode4Plus9Accession(buf_ptr, acc_ptr, suffix, &buf_ptr))
-                return 0;
-        } else {
-            /* Non-standard case - no prefix compression, end prefix with null
-               byte. For suffix use 2 or 4 bytes depending on its value. */
-            if (acc_pos > 0) {
-                memcpy(buf_ptr, accession, acc_pos);
-                buf_ptr += acc_pos;
-            }
-            *buf_ptr = 0;
-            ++buf_ptr;
-            buf_ptr += s_EncodeInt4(buf_ptr, suffix);
-        }
-
-        suffix_length -= 2;
-    } else {
-        no_encoding = 1; 
-        suffix_length = 0;
-    }
-
-    outbuf[0] |= (suffix_length == 0 ? 0 : suffix_length);
-
-    if (no_encoding) {
-        /* Sanity check - the input buffer size is = MAX_ACCESSION_LENGTH, so we 
-           cannot save more than this size. */
-        int available_size = MAX_ACCESSION_LENGTH - 1 - (buf_ptr - outbuf);
-        if (acc_length > available_size) {
-            strncpy(buf_ptr, accession, available_size);
-            buf_ptr[available_size] = NULLB;
-            buf_ptr += available_size + 1;
-        } else {
-            strncpy(buf_ptr, accession, acc_length+1);
-            buf_ptr += acc_length + 1;
-        }
-    }
-
-    *encoded_length = buf_ptr - outbuf;
-
-    return 1;
+int GICache_LoadEnd() {
+	if (gi_cache) {
+		x_Commit(gi_cache);
+		GiDataIndex_Free(gi_cache);
+		gi_cache = NULL;
+	}
+    return 0;
 }
 
-static int
-s_DecodeGiAccession(const char* inbuf, char* acc, int acc_len)
-{
-    Uint1 control_byte = *inbuf;
-    Uint1 suffix_length = control_byte & 0x07;
-    int version = 1;
-    /* Use internal buffer to retrieve accession */
-    char acc_buf[MAX_ACCESSION_LENGTH];
-    int retval = 1;
-
-    const char* buf = inbuf + 1;
-
-    /* Skip the bytes containing sequence length */
-    if ((buf[0]) & 0x80) {
-        buf += 4;
-    } else {
-        buf += 2;
-    }
-
-    /* Retrieve version */
-    if (control_byte & (1<<3))
-        buf += s_DecodeInt2(buf, &version);
-
-    /* Retrieve integer accession suffix */
-    if (suffix_length > 0) {
-        int suffix = 0;
-        int prefix_length = 0;
-        if ((control_byte & (1<<4)) != 0) {
-            retval = s_Decode2LetterAccession(buf, control_byte, acc_buf,
-                                              &prefix_length, &suffix);
-        } else if ((control_byte & 0xf0) == (1<<5)) {
-            retval = s_Decode3Plus5Accession(buf, acc_buf, &prefix_length,
-                                             &suffix);
-        } else if ((control_byte & (1<<6)) != 0) {
-            retval = s_Decode4Plus9Accession(buf, control_byte, acc_buf,
-                                             &prefix_length, &suffix);
-        } else {
-            int version_len = 0;
-            if (version > 0) {
-                char version_buf[6];
-                sprintf(version_buf, "%d", version);
-                version_len = strlen(version_buf) + 1; /* including '.' */
-            }
-            if ((prefix_length = strlen(buf)) <=
-                MAX_ACCESSION_LENGTH - suffix_length - version_len - 1) {
-                strncpy(acc_buf, buf, prefix_length);
-                buf += prefix_length + 1;
-                buf += s_DecodeInt4(buf, &suffix);
-            } else
-                retval = -1;
-        }
-
-        if (retval < 0)
-            return retval;
-        sprintf(acc_buf+prefix_length, "%.*d", suffix_length+2, suffix);
-    } else
-    {
-        /* sprintf(acc_buf, "%s", buf); */
-        strncpy( acc_buf, buf, MAX_ACCESSION_LENGTH  - 8);
-    }
-
-    if (version > 0)
-        sprintf(&acc_buf[strlen(acc_buf)], ".%d", version);
-
-    /* If retrieved accession fits into the client-supplied buffer, then just
-     * copy, otherwise copy the part that fits into the supplied buffer.
-     */
-    if (strlen(acc_buf) < acc_len) {
-        strcpy(acc, acc_buf);
-    } else {
-        strncpy(acc, acc_buf, acc_len - 1);
-        acc[acc_len-1] = NULLB;
-        retval = 0;
-    }
-    return retval;
+void GICache_SetLog(void (*logfunc)(char*)) {
+    LogFunc = logfunc;
 }
 
-/****************************************************************************
- *
- * gicache_lib.c 
- *
- ****************************************************************************/
-
-static SGiDataIndex *gi_cache=NULL;
+void GICache_Dump(const char* cache_prefix, const char* filename) {
+	FILE* f;
+	char logmsg[256];
+	int needopen;
+	int rc;
+	MDB_txn *txn = NULL;
+	MDB_cursor *cur = NULL;
+	MDB_val key;
+	MDB_val data = {0};
+
+	needopen = gi_cache == NULL;
+	if (needopen) {
+		rc = x_GICacheInit(cache_prefix, 1, 0);
+		if(!gi_cache) return;
+	}
+	f = fopen(filename, "w");
+	if (!f) {
+		snprintf(logmsg, sizeof(logmsg), "Failed to open file %s, error: %d", filename, errno);
+		goto ERROR;
+	}
+	setvbuf(f, NULL, _IOFBF, 128 * 1024);
 
-static int x_GICacheInit(const char* prefix, Uint1 readonly, Uint1 is_64bit)
-{
-    char prefix_str[256];
+	rc = mdb_txn_begin(gi_cache->m_env, NULL, MDB_RDONLY, &txn);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to start transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-    // First try local files
-    sprintf(prefix_str, "%s", (prefix ? prefix : DEFAULT_GI_CACHE_PREFIX));
+	rc = mdb_cursor_open(txn, gi_cache->m_gi_dbi, &cur);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to open cursor: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-    if (!prefix && is_64bit)
-       strcat(prefix_str, DEFAULT_64BIT_SUFFIX);
+	key.mv_size = 0;
+	key.mv_data = NULL;
+	while ((rc = mdb_cursor_get(cur, &key, &data, MDB_NEXT)) == MDB_SUCCESS) {
+		char acc_buf[MAX_ACCESSION_LENGTH];
+		int64_t gi_len = 0;
+		acc_buf[0] = 0;
+		int64_t gi64 = 0;
+
+		if (!key.mv_data || key.mv_size != sizeof(gi64)) {
+			snprintf(logmsg, sizeof(logmsg), "GI_CACHE: last record contains no valid gi\n");
+			if (LogFunc)
+				LogFunc(logmsg);
+			continue;
+		}
+		gi64 = *(int64_t*)key.mv_data;
+		if (x_DataToGiData(gi64, &data, acc_buf, sizeof(acc_buf), &gi_len) == 0) {
+			char line[512];
+			snprintf(line, sizeof(line), "%" PRId64 " %s %" PRId64 "\n", gi64, acc_buf, gi_len);
+			fputs(line, f);
+		}
+	}
 
-    strcat(prefix_str, ".");
+	mdb_cursor_close(cur);
+	cur = NULL;
 
-    /* When reading data, use readonly mode. */
-    if (gi_cache) return 0;
+	rc = mdb_txn_commit(txn);
+	txn = NULL;
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to close transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-    gi_cache = GiDataIndex_New(NULL, MAX_ACCESSION_LENGTH, prefix_str, readonly,
-                               1, is_64bit);
+	fclose(f);
+	if (needopen) {
+		GICache_ReadEnd();
+	}
+	return;
 
-    if (readonly) {
-        /* Check whether gi cache is available at this location, by trying to
-           map it right away. If local cache isn't found, use default path and
-           try again. */
-        Uint1 cache_found = GiDataIndex_ReMap(gi_cache, 0);
-
-        if (!cache_found) {
-            const char* suffix = (is_64bit ? DEFAULT_64BIT_SUFFIX : "");
-            sprintf(prefix_str, "%s/%s%s.", DEFAULT_GI_CACHE_PATH,
-                    DEFAULT_GI_CACHE_PREFIX, suffix);
-            gi_cache = GiDataIndex_Free(gi_cache);
-            gi_cache = GiDataIndex_New(NULL, MAX_ACCESSION_LENGTH, prefix_str,
-                                       readonly, 1, is_64bit);
-        }
-    }
+ERROR:
+	if (f) {
+		fclose(f);
+		f = NULL;
+	}
+	if (cur) {
+		mdb_cursor_close(cur);
+		cur = NULL;
+	}
+	if (txn) {
+		mdb_txn_abort(txn);
+		txn = NULL;
+	}
+	if (LogFunc) {
+		LogFunc(logmsg);
+	}
+	if (needopen) {
+		GICache_ReadEnd();
+	}
 
-    return (gi_cache ? 0 : 1);    
 }
 
-int GICache_ReadData(const char *prefix)
-{
-    Uint1 is_64bit = 0;
-    int rc;
+int GICache_DropDb() {
+	int rc;
+	char logmsg[256];
+	int transtarted = 0;
 
-    if (sizeof(void*) >= 8 &&
-        (!prefix || (strstr(prefix, DEFAULT_64BIT_SUFFIX) != NULL)))
-        is_64bit = 1;
+	if (!gi_cache || !gi_cache->m_env) {
+		snprintf(logmsg, sizeof(logmsg), "GICache_DropDb: failed to drop DB, database is not open");
+		goto ERROR;
+	}
+	if (gi_cache->m_ReadOnlyMode) {
+		snprintf(logmsg, sizeof(logmsg), "GICache_DropDb: failed to drop DB, database is open in readonly mode");
+		goto ERROR;
+	}
+	if (gi_cache->m_txn) {
+		snprintf(logmsg, sizeof(logmsg), "GICache_DropDb: failed to drop DB, database has an active transaction");
+		goto ERROR;
+	}
+	rc = mdb_txn_begin(gi_cache->m_env, NULL, 0, &gi_cache->m_txn);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to start transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
+	transtarted = 1;
+	rc = mdb_drop(gi_cache->m_txn, gi_cache->m_gi_dbi, 0);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GICache_DropDb: failed to drop DB: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
+	rc = mdb_drop(gi_cache->m_txn, gi_cache->m_meta_dbi, 0);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GICache_DropDb: failed to drop meta DB: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
+	rc = mdb_txn_commit(gi_cache->m_txn);
+	gi_cache->m_txn = NULL;
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to close transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
+	
+    return 0;
+ERROR:
+	if (LogFunc) {
+		LogFunc(logmsg);
+	}
+	if (gi_cache && gi_cache->m_txn && transtarted) {
+		mdb_txn_abort(gi_cache->m_txn);
+		gi_cache->m_txn = NULL;
+	}
+	return 1;
+}
 
-    rc = x_GICacheInit(prefix, 1, is_64bit);
+static int x_PutMeta(const char* Name, const char* Value) {
+	MDB_val key;
+	MDB_val data;
+	int rc;
 
-    return rc;
+	key.mv_data = (char*)Name;
+	key.mv_size = strlen(Name);
+	if (Value) {
+		data.mv_data = (char*)Value;
+		data.mv_size = strlen(Value);
+		rc = mdb_put(gi_cache->m_txn, gi_cache->m_meta_dbi, &key, &data, 0);
+	}
+	else {
+		rc = mdb_del(gi_cache->m_txn, gi_cache->m_meta_dbi, &key, NULL);
+		if (rc == MDB_NOTFOUND)
+			rc = 0;
+	}
+	if (rc) {
+		char logmsg[256];
+		snprintf(logmsg, sizeof(logmsg), "GICache_UpdateMeta: failed to update META: %s\n", mdb_strerror(rc));
+		if (LogFunc)
+			LogFunc(logmsg);
+	}
+	return rc;
 }
 
-void GICache_ReMap(int delay_in_sec) {
-    /* If this library function is being called, delayed remapping is
-       established, i.e. any future remapping is only done from here, but not on
-       read attempts. */
-    if(gi_cache) {
-      gi_cache->m_RemapOnRead = 0;
-      GiDataIndex_ReMap(gi_cache, delay_in_sec*1000);
-    }
-}
+int GICache_SetMeta(const char* Name, const char* Value) {
+	int rc;
+	char logmsg[256];
+	int transtarted = 0;	
+	char meta[512], stime[128];
 
-int GICache_GetAccession(int gi, char* acc, int acc_len)
-{
-    int retval = 0;
-	int rv;
-	const char* gi_data = NULL;
-    if(!gi_cache) return 0;
-    rv = GiDataIndex_GetData(gi_cache, gi, &gi_data);
-    if (rv) {
-        if ((retval = s_DecodeGiAccession(gi_data, acc, acc_len)) < 0) {
-            /* If returned "accession" is invalid, force a remap and return empty
-               string */
-            acc[0] = NULLB;
-            gi_cache->m_NeedRemap = 1;
-        }
-		MT_LOCK_Do(gi_cache->m_RemapLock, eMT_Unlock);
-    } else {
-        acc[0] = NULLB;
-    }
-    return retval;
+	logmsg[0] = 0;
+	if (!gi_cache || !gi_cache->m_env) {
+		snprintf(logmsg, sizeof(logmsg), "GICache_SetMeta: failed to update META, database is not open");
+		goto ERROR;
+	}
+	if (gi_cache->m_ReadOnlyMode) {
+		snprintf(logmsg, sizeof(logmsg), "GICache_SetMeta: failed to update META, database is open in readonly mode");
+		goto ERROR;
+	}
+	if (gi_cache->m_txn) {
+		snprintf(logmsg, sizeof(logmsg), "GICache_SetMeta: failed to update META, database has an active transaction");
+		goto ERROR;
+	}
+	rc = mdb_txn_begin(gi_cache->m_env, NULL, 0, &gi_cache->m_txn);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to start transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
+	rc = x_PutMeta(Name, Value);
+	if (rc)
+		goto ERROR;
+	rc = mdb_txn_commit(gi_cache->m_txn);
+	gi_cache->m_txn = NULL;
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to commit transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
+	
+    return 0;
+ERROR:
+	if (LogFunc && logmsg[0]) {
+		LogFunc(logmsg);
+	}
+	if (gi_cache && gi_cache->m_txn && transtarted) {
+		mdb_txn_abort(gi_cache->m_txn);
+		gi_cache->m_txn = NULL;
+	}
+	return 1;
+}
+
+int GICache_UpdateMeta(int is_incremental, const char* DB, time_t starttime) {
+	int rc;
+	char logmsg[256];
+	char meta[512], stime[128];
+
+	logmsg[0] = 0;
+	if (gethostname(meta, sizeof(meta)) != 0)
+		meta[0] = 0;
+	rc = GICache_SetMeta(is_incremental ? META_INCREMENTAL_HOST : META_FULL_HOST, meta);
+	if (rc)
+		goto ERROR;
+	rc = GICache_SetMeta(is_incremental ? META_INCREMENTAL_DB : META_FULL_DB, DB);
+	if (rc)
+		goto ERROR;	
+	snprintf(stime, sizeof(stime), "%" PRId64, (int64_t)starttime);
+	rc = GICache_SetMeta(is_incremental ? META_INCREMENTAL_TIME : META_FULL_TIME, stime);
+	if (rc)
+		goto ERROR;
+    return 0;
+ERROR:
+	if (LogFunc && logmsg[0]) {
+		LogFunc(logmsg);
+	}
+	return 1;
 }
 
-int GICache_GetLength(int gi)
-{
-	const char *x = NULL;
-    int length = 0;
-	int rv;
-    if(!gi_cache) return 0;
-    rv = GiDataIndex_GetData(gi_cache, gi, &x);
+int	GICache_GetMeta(const char* Name, char* Value, size_t ValueSz) {
+	char logmsg[256];
+	int rc;
+	MDB_txn *txn = NULL;
+	MDB_val key;
+	MDB_val data;
 
-    if(!rv) return 0;
+	Value[0] = 0;
+	logmsg[0] = 0;
+	if (!gi_cache || !gi_cache->m_env) {
+		snprintf(logmsg, sizeof(logmsg), "GICache_GetMeta: failed to read META, database is not open");
+		goto ERROR;
+	}
+	rc = mdb_txn_begin(gi_cache->m_env, NULL, MDB_RDONLY, &txn);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to start transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
+	key.mv_size = strlen(Name);
+	key.mv_data = (char*)Name;
+	data.mv_size = 0;
+	data.mv_data = 0;
+	rc = mdb_get(txn, gi_cache->m_meta_dbi, &key, &data);
+	if (rc == MDB_NOTFOUND) // silent error
+		goto ERROR;
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GICache_GetMeta: failed to read meta: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
+	snprintf(Value, ValueSz, "%.*s", (int)data.mv_size, (const char*)data.mv_data);
+	
+	rc = mdb_txn_commit(txn);
+	txn = NULL;
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to close transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
+	return 0;
 
-    x++; /* Skip control byte */
-    x += s_DecodeInt4(x, &length);
-	MT_LOCK_Do(gi_cache->m_RemapLock, eMT_Unlock);
-    return length;
+ERROR:
+	if (LogFunc && logmsg[0]) {
+		LogFunc(logmsg);
+	}
+	if (gi_cache && txn) {
+		mdb_txn_abort(txn);
+		txn = NULL;
+	}
+	return 1;
 }
 
-int GICache_GetMaxGi()
-{
-    if(!gi_cache) return 0;
-    return GiDataIndex_GetMaxGi(gi_cache);
-}
 
-int GICache_LoadStart(const char* cache_prefix)
-{
-    Uint1 is_64bit = 0;
-    int rc;
+int GICache_GetAccFreqTab(FreqTab* tab, const FreqTab* tablen) {
+	char logmsg[256];
+	int rc;
+	MDB_txn *txn = NULL;
+	MDB_cursor *cur = NULL;
+	MDB_val key;
+	MDB_val data = {0};
+	int64_t totlen = 0, totcomprlen = 0;
 
-    if (sizeof(void*) >= 8 && cache_prefix &&
-        (strstr(cache_prefix, DEFAULT_64BIT_SUFFIX) != NULL))
-        is_64bit = 1;
+	memset(tab, 0, sizeof(*tab));
+	logmsg[0] = 0;
+	if (!gi_cache || !gi_cache->m_env) {
+		snprintf(logmsg, sizeof(logmsg), "GICache_GetAccFreqTab: failed to get frequency table, database is not open");
+		goto ERROR;
+	}
+	
+	rc = mdb_txn_begin(gi_cache->m_env, NULL, MDB_RDONLY, &txn);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to start transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-    rc = x_GICacheInit(cache_prefix, 0, is_64bit);
+	rc = mdb_cursor_open(txn, gi_cache->m_gi_dbi, &cur);
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to open cursor: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-    return rc;
-}
+	key.mv_size = 0;
+	key.mv_data = NULL;
+	while ((rc = mdb_cursor_get(cur, &key, &data, MDB_NEXT)) == MDB_SUCCESS) {
+		char acc_buf[MAX_ACCESSION_LENGTH];
+		int64_t gi_len = 0;
+		acc_buf[0] = 0;
+		int64_t gi64 = 0;
+
+		if (!key.mv_data || key.mv_size != sizeof(gi64)) {
+			snprintf(logmsg, sizeof(logmsg), "GI_CACHE: record contains no valid gi\n");
+			if (LogFunc)
+				LogFunc(logmsg);
+			continue;
+		}
+		gi64 = *(int64_t*)key.mv_data;
+		if (x_DataToGiData(gi64, &data, acc_buf, sizeof(acc_buf), NULL) == 0) {
+			char *p = acc_buf;
+			int no_compr = 0;
+			int compr = 0;
+			int len = 0;
+			while (*p) {
+				tab->Count[(unsigned int)(*p)]++;
+				if (tablen) {
+					int bits = tablen->Count[(unsigned int)(*p)];
+					if (bits == 0)
+						no_compr = 1;
+					else
+						compr += bits;
+				}
+				else
+					no_compr = 1;
+				p++;
+				len++;
+			}
+			totlen += len;
+			if (no_compr)
+				totcomprlen += len;
+			else
+				totcomprlen += (compr + 7) / 8;
+		}
+	}
 
-int GICache_LoadAdd(int gi, int len, const char* acc, int version)
-{
-    int acc_len;
+	mdb_cursor_close(cur);
+	cur = NULL;
 
-    static char buf[MAX_ACCESSION_LENGTH];
-    if(!gi_cache) return 0;
-    
-    if (!s_EncodeGiData(acc, version, len, buf, &acc_len))
-        return 0;
-
-    /* Primary accession and length for a given gi never change, hence there
-     * is never a need to overwrite gi data if it is already present in
-     * cache.
-     * NB: The "overwrite" parameter is 1, because the only possible change
-     * in gi data is that it gets a version when previously there was no
-     * version. This does not change the encoded data size, so data can be
-     * modified in place.
-     */
-    return GiDataIndex_PutData(gi_cache, gi, buf, 1, acc_len);
-}
+	rc = mdb_txn_commit(txn);
+	txn = NULL;
+	if (rc) {
+		snprintf(logmsg, sizeof(logmsg), "GI_CACHE: failed to close transaction: %s\n", mdb_strerror(rc));
+		goto ERROR;
+	}
 
-int GICache_LoadEnd()
-{
-    /* NB: This will not free the structure, and in particular the prefix name 
-       would still be available. */
-    gi_cache = GiDataIndex_Free(gi_cache);
-    return 0;
-}
+	if (totlen == 0)
+		totlen = 1;
+	return (totcomprlen * 100L) / totlen;
 
-void GICache_SetLog(void (*logfunc)(char*))
-{
-    LogFunc = logfunc;
-}
+ERROR:
+	if (cur) {
+		mdb_cursor_close(cur);
+		cur = NULL;
+	}
+	if (txn) {
+		mdb_txn_abort(txn);
+		txn = NULL;
+	}
+	if (LogFunc && logmsg[0]) {
+		LogFunc(logmsg);
+	}
+	return -1;
+	
+}
\ No newline at end of file
diff --git a/c++/src/objtools/data_loaders/genbank/gicache/gicache.h b/c++/src/objtools/data_loaders/genbank/gicache/gicache.h
index b33f6c2..b00660f 100644
--- a/c++/src/objtools/data_loaders/genbank/gicache/gicache.h
+++ b/c++/src/objtools/data_loaders/genbank/gicache/gicache.h
@@ -1,52 +1,68 @@
 #ifndef _GI_CACHE_HPP__
 #define _GI_CACHE_HPP__
 
+#include <ncbi_toolkit.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #define DEFAULT_GI_CACHE_PATH "//panfs/pan1.be-md.ncbi.nlm.nih.gov/id_dumps/gi_cache"
-#define DEFAULT_GI_CACHE_PREFIX "gi2acc"
-#define DEFAULT_64BIT_SUFFIX ".64"
+#define DEFAULT_GI_CACHE_PREFIX "gi2acc_lmdb"
 
-/* Populates the cache. One of 3 options are available to determine which gis
- * to include in cache on this run:
- * 1. Use provided SQL condition;
- * 2. Use provided temporary table (in tempdb database) with a list of gis;
- * 3. Start from the next gi after the maximal gi currently present in cache;
- */
-int         GICache_PopulateAccessions(char *server, const char *cache_prefix,
-                                       const char *sql_gi_cond,
-                                       const char *temptable);
+#define META_INCREMENTAL_HOST "INC_HOST"
+#define META_FULL_HOST "FULL_HOST"
+#define META_INCREMENTAL_DB "INC_DB"
+#define META_FULL_DB "FULL_DB"
+#define META_INCREMENTAL_TIME "INC_TIME"
+#define META_FULL_TIME "FULL_TIME"
+#define META_GIBYTIME_TIME "GI_BYTIME_TIME"
+#define RC_ALREADY_EXISTS 2
+
+typedef struct {
+	int64_t Count[256];
+} FreqTab;
 
 /* Initializes the cache. If cache_prefix argument is not provided, default name
  * is used. If local cache is not available, use default path and prefix.
  * Return value: 0 on success, 1 on failure. 
+ * Resources should be released with GICache_ReadEnd() call
  */
 int         GICache_ReadData(const char *cache_prefix);
-/* Remaps cache files */
-void        GICache_ReMap(int delay_in_sec);
 /* Retrieves accession.version by gi.
  * Accession buffer must be preallocated by caller. 
  * If buffer is too small, retrieved accession is truncated, and return code 
  * is 0, otherwise return code is 1.
  */
-int         GICache_GetAccession(int gi, char* acc, int buf_len);
+int         GICache_GetAccession(int64_t gi, char* acc, int buf_len);
 /* Retrieves gi length */
-int         GICache_GetLength(int gi);
+int64_t     GICache_GetLength(int64_t gi);
 /* Returns maximal gi available in cache */
-int         GICache_GetMaxGi(void);
-
+int64_t     GICache_GetMaxGi(void);
+/* Finish read, release resources */
+void         GICache_ReadEnd(void);
 /* Internal loading interface, non MT safe */
 /* Initialize cache for loading */
-int         GICache_LoadStart(const char *cache_prefix);
+int         GICache_LoadStart(const char *cache_prefix, int enablesync);
 /* Add gi's data to cache */
-int         GICache_LoadAdd(int gi, int len, const char* accession, int version);
+int         GICache_LoadAdd(int64_t gi, int64_t gi_len, const char* accession, int version, int is_incremental);
 /* Finish load, flush modifications to disk */
+int 		GiDataIndex_Commit(void);
+/* Close DB handle */
 int         GICache_LoadEnd(void);
-
-void        GICache_SetLog(void (*logfunc)(char*)); 
-
+/* Erase data in DB before full update */
+int         GICache_DropDb(void);
+/* Update meta info */
+int			GICache_SetMeta(const char* Name, const char* Value);
+/* Store meta info */
+int         GICache_UpdateMeta(int is_incremental, const char* DB, time_t starttime);
+/* Retrieve meta info */
+int			GICache_GetMeta(const char* Name, char* Value, size_t ValueSz);
+/* Install logger CB */
+void        GICache_SetLog(void (*logfunc)(char*));
+/* Dumps out content of the cache. Result is a text file with 3 columns: gi, accession, length  */
+void		GICache_Dump(const char* cache_prefix, const char* filename);
+int GICache_GetAccFreqTab(FreqTab* tab, const FreqTab* tablen);
 #ifdef __cplusplus
 }
 #endif
diff --git a/c++/src/objtools/data_loaders/genbank/gicache/gicache_cxx.cpp b/c++/src/objtools/data_loaders/genbank/gicache/gicache_cxx.cpp
deleted file mode 100644
index e62e0b8..0000000
--- a/c++/src/objtools/data_loaders/genbank/gicache/gicache_cxx.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*  $Id: gicache_cxx.cpp 484420 2015-11-10 19:50:38Z ucko $
-* ===========================================================================
-*
-*                            PUBLIC DOMAIN NOTICE
-*               National Center for Biotechnology Information
-*
-*  This software/database is a "United States Government Work" under the
-*  terms of the United States Copyright Act.  It was written as part of
-*  the author's official duties as a United States Government employee and
-*  thus cannot be copyrighted.  This software/database is freely available
-*  to the public for use. The National Library of Medicine and the U.S.
-*  Government have not placed any restriction on its use or reproduction.
-*
-*  Although all reasonable efforts have been taken to ensure the accuracy
-*  and reliability of the software and data, the NLM and the U.S.
-*  Government do not and cannot warrant the performance or results that
-*  may be obtained by using this software or data. The NLM and the U.S.
-*  Government disclaim all warranties, express or implied, including
-*  warranties of performance, merchantability or fitness for any particular
-*  purpose.
-*
-*  Please cite the author in any work or product based on this material.
-*
-* ===========================================================================
-*
-* Author:  Aaron Ucko
-*
-* File Description:
-*   Accommodate gicache.c's use of MT_LOCK_cxx2c from ncbi_core_cxx.hpp
-*   when built as part of the C++ Toolkit.
-*
-* ===========================================================================
-*/
-
-#include <ncbi_pch.hpp>
-#include <corelib/ncbistl.hpp>
-USING_NCBI_SCOPE;
-#include "gicache.c"
diff --git a/c++/src/objtools/data_loaders/genbank/gicache/reader_gicache.cpp b/c++/src/objtools/data_loaders/genbank/gicache/reader_gicache.cpp
index 8b1ecc0..1c485cc 100644
--- a/c++/src/objtools/data_loaders/genbank/gicache/reader_gicache.cpp
+++ b/c++/src/objtools/data_loaders/genbank/gicache/reader_gicache.cpp
@@ -1,4 +1,4 @@
-/*  $Id: reader_gicache.cpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: reader_gicache.cpp 514597 2016-09-22 17:30:12Z ivanov $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
@@ -76,7 +76,7 @@ CGICacheReader::CGICacheReader(const TPluginManagerParamTree* params,
 CGICacheReader::~CGICacheReader()
 {
     CMutexGuard guard(m_Mutex);
-    GICache_LoadEnd();
+    GICache_ReadEnd();
 }
 
 
@@ -85,12 +85,11 @@ void CGICacheReader::x_Initialize(void)
     string index = m_Path;
     if ( CFile(index).IsDir() ) {
         const char* file;
-        if ( sizeof(void*) == 4 ) {
-            file = DEFAULT_GI_CACHE_PREFIX;
-        }
-        else {
-            file = DEFAULT_GI_CACHE_PREFIX DEFAULT_64BIT_SUFFIX;
-        }
+#if defined(DEFAULT_64BIT_SUFFIX)  &&  SIZEOF_VOIDP > 4
+        file = DEFAULT_GI_CACHE_PREFIX DEFAULT_64BIT_SUFFIX;
+#else
+        file = DEFAULT_GI_CACHE_PREFIX;
+#endif
         index = CFile::MakePath(index, file);
     }
     CMutexGuard guard(m_Mutex);
diff --git a/c++/src/objtools/data_loaders/genbank/id1/reader_id1.cpp b/c++/src/objtools/data_loaders/genbank/id1/reader_id1.cpp
index 25dced3..d55a390 100644
--- a/c++/src/objtools/data_loaders/genbank/id1/reader_id1.cpp
+++ b/c++/src/objtools/data_loaders/genbank/id1/reader_id1.cpp
@@ -1,4 +1,4 @@
-/*  $Id: reader_id1.cpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: reader_id1.cpp 508267 2016-07-26 20:12:43Z vasilche $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
@@ -282,7 +282,7 @@ bool CId1Reader::LoadSeq_idGi(CReaderRequestResult& result,
     TSequenceGi gi;
     if ( id1_reply.IsGotgi() ) {
         gi.gi = id1_reply.GetGotgi();
-        gi.sequence_found = true;
+        gi.sequence_found = gi.gi != ZERO_GI;
     }
     SetAndSaveSeq_idGi(result, seq_id, gi);
     return true;
diff --git a/c++/src/objtools/data_loaders/genbank/id2/reader_id2.cpp b/c++/src/objtools/data_loaders/genbank/id2/reader_id2.cpp
index 3e7b4c3..c617027 100644
--- a/c++/src/objtools/data_loaders/genbank/id2/reader_id2.cpp
+++ b/c++/src/objtools/data_loaders/genbank/id2/reader_id2.cpp
@@ -1,4 +1,4 @@
-/*  $Id: reader_id2.cpp 440703 2014-07-16 15:38:41Z vasilche $
+/*  $Id: reader_id2.cpp 490804 2016-01-28 19:50:29Z vasilche $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
@@ -78,7 +78,7 @@ BEGIN_SCOPE(objects)
 
 #define DEFAULT_SERVICE  "ID2"
 #define DEFAULT_NUM_CONN 3
-#define MAX_MT_CONN      5
+#define MAX_MT_CONN      256
 
 //#define GENBANK_ID2_RANDOM_FAILS 1
 #define GENBANK_ID2_RANDOM_FAILS_FREQUENCY 20
diff --git a/c++/src/objtools/data_loaders/genbank/info_cache.cpp b/c++/src/objtools/data_loaders/genbank/info_cache.cpp
index c3725c6..f100322 100644
--- a/c++/src/objtools/data_loaders/genbank/info_cache.cpp
+++ b/c++/src/objtools/data_loaders/genbank/info_cache.cpp
@@ -1,4 +1,4 @@
-/*  $Id: info_cache.cpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: info_cache.cpp 493171 2016-02-24 19:31:13Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/data_loaders/genbank/processors.cpp b/c++/src/objtools/data_loaders/genbank/processors.cpp
index d2c99c2..9f46052 100644
--- a/c++/src/objtools/data_loaders/genbank/processors.cpp
+++ b/c++/src/objtools/data_loaders/genbank/processors.cpp
@@ -1,4 +1,4 @@
-/*  $Id: processors.cpp 490251 2016-01-22 15:40:54Z vasilche $
+/*  $Id: processors.cpp 507982 2016-07-22 19:52:48Z vasilche $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
@@ -708,13 +708,15 @@ static const int kForceDescrMask = ((1<<CSeqdesc::e_Pub) |
 static const int kOptionalDescrMask = ((1<<CSeqdesc::e_Source) |
                                        (1<<CSeqdesc::e_Molinfo) |
                                        (1<<CSeqdesc::e_Create_date) |
-                                       (1<<CSeqdesc::e_Update_date));
+                                       (1<<CSeqdesc::e_Update_date) |
+                                       (1<<CSeqdesc::e_Genbank) |
+                                       (1<<CSeqdesc::e_Embl));
 
 static const int kGoodDescrMask = kForceDescrMask | kOptionalDescrMask;
 
 
 static
-bool s_IsGoodDescr(const CSeqdesc& desc)
+bool s_IsGoodDescr(const CSeqdesc& desc, int mask)
 {
     if ( desc.Which() == CSeqdesc::e_User ) {
         const CObject_id& type = desc.GetUser().GetType();
@@ -728,7 +730,7 @@ bool s_IsGoodDescr(const CSeqdesc& desc)
             }
         }
     }
-    else if ( (1 << desc.Which()) & kGoodDescrMask ) {
+    else if ( (1 << desc.Which()) & mask ) {
         return true;
     }
     return false;
@@ -761,7 +763,8 @@ void s_AddMasterDescr(CBioseq_Info& seq, const CSeq_descr& src)
 
 static
 CRef<CSeq_descr> s_GetWGSMasterDescr(CDataLoader* loader,
-                                     const CSeq_id_Handle& master_idh)
+                                     const CSeq_id_Handle& master_idh,
+                                     int mask)
 {
     CRef<CSeq_descr> ret;
     CDataLoader::TTSE_LockSet locks =
@@ -775,7 +778,7 @@ CRef<CSeq_descr> s_GetWGSMasterDescr(CDataLoader* loader,
         if ( bs_info->IsSetDescr() ) {
             const CSeq_descr::Tdata& descr = bs_info->GetDescr().Get();
             ITERATE ( CSeq_descr::Tdata, it, descr ) {
-                if ( s_IsGoodDescr(**it) ) {
+                if ( s_IsGoodDescr(**it, mask) ) {
                     if ( !ret ) {
                         ret = new CSeq_descr;
                     }
@@ -857,26 +860,40 @@ private:
 class CWGSMasterChunkInfo : public CTSE_Chunk_Info
 {
 public:
-    CWGSMasterChunkInfo(const CSeq_id_Handle& master_idh)
+    CWGSMasterChunkInfo(const CSeq_id_Handle& master_idh,
+                        int mask)
         : CTSE_Chunk_Info(kMasterWGS_ChunkId),
-          m_MasterId(master_idh)
+          m_MasterId(master_idh),
+          m_DescrMask(mask)
         {
         }
 
     CSeq_id_Handle m_MasterId;
+    int m_DescrMask;
 };
 
 
 END_LOCAL_NAMESPACE;
 
 
+const bool kAddMasterDescrToTSE = true;
+
+
 void CProcessor::LoadWGSMaster(CDataLoader* loader,
                                CRef<CTSE_Chunk_Info> chunk)
 {
-    CSeq_id_Handle id = dynamic_cast<CWGSMasterChunkInfo&>(*chunk).m_MasterId;
-    CRef<CSeq_descr> descr = s_GetWGSMasterDescr(loader, id);
-    CRef<CBioseqUpdater> upd(new CWGSBioseqUpdaterDescr(id, descr));
-    const_cast<CTSE_Split_Info&>(chunk->GetSplitInfo()).x_SetBioseqUpdater(upd);
+    CWGSMasterChunkInfo& chunk_info =
+        dynamic_cast<CWGSMasterChunkInfo&>(*chunk);
+    CSeq_id_Handle id = chunk_info.m_MasterId;
+    int mask = chunk_info.m_DescrMask;
+    CRef<CSeq_descr> descr = s_GetWGSMasterDescr(loader, id, mask);
+    if ( kAddMasterDescrToTSE ) {
+        chunk->x_LoadDescr(CTSE_Chunk_Info::TPlace(), *descr);
+    }
+    else {
+        CRef<CBioseqUpdater> upd(new CWGSBioseqUpdaterDescr(id, descr));
+        const_cast<CTSE_Split_Info&>(chunk->GetSplitInfo()).x_SetBioseqUpdater(upd);
+    }
     chunk->SetLoaded();
 }
 
@@ -888,10 +905,20 @@ void CProcessor::AddWGSMaster(CLoadLockSetter& blob)
     lock->GetBioseqsIds(ids);
     ITERATE ( CTSE_Info::TSeqIds, it, ids ) {
         if ( CSeq_id_Handle id = s_GetWGSMasterSeq_id(*it) ) {
-            CRef<CTSE_Chunk_Info> chunk(new CWGSMasterChunkInfo(id));
+            int mask = kGoodDescrMask;
+            if ( kAddMasterDescrToTSE ) {
+                // exclude existing descr types
+                mask &= ~lock->x_GetBaseInfo().x_GetExistingDescrMask();
+            }
+            CRef<CTSE_Chunk_Info> chunk(new CWGSMasterChunkInfo(id, mask));
             lock->GetSplitInfo().AddChunk(*chunk);
-            CRef<CBioseqUpdater> upd(new CWGSBioseqUpdaterChunk(id));
-            lock->SetBioseqUpdater(upd);
+            if ( kAddMasterDescrToTSE ) {
+                chunk->x_AddDescInfo(mask, 0);
+            }
+            else {
+                CRef<CBioseqUpdater> upd(new CWGSBioseqUpdaterChunk(id));
+                lock->SetBioseqUpdater(upd);
+            }
             break;
         }
     }
diff --git a/c++/src/objtools/data_loaders/genbank/reader.cpp b/c++/src/objtools/data_loaders/genbank/reader.cpp
index c19b1e3..afdf9aa 100644
--- a/c++/src/objtools/data_loaders/genbank/reader.cpp
+++ b/c++/src/objtools/data_loaders/genbank/reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: reader.cpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: reader.cpp 493171 2016-02-24 19:31:13Z vasilche $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
diff --git a/c++/src/objtools/data_loaders/genbank/reader_id1_base.cpp b/c++/src/objtools/data_loaders/genbank/reader_id1_base.cpp
index bfedb07..92b49a5 100644
--- a/c++/src/objtools/data_loaders/genbank/reader_id1_base.cpp
+++ b/c++/src/objtools/data_loaders/genbank/reader_id1_base.cpp
@@ -1,4 +1,4 @@
-/*  $Id: reader_id1_base.cpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: reader_id1_base.cpp 493171 2016-02-24 19:31:13Z vasilche $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
diff --git a/c++/src/objtools/data_loaders/genbank/reader_id2_base.cpp b/c++/src/objtools/data_loaders/genbank/reader_id2_base.cpp
index 3c3dd2a..17ff2ca 100644
--- a/c++/src/objtools/data_loaders/genbank/reader_id2_base.cpp
+++ b/c++/src/objtools/data_loaders/genbank/reader_id2_base.cpp
@@ -1,4 +1,4 @@
-/*  $Id: reader_id2_base.cpp 500239 2016-05-03 15:03:41Z ivanov $
+/*  $Id: reader_id2_base.cpp 508114 2016-07-25 22:09:48Z vasilche $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
@@ -179,7 +179,7 @@ CId2ReaderBase::CId2ReaderBase(void)
 {
     vector<string> proc_list;
     string proc_param = NCBI_PARAM_TYPE(GENBANK, ID2_PROCESSOR)::GetDefault();
-    NStr::Tokenize(proc_param, ";", proc_list, NStr::eNoMergeDelims);
+    NStr::Split(proc_param, ";", proc_list);
     ITERATE ( vector<string>, it, proc_list ) {
         const string& proc_name = *it;
         CRef<CID2Processor> proc;
@@ -302,7 +302,7 @@ bool CId2ReaderBase::LoadSeq_idGi(CReaderRequestResult& result,
     CID2_Request::C_Request::TGet_seq_id& get_id =
         req.SetRequest().SetGet_seq_id();
     get_id.SetSeq_id().SetSeq_id().Assign(*seq_id.GetSeqId());
-    get_id.SetSeq_id_type(CID2_Request_Get_Seq_id::eSeq_id_type_gi);
+    get_id.SetSeq_id_type(CID2_Request_Get_Seq_id::eSeq_id_type_all);
     x_ProcessRequest(result, req, 0);
 
     if ( !lock.IsLoadedGi() ) {
@@ -324,7 +324,7 @@ bool CId2ReaderBase::LoadSeq_idAccVer(CReaderRequestResult& result,
     CID2_Request::C_Request::TGet_seq_id& get_id =
         req.SetRequest().SetGet_seq_id();
     get_id.SetSeq_id().SetSeq_id().Assign(*seq_id.GetSeqId());
-    get_id.SetSeq_id_type(CID2_Request_Get_Seq_id::eSeq_id_type_text);
+    get_id.SetSeq_id_type(CID2_Request_Get_Seq_id::eSeq_id_type_all);
     x_ProcessRequest(result, req, 0);
 
     if ( lock.IsLoadedAccVer() ) {
@@ -502,7 +502,7 @@ bool CId2ReaderBase::LoadAccVers(CReaderRequestResult& result,
         CID2_Request::C_Request::TGet_seq_id& get_id =
             req->SetRequest().SetGet_seq_id();
         get_id.SetSeq_id().SetSeq_id().Assign(*ids[i].GetSeqId());
-        get_id.SetSeq_id_type(CID2_Request_Get_Seq_id::eSeq_id_type_text);
+        get_id.SetSeq_id_type(CID2_Request_Get_Seq_id::eSeq_id_type_all);
         if ( packet.Set().empty() ) {
             packet_start = i;
         }
@@ -581,7 +581,7 @@ bool CId2ReaderBase::LoadGis(CReaderRequestResult& result,
         CID2_Request::C_Request::TGet_seq_id& get_id =
             req->SetRequest().SetGet_seq_id();
         get_id.SetSeq_id().SetSeq_id().Assign(*ids[i].GetSeqId());
-        get_id.SetSeq_id_type(CID2_Request_Get_Seq_id::eSeq_id_type_gi);
+        get_id.SetSeq_id_type(CID2_Request_Get_Seq_id::eSeq_id_type_all);
         if ( packet.Set().empty() ) {
             packet_start = i;
         }
@@ -1573,15 +1573,27 @@ void CId2ReaderBase::x_ProcessRequest(CReaderRequestResult& result,
 }
 
 
-BEGIN_LOCAL_NAMESPACE;
+struct SId2PacketInfo
+{
+    int request_count, remaining_count;
+    int start_serial_num;
+    vector<char> done;
+};
 
 
-class CProcessorResolver : public CID2ProcessorResolver
+struct SId2PacketReplies
+{
+    typedef vector< CRef<CID2_Reply> > TRequestReplies;
+    vector<TRequestReplies> replies;
+};
+
+
+class CId2ReaderProcessorResolver : public CID2ProcessorResolver
 {
 public:
-    CProcessorResolver(CReadDispatcher& dispatcher,
-                       CReaderRequestResult& result)
-        : m_Dispatcher(dispatcher),
+    CId2ReaderProcessorResolver(CId2ReaderBase& reader,
+                                CReaderRequestResult& result)
+        : m_Reader(reader),
           m_RequestResult(result)
         {
         }
@@ -1593,7 +1605,7 @@ public:
             CLoadLockSeqIds lock(m_RequestResult, idh);
             if ( !lock.IsLoaded() ) {
                 CReaderRequestResultRecursion recurse(m_RequestResult, true);
-                m_Dispatcher.LoadSeq_idSeq_ids(m_RequestResult, idh);
+                m_Reader.m_Dispatcher->LoadSeq_idSeq_ids(m_RequestResult, idh);
             }
             CFixedSeq_ids ids = lock.GetSeq_ids();
             ITERATE ( CFixedSeq_ids, it, ids ) {
@@ -1602,15 +1614,71 @@ public:
             return ret;
         }
 
+    /*
+    CRef<CID2_Reply> MakeReply(const CID2_Request& req)
+        {
+            CRef<CID2_Reply> reply(new CID2_Reply);
+            if ( req.IsSetSerial_number() ) {
+                reply->SetSerial_number(req.GetSerial_number());
+            }
+            return reply;
+        }
+
+    void ProcessGetBlobIds(TReplies& replies,
+                           const CID2_Request& req)
+        {
+            auto reply = MakeReply(req);
+
+            CRef<CID2_Error> error(new CID2_Error);
+            error->SetSeverity(CID2_Error::eSeverity_unsupported_command);
+            reply->SetError().push_back(error);
+            reply->SetReply().SetEmpty();
+
+            replies.push_back(reply);
+            replies.back()->SetEnd_of_reply();
+        }
+
+    void ProcessOther(TReplies& replies,
+                      const CID2_Request& req)
+        {
+            auto reply = MakeReply(req);
+
+            CRef<CID2_Error> error(new CID2_Error);
+            error->SetSeverity(CID2_Error::eSeverity_unsupported_command);
+            reply->SetError().push_back(error);
+            reply->SetReply().SetEmpty();
+
+            replies.push_back(reply);
+            replies.back()->SetEnd_of_reply();
+        }
+
+    void ProcessRequest(TReplies& replies,
+                        const CID2_Request& req)
+        {
+            switch ( req.GetRequest().Which() ) {
+            case CID2_Request::TRequest::e_Get_blob_id:
+                ProcessGetBlobIds(replies, req);
+                break;
+            default:
+                ProcessOther(replies, req);
+                break;
+            }
+        }
+    */
+
+    virtual void ProcessPacket(TReplies& replies,
+                               CID2_Request_Packet& packet)
+        {
+            SId2PacketReplies replies2;
+            m_Reader.x_GetPacketReplies(m_RequestResult, replies2, packet);
+        }
+
 private:
-    CReadDispatcher& m_Dispatcher;
+    CId2ReaderBase& m_Reader;
     CReaderRequestResult& m_RequestResult;
 };
 
 
-END_LOCAL_NAMESPACE;
-
-
 void CId2ReaderBase::x_SetContextData(CID2_Request& request)
 {
     if ( request.GetRequest().IsInit() ) {
@@ -1646,9 +1714,121 @@ void CId2ReaderBase::x_SetContextData(CID2_Request& request)
 }
 
 
-void CId2ReaderBase::x_ProcessPacket(CReaderRequestResult& result,
-                                     CID2_Request_Packet& packet,
-                                     const SAnnotSelector* sel)
+void CId2ReaderBase::x_DumpPacket(TConn conn,
+                                  const CID2_Request_Packet& packet)
+{
+    if ( GetDebugLevel() >= eTraceConn ) {
+        CDebugPrinter s(conn, "CId2Reader");
+        s << "Sending";
+        if ( GetDebugLevel() >= eTraceASN ) {
+            s << ": " << MSerial_AsnText << packet;
+        }
+        else {
+            s << " ID2-Request-Packet";
+        }
+        s << "...";
+    }
+}
+
+
+void CId2ReaderBase::x_DumpReply(TConn conn,
+                                 const char* source,
+                                 CID2_Reply& reply)
+{
+    if ( GetDebugLevel() >= eTraceConn   ) {
+        CDebugPrinter s(0, "CId2Reader");
+        s << "Received" << source;
+        if ( GetDebugLevel() >= eTraceASN ) {
+            if ( GetDebugLevel() >= eTraceBlobData ) {
+                s << ": " << MSerial_AsnText << reply;
+            }
+            else {
+                CTypeIterator<CID2_Reply_Data> iter = Begin(reply);
+                if ( iter && iter->IsSetData() ) {
+                    CID2_Reply_Data::TData save;
+                    save.swap(iter->SetData());
+                    size_t size = 0, count = 0, max_chunk = 0;
+                    ITERATE ( CID2_Reply_Data::TData, i, save ) {
+                        ++count;
+                        size_t chunk = (*i)->size();
+                        size += chunk;
+                        max_chunk = max(max_chunk, chunk);
+                    }
+                    s << ": " << MSerial_AsnText << reply <<
+                        "Data: " << size << " bytes in " <<
+                        count << " chunks with " <<
+                        max_chunk << " bytes in chunk max";
+                    save.swap(iter->SetData());
+                }
+                else {
+                    s << ": " << MSerial_AsnText << reply;
+                }
+            }
+        }
+        else {
+            s << " ID2-Reply.";
+        }
+    }
+    if ( GetDebugLevel() >= eTraceBlob ) {
+        for ( CTypeConstIterator<CID2_Reply_Data> it(Begin(reply));
+              it; ++it ) {
+            if ( it->IsSetData() ) {
+                try {
+                    CProcessor_ID2::DumpDataAsText(*it, NcbiCout);
+                }
+                catch ( CException& exc ) {
+                    ERR_POST_X(1, "Exception while dumping data: "
+                               <<exc);
+                }
+            }
+        }
+    }
+}
+
+
+void CId2ReaderBase::x_SendToConnection(TConn conn,
+                                        CID2_Request_Packet& packet)
+{
+    CProcessor::OffsetAllGisFromOM(packet);
+    x_DumpPacket(conn, packet);
+    try {
+        x_SendPacket(conn, packet);
+    }
+    catch ( CException& exc ) {
+        NCBI_RETHROW(exc, CLoaderException, eConnectionFailed,
+                     "failed to send request: "+
+                     x_ConnDescription(conn));
+    }
+    if ( GetDebugLevel() >= eTraceConn ) {
+        CDebugPrinter s(conn, "CId2Reader");
+        s << "Sent ID2-Request-Packet.";
+    }
+}
+
+
+CRef<CID2_Reply> CId2ReaderBase::x_ReceiveFromConnection(TConn conn)
+{
+    if ( GetDebugLevel() >= eTraceConn ) {
+        CDebugPrinter s(conn, "CId2Reader");
+        s << "Receiving ID2-Reply...";
+    }
+    CRef<CID2_Reply> reply(new CID2_Reply);
+    try {
+        x_ReceiveReply(conn, *reply);
+    }
+    catch ( CException& exc ) {
+        NCBI_RETHROW(exc, CLoaderException, eConnectionFailed,
+                     "reply deserialization failed: "+
+                     x_ConnDescription(conn));
+    }
+    x_DumpReply(conn, "", *reply);
+    CProcessor::OffsetAllGisToOM(*reply);
+    return reply;
+}
+
+
+void CId2ReaderBase::x_AssignSerialNumbers(SId2PacketInfo& info,
+                                           CID2_Request_Packet& packet)
 {
     // Fill request context information
     if ( !packet.Get().empty() ) {
@@ -1656,113 +1836,181 @@ void CId2ReaderBase::x_ProcessPacket(CReaderRequestResult& result,
     }
 
     // prepare serial nums and result state
-    int request_count = static_cast<int>(packet.Get().size());
-    int end_serial_num = static_cast<int>(m_RequestSerialNumber.Add(request_count));
-    while ( end_serial_num <= request_count ) {
+    info.request_count = static_cast<int>(packet.Get().size());
+    info.remaining_count = info.request_count;
+    int end_serial_num =
+        static_cast<int>(m_RequestSerialNumber.Add(info.request_count));
+    while ( end_serial_num <= info.request_count ) {
         // int overflow, adjust to 1
         {{
             DEFINE_STATIC_FAST_MUTEX(sx_Mutex);
             CFastMutexGuard guard(sx_Mutex);
             int num = static_cast<int>(m_RequestSerialNumber.Get());
-            if ( num <= request_count ) {
+            if ( num <= info.request_count ) {
                 m_RequestSerialNumber.Set(1);
             }
         }}
-        end_serial_num = static_cast<int>(m_RequestSerialNumber.Add(request_count));
+        end_serial_num =
+            static_cast<int>(m_RequestSerialNumber.Add(info.request_count));
     }
-    int start_serial_num = end_serial_num - request_count;
+    info.start_serial_num = end_serial_num - info.request_count;
     {{
-        int cur_serial_num = start_serial_num;
+        int cur_serial_num = info.start_serial_num;
         NON_CONST_ITERATE ( CID2_Request_Packet::Tdata, it, packet.Set() ) {
             (*it)->SetSerial_number(cur_serial_num++);
         }
     }}
-    vector<char> done(request_count);
-    vector<SId2LoadedSet> loaded_sets(request_count);
+    info.done.assign(info.request_count, false);
+}
+
+
+int CId2ReaderBase::x_GetReplyIndex(CReaderRequestResult& result,
+                                    CConn* conn,
+                                    SId2PacketInfo& packet,
+                                    const CID2_Reply& reply)
+{
+    int num = reply.GetSerial_number() - packet.start_serial_num;
+    if ( reply.IsSetDiscard() ) {
+        // discard whole reply for now
+        return -1;
+    }
+    if ( num < 0 || num >= packet.request_count || packet.done[num] ) {
+        // unknown serial num - bad reply
+        string descr;
+        if ( conn ) {
+            descr = x_ConnDescription(*conn);
+        }
+        else {
+            descr = " (processor)";
+        }
+        if ( TErrorFlags error = x_GetError(result, reply) ) {
+            if ( error & fError_inactivity_timeout ) {
+                if ( conn ) {
+                    conn->Restart();
+                }
+                NCBI_THROW_FMT(CLoaderException, eRepeatAgain,
+                               "CId2ReaderBase: connection timed out"<<descr);
+            }
+            if ( error & fError_bad_connection ) {
+                NCBI_THROW_FMT(CLoaderException, eConnectionFailed,
+                               "CId2ReaderBase: connection failed"<<descr);
+            }
+        }
+        else if ( reply.GetReply().IsEmpty() ) {
+            ERR_POST_X(8, "CId2ReaderBase: bad reply serial number: "<<descr);
+            return num;
+        }
+        NCBI_THROW_FMT(CLoaderException, eOtherError,
+                       "CId2ReaderBase: bad reply serial number: "<<descr);
+    }
+    return num;
+}
+
+
+bool CId2ReaderBase::x_DoneReply(SId2PacketInfo& info,
+                                 int num,
+                                 const CID2_Reply& reply)
+{
+    if ( reply.IsSetEnd_of_reply() ) {
+        info.done[num] = true;
+        --info.remaining_count;
+        return true;
+    }
+    return false;
+}
+
+
+void CId2ReaderBase::x_GetPacketReplies(CReaderRequestResult& result,
+                                        SId2PacketReplies& replies,
+                                        CID2_Request_Packet& packet)
+{
+    SId2PacketInfo packet_info;
+    x_AssignSerialNumbers(packet_info, packet);
+    replies.replies.resize(packet_info.request_count);
+
+    CConn conn(result, this);
+    CRef<CID2_Reply> reply;
+    try {
+        // send request
+        x_SendToConnection(conn, packet);
+
+        // process replies
+        while ( packet_info.remaining_count ) {
+            reply = x_ReceiveFromConnection(conn);
+            int num = x_GetReplyIndex(result, &conn, packet_info, *reply);
+            if ( num >= 0 ) {
+                replies.replies[num].push_back(reply);
+                if ( x_DoneReply(packet_info, num, *reply) ) {
+                    // do nothing
+                }
+            }
+            reply = null;
+        }
+        if ( conn.IsAllocated() ) {
+            x_EndOfPacket(conn);
+        }
+    }
+    catch ( exception& /*rethrown*/ ) {
+        if ( GetDebugLevel() >= eTraceError ) {
+            CDebugPrinter s(conn, "CId2Reader");
+            s << "Error processing request: " << MSerial_AsnText << packet;
+            if ( reply &&
+                 (reply->IsSetSerial_number() ||
+                  reply->IsSetParams() ||
+                  reply->IsSetError() ||
+                  reply->IsSetEnd_of_reply() ||
+                  reply->IsSetReply()) ) {
+                try {
+                    s << "Last reply: " << MSerial_AsnText << *reply;
+                }
+                catch ( exception& /*ignored*/ ) {
+                }
+            }
+        }
+        throw;
+    }
+    conn.Release();
+}
+
+
+void CId2ReaderBase::x_ProcessPacket(CReaderRequestResult& result,
+                                     CID2_Request_Packet& packet,
+                                     const SAnnotSelector* sel)
+{
+    SId2PacketInfo packet_info;
+    x_AssignSerialNumbers(packet_info, packet);
+
+    vector<SId2LoadedSet> loaded_sets(packet_info.request_count);
     
-    int remaining_count = request_count;
     NON_CONST_ITERATE ( TProcessors, it, m_Processors ) {
         if ( result.IsInProcessor() ) {
             break;
         }
-        CProcessorResolver resolver(*m_Dispatcher, result);
+        CId2ReaderProcessorResolver resolver(*this, result);
         CID2Processor::TReplies replies =
             (*it)->ProcessSomeRequests(packet, &resolver);
         ITERATE ( CID2Processor::TReplies, it, replies ) {
             CRef<CID2_Reply> reply = *it;
-            if ( GetDebugLevel() >= eTraceConn   ) {
-                CDebugPrinter s(0, "CId2Reader");
-                s << "Received from processor";
-                if ( GetDebugLevel() >= eTraceASN ) {
-                    if ( GetDebugLevel() >= eTraceBlobData ) {
-                        s << ": " << MSerial_AsnText << *reply;
-                    }
-                    else {
-                        CTypeIterator<CID2_Reply_Data> iter = Begin(*reply);
-                        if ( iter && iter->IsSetData() ) {
-                            CID2_Reply_Data::TData save;
-                            save.swap(iter->SetData());
-                            size_t size = 0, count = 0, max_chunk = 0;
-                            ITERATE ( CID2_Reply_Data::TData, i, save ) {
-                                ++count;
-                                size_t chunk = (*i)->size();
-                                size += chunk;
-                                max_chunk = max(max_chunk, chunk);
-                            }
-                            s << ": " << MSerial_AsnText << *reply <<
-                                "Data: " << size << " bytes in " <<
-                                count << " chunks with " <<
-                                max_chunk << " bytes in chunk max";
-                            save.swap(iter->SetData());
-                        }
-                        else {
-                            s << ": " << MSerial_AsnText << *reply;
-                        }
-                    }
+            x_DumpReply(0, " from processor", *reply);
+            int num = x_GetReplyIndex(result, 0, packet_info, *reply);
+            if ( num >= 0 ) {
+                try {
+                    x_ProcessReply(result, loaded_sets[num], *reply);
                 }
-                else {
-                    s << " ID2-Reply.";
+                catch ( CException& exc ) {
+                    NCBI_RETHROW(exc, CLoaderException, eOtherError,
+                                 "CId2ReaderBase: failed to process reply");
                 }
-            }
-            if ( GetDebugLevel() >= eTraceBlob ) {
-                for ( CTypeConstIterator<CID2_Reply_Data> it(Begin(*reply));
-                      it; ++it ) {
-                    if ( it->IsSetData() ) {
-                        try {
-                            CProcessor_ID2::DumpDataAsText(*it, NcbiCout);
-                        }
-                        catch ( CException& exc ) {
-                            ERR_POST_X(1, "Exception while dumping data: "
-                                       <<exc);
-                        }
-                    }
+                if ( x_DoneReply(packet_info, num, *reply) ) {
+                    x_UpdateLoadedSet(result, loaded_sets[num], sel);
                 }
             }
-            int num = reply->GetSerial_number() - start_serial_num;
-            if ( reply->IsSetDiscard() ||
-                 num < 0 || num >= request_count || done[num] ) {
-                // unknown serial num - bad reply
-                NCBI_THROW_FMT(CLoaderException, eOtherError,
-                               "CId2ReaderBase: bad reply serial number");
-            }
-            try {
-                x_ProcessReply(result, loaded_sets[num], *reply);
-            }
-            catch ( CException& exc ) {
-                NCBI_RETHROW(exc, CLoaderException, eOtherError,
-                             "CId2ReaderBase: failed to process reply");
-            }
-            if ( reply->IsSetEnd_of_reply() ) {
-                done[num] = true;
-                x_UpdateLoadedSet(result, loaded_sets[num], sel);
-                --remaining_count;
-            }
         }
-        if ( size_t(remaining_count) != packet.Get().size() ) {
+        if ( size_t(packet_info.remaining_count) != packet.Get().size() ) {
             NCBI_THROW(CLoaderException, eOtherError,
                        "CId2ReaderBase: processor discrepancy");
         }
-        if ( packet.Get().empty() ) {
+        if ( packet_info.remaining_count == 0 ) {
             return;
         }
     }
@@ -1771,142 +2019,27 @@ void CId2ReaderBase::x_ProcessPacket(CReaderRequestResult& result,
     CRef<CID2_Reply> reply;
     try {
         // send request
-
-        CProcessor::OffsetAllGisFromOM(packet);
-        {{
-            if ( GetDebugLevel() >= eTraceConn ) {
-                CDebugPrinter s(conn, "CId2Reader");
-                s << "Sending";
-                if ( GetDebugLevel() >= eTraceASN ) {
-                    s << ": " << MSerial_AsnText << packet;
-                }
-                else {
-                    s << " ID2-Request-Packet";
-                }
-                s << "...";
-            }
-            try {
-                x_SendPacket(conn, packet);
-            }
-            catch ( CException& exc ) {
-                NCBI_RETHROW(exc, CLoaderException, eConnectionFailed,
-                             "failed to send request: "+
-                             x_ConnDescription(conn));
-            }
-            if ( GetDebugLevel() >= eTraceConn ) {
-                CDebugPrinter s(conn, "CId2Reader");
-                s << "Sent ID2-Request-Packet.";
-            }
-        }}
+        x_SendToConnection(conn, packet);
 
         // process replies
-        while ( remaining_count > 0 ) {
-            reply.Reset(new CID2_Reply);
-            if ( GetDebugLevel() >= eTraceConn ) {
-                CDebugPrinter s(conn, "CId2Reader");
-                s << "Receiving ID2-Reply...";
-            }
-            try {
-                x_ReceiveReply(conn, *reply);
-            }
-            catch ( CException& exc ) {
-                NCBI_RETHROW(exc, CLoaderException, eConnectionFailed,
-                             "reply deserialization failed: "+
-                             x_ConnDescription(conn));
-            }
-            if ( GetDebugLevel() >= eTraceConn   ) {
-                CDebugPrinter s(conn, "CId2Reader");
-                s << "Received";
-                if ( GetDebugLevel() >= eTraceASN ) {
-                    if ( GetDebugLevel() >= eTraceBlobData ) {
-                        s << ": " << MSerial_AsnText << *reply;
-                    }
-                    else {
-                        CTypeIterator<CID2_Reply_Data> iter = Begin(*reply);
-                        if ( iter && iter->IsSetData() ) {
-                            CID2_Reply_Data::TData save;
-                            save.swap(iter->SetData());
-                            size_t size = 0, count = 0, max_chunk = 0;
-                            ITERATE ( CID2_Reply_Data::TData, i, save ) {
-                                ++count;
-                                size_t chunk = (*i)->size();
-                                size += chunk;
-                                max_chunk = max(max_chunk, chunk);
-                            }
-                            s << ": " << MSerial_AsnText << *reply <<
-                                "Data: " << size << " bytes in " <<
-                                count << " chunks with " <<
-                                max_chunk << " bytes in chunk max";
-                            save.swap(iter->SetData());
-                        }
-                        else {
-                            s << ": " << MSerial_AsnText << *reply;
-                        }
-                    }
-                }
-                else {
-                    s << " ID2-Reply.";
-                }
-            }
-            if ( GetDebugLevel() >= eTraceBlob ) {
-                for ( CTypeConstIterator<CID2_Reply_Data> it(Begin(*reply));
-                      it; ++it ) {
-                    if ( it->IsSetData() ) {
-                        try {
-                            CProcessor_ID2::DumpDataAsText(*it, NcbiCout);
-                        }
-                        catch ( CException& exc ) {
-                            ERR_POST_X(1, "Exception while dumping data: "
-                                       <<exc);
-                        }
-                    }
+        while ( packet_info.remaining_count > 0 ) {
+            reply = x_ReceiveFromConnection(conn);
+            int num = x_GetReplyIndex(result, &conn, packet_info, *reply);
+            if ( num >= 0 ) {
+                try {
+                    x_ProcessReply(result, loaded_sets[num], *reply);
                 }
-            }
-            CProcessor::OffsetAllGisToOM(*reply);
-            int num = reply->GetSerial_number() - start_serial_num;
-            if ( reply->IsSetDiscard() ) {
-                // discard whole reply for now
-                continue;
-            }
-            if ( num < 0 || num >= request_count || done[num] ) {
-                // unknown serial num - bad reply
-                if ( TErrorFlags error = x_GetError(result, *reply) ) {
-                    if ( error & fError_inactivity_timeout ) {
-                        conn.Restart();
-                        NCBI_THROW_FMT(CLoaderException, eRepeatAgain,
-                                       "CId2ReaderBase: connection timed out"<<
-                                       x_ConnDescription(conn));
-                    }
-                    if ( error & fError_bad_connection ) {
-                        NCBI_THROW_FMT(CLoaderException, eConnectionFailed,
-                                       "CId2ReaderBase: connection failed"<<
-                                       x_ConnDescription(conn));
-                    }
+                catch ( CException& exc ) {
+                    NCBI_RETHROW(exc, CLoaderException, eOtherError,
+                                 "CId2ReaderBase: failed to process reply: "+
+                                 x_ConnDescription(conn));
                 }
-                else if ( reply->GetReply().IsEmpty() ) {
-                    ERR_POST_X(8, "CId2ReaderBase: bad reply serial number: "<<
-                               x_ConnDescription(conn));
-                    continue;
+                if ( x_DoneReply(packet_info, num, *reply) ) {
+                    x_UpdateLoadedSet(result, loaded_sets[num], sel);
                 }
-                NCBI_THROW_FMT(CLoaderException, eOtherError,
-                               "CId2ReaderBase: bad reply serial number: "<<
-                               x_ConnDescription(conn));
-            }
-            try {
-                x_ProcessReply(result, loaded_sets[num], *reply);
-            }
-            catch ( CException& exc ) {
-                NCBI_RETHROW(exc, CLoaderException, eOtherError,
-                             "CId2ReaderBase: failed to process reply: "+
-                             x_ConnDescription(conn));
-            }
-            if ( reply->IsSetEnd_of_reply() ) {
-                done[num] = true;
-                x_UpdateLoadedSet(result, loaded_sets[num], sel);
-                --remaining_count;
             }
+            reply.Reset();
         }
-        reply.Reset();
         if ( conn.IsAllocated() ) {
             x_EndOfPacket(conn);
         }
@@ -2387,10 +2520,10 @@ void CId2ReaderBase::x_ProcessGetSeqIdSeqId(
         ITERATE ( CID2_Reply_Get_Seq_id::TSeq_id, it, reply.GetSeq_id() ) {
             if ( (**it).IsGi() ) {
                 ret.gi = (**it).GetGi();
-                ret.sequence_found = true;
                 break;
             }
         }
+        ret.sequence_found = !got_no_ids;
         SetAndSaveSeq_idGi(result, seq_id, ret);
     }
     if ( req.GetSeq_id_type() & req.eSeq_id_type_text ) {
@@ -2398,10 +2531,10 @@ void CId2ReaderBase::x_ProcessGetSeqIdSeqId(
         ITERATE ( CID2_Reply_Get_Seq_id::TSeq_id, it, reply.GetSeq_id() ) {
             if ( (**it).GetTextseq_Id() ) {
                 ret.acc_ver = CSeq_id_Handle::GetHandle(**it);
-                ret.sequence_found = true;
                 break;
             }
         }
+        ret.sequence_found = !got_no_ids;
         SetAndSaveSeq_idAccVer(result, seq_id, ret);
     }
     if ( req.GetSeq_id_type() & req.eSeq_id_type_label ) {
diff --git a/c++/src/objtools/data_loaders/genbank/reader_service.cpp b/c++/src/objtools/data_loaders/genbank/reader_service.cpp
index ad7d9c4..eec153d 100644
--- a/c++/src/objtools/data_loaders/genbank/reader_service.cpp
+++ b/c++/src/objtools/data_loaders/genbank/reader_service.cpp
@@ -1,4 +1,4 @@
-/*  $Id: reader_service.cpp 446572 2014-09-16 19:05:59Z grichenk $
+/*  $Id: reader_service.cpp 505968 2016-06-30 15:11:12Z vasilche $
 * ===========================================================================
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
@@ -176,7 +176,8 @@ CReaderServiceConnector::Connect(int error_count)
     
     CRef<SServerScanInfo> scan_info;
 
-    if ( NStr::StartsWith(m_ServiceName, "http://") ) {
+    if ( NStr::StartsWith(m_ServiceName, "http://") ||
+         NStr::StartsWith(m_ServiceName, "https://") ) {
         if ( s_GetDebugLevel() > 0 ) {
             CDebugPrinter s("CReaderConnector");
             s << "Opening HTTP connection to " << m_ServiceName;
diff --git a/c++/src/objtools/data_loaders/genbank/reader_snp.cpp b/c++/src/objtools/data_loaders/genbank/reader_snp.cpp
index ae8237b..ad89b59 100644
--- a/c++/src/objtools/data_loaders/genbank/reader_snp.cpp
+++ b/c++/src/objtools/data_loaders/genbank/reader_snp.cpp
@@ -1,4 +1,4 @@
-/*  $Id: reader_snp.cpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: reader_snp.cpp 493171 2016-02-24 19:31:13Z vasilche $
  * ===========================================================================
  *                            PUBLIC DOMAIN NOTICE
  *               National Center for Biotechnology Information
diff --git a/c++/src/objtools/data_loaders/genbank/request_result.cpp b/c++/src/objtools/data_loaders/genbank/request_result.cpp
index a13aae5..5b574ff 100644
--- a/c++/src/objtools/data_loaders/genbank/request_result.cpp
+++ b/c++/src/objtools/data_loaders/genbank/request_result.cpp
@@ -1,4 +1,4 @@
-/*  $Id: request_result.cpp 494478 2016-03-07 19:26:06Z ivanov $
+/*  $Id: request_result.cpp 493171 2016-02-24 19:31:13Z vasilche $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/edit/Makefile.edit.lib b/c++/src/objtools/edit/Makefile.edit.lib
index 2e9c44c..e5f6752 100644
--- a/c++/src/objtools/edit/Makefile.edit.lib
+++ b/c++/src/objtools/edit/Makefile.edit.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.edit.lib 493845 2016-03-02 14:05:29Z ivanov $
+# $Id: Makefile.edit.lib 501626 2016-05-17 17:32:10Z kornbluh $
 
 # Build library "xobjedit"
 ###############################
@@ -18,7 +18,7 @@ DLL_LIB = $(XFORMAT_LIBS) xregexp $(PCRE_LIB) $(SOBJMGR_LIBS)
 
 ASN_DEP = seqset valid macro
 
-WATCHERS = bollin kornbluh gotvyans
+WATCHERS = bollin gotvyans
 
 
 USES_LIBRARIES =  \
diff --git a/c++/src/objtools/edit/apply_object.cpp b/c++/src/objtools/edit/apply_object.cpp
index 596a275..9dfde06 100644
--- a/c++/src/objtools/edit/apply_object.cpp
+++ b/c++/src/objtools/edit/apply_object.cpp
@@ -1,4 +1,4 @@
-/*  $Id: apply_object.cpp 447037 2014-09-22 11:21:25Z bollin $
+/*  $Id: apply_object.cpp 494538 2016-03-08 14:31:04Z bollin $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/edit/autodef.cpp b/c++/src/objtools/edit/autodef.cpp
index 1a73f36..e95008b 100644
--- a/c++/src/objtools/edit/autodef.cpp
+++ b/c++/src/objtools/edit/autodef.cpp
@@ -1,4 +1,4 @@
-/*  $Id: autodef.cpp 499840 2016-04-28 16:08:14Z ivanov $
+/*  $Id: autodef.cpp 511804 2016-08-24 17:35:08Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -70,6 +70,28 @@ CAutoDef::~CAutoDef()
 }
 
 
+bool s_NeedFeatureClause(const CBioseq& b) 
+{
+    if (!b.IsSetAnnot()) {
+        return true;
+    }
+    size_t num_features = 0;
+
+    ITERATE(CBioseq::TAnnot, a, b.GetAnnot()) {
+        if ((*a)->IsFtable()) {
+            num_features += (*a)->GetData().GetFtable().size();
+            if (num_features > 100) {
+                break;
+            }
+        }
+    }
+    if (num_features < 100) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
 void CAutoDef::AddSources (CSeq_entry_Handle se)
 {
     
@@ -78,7 +100,7 @@ void CAutoDef::AddSources (CSeq_entry_Handle se)
     for ( ; seq_iter; ++seq_iter ) {
         CSeqdesc_CI dit((*seq_iter), CSeqdesc::e_Source);
         if (dit) {
-            string feature_clauses = x_GetFeatureClauses(*seq_iter);
+            string feature_clauses = s_NeedFeatureClause(*(seq_iter->GetCompleteBioseq())) ? x_GetFeatureClauses(*seq_iter) : kEmptyStr;
             const CBioSource& bsrc = dit->GetSource();
             m_OrigModCombo.AddSource(bsrc, feature_clauses);
         }
@@ -480,6 +502,11 @@ void CAutoDef::x_RemoveOptionalFeatures(CAutoDefFeatureClause_Base *main_clause,
         main_clause->RemoveOptionalMobileElements();
     }
     
+    // keep misc_recombs only if requested
+    if (!m_Options.GetKeepMiscRecomb()) {
+        main_clause->RemoveFeaturesByType(CSeqFeatData::eSubtype_misc_recomb);
+    }
+
     // delete subclauses at end, so that loneliness calculations will be correct
     main_clause->RemoveDeletedSubclauses();
 }
@@ -622,6 +649,11 @@ bool s_HasPromoter(CBioseq_Handle bh)
 
 string CAutoDef::x_GetFeatureClauses(CBioseq_Handle bh)
 {
+    const string& custom = m_Options.GetCustomFeatureClause();
+    if (!NStr::IsBlank(custom)) {
+        return custom;
+    }
+
     CAutoDefFeatureClause_Base main_clause;
     CAutoDefFeatureClause *new_clause;
     CRange<TSeqPos> range;
@@ -726,6 +758,11 @@ string CAutoDef::x_GetFeatureClauses(CBioseq_Handle bh)
         }
         ++feat_ci;
     }
+
+    // optionally remove misc_feature subfeatures
+    if (m_Options.GetSuppressMiscFeatureSubfeatures()) {
+        main_clause.RemoveFeaturesUnderType(CSeqFeatData::eSubtype_misc_feature);
+    }
     
     // Group alt-spliced exons first, so that they will be associated with the correct genes and mRNAs
     main_clause.GroupAltSplicedExons(bh);
@@ -1029,7 +1066,10 @@ string CAutoDef::GetOneFeatureClauseList(CBioseq_Handle bh, unsigned int genome_
     string feature_clauses = "";
     if (m_Options.GetFeatureListType() == CAutoDefOptions::eListAllFeatures ||
         (IsBioseqmRNA(bh) && IsInGenProdSet(bh))) {
-        feature_clauses = " " + x_GetFeatureClauses(bh);
+        feature_clauses = x_GetFeatureClauses(bh);
+        if (!NStr::IsBlank(feature_clauses)) {
+            feature_clauses = " " + feature_clauses;
+        }
         string ending = x_GetFeatureClauseProductEnding(feature_clauses, bh);
         if (m_Options.GetAltSpliceFlag()) {
             if (NStr::IsBlank(ending)) {
diff --git a/c++/src/objtools/edit/autodef_available_modifier.cpp b/c++/src/objtools/edit/autodef_available_modifier.cpp
index 8367541..b2261d7 100644
--- a/c++/src/objtools/edit/autodef_available_modifier.cpp
+++ b/c++/src/objtools/edit/autodef_available_modifier.cpp
@@ -1,4 +1,4 @@
-/*  $Id: autodef_available_modifier.cpp 500380 2016-05-04 13:50:52Z ivanov $
+/*  $Id: autodef_available_modifier.cpp 514107 2016-09-19 16:06:20Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -353,90 +353,21 @@ string CAutoDefAvailableModifier::GetOrgModLabel(COrgMod::ESubtype st)
         case COrgMod::eSubtype_nat_host:
             label = "specific host";
             break;
-        case COrgMod::eSubtype_strain:
-            label = "strain";
-            break;
-        case COrgMod::eSubtype_substrain:
-            label = "substrain";
-            break;
-        case COrgMod::eSubtype_type:
-            label = "type";
-            break;
-        case COrgMod::eSubtype_subtype:
-            label = "subtype";
-            break;
-        case COrgMod::eSubtype_variety:
-            label = "variety";
-            break;
-        case COrgMod::eSubtype_serotype:
-            label = "serotype";
-            break;
-        case COrgMod::eSubtype_serogroup:
-            label = "serogroup";
-            break;
-        case COrgMod::eSubtype_serovar:
-            label = "serovar";
-            break;
-        case COrgMod::eSubtype_cultivar:
-            label = "cultivar";
-            break;
-        case COrgMod::eSubtype_pathovar:
-            label = "pathovar";
-            break;
-        case COrgMod::eSubtype_chemovar:
-            label = "chemovar";
-            break;
-        case COrgMod::eSubtype_biovar:
-            label = "biovar";
-            break;
-        case COrgMod::eSubtype_biotype:
-            label = "biotype";
-            break;
-        case COrgMod::eSubtype_group:
-            label = "group";
-            break;
-        case COrgMod::eSubtype_subgroup:
-            label = "subgroup";
-            break;
-        case COrgMod::eSubtype_isolate:
-            label = "isolate";
+        case COrgMod::eSubtype_culture_collection:
+            label = "culture";
             break;
         case COrgMod::eSubtype_common:
             label = "common name";
             break;
-        case COrgMod::eSubtype_acronym:
-            label = "acronym";
-            break;
         case COrgMod::eSubtype_sub_species:
             label = "subspecies";
             break;
         case COrgMod::eSubtype_specimen_voucher:
             label = "voucher";
             break;
-        case COrgMod::eSubtype_authority:
-            label = "authority";
-            break;
-        case COrgMod::eSubtype_forma:
-            label = "forma";
-            break;
         case COrgMod::eSubtype_forma_specialis:
             label = "forma specialis";
             break;
-        case COrgMod::eSubtype_ecotype:
-            label = "ecotype";
-            break;
-        case COrgMod::eSubtype_synonym:
-            label = "synonym";
-            break;
-        case COrgMod::eSubtype_anamorph:
-            label = "anamorph";
-            break;
-        case COrgMod::eSubtype_teleomorph:
-            label = "teleomorph";
-            break;
-        case COrgMod::eSubtype_breed:
-            label = "breed";
-            break;
         case COrgMod::eSubtype_gb_acronym:
             label = "acronym";
             break;
@@ -457,9 +388,17 @@ string CAutoDefAvailableModifier::GetOrgModLabel(COrgMod::ESubtype st)
 string CAutoDefAvailableModifier::Label() const
 {
     if (m_IsOrgMod) {
-        return GetOrgModLabel(m_OrgModType);
+        if (m_OrgModType == COrgMod::eSubtype_other) {
+            return "OrgMod Note";
+        } else {
+            return GetOrgModLabel(m_OrgModType);
+        }
     } else {
-        return GetSubSourceLabel(m_SubSrcType);
+        if (m_SubSrcType == CSubSource::eSubtype_other) {
+            return "SubSource Note";
+        } else {
+            return GetSubSourceLabel(m_SubSrcType);
+        }
     }
 }
 
diff --git a/c++/src/objtools/edit/autodef_feature_clause.cpp b/c++/src/objtools/edit/autodef_feature_clause.cpp
index 33f2f5e..b74de87 100644
--- a/c++/src/objtools/edit/autodef_feature_clause.cpp
+++ b/c++/src/objtools/edit/autodef_feature_clause.cpp
@@ -1,4 +1,4 @@
-/*  $Id: autodef_feature_clause.cpp 494438 2016-03-07 17:09:04Z ivanov $
+/*  $Id: autodef_feature_clause.cpp 519214 2016-11-14 16:05:29Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -32,7 +32,6 @@
 
 #include <ncbi_pch.hpp>
 #include <objtools/edit/autodef.hpp>
-#include <objtools/edit/gene_utils.hpp>
 #include <corelib/ncbimisc.hpp>
 #include <objmgr/seqdesc_ci.hpp>
 #include <objmgr/bioseq_ci.hpp>
@@ -198,8 +197,10 @@ bool CAutoDefFeatureClause::IsRecognizedFeature()
         || subtype == CSeqFeatData::eSubtype_misc_RNA
         || subtype == CSeqFeatData::eSubtype_ncRNA
         || subtype == CSeqFeatData::eSubtype_preRNA
+        || subtype == CSeqFeatData::eSubtype_tmRNA
         || subtype == CSeqFeatData::eSubtype_D_loop
         || subtype == CSeqFeatData::eSubtype_regulatory
+        || subtype == CSeqFeatData::eSubtype_misc_recomb
         || IsNoncodingProductFeat()
         || IsMobileElement()
         || IsInsertionSequence()
@@ -238,6 +239,19 @@ bool CAutoDefFeatureClause::x_IsPseudo()
 }
 
 
+void CAutoDefFeatureClause::x_TypewordFromSequence()
+{
+    if (m_Biomol == CMolInfo::eBiomol_genomic) {
+        m_Typeword = "genomic sequence";
+    } else if (m_Biomol == CMolInfo::eBiomol_mRNA) {
+        m_Typeword = "mRNA sequence";
+    } else {
+        m_Typeword = "sequence";
+    }
+    m_TypewordChosen = true;
+}
+
+
 bool CAutoDefFeatureClause::x_GetFeatureTypeWord(string &typeword)
 {
     string qual, comment;
@@ -300,6 +314,10 @@ bool CAutoDefFeatureClause::x_GetFeatureTypeWord(string &typeword)
                 }
             }
             break;
+        case CSeqFeatData::eSubtype_misc_recomb:
+            x_TypewordFromSequence();
+            return true;
+            break;
         case CSeqFeatData::eSubtype_biosrc:
             if (IsEndogenousVirusSourceFeature()) {
                 typeword = "endogenous virus";
@@ -588,6 +606,18 @@ string CAutoDefFeatureClause::x_GetGeneName(const CGene_ref& gref, bool suppress
 }
 
 
+void s_UseCommentBeforeSemicolon(const CSeq_feat& feat, string& label)
+{
+    if (feat.IsSetComment()) {
+        label = feat.GetComment();
+        string::size_type pos = NStr::Find(label, ";");
+        if (pos != NCBI_NS_STD::string::npos) {
+            label = label.substr(0, pos);
+        }
+    }
+}
+
+
 /* Frequently the product associated with a feature is listed as part of the
  * description of the feature in the definition line.  This function determines
  * the name of the product associated with this specific feature.  Some
@@ -623,6 +653,9 @@ bool CAutoDefFeatureClause::x_GetProductName(string &product_name)
             product_name = comment;
             return true;
         }
+    } else if (m_MainFeat.GetData().GetSubtype() == CSeqFeatData::eSubtype_tmRNA) {
+        product_name = "tmRNA";
+        return true;
     } else if (m_MainFeat.GetData().Which() == CSeqFeatData::e_Rna) {
         product_name = m_MainFeat.GetData().GetRna().GetRnaProductName();
         if (NStr::IsBlank(product_name) && m_MainFeat.IsSetComment()) {
@@ -631,6 +664,18 @@ bool CAutoDefFeatureClause::x_GetProductName(string &product_name)
         return true;
     } else if (m_MainFeat.GetData().GetSubtype() == CSeqFeatData::eSubtype_regulatory) {
         return true;
+    } else if (m_MainFeat.GetData().GetSubtype() == CSeqFeatData::eSubtype_misc_recomb) {
+        if (m_MainFeat.IsSetQual()) {
+            ITERATE(CSeq_feat::TQual, q, m_MainFeat.GetQual()) {
+                if ((*q)->IsSetQual() && NStr::Equal((*q)->GetQual(), "recombination_class") &&
+                    (*q)->IsSetVal() && !NStr::IsBlank((*q)->GetVal())) {
+                    product_name = (*q)->GetVal();
+                    return true;
+                }
+            }
+        }
+        s_UseCommentBeforeSemicolon(m_MainFeat, product_name);
+        return true;
     } else {
         string label;
         
@@ -646,6 +691,11 @@ bool CAutoDefFeatureClause::x_GetProductName(string &product_name)
         
         if (NStr::IsBlank(label)) {                    
             feature::GetLabel(m_MainFeat, &label, feature::fFGL_Content);
+            if ((subtype == CSeqFeatData::eSubtype_exon && NStr::Equal(label, "exon"))
+                || (subtype == CSeqFeatData::eSubtype_intron && NStr::Equal(label, "[intron]"))
+                || (subtype != CSeqFeatData::eSubtype_exon && subtype != CSeqFeatData::eSubtype_intron)) {
+                label = "";
+            }
         }
         if ((subtype == CSeqFeatData::eSubtype_cdregion && !NStr::Equal(label, "CDS"))
             || (subtype == CSeqFeatData::eSubtype_mRNA && !NStr::Equal(label, "mRNA"))
@@ -662,12 +712,6 @@ bool CAutoDefFeatureClause::x_GetProductName(string &product_name)
         }
        
         if (!NStr::IsBlank(label)) {
-            string::size_type pos = NStr::Find(label, ";");
-            if (pos != NCBI_NS_STD::string::npos) {
-                label = label.substr(0, pos);
-            }
-        }
-        if (!NStr::IsBlank(label)) {
             product_name = label;
             return true;
         } else {
@@ -696,7 +740,8 @@ bool CAutoDefFeatureClause::x_GetExonDescription(string &description)
     string label;
     feature::GetLabel(m_MainFeat, &label, feature::fFGL_Content);
 
-    if ((subtype == CSeqFeatData::eSubtype_exon && NStr::Equal(label, "exon"))
+    if ((subtype == CSeqFeatData::eSubtype_exon && 
+         (NStr::Equal(label, "exon") || NStr::Equal(label, "[exon]")))
         || (subtype == CSeqFeatData::eSubtype_intron && NStr::Equal(label, "[intron]"))
         || (subtype != CSeqFeatData::eSubtype_exon && subtype != CSeqFeatData::eSubtype_intron)) {
         description = "";
@@ -738,6 +783,9 @@ bool CAutoDefFeatureClause::x_GetDescription(string &description)
             description = m_MainFeat.GetNamedQual("rpt_family");
             if (NStr::IsBlank(description) && m_MainFeat.IsSetComment()) {
                 description = m_MainFeat.GetComment();
+                if (IsLTR() && NStr::EndsWith(description, " LTR")) {
+                    description = description.substr(0, description.length() - 4);
+                }
             }
             return true;
         }
@@ -860,6 +908,22 @@ bool CAutoDefFeatureClause::IsLTR(const CSeq_feat& feat)
     return false;
 }
 
+/* operons suppress all subfeatures except promoters (see GB-5635) */
+void CAutoDefFeatureClause::x_GetOperonSubfeatures(string &interval)
+{
+    bool has_promoter = false;
+
+    ITERATE(TClauseList, it, m_ClauseList) {
+        if ((*it)->IsPromoter()) {
+            has_promoter = true;
+            break;
+        }
+    }
+    if (has_promoter) {
+        interval += ", promoter region, ";
+    }
+}
+
 
 /* This function calculates the "interval" for a clause in the definition
  * line.  The interval could be an empty string, it could indicate whether
@@ -891,13 +955,17 @@ bool CAutoDefFeatureClause::x_GetGenericInterval (string &interval, bool suppres
         || subtype == CSeqFeatData::eSubtype_5UTR
         || subtype == CSeqFeatData::eSubtype_3UTR
         || (subtype == CSeqFeatData::eSubtype_repeat_region && !NStr::Equal(m_Typeword, "endogenous virus"))
+        || subtype == CSeqFeatData::eSubtype_misc_recomb
         || IsLTR()) {
         return false;
     } 
     
     CAutoDefFeatureClause_Base *utr3 = NULL;
     
-    if (!m_SuppressSubfeatures) {
+    if (subtype == CSeqFeatData::eSubtype_operon) {
+        // suppress subclauses except promoters
+        x_GetOperonSubfeatures(interval);
+    } else if (!m_SuppressSubfeatures) {
         // label subclauses
         // check to see if 3'UTR is present, and whether there are any other features
         for (k = 0; k < m_ClauseList.size(); k++) {
@@ -1010,7 +1078,7 @@ bool CAutoDefFeatureClause::SameStrand(const CSeq_loc& loc)
     
 }
 
-bool CAutoDefFeatureClause::IsPartial()
+bool CAutoDefFeatureClause::IsPartial() const
 {
     if (m_ClauseLocation->IsPartialStart(eExtreme_Biological)
         || m_ClauseLocation->IsPartialStop(eExtreme_Biological)) {
@@ -1128,6 +1196,8 @@ bool CAutoDefFeatureClause::AddGene (CAutoDefFeatureClause_Base *gene_clause, bo
         && subtype != CSeqFeatData::eSubtype_otherRNA
         && subtype != CSeqFeatData::eSubtype_ncRNA
         && subtype != CSeqFeatData::eSubtype_precursor_RNA
+        && subtype != CSeqFeatData::eSubtype_preRNA
+        && subtype != CSeqFeatData::eSubtype_tmRNA
         && subtype != CSeqFeatData::eSubtype_intron
         && subtype != CSeqFeatData::eSubtype_exon
         && !x_GetNoncodingProductFeatProduct(noncoding_product_name)) {
@@ -1140,7 +1210,7 @@ bool CAutoDefFeatureClause::AddGene (CAutoDefFeatureClause_Base *gene_clause, bo
         // find overlapping gene for this feature    
         CAutoDefGeneClause *gene = dynamic_cast<CAutoDefGeneClause *>(gene_clause);
         bool suppress_locus_tag = gene ? gene->GetSuppressLocusTag() : false;
-        CConstRef <CSeq_feat> gene_for_feat = edit::GetGeneForFeature(m_MainFeat, m_BH.GetScope());
+        CConstRef <CSeq_feat> gene_for_feat = sequence::GetGeneForFeature(m_MainFeat, m_BH.GetScope());
         if (gene_for_feat && NStr::Equal(x_GetGeneName(gene_for_feat->GetData().GetGene(), suppress_locus_tag), gene_clause->GetGeneName())) {
             used_gene = true;
             m_HasGene = true;
@@ -1175,6 +1245,10 @@ bool CAutoDefFeatureClause::OkToGroupUnderByType(CAutoDefFeatureClause_Base *par
     }
     CSeqFeatData::ESubtype subtype = m_MainFeat.GetData().GetSubtype();
     CSeqFeatData::ESubtype parent_subtype = parent_clause->GetMainFeatureSubtype();
+
+    if (parent_subtype == CSeqFeatData::eSubtype_mobile_element) {
+        return true;
+    }
     
     if (subtype == CSeqFeatData::eSubtype_exon || subtype == CSeqFeatData::eSubtype_intron) {
         if (parent_subtype == CSeqFeatData::eSubtype_cdregion
@@ -1339,12 +1413,12 @@ void CAutoDefFeatureClause::ReverseCDSClauseLists()
         && GetMainFeatureSubtype() == CSeqFeatData::eSubtype_cdregion) {
         TClauseList tmp;
         tmp.clear();
-        for (unsigned int k = m_ClauseList.size(); k > 0; k--) {
+        for (size_t k = m_ClauseList.size(); k > 0; k--) {
             tmp.push_back(m_ClauseList[k - 1]);
             m_ClauseList[k - 1] = NULL;
         }
         m_ClauseList.clear();
-        for (unsigned int k = 0; k < tmp.size(); k++) {
+        for (size_t k = 0; k < tmp.size(); k++) {
             m_ClauseList.push_back(tmp[k]);
             tmp[k] = NULL;
         }
@@ -1357,6 +1431,7 @@ void CAutoDefFeatureClause::ReverseCDSClauseLists()
 }
 
 
+
 bool CAutoDefFeatureClause::ShouldRemoveExons()
 {
     unsigned int subtype = GetMainFeatureSubtype();
@@ -1364,12 +1439,43 @@ bool CAutoDefFeatureClause::ShouldRemoveExons()
     if (subtype == CSeqFeatData::eSubtype_mRNA) {
         return false;
     } else if (subtype == CSeqFeatData::eSubtype_cdregion) {
-        return ! IsPartial();
+        if (IsPartial()) {
+            // keep only if exons have numbers
+            for (size_t k = 0; k < m_ClauseList.size(); k++) {
+                if (m_ClauseList[k]->IsExonWithNumber()) {
+                    return false;
+                }
+            }
+            return true;
+        } else {
+            return true;
+        }
     } else {
         return true;
     }
 }
 
+bool CAutoDefFeatureClause::IsExonWithNumber()
+{
+    bool rval = false;
+
+    if (m_MainFeat.IsSetData() &&
+        m_MainFeat.GetData().GetSubtype() == CSeqFeatData::eSubtype_exon &&
+        m_MainFeat.IsSetQual()) {
+        ITERATE(CSeq_feat::TQual, it, m_MainFeat.GetQual()) {
+            if ((*it)->IsSetQual() &&
+                NStr::Equal((*it)->GetQual(), "number") &&
+                (*it)->IsSetVal() &&
+                !NStr::IsBlank((*it)->GetVal())) {
+                rval = true;
+                break;
+            }
+        }
+    }
+    return rval;
+}
+
+
 bool CAutoDefFeatureClause::IsBioseqPrecursorRNA()
 {
     if (m_Biomol == CMolInfo::eBiomol_pre_RNA && GetMainFeatureSubtype() == CSeqFeatData::eSubtype_preRNA) {
@@ -1813,6 +1919,23 @@ void CAutoDefParsedClause::SetMiscRNAWord(const string& phrase)
         }
         SetTypeword("gene");
         SetTypewordFirst(false);
+    } else if (word_type == eMiscRnaWordType_tRNA) {
+        string gene_name;
+        string product_name;
+        if (CAutoDefParsedtRNAClause::ParseString(phrase, gene_name, product_name)) {
+            m_TypewordChosen = true;
+            m_GeneName = gene_name;
+            if (!NStr::IsBlank(m_GeneName)) {
+                m_HasGene = true;
+            }
+            m_ProductName = product_name;
+            m_ProductNameChosen = true;
+            x_GetDescription(m_Description);
+        } else {
+            m_Description = phrase;
+        }
+        SetTypeword("gene");
+        SetTypewordFirst(false);
     }
     NStr::TruncateSpacesInPlace(m_Description);
     m_DescriptionChosen = true;
@@ -1885,14 +2008,13 @@ CAutoDefMiscCommentClause::CAutoDefMiscCommentClause(CBioseq_Handle bh, const CS
         }
         m_DescriptionChosen = true;
     }
-    if (m_Biomol == CMolInfo::eBiomol_genomic) {
-        m_Typeword = "genomic sequence";
-    } else if (m_Biomol == CMolInfo::eBiomol_mRNA) {
-        m_Typeword = "mRNA sequence";
-    } else {
+    if (NStr::EndsWith(m_Description, " sequence")) {
+        m_Description = m_Description.substr(0, m_Description.length() - 9);
         m_Typeword = "sequence";
+        m_TypewordChosen = true;
+    } else {
+        x_TypewordFromSequence();
     }
-    m_TypewordChosen = true;
     m_Interval = "";
 }
 
diff --git a/c++/src/objtools/edit/autodef_feature_clause_base.cpp b/c++/src/objtools/edit/autodef_feature_clause_base.cpp
index e6a74f2..c7e4b13 100644
--- a/c++/src/objtools/edit/autodef_feature_clause_base.cpp
+++ b/c++/src/objtools/edit/autodef_feature_clause_base.cpp
@@ -1,4 +1,4 @@
-/*  $Id: autodef_feature_clause_base.cpp 490362 2016-01-25 12:43:11Z bollin $
+/*  $Id: autodef_feature_clause_base.cpp 519214 2016-11-14 16:05:29Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -349,7 +349,7 @@ string CAutoDefFeatureClause_Base::ListClauses(bool allow_semicolons, bool suppr
     bool is_last, is_second_to_last;
     bool two_more_in_list;
     
-    unsigned int last_interval_change_before_end = x_LastIntervalChangeBeforeEnd();
+    size_t last_interval_change_before_end = x_LastIntervalChangeBeforeEnd();
     
     string full_clause_list;
     
@@ -585,14 +585,14 @@ string CAutoDefFeatureClause_Base::ListClauses(bool allow_semicolons, bool suppr
 }
 
 
-unsigned int CAutoDefFeatureClause_Base::x_LastIntervalChangeBeforeEnd ()
+size_t CAutoDefFeatureClause_Base::x_LastIntervalChangeBeforeEnd () const
 {
     if (m_ClauseList.size() < 2) {
         return 0;
     }
     string last_interval = m_ClauseList[m_ClauseList.size() - 1]->GetInterval();
     
-    for (unsigned int k = m_ClauseList.size() - 2; k > 0; k--) {
+    for (size_t k = m_ClauseList.size() - 2; k > 0; k--) {
         if (!NStr::Equal(m_ClauseList[k]->GetInterval(), last_interval)
             || (m_ClauseList[k]->IsAltSpliced() && ! m_ClauseList[k + 1]->IsAltSpliced())
             || (!m_ClauseList[k]->IsAltSpliced() && m_ClauseList[k + 1]->IsAltSpliced())) {
@@ -710,36 +710,48 @@ void CAutoDefFeatureClause_Base::ShowSubclauses()
 }
 
 
-bool CAutoDefFeatureClause_Base::x_OkToConsolidate (unsigned int clause1, unsigned int clause2)
+bool CAutoDefFeatureClause_Base::x_OkToConsolidate(const CAutoDefFeatureClause_Base& other) const
 {
-    if (clause1 == clause2
-        || clause1 >= m_ClauseList.size() || clause2 >= m_ClauseList.size()
-        || m_ClauseList[clause1]->IsMarkedForDeletion()
-        || m_ClauseList[clause2]->IsMarkedForDeletion()
-        || (m_ClauseList[clause1]->IsPartial() && !m_ClauseList[clause2]->IsPartial())
-        || (!m_ClauseList[clause1]->IsPartial() && m_ClauseList[clause2]->IsPartial())
-        || !NStr::Equal(m_ClauseList[clause1]->GetDescription(), m_ClauseList[clause2]->GetDescription())
-        || (m_ClauseList[clause1]->IsAltSpliced() && !m_ClauseList[clause2]->IsAltSpliced())
-        || (!m_ClauseList[clause1]->IsAltSpliced() && m_ClauseList[clause2]->IsAltSpliced())) {
-        
+    if (IsMarkedForDeletion() ||
+        other.IsMarkedForDeletion() ||
+        (IsPartial() && !other.IsPartial()) ||
+        (!IsPartial() && other.IsPartial())
+        || !NStr::Equal(GetDescription(), other.GetDescription())
+        || (IsAltSpliced() && !other.IsAltSpliced())
+        || (!IsAltSpliced() && other.IsAltSpliced())
+        || !NStr::Equal(GetTypeword(), other.GetTypeword())) {
+
         return false;
     }
-    
-    CSeqFeatData::ESubtype subtype1 = m_ClauseList[clause1]->GetMainFeatureSubtype();
-    CSeqFeatData::ESubtype subtype2 = m_ClauseList[clause2]->GetMainFeatureSubtype();
-    
-    if ((subtype1 == CSeqFeatData::eSubtype_cdregion 
-         && subtype2 != CSeqFeatData::eSubtype_cdregion
-         && subtype2 != CSeqFeatData::eSubtype_gene)
+
+    CSeqFeatData::ESubtype subtype1 = GetMainFeatureSubtype();
+    CSeqFeatData::ESubtype subtype2 = other.GetMainFeatureSubtype();
+
+    if ((subtype1 == CSeqFeatData::eSubtype_cdregion
+        && subtype2 != CSeqFeatData::eSubtype_cdregion
+        && subtype2 != CSeqFeatData::eSubtype_gene)
         || (subtype1 != CSeqFeatData::eSubtype_cdregion
-            && subtype1 != CSeqFeatData::eSubtype_gene
-            && subtype2 == CSeqFeatData::eSubtype_cdregion)) {
+        && subtype1 != CSeqFeatData::eSubtype_gene
+        && subtype2 == CSeqFeatData::eSubtype_cdregion)) {
         return false;
     }
     return true;
 }
 
 
+bool CAutoDefFeatureClause_Base::x_OkToConsolidate (unsigned int clause1, unsigned int clause2)
+{
+    if (clause1 == clause2 || 
+        clause1 >= m_ClauseList.size() || 
+        clause2 >= m_ClauseList.size() ||
+        !m_ClauseList[clause1] || 
+        !m_ClauseList[clause2]) {
+        return false;
+    }
+    return m_ClauseList[clause1]->x_OkToConsolidate(*(m_ClauseList[clause2]));
+}
+
+
 void CAutoDefFeatureClause_Base::Consolidate(CAutoDefFeatureClause_Base& other, bool suppress_allele)
 {
     // Add subfeatures from new clause to last clause
@@ -851,7 +863,7 @@ bool ShareInterval(const CSeq_loc& loc1, const CSeq_loc& loc2)
  * must have the same gene, must share a complete interval, and must have
  * similarly named products.
  */
-bool CAutoDefFeatureClause_Base::x_MeetAltSpliceRules (unsigned int clause1, unsigned int clause2, string &splice_name)
+bool CAutoDefFeatureClause_Base::x_MeetAltSpliceRules (size_t clause1, size_t clause2, string &splice_name)
 {
     if (clause1 >= m_ClauseList.size() || clause2 >= m_ClauseList.size()
         || m_ClauseList[clause1]->GetMainFeatureSubtype() != CSeqFeatData::eSubtype_cdregion
@@ -888,8 +900,8 @@ bool CAutoDefFeatureClause_Base::x_MeetAltSpliceRules (unsigned int clause1, uns
     }
     
     unsigned int match_left_len = 1, match_left_token = 0;
-    unsigned int len1 = product1.length();
-    unsigned int len2 = product2.length();
+    size_t len1 = product1.length();
+    size_t len2 = product2.length();
 
     // find the length of match on the left
     while (match_left_len < len1 && match_left_len < len2
@@ -969,7 +981,7 @@ bool CAutoDefFeatureClause_Base::x_MeetAltSpliceRules (unsigned int clause1, uns
 
 void CAutoDefFeatureClause_Base::FindAltSplices(bool suppress_allele)
 {
-    unsigned int last_cds = m_ClauseList.size();
+    size_t last_cds = m_ClauseList.size();
     string splice_name;
     
     for (unsigned int k = 0; k < m_ClauseList.size(); k++) {
@@ -1226,13 +1238,13 @@ void CAutoDefFeatureClause_Base::GroupAltSplicedExons(CBioseq_Handle bh)
 
 void CAutoDefFeatureClause_Base::ExpandExonLists()
 {
-    unsigned int k = 0;
+    size_t k = 0;
     
     while (k < m_ClauseList.size()) {
         if (m_ClauseList[k]->IsExonList()) {
             TClauseList remaining;
             remaining.clear();
-            for (unsigned int j = k + 1; j < m_ClauseList.size(); j++) {
+            for (size_t j = k + 1; j < m_ClauseList.size(); j++) {
                 remaining.push_back(m_ClauseList[j]);
                 m_ClauseList[j] = NULL;
             }
@@ -1434,6 +1446,28 @@ void CAutoDefFeatureClause_Base::RemoveFeaturesByType(unsigned int feature_type,
 }
 
 
+void CAutoDefFeatureClause_Base::RemoveFeaturesUnderType(unsigned int feature_type)
+{
+    for (unsigned int k = 0; k < m_ClauseList.size(); k++) {
+        if ((unsigned int)m_ClauseList[k]->GetMainFeatureSubtype() == feature_type) {
+            RemoveFeaturesInLocation(*(m_ClauseList[k]->GetLocation()));
+        }
+    }
+}
+
+
+void CAutoDefFeatureClause_Base::RemoveFeaturesInLocation(const CSeq_loc& loc)
+{
+    for (unsigned int k = 0; k < m_ClauseList.size(); k++) {
+        if (m_ClauseList[k]->CompareLocation(loc) == sequence::eContains) {
+            m_ClauseList[k]->MarkForDeletion();
+        } else {
+            m_ClauseList[k]->RemoveFeaturesInLocation(loc);
+        }        
+    }
+}
+
+
 bool CAutoDefFeatureClause_Base::IsFeatureTypeLonely(unsigned int feature_type)
 {
     unsigned int k, subtype;
@@ -1465,12 +1499,6 @@ void CAutoDefFeatureClause_Base::RemoveFeaturesInmRNAsByType(unsigned int featur
 }
 
 
-bool CAutoDefFeatureClause_Base::ShouldRemoveExons()
-{
-    return false;
-}
-
-
 void CAutoDefFeatureClause_Base::RemoveUnwantedExons()
 {
     for (unsigned int k = 0; k < m_ClauseList.size(); k++) {
@@ -1702,7 +1730,8 @@ static string kRNAMiscWords[] = {
     "external transcribed spacer",
     "ribosomal RNA intergenic spacer",
     "ribosomal RNA",
-    "intergenic spacer"
+    "intergenic spacer",
+    "tRNA-"
 };
 
 CAutoDefFeatureClause_Base::ERnaMiscWord CAutoDefFeatureClause_Base::x_GetRnaMiscWordType(const string& phrase)
@@ -1745,7 +1774,7 @@ vector<string> CAutoDefFeatureClause_Base::GetMiscRNAElements(const string& comm
 {
     vector<string> elements;
     vector<string> parts;
-    NStr::Tokenize(comment, ",", parts, NStr::eMergeDelims);
+    NStr::Split(comment, ",", parts, NStr::fSplit_MergeDelimiters);
     if (parts.empty()) {
         return elements;
     }
@@ -1901,7 +1930,7 @@ vector<string> CAutoDefFeatureClause_Base::GetTrnaIntergenicSpacerClausePhrases(
     vector<string> elements;
 
     vector<string> parts;
-    NStr::Tokenize(comment, ",", parts, NStr::eMergeDelims);
+    NStr::Split(comment, ",", parts, NStr::fSplit_MergeDelimiters);
     if (parts.empty()) {
         return elements;
     }
@@ -1949,7 +1978,7 @@ vector<string> CAutoDefFeatureClause_Base::GetFeatureClausePhrases(string commen
         comment = comment.substr(9);
     }
     vector<string> elements;
-    NStr::Tokenize(comment, ",", elements);
+    NStr::Split(comment, ",", elements);
     bool fail = false;
     ITERATE(vector<string>, it, elements)
     {
diff --git a/c++/src/objtools/edit/autodef_mod_combo.cpp b/c++/src/objtools/edit/autodef_mod_combo.cpp
index 042644c..ed3d847 100644
--- a/c++/src/objtools/edit/autodef_mod_combo.cpp
+++ b/c++/src/objtools/edit/autodef_mod_combo.cpp
@@ -1,4 +1,4 @@
-/*  $Id: autodef_mod_combo.cpp 500380 2016-05-04 13:50:52Z ivanov $
+/*  $Id: autodef_mod_combo.cpp 514107 2016-09-19 16:06:20Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -580,6 +580,7 @@ typedef struct {
 
 static const SPreferredQual s_PreferredList[] = {
     { CSubSource::eSubtype_transgenic, false } ,
+    { COrgMod::eSubtype_culture_collection, true },
     { COrgMod::eSubtype_strain, true },
     { COrgMod::eSubtype_isolate, true },
     { COrgMod::eSubtype_cultivar, true },
@@ -592,7 +593,6 @@ static const SPreferredQual s_PreferredList[] = {
     { COrgMod::eSubtype_biotype, true },
     { COrgMod::eSubtype_biovar, true },
     { COrgMod::eSubtype_chemovar, true },
-    { COrgMod::eSubtype_culture_collection, true },
     { COrgMod::eSubtype_pathovar, true },
     { COrgMod::eSubtype_serogroup, true },
     { COrgMod::eSubtype_serovar, true },
diff --git a/c++/src/objtools/edit/autodef_options.cpp b/c++/src/objtools/edit/autodef_options.cpp
index d1a613a..6fcdc5f 100644
--- a/c++/src/objtools/edit/autodef_options.cpp
+++ b/c++/src/objtools/edit/autodef_options.cpp
@@ -1,4 +1,4 @@
-/*  $Id: autodef_options.cpp 499840 2016-04-28 16:08:14Z ivanov $
+/*  $Id: autodef_options.cpp 510717 2016-08-15 17:12:40Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -74,6 +74,9 @@ CRef<CUser_object> CAutoDefOptions::MakeUserObject() const
     if (!NStr::IsBlank(m_TargetedLocusName)) {
         user->SetData().push_back(x_MakeTargetedLocusName());
     }
+    if (!NStr::IsBlank(m_CustomFeatureClause)) {
+        user->SetData().push_back(x_MakeCustomFeatureClause());
+    }
 
     return user;
 }
@@ -132,6 +135,10 @@ void CAutoDefOptions::InitFromUserObject(const CUser_object& obj)
                 if ((*it)->IsSetData() && (*it)->GetData().IsStr()) {
                     m_TargetedLocusName = (*it)->GetString();
                 }
+            } else if (field_type == eOptionFieldType_CustomFeatureClause) {
+                if ((*it)->IsSetData() && (*it)->GetData().IsStr()) {
+                    m_CustomFeatureClause = (*it)->GetString();
+                }
             }
         }
     }
@@ -161,6 +168,7 @@ typedef SStaticPair<const char *, unsigned int> TNameValPair;
 const TNameValPair sc_FieldTypes[] = {
         { "AllowModAtEndOfTaxname", CAutoDefOptions::eOptionFieldType_AllowModAtEndOfTaxname },
         { "AltSpliceFlag", CAutoDefOptions::eOptionFieldType_AltSpliceFlag },
+        { "CustomFeatureClause", CAutoDefOptions::eOptionFieldType_CustomFeatureClause },
         { "DoNotApplyToAff", CAutoDefOptions::eOptionFieldType_DoNotApplyToAff },
         { "DoNotApplyToCf", CAutoDefOptions::eOptionFieldType_DoNotApplyToCf },
         { "DoNotApplyToNr", CAutoDefOptions::eOptionFieldType_DoNotApplyToNr },
@@ -175,6 +183,7 @@ const TNameValPair sc_FieldTypes[] = {
         { "KeepExons", CAutoDefOptions::eOptionFieldType_KeepExons },
         { "KeepIntrons", CAutoDefOptions::eOptionFieldType_KeepIntrons },
         { "KeepLTRs", CAutoDefOptions::eOptionFieldType_KeepLTRs },
+        { "KeepMiscRecomb", CAutoDefOptions::eOptionFieldType_KeepMiscRecomb },
         { "KeepMobileElements", CAutoDefOptions::eOptionFieldType_KeepMobileElements },
         { "KeepPrecursorRNA", CAutoDefOptions::eOptionFieldType_KeepPrecursorRNA },
         { "KeepRegulatoryFeatures", CAutoDefOptions::eOptionFieldType_KeepRegulatoryFeatures },
@@ -191,6 +200,7 @@ const TNameValPair sc_FieldTypes[] = {
         { "SuppressedFeatures", CAutoDefOptions::eOptionFieldType_SuppressedFeatures },
         { "SuppressFeatureAltSplice", CAutoDefOptions::eOptionFieldType_SuppressFeatureAltSplice },
         { "SuppressLocusTags", CAutoDefOptions::eOptionFieldType_SuppressLocusTags },
+        { "SuppressMiscFeatureSubfeatures", CAutoDefOptions::eOptionFieldType_SuppressMiscFeatureSubfeatures },
         { "SuppressMobileElementSubfeatures", CAutoDefOptions::eOptionFieldType_SuppressMobileElementSubfeatures },
         { "Targeted Locus Name", CAutoDefOptions::eOptionFieldType_TargetedLocusName },
         { "UseFakePromoters", CAutoDefOptions::eOptionFieldType_UseFakePromoters },
@@ -292,6 +302,7 @@ bool CAutoDefOptions::x_IsBoolean(TFieldType field_type) const
         case eOptionFieldType_ModifierList:
         case eOptionFieldType_MaxMods:
         case eOptionFieldType_TargetedLocusName:
+        case eOptionFieldType_CustomFeatureClause:
             rval = false;
             break;
         default:
@@ -495,6 +506,15 @@ CRef<CUser_field> CAutoDefOptions::x_MakeTargetedLocusName() const
 }
 
 
+CRef<CUser_field> CAutoDefOptions::x_MakeCustomFeatureClause() const
+{
+    CRef<CUser_field> field(new CUser_field());
+    field->SetLabel().SetStr(GetFieldType(eOptionFieldType_CustomFeatureClause));
+    field->SetData().SetStr(m_CustomFeatureClause);
+    return field;
+}
+
+
 
 END_SCOPE(objects)
 END_NCBI_SCOPE
diff --git a/c++/src/objtools/edit/cds_fix.cpp b/c++/src/objtools/edit/cds_fix.cpp
index 6bc97b5..9a0dec0 100644
--- a/c++/src/objtools/edit/cds_fix.cpp
+++ b/c++/src/objtools/edit/cds_fix.cpp
@@ -1,4 +1,4 @@
-/*  $Id: cds_fix.cpp 499445 2016-04-26 14:17:08Z ivanov $
+/*  $Id: cds_fix.cpp 501569 2016-05-17 12:33:15Z filippov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -880,6 +880,7 @@ bool TruncateCDSAtStop(CSeq_feat& cds, CScope& scope)
             if (len_wanted > 0) {
                 new_loc = TruncateSeqLoc (cds.GetLocation(), len_wanted);
                 if (new_loc) {
+                    new_loc->SetPartialStart(cds.GetLocation().IsPartialStart(eExtreme_Biological), eExtreme_Biological);
                     new_loc->SetPartialStop(false, eExtreme_Biological);
                     cds.SetLocation().Assign(*new_loc);
                     if (cds.GetLocation().IsPartialStart(eExtreme_Biological)) {
diff --git a/c++/src/objtools/edit/feattable_edit.cpp b/c++/src/objtools/edit/feattable_edit.cpp
index ad6bfa7..36d9979 100644
--- a/c++/src/objtools/edit/feattable_edit.cpp
+++ b/c++/src/objtools/edit/feattable_edit.cpp
@@ -1,4 +1,4 @@
-/*  $Id: feattable_edit.cpp 498135 2016-04-13 17:19:58Z ivanov $
+/*  $Id: feattable_edit.cpp 520505 2016-11-29 16:02:37Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -150,11 +150,6 @@ void CFeatTableEdit::GenerateMissingMrnaForCds()
         if (pOverlappingRna) {
             continue;
         }
-        //CRef<CSeq_feat> pRna = edit::MakemRNAforCDS(cds, *mpScope);
-        //if (!pRna) {
-        //    //should never happen!
-        //    continue;
-        //}
         CRef<CSeq_feat> pRna(new CSeq_feat);
         pRna->SetData().SetRna().SetType(CRNA_ref::eType_mRNA);
         pRna->SetLocation().Assign(cds.GetLocation());
@@ -164,12 +159,36 @@ void CFeatTableEdit::GenerateMissingMrnaForCds()
         //product name
         pRna->SetData().SetRna().SetExt().SetName(
             sGetCdsProductName(cds, *mpScope));
+
         //find proper name for rna
         string rnaId(xNextFeatId());
         pRna->SetId().SetLocal().SetStr(rnaId);
+
         //add rna xref to cds
         CSeq_feat_EditHandle feh(mpScope->GetObjectHandle(cds));
         feh.AddFeatXref(rnaId);
+
+        //add cds xref to rna
+        CRef<CFeat_id> pFeatId(new CFeat_id);
+        pFeatId->Assign(cds.GetId());
+        CRef<CSeqFeatXref> pRnaXref(new CSeqFeatXref);
+        pRnaXref->SetId(*pFeatId);
+        pRna->SetXref().push_back(pRnaXref);
+
+        CMappedFeat parentGene = feature::GetBestGeneForFeat(*it, &mTree);
+        if (parentGene) {
+            //if gene exists, add gene xref to rna
+            CSeq_feat_EditHandle geh(mpScope->GetObjectHandle(
+                parentGene.GetOriginalFeature()));
+            geh.AddFeatXref(rnaId);
+            //if gene exists, add rna xref to gene
+            CRef<CFeat_id> pGeneId(new CFeat_id);
+            pGeneId->Assign(parentGene.GetId());
+            CRef<CSeqFeatXref> pRnaXref(new CSeqFeatXref);
+            pRnaXref->SetId(*pGeneId);
+            pRna->SetXref().push_back(pRnaXref);
+        }
+
         //add new rna to feature table
         mEditHandle.AddFeat(*pRna);
         mTree.AddFeature(mpScope->GetObjectHandle(*pRna));
@@ -259,6 +278,9 @@ void CFeatTableEdit::SubmitFixProducts()
     sel.IncludeFeatSubtype(CSeqFeatData::eSubtype_cdregion);
     for (CFeat_CI it(mHandle, sel); it; ++it){
         CMappedFeat mf = *it;
+        if (mf.IsSetProduct()) {
+            continue;
+        }
         //debug CSeqFeatData::ESubtype st = mf.GetFeatSubtype();
         string product = mf.GetNamedQual("Product");
         CRef<CSeq_feat> pEditedFeature(new CSeq_feat);
@@ -279,6 +301,10 @@ void CFeatTableEdit::EliminateBadQualifiers()
 {
     typedef CSeq_feat::TQual QUALS;
 
+    vector<string> specialQuals{
+        "Protein", "protein",
+        "go_function", "go_component", "go_process" };
+
     CFeat_CI it(mHandle);
     for ( ; it; ++it) {
         CSeqFeatData::ESubtype subtype = it->GetData().GetSubtype();
@@ -288,23 +314,28 @@ void CFeatTableEdit::EliminateBadQualifiers()
         vector<string> badQuals;
         for (QUALS::const_iterator qual = quals.begin(); qual != quals.end(); 
                 ++qual) {
-            string qualVal = (*qual)->GetQual();
-            if (qualVal == "transcript_id") {
+            string qualKey = (*qual)->GetQual();
+            if (std::find(specialQuals.begin(), specialQuals.end(), qualKey) 
+                    != specialQuals.end()) {
                 continue;
             }
-            if (qualVal == "protein_id") {
+            if (qualKey == "transcript_id") {
+                if (!NStr::StartsWith((*qual)->GetVal(), "gnl|")) {
+                    badQuals.push_back(qualKey);
+                }
                 continue;
             }
-            if (qualVal == "Protein") {
+            if (qualKey == "protein_id") {
+                if (!NStr::StartsWith((*qual)->GetVal(), "gnl|")) {
+                    badQuals.push_back(qualKey);
+                }
                 continue;
             }
-            if (qualVal == "protein") {
+            CSeqFeatData::EQualifier qualType = CSeqFeatData::GetQualifierType(qualKey);
+            if (CSeqFeatData::IsLegalQualifier(subtype, qualType)) {
                 continue;
             }
-            CSeqFeatData::EQualifier qualType = CSeqFeatData::GetQualifierType(qualVal);
-            if (!CSeqFeatData::IsLegalQualifier(subtype, qualType)) {
-                badQuals.push_back(qualVal);
-            }
+            badQuals.push_back(qualKey);
         }
         for (vector<string>::const_iterator badIt = badQuals.begin();
                 badIt != badQuals.end(); ++badIt) {
@@ -313,12 +344,14 @@ void CFeatTableEdit::EliminateBadQualifiers()
     }
 }
 
+
 //  ----------------------------------------------------------------------------
 void CFeatTableEdit::GenerateProteinAndTranscriptIds()
 //  ----------------------------------------------------------------------------
 {
     SAnnotSelector sel;
-    sel.IncludeFeatSubtype(CSeqFeatData::eSubtype_mRNA);
+    //sel.IncludeFeatSubtype(CSeqFeatData::eSubtype_mRNA);
+    sel.IncludeFeatType(CSeqFeatData::e_Rna);
     sel.IncludeFeatSubtype(CSeqFeatData::eSubtype_cdregion);
     for (CFeat_CI it(mHandle, sel); it; ++it){
         CMappedFeat mf = *it;
@@ -328,6 +361,23 @@ void CFeatTableEdit::GenerateProteinAndTranscriptIds()
 }
 
 //  ---------------------------------------------------------------------------
+void CFeatTableEdit::xGenerateMissingGeneForChoice(
+    CSeqFeatData::E_Choice choice)
+//  ---------------------------------------------------------------------------
+{
+    SAnnotSelector sel;
+    sel.IncludeFeatType(choice);
+    CFeat_CI it(mHandle, sel);
+    for ( ; it; ++it) {
+        CMappedFeat mf = *it;
+        if (xCreateMissingParentGene(mf)) {
+            xAdjustExistingParentGene(mf);
+        }
+    }
+}
+
+
+//  ---------------------------------------------------------------------------
 void CFeatTableEdit::xGenerateMissingGeneForSubtype(
     CSeqFeatData::ESubtype subType)
 //  ---------------------------------------------------------------------------
@@ -337,38 +387,68 @@ void CFeatTableEdit::xGenerateMissingGeneForSubtype(
     CFeat_CI it(mHandle, sel);
     for ( ; it; ++it) {
         CMappedFeat mf = *it;
-        CRef<CSeq_feat> pGene = xMakeGeneForFeature(mf);
-        if (pGene) {
-            // missing gene was created. make it fit and add to table:
-            string geneId(xNextFeatId());
-            pGene->SetId().SetLocal().SetStr(geneId);
-            CSeq_feat_EditHandle feh(
-                mpScope->GetObjectHandle(mf.GetOriginalFeature()));
-            feh.AddFeatXref(geneId);
-            mEditHandle.AddFeat(*pGene);
-            mTree.AddFeature(mpScope->GetObjectHandle(*pGene));
+        if (xCreateMissingParentGene(mf)) {
+            xAdjustExistingParentGene(mf);
         }
-        else {
-            // gene wasn't missing. just adjust partialness if necessary:
-            if (!mf.IsSetPartial()  ||  !mf.GetPartial()) {
-                continue;
-            }
-            CMappedFeat parentGene = feature::GetBestGeneForFeat(mf, &mTree);
-            //assert(parentGene); //we would not be "else" if not
-            if (parentGene.IsSetPartial()  &&  parentGene.GetPartial()) {
-                continue;
-            }
-            CRef<CSeq_feat> pEditedGene(new CSeq_feat);
-            pEditedGene->Assign(parentGene.GetOriginalFeature());
-            pEditedGene->SetPartial(true);
-            CSeq_feat_EditHandle geneEH(
-                mpScope->GetObjectHandle(parentGene.GetOriginalFeature()));
-            geneEH.Replace(*pEditedGene);
-        }        
     }
 }
 
 //  ----------------------------------------------------------------------------
+bool
+CFeatTableEdit::xAdjustExistingParentGene(
+    CMappedFeat mf)
+//  ----------------------------------------------------------------------------
+{
+    if (!mf.IsSetPartial()  ||  !mf.GetPartial()) {
+        return true;
+    }
+    CMappedFeat parentGene = feature::GetBestGeneForFeat(mf, &mTree);
+    if (!parentGene) {
+        return false;
+    }
+
+    if (parentGene.IsSetPartial()  &&  parentGene.GetPartial()) {
+        return true;
+    }
+    CRef<CSeq_feat> pEditedGene(new CSeq_feat);
+    pEditedGene->Assign(parentGene.GetOriginalFeature());
+    pEditedGene->SetPartial(true);
+    CSeq_feat_EditHandle geneEH(
+        mpScope->GetObjectHandle(parentGene.GetOriginalFeature()));
+    geneEH.Replace(*pEditedGene);
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
+bool
+CFeatTableEdit::xCreateMissingParentGene(
+    CMappedFeat mf)
+//  ----------------------------------------------------------------------------
+{
+    CRef<CSeq_feat> pGene = xMakeGeneForFeature(mf);
+    if (!pGene) {
+        return false;
+    }
+    // missing gene was created. now attach ids and xrefs:
+    string geneId(xNextFeatId());
+    pGene->SetId().SetLocal().SetStr(geneId);
+    CSeq_feat_EditHandle feh(
+        mpScope->GetObjectHandle(mf.GetOriginalFeature()));
+    feh.AddFeatXref(geneId);
+
+    CRef<CFeat_id> pFeatId(new CFeat_id);
+    pFeatId->Assign(mf.GetId());
+    CRef<CSeqFeatXref> pGeneXref(new CSeqFeatXref);
+    pGeneXref->SetId(*pFeatId);
+    pGene->SetXref().push_back(pGeneXref);
+
+    mEditHandle.AddFeat(*pGene);
+    mTree.AddFeature(mpScope->GetObjectHandle(*pGene));
+    return true;
+}
+
+
+//  ----------------------------------------------------------------------------
 void CFeatTableEdit::xFeatureAddProteinId(
     CMappedFeat mf)
 //  ----------------------------------------------------------------------------
@@ -387,8 +467,7 @@ void CFeatTableEdit::xFeatureAddProteinId(
 
     switch (mf.GetFeatSubtype()) {
         default:
-            // we do this only for select feature types
-            return;
+            break;
         case CSeqFeatData::eSubtype_mRNA:
             associateFeat = feature::GetBestCdsForMrna(mf, &mTree);
             break;
@@ -402,7 +481,9 @@ void CFeatTableEdit::xFeatureAddProteinId(
     if (protein_id.empty()) {
         protein_id = xNextProteinId(mf);
     }
-    xFeatureAddQualifier(mf, "protein_id", protein_id);
+    if (!protein_id.empty()) {
+        xFeatureAddQualifier(mf, "protein_id", protein_id);
+    }
 }
 
 //  ----------------------------------------------------------------------------
@@ -424,8 +505,7 @@ void CFeatTableEdit::xFeatureAddTranscriptId(
 
     switch (mf.GetFeatSubtype()) {
     default:
-        // we do this only for select feature types
-        return;
+        break;
     case CSeqFeatData::eSubtype_mRNA:
         associateFeat = feature::GetBestCdsForMrna(mf, &mTree);
         break;
@@ -439,7 +519,9 @@ void CFeatTableEdit::xFeatureAddTranscriptId(
     if (transcript_id.empty()) {
         transcript_id = xNextTranscriptId(mf);
     }
-    xFeatureAddQualifier(mf, "transcript_id", transcript_id);
+    if (!transcript_id.empty()) {
+        xFeatureAddQualifier(mf, "transcript_id", transcript_id);
+    }
 }
 
 //  ----------------------------------------------------------------------------
@@ -468,6 +550,7 @@ void CFeatTableEdit::xGenerateLocusIdsRegenerate()
     //make sure genes got proper locus tags
     SAnnotSelector selGenes;
     selGenes.IncludeFeatSubtype(CSeqFeatData::eSubtype_gene);
+    selGenes.SetSortOrder(SAnnotSelector::eSortOrder_Normal);
     for (CFeat_CI it(mHandle, selGenes); it; ++it) {
         CMappedFeat mf = *it;
         CSeq_feat_EditHandle feh(mf);
@@ -566,6 +649,10 @@ void CFeatTableEdit::xGenerateLocusIdsUseExisting()
     }
 }
 
+bool idAlpha(const CSeq_id_Handle& idh1, const CSeq_id_Handle idh2) {
+    return (idh1.AsString() < idh2.AsString());
+}
+
 //  ----------------------------------------------------------------------------
 void CFeatTableEdit::GenerateLocusTags()
 //  ----------------------------------------------------------------------------
@@ -576,17 +663,53 @@ void CFeatTableEdit::GenerateLocusTags()
 
 	CRef<CGb_qual> pLocusTag;
     SAnnotSelector selGenes;
+    vector<CSeq_id_Handle> annotIds;
+    selGenes.SetSortOrder(SAnnotSelector::eSortOrder_Normal);
     selGenes.IncludeFeatSubtype(CSeqFeatData::eSubtype_gene);
     CFeat_CI itGenes(mHandle, selGenes);
     for ( ; itGenes; ++itGenes) {
-        CSeq_feat_EditHandle feh(mpScope->GetObjectHandle(
-            itGenes->GetOriginalFeature()));
-        CRef<CSeq_feat> pEditedFeat(new CSeq_feat);
-        pEditedFeat->Assign(itGenes->GetOriginalFeature());
-        pEditedFeat->RemoveQualifier("locus_tag");
-        pEditedFeat->SetData().SetGene().SetLocus_tag(xNextLocusTag());
-		feh.Replace(*pEditedFeat);
-	}
+        CSeq_feat_Handle fh = *itGenes;
+        CSeq_id_Handle idh = fh.GetLocationId();
+        vector<CSeq_id_Handle>::const_iterator compIt;
+        for ( compIt = annotIds.begin(); 
+                compIt != annotIds.end(); 
+                ++compIt) {
+            if (*compIt == idh) {
+                break;
+            }
+        }
+        if (compIt == annotIds.end()) {
+            annotIds.push_back(idh);
+        }
+    }
+    std::sort(annotIds.begin(), annotIds.end(), idAlpha);
+
+    for (vector<CSeq_id_Handle>::const_iterator idIt = annotIds.begin();
+            idIt != annotIds.end();
+            ++idIt) {
+        CSeq_id_Handle curId = *idIt;
+
+	    CRef<CGb_qual> pLocusTag;
+        SAnnotSelector selGenes;
+        selGenes.SetSortOrder(SAnnotSelector::eSortOrder_None);
+        selGenes.IncludeFeatSubtype(CSeqFeatData::eSubtype_gene);
+        CFeat_CI itGenes(mHandle, selGenes);
+        for ( ; itGenes; ++itGenes) {
+            CSeq_feat_Handle fh = *itGenes;
+            string id1 = fh.GetLocationId().AsString();
+            string id2 = curId.AsString();
+            if (fh.GetLocationId() != curId) {
+                continue;
+            }
+            CSeq_feat_EditHandle feh(mpScope->GetObjectHandle(
+                itGenes->GetOriginalFeature()));
+            CRef<CSeq_feat> pEditedFeat(new CSeq_feat);
+            pEditedFeat->Assign(itGenes->GetOriginalFeature());
+            pEditedFeat->RemoveQualifier("locus_tag");
+            pEditedFeat->SetData().SetGene().SetLocus_tag(xNextLocusTag());
+		    feh.Replace(*pEditedFeat);
+        }
+    }
 	SAnnotSelector selOther;
 	selOther.ExcludeFeatSubtype(CSeqFeatData::eSubtype_gene);
     CFeat_CI itOther(mHandle, selOther);
@@ -602,6 +725,40 @@ void CFeatTableEdit::GenerateLocusTags()
 	}
 }
 
+
+//  ----------------------------------------------------------------------------
+void CFeatTableEdit::GenerateMissingParentFeatures(
+    bool forEukaryote)
+//  ----------------------------------------------------------------------------
+{
+    if (forEukaryote) {
+        GenerateMissingParentFeaturesForEukaryote();
+    }
+    else {
+        GenerateMissingParentFeaturesForProkaryote();
+    }
+    mTree = feature::CFeatTree(mHandle);
+}
+
+
+//  ----------------------------------------------------------------------------
+void CFeatTableEdit::GenerateMissingParentFeaturesForEukaryote()
+//  ----------------------------------------------------------------------------
+{
+    GenerateMissingMrnaForCds();
+    xGenerateMissingGeneForChoice(CSeqFeatData::e_Rna);
+}
+
+
+//  ----------------------------------------------------------------------------
+void CFeatTableEdit::GenerateMissingParentFeaturesForProkaryote()
+//  ----------------------------------------------------------------------------
+{
+    xGenerateMissingGeneForChoice(CSeqFeatData::e_Cdregion);
+    xGenerateMissingGeneForChoice(CSeqFeatData::e_Rna);
+}
+
+
 //  ----------------------------------------------------------------------------
 void CFeatTableEdit::xFeatureAddQualifier(
     CMappedFeat mf,
@@ -660,6 +817,9 @@ string CFeatTableEdit::xNextProteinId(
     if (!parentGene) {
 		return "";
 	}
+    if (!parentGene.GetData().GetGene().IsSetLocus_tag()) {
+        return "";
+    }
     string locusTag = parentGene.GetData().GetGene().GetLocus_tag();
 	string disAmbig = "";
 	map<string, int>::iterator it = mMapProtIdCounts.find(locusTag);
@@ -670,7 +830,14 @@ string CFeatTableEdit::xNextProteinId(
 		++mMapProtIdCounts[locusTag];
 		disAmbig = string("_") + NStr::IntToString(mMapProtIdCounts[locusTag]);
 	}
-    return (dbPrefix + mLocusTagPrefix + "|" + locusTag + disAmbig);
+    string db = mLocusTagPrefix;
+    if (db.empty()) {
+        string prefix, suffix;
+        NStr::SplitInTwo(locusTag, "_", prefix, suffix);
+        db = prefix;
+    }
+    string proteinId = dbPrefix + db + "|" + locusTag + disAmbig;
+    return proteinId;
 }
 
 //	----------------------------------------------------------------------------
@@ -685,13 +852,23 @@ string CFeatTableEdit::xNextTranscriptId(
     if (!parentGene) {
 		return "";
 	}
+    if (!parentGene.GetData().GetGene().IsSetLocus_tag()) {
+        return "";
+    }
     string locusTag = parentGene.GetData().GetGene().GetLocus_tag();
     string disAmbig = "";
 	map<string, int>::iterator it = mMapProtIdCounts.find(locusTag);
 	if (it != mMapProtIdCounts.end()  &&  mMapProtIdCounts[locusTag] != 0) {
 		disAmbig = string("_") + NStr::IntToString(mMapProtIdCounts[locusTag]);
 	}
-	return (dbPrefix + mLocusTagPrefix + "|mrna." + locusTag + disAmbig);
+    string db = mLocusTagPrefix;
+    if (db.empty()) {
+        string prefix, suffix;
+        NStr::SplitInTwo(locusTag, "_", prefix, suffix);
+        db = prefix;
+    }
+    string transcriptId = dbPrefix + db + "|mrna." + locusTag + disAmbig;
+	return transcriptId;
 }
 
 //  ----------------------------------------------------------------------------
@@ -717,6 +894,7 @@ CRef<CSeq_feat> CFeatTableEdit::xMakeGeneForFeature(
         eExtreme_Positional));
     pGene->SetLocation().SetInt().SetTo(rna.GetLocation().GetStop(
         eExtreme_Positional));
+    pGene->SetLocation().SetInt().SetStrand(rna.GetLocation().GetStrand());
     pGene->SetData().SetGene();
     return pGene;
 }
diff --git a/c++/src/objtools/edit/gaps_edit.cpp b/c++/src/objtools/edit/gaps_edit.cpp
index 47882a0..9bda11d 100644
--- a/c++/src/objtools/edit/gaps_edit.cpp
+++ b/c++/src/objtools/edit/gaps_edit.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gaps_edit.cpp 468747 2015-05-27 18:57:10Z gotvyans $
+/*  $Id: gaps_edit.cpp 515961 2016-10-06 18:15:52Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -213,9 +213,14 @@ CRef<CDelta_seq> MakeGap(CBioseq::TInst& inst, TSeqPos gap_start, TSeqPos gap_le
 
 }
 
+CGapsEditor::CGapsEditor(CSeq_gap::EType gap_type, const TEvidenceSet& evidences,
+    TSeqPos gapNmin, TSeqPos gap_Unknown_length)
+    :m_gap_type(gap_type), m_evidences(evidences), m_gapNmin(gapNmin), m_gap_Unknown_length(gap_Unknown_length)
+{
+}
+
 CRef<CDelta_seq> 
-CGapsEditor::CreateGap(CBioseq& bioseq, TSeqPos gap_start, TSeqPos gap_length, CSeq_gap::EType gap_type,
-   const TEvidenceSet& evidences)
+CGapsEditor::CreateGap(CBioseq& bioseq, TSeqPos gap_start, TSeqPos gap_length)
 {
     if (!bioseq.IsSetInst())
         return CRef<CDelta_seq>();
@@ -224,24 +229,12 @@ CGapsEditor::CreateGap(CBioseq& bioseq, TSeqPos gap_start, TSeqPos gap_length, C
     if (seq.NotEmpty())
     {
         CDelta_seq::TLiteral& lit = seq->SetLiteral();
-
-        lit.SetSeq_data().SetGap().SetType(gap_type);
-        if (evidences.size() > 0)
-        {
-            lit.SetSeq_data().SetGap().SetLinkage_evidence().clear();
-            ITERATE(TEvidenceSet, it, evidences)
-            {
-                CRef<CLinkage_evidence> le(new CLinkage_evidence);
-                le->SetType(*it);
-                lit.SetSeq_data().SetGap().SetLinkage_evidence().push_back(le);
-            }
-            lit.SetSeq_data().SetGap().SetLinkage(CSeq_gap::eLinkage_linked);
-        }
+        x_SetGapParameters(*seq);
     }
     return seq;
 }
 
-void  CGapsEditor::ConvertNs2Gaps(const CSeq_data& data, TSeqPos len, CDelta_ext& ext, TSeqPos gap_min)
+void  CGapsEditor::ConvertNs2Gaps(const CSeq_data& data, TSeqPos len, CDelta_ext& ext)
 {
     string decoded;
     if (!Make_Iupacna(data, decoded, len))
@@ -251,18 +244,18 @@ void  CGapsEditor::ConvertNs2Gaps(const CSeq_data& data, TSeqPos len, CDelta_ext
         size_t index = 0;
         CTempString current(decoded);
         size_t start;
-        while (index + gap_min <= current.length() && ((start = current.find_first_of("Nn", index)) != CTempString::npos))
+        while (index + m_gapNmin <= current.length() && ((start = current.find_first_of("Nn", index)) != CTempString::npos))
         {
             size_t end = current.find_first_not_of("Nn", start);
             if (end == CTempString::npos)
                 end = current.length();
-            if (end - start >= gap_min)
+            if (end - start >= m_gapNmin)
             {
                 if (start > 0)
                     ext.AddAndSplit(current, CSeq_data::e_Iupacna, TSeqPos(start), false, true);
 
                 CDelta_seq& gap = ext.AddLiteral(TSeqPos(end-start));
-                gap.SetLiteral().SetSeq_data().SetGap().SetType(CSeq_gap::eType_unknown);
+                x_SetGapParameters(gap);
                 current.assign(current.data(), end, current.length() - end);
                 end = 0;
             }
@@ -273,7 +266,7 @@ void  CGapsEditor::ConvertNs2Gaps(const CSeq_data& data, TSeqPos len, CDelta_ext
     }
 }
 
-void CGapsEditor::ConvertNs2Gaps(CBioseq::TInst& inst, TSeqPos gap_min)
+void CGapsEditor::ConvertNs2Gaps(CBioseq::TInst& inst)
 {
     if (inst.IsAa()  ||  !inst.IsSetSeq_data()  ||  inst.IsSetExt()) {
         return;
@@ -282,7 +275,7 @@ void CGapsEditor::ConvertNs2Gaps(CBioseq::TInst& inst, TSeqPos gap_min)
 
     CDelta_ext& ext = inst.SetExt().SetDelta();
 
-    ConvertNs2Gaps(data, inst.GetLength(), ext, gap_min);
+    ConvertNs2Gaps(data, inst.GetLength(), ext);
 
     if (ext.Get().size() > 1) { // finalize
         inst.SetRepr(CSeq_inst::eRepr_delta);
@@ -292,14 +285,11 @@ void CGapsEditor::ConvertNs2Gaps(CBioseq::TInst& inst, TSeqPos gap_min)
     }
 }
 
-void CGapsEditor::ConvertNs2Gaps(CBioseq& bioseq, 
-    TSeqPos gapNmin, TSeqPos gap_Unknown_length, 
-    CSeq_gap::EType gap_type,
-    const TEvidenceSet& evidences)
+void CGapsEditor::ConvertNs2Gaps(CBioseq& bioseq)
 {
     if (bioseq.IsSetInst() && bioseq.GetInst().IsSetSeq_data() && !bioseq.GetInst().GetSeq_data().IsGap())
     {
-        ConvertNs2Gaps(bioseq.SetInst(), gapNmin);
+        ConvertNs2Gaps(bioseq.SetInst());
     }
 
 
@@ -330,53 +320,56 @@ void CGapsEditor::ConvertNs2Gaps(CBioseq& bioseq,
         // split a literal to elements if needed
         if (lit.IsSetSeq_data() && !lit.GetSeq_data().IsGap())
         {
-            ConvertNs2Gaps(lit.GetSeq_data(), lit.GetLength(), dst_data, gapNmin);
-            continue;
+            ConvertNs2Gaps(lit.GetSeq_data(), lit.GetLength(), dst_data);
         }
-
-        // otherwise add it as is and possible update some parameters
-        dst_data.Set().push_back(*it);
-
-        if (lit.IsSetLength() && lit.GetLength() == gap_Unknown_length)
+        else
         {
-            lit.SetFuzz().SetLim(CInt_fuzz::eLim_unk);
+            // otherwise add it as is and possible update some parameters
+            dst_data.Set().push_back(*it);
+            x_SetGapParameters(**it);
         }
-        if (evidences.size() > 0)
-        {
-            if (lit.IsSetSeq_data() && lit.GetSeq_data().IsGap() && lit.GetSeq_data().GetGap().GetLinkage_evidence().size() > 0)
-                continue;
+    }
+}
 
-            ITERATE(TEvidenceSet, it, evidences)
-            {
-                CRef<CLinkage_evidence> le(new CLinkage_evidence);
-                le->SetType(*it);
-                lit.SetSeq_data().SetGap().SetLinkage_evidence().push_back(le);
-            }
-            lit.SetSeq_data().SetGap().SetLinkage(CSeq_gap::eLinkage_linked);
-            lit.SetSeq_data().SetGap().SetType(gap_type);
+void CGapsEditor::x_SetGapParameters(CDelta_seq& lit)
+{
+    CDelta_seq::TLiteral& gap = lit.SetLiteral();
+    if (gap.IsSetLength() && gap.GetLength() == m_gap_Unknown_length)
+    {
+        gap.SetFuzz().SetLim(CInt_fuzz::eLim_unk);
+    }
+    if (m_evidences.size() > 0)
+    {
+        if (gap.IsSetSeq_data() && gap.GetSeq_data().IsGap() && gap.GetSeq_data().GetGap().GetLinkage_evidence().size() > 0)
+            return;
+
+        ITERATE(TEvidenceSet, it, m_evidences)
+        {
+            CRef<CLinkage_evidence> le(new CLinkage_evidence);
+            le->SetType(*it);
+            gap.SetSeq_data().SetGap().SetLinkage_evidence().push_back(le);
         }
+        gap.SetSeq_data().SetGap().SetLinkage(CSeq_gap::eLinkage_linked);
+        gap.SetSeq_data().SetGap().SetType(m_gap_type);
     }
 }
 
-void CGapsEditor::ConvertNs2Gaps(
-    objects::CSeq_entry& entry, TSeqPos gapNmin, TSeqPos gap_Unknown_length,
-    CSeq_gap::EType gap_type,
-    const TEvidenceSet& evidences)
+void CGapsEditor::ConvertNs2Gaps(objects::CSeq_entry& entry)
 {
-    if (gapNmin==0 && gap_Unknown_length > 0)
+    if (m_gapNmin == 0 && m_gap_Unknown_length > 0)
         return;
 
     switch(entry.Which())
     {
     case CSeq_entry::e_Seq:
         {
-            ConvertNs2Gaps(entry.SetSeq(), gapNmin, gap_Unknown_length, gap_type, evidences);
+            ConvertNs2Gaps(entry.SetSeq());
         }
         break;
     case CSeq_entry::e_Set:
         NON_CONST_ITERATE(CSeq_entry::TSet::TSeq_set, it, entry.SetSet().SetSeq_set())
         {
-            ConvertNs2Gaps(**it, gapNmin, gap_Unknown_length, gap_type, evidences);
+            ConvertNs2Gaps(**it);
         }
         break;
     default:
@@ -384,5 +377,39 @@ void CGapsEditor::ConvertNs2Gaps(
     }
 }
 
+void CGapsEditor::ConvertBioseqToDelta(CBioseq& bioseq)
+{
+    TSeqPos len = bioseq.GetInst().GetLength();
+    CDelta_ext& delta_ext = bioseq.SetInst().SetExt().SetDelta();
+    CRef<CDelta_seq> delta_seq(new CDelta_seq);
+    delta_seq->SetLiteral().SetSeq_data(bioseq.SetInst().SetSeq_data());
+    delta_seq->SetLiteral().SetLength(len);
+    delta_ext.Set().push_back(delta_seq);
+    bioseq.SetInst().ResetSeq_data();
+    bioseq.SetInst().SetRepr(CSeq_inst::eRepr_delta);
+}
+
+void CGapsEditor::AppendGap(CBioseq& bioseq)
+{
+    CRef<CDelta_seq> delta_seq(new CDelta_seq);
+    CDelta_seq::TLiteral& lit = delta_seq->SetLiteral();
+    lit.SetLength(0);
+    x_SetGapParameters(*delta_seq);
+    lit.SetLength(100);
+    bioseq.SetInst().SetExt().SetDelta().Set().push_back(delta_seq);
+}
+
+void CGapsEditor::AddBioseqAsLiteral(CBioseq& parent, CBioseq& bioseq)
+{
+    CDelta_ext& delta_ext = parent.SetInst().SetExt().SetDelta();
+
+    CRef<CDelta_seq> delta_seq(new CDelta_seq);
+    delta_seq->SetLiteral().SetSeq_data(bioseq.SetInst().SetSeq_data());
+    delta_seq->SetLiteral().SetLength(bioseq.GetInst().GetLength());
+    delta_ext.Set().push_back(delta_seq);
+    parent.SetInst().SetLength(parent.GetInst().GetLength() + bioseq.GetInst().GetLength());
+}
+
+
 END_SCOPE(objects)
 END_NCBI_SCOPE
diff --git a/c++/src/objtools/edit/loc_edit.cpp b/c++/src/objtools/edit/loc_edit.cpp
index f5da4e8..769aded 100644
--- a/c++/src/objtools/edit/loc_edit.cpp
+++ b/c++/src/objtools/edit/loc_edit.cpp
@@ -1,4 +1,4 @@
-/*  $Id: loc_edit.cpp 499445 2016-04-26 14:17:08Z ivanov $
+/*  $Id: loc_edit.cpp 496298 2016-03-25 13:38:39Z gotvyans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/edit/mail_report.cpp b/c++/src/objtools/edit/mail_report.cpp
index 3e6f391..af920c6 100644
--- a/c++/src/objtools/edit/mail_report.cpp
+++ b/c++/src/objtools/edit/mail_report.cpp
@@ -1,4 +1,4 @@
-/*  $Id: mail_report.cpp 435187 2014-05-14 14:28:00Z bollin $
+/*  $Id: mail_report.cpp 519250 2016-11-14 18:26:30Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -46,6 +46,7 @@
 #include <objmgr/bioseq_handle.hpp>
 #include <objmgr/seqdesc_ci.hpp>
 #include <objmgr/bioseq_ci.hpp>
+#include <objmgr/util/sequence.hpp>
 
 BEGIN_NCBI_SCOPE
 BEGIN_SCOPE(objects)
@@ -157,10 +158,19 @@ void PrintReportLineHeader(CNcbiOstrstream& lines)
 }
 
 
-void ReportMailReportLine(CNcbiOstrstream& lines, const CSeq_table& table, size_t i)
+void ReportMailReportLine(CNcbiOstrstream& lines, const CSeq_table& table, size_t i, CScope* scope = NULL)
 {
     string id;
-    table.GetColumns()[0]->GetData().GetId()[i]->GetLabel(&id, CSeq_id::eContent);
+    if (scope)
+    {
+        CBioseq_Handle bsh =  scope->GetBioseqHandle(*table.GetColumns()[0]->GetData().GetId()[i]);
+        CSeq_id_Handle best = sequence::GetId(bsh, sequence::eGetId_Best);
+        best.GetSeqId()->GetLabel(&id, CSeq_id::eContent);
+    }
+    else
+    {
+        table.GetColumns()[0]->GetData().GetId()[i]->GetLabel(&id, CSeq_id::eContent);
+    }
     lines << id;
     lines << "\t";
     lines << table.GetColumns()[1]->GetData().GetString()[i];
@@ -170,7 +180,7 @@ void ReportMailReportLine(CNcbiOstrstream& lines, const CSeq_table& table, size_
 }
 
 
-string GetReportFromMailReportTable(const CSeq_table& table)
+string GetReportFromMailReportTable(const CSeq_table& table, CScope* scope)
 {
     CNcbiOstrstream lines;
 
@@ -178,7 +188,7 @@ string GetReportFromMailReportTable(const CSeq_table& table)
     PrintReportLineHeader(lines);
     for (size_t i = 0; i < table.GetColumns().front()->GetData().GetSize(); i++) {
         if (table.GetColumns()[4]->GetData().GetInt()[i] == 0) {
-            ReportMailReportLine(lines, table, i);
+            ReportMailReportLine(lines, table, i, scope);
         }
     }
     lines << "\n\nSp. Replaced with Real\n";
@@ -186,7 +196,7 @@ string GetReportFromMailReportTable(const CSeq_table& table)
     for (size_t i = 0; i < table.GetColumns().front()->GetData().GetSize(); i++) {
         if (NStr::Find(table.GetColumns()[1]->GetData().GetString()[i], " sp.") != string::npos
             && NStr::Find(table.GetColumns()[3]->GetData().GetString()[i], " sp.") == string::npos) {
-            ReportMailReportLine(lines, table, i);
+            ReportMailReportLine(lines, table, i, scope);
         }
     }
 
@@ -194,7 +204,7 @@ string GetReportFromMailReportTable(const CSeq_table& table)
     PrintReportLineHeader(lines);
     for (size_t i = 0; i < table.GetColumns().front()->GetData().GetSize(); i++) {
         if (table.GetColumns()[5]->GetData().GetInt()[i] != 0) {
-            ReportMailReportLine(lines, table, i);
+            ReportMailReportLine(lines, table, i, scope);
         }
     }
 
diff --git a/c++/src/objtools/edit/publication_edit.cpp b/c++/src/objtools/edit/publication_edit.cpp
index f97b258..9b2e55b 100644
--- a/c++/src/objtools/edit/publication_edit.cpp
+++ b/c++/src/objtools/edit/publication_edit.cpp
@@ -1,4 +1,4 @@
-/*  $Id: publication_edit.cpp 493845 2016-03-02 14:05:29Z ivanov $
+/*  $Id: publication_edit.cpp 491874 2016-02-09 20:13:49Z asztalos $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/edit/remote_updater.cpp b/c++/src/objtools/edit/remote_updater.cpp
index 1f82898..8bb0214 100644
--- a/c++/src/objtools/edit/remote_updater.cpp
+++ b/c++/src/objtools/edit/remote_updater.cpp
@@ -1,4 +1,4 @@
-/*  $Id: remote_updater.cpp 499431 2016-04-26 14:13:07Z ivanov $
+/*  $Id: remote_updater.cpp 493987 2016-03-02 20:43:23Z gotvyans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/edit/rna_edit.cpp b/c++/src/objtools/edit/rna_edit.cpp
index 5e954ce..ec9eb4f 100755
--- a/c++/src/objtools/edit/rna_edit.cpp
+++ b/c++/src/objtools/edit/rna_edit.cpp
@@ -1,4 +1,4 @@
-/*  $Id: rna_edit.cpp 460068 2015-02-24 19:12:10Z filippov $
+/*  $Id: rna_edit.cpp 513682 2016-09-14 14:50:59Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -59,11 +59,13 @@ CRef <CSeq_feat> CFindITSParser :: x_ParseLine(const CTempString &line, CSeq_ent
 {
     CRef <CSeq_feat> null_mrna(NULL);
     vector<string> arr;
-    NStr::Tokenize(line,"\t",arr);
+    NStr::Split(line,"\t",arr);
     if (arr.size() != 9)  
     {
-        msg = "Unable to parse extractor line ";
-        msg += line;
+        if (arr.size() == 1)
+            msg = "No features found for: " + line;
+        else if (!arr.empty())
+            msg = "Malformed line: " + line;
         return null_mrna;
     }
     string accession = arr[0];
@@ -74,6 +76,14 @@ CRef <CSeq_feat> CFindITSParser :: x_ParseLine(const CTempString &line, CSeq_ent
     string lsu = arr[6];
     string error = arr[7];  
     string strand = arr[8]; 
+
+    bsh = x_GetBioseqHandleFromIdGuesser(accession,tse);
+    if (!bsh) 
+    {
+        msg = "No bioseq found for: " + accession;
+        return null_mrna;
+    }
+
     arr.clear();
     NStr::TruncateSpacesInPlace(error);  
     if (!error.empty() && error !=  "Broken or partial sequence, no 5.8S!" && error !=  "Broken or partial sequence, only partial 5.8S!")
@@ -82,66 +92,187 @@ CRef <CSeq_feat> CFindITSParser :: x_ParseLine(const CTempString &line, CSeq_ent
         return null_mrna;
     }
 
-    NStr::Tokenize(ssu,":",arr);
+    NStr::Split(ssu,":",arr);
     ssu = arr.back();
     NStr::TruncateSpacesInPlace(ssu);
     arr.clear();
 
-    NStr::Tokenize(its1,":",arr);
+    NStr::Split(its1,":",arr);
     its1 = arr.back();
     NStr::TruncateSpacesInPlace(its1);
     arr.clear();
 
-    NStr::Tokenize(r58S,":",arr);
+    NStr::Split(r58S,":",arr);
     r58S = arr.back();
     NStr::TruncateSpacesInPlace(r58S);
     arr.clear();
 
-    NStr::Tokenize(its2,":",arr);
+    NStr::Split(its2,":",arr);
     its2 = arr.back();
     NStr::TruncateSpacesInPlace(its2);
     arr.clear();
 
-    NStr::Tokenize(lsu,":",arr);
+    NStr::Split(lsu,":",arr);
     lsu = arr.back();
     NStr::TruncateSpacesInPlace(lsu);
     arr.clear();
 
+    bool ssu_present(false);
+    bool lsu_present(false);
+    bool ssu_too_large(false);
+    bool lsu_too_large(false);
+    bool r58S_too_large(false);
+    bool its1_span(false);
+    bool its2_span(false);
+   
+    vector<int> starts;
+    vector<int> stops;
+    vector<bool> spans;
+    int bioseq_length = bsh.GetBioseqLength();
+    GetSpan(ssu, starts, stops, spans);
+    GetSpan(its1, starts, stops, spans);
+    GetSpan(r58S, starts, stops, spans);
+    GetSpan(its2, starts, stops, spans);
+    GetSpan(lsu, starts, stops, spans);
+
+    its1_span = spans[1];
+    its2_span = spans[3];
+  
     vector<string> comments;
     if (ssu != "Not found")
-        comments.push_back("18S ribosomal RNA");
+    {
+        comments.push_back("small subunit ribosomal RNA");
+        ssu_present = true;
+        ssu_too_large = IsLengthTooLarge(ssu, 2200, 0, starts, stops, spans, bioseq_length);
+    }
     if (its1 != "Not found")
-        comments.push_back("internal transcribed spacer 1");
+    {
+        comments.push_back("internal transcribed spacer 1");     
+    }
     if (r58S != "Not found")
+    {
         comments.push_back("5.8S ribosomal RNA");
+        r58S_too_large = IsLengthTooLarge(r58S, 200, 2, starts, stops, spans, bioseq_length);
+    }
     if (its2 != "Not found")
-        comments.push_back("internal transcribed spacer 2");
+    {
+        comments.push_back("internal transcribed spacer 2");      
+    }
     if (lsu != "Not found")
-        comments.push_back("28S ribosomal RNA");
+    {
+        comments.push_back("large subunit ribosomal RNA");
+        lsu_present = true;
+        lsu_too_large = IsLengthTooLarge(lsu, 5100, 4, starts, stops, spans, bioseq_length);
+    }
 
-/*    if ((r58S == "Not found"  || r58S == "No start" || r58S == "No end")&& 
-        (ssu  != "Not found" || its1  != "Not found" || its2  != "Not found" || lsu  != "Not found"))
+    if (its1_span && its2_span && (r58S == "Not found" || r58S == "No end" || r58S == "No start"))
+    {
+        msg = "5.8S is not found while ITS1 and ITS2 spans exist in: "+accession;
+        return null_mrna;
+    }
+    if (ssu_too_large)
+    {
+        msg = "SSU too large in: "+accession;
+        return null_mrna;
+    }
+    if (lsu_too_large)
     {
-        msg = "5.8S not found, but flanking regions have been found.";
+        msg = "LSU too large in: "+accession;
         return null_mrna;
     }
-    */
+    if (r58S_too_large)
+    {
+        msg = "5.8S too large in: "+accession;
+        return null_mrna;
+    }
+    
+
     string comment;
     switch(comments.size())
     {
     case 0 : comment = "does not contain rna label";break;
-    case 1 : comment = "contains "+comments.front();break;
+    case 1 : 
+    {
+        if (!ssu_present && !lsu_present) 
+        {
+            comment = "contains "+comments.front();
+        } 
+    }
+    break;
     case 2 : comment = "contains " + comments[0]+" and "+comments[1];break;
     default : comment = "contains "+comments[0]; for (unsigned int j=1; j<comments.size()-1;j++) comment += ", "+comments[j]; comment += ", and "+comments.back();break;
     }
     negative = strand == "1";
-    bsh = x_GetBioseqHandleFromIdGuesser(accession,tse);
-    if (!bsh) return null_mrna;
-    return x_CreateMiscRna(accession,comment,bsh);
+    if (comments.size() == 1 && (ssu_present || lsu_present))
+        return x_CreateRRna(comments.front(), bsh);
+    return x_CreateMiscRna(comment,bsh);
+}
+
+void CFindITSParser :: GetSpan(const string& str, vector<int>& starts, vector<int>& stops, vector<bool>& spans)
+{
+    int start, stop;
+    bool span(false);
+    vector<string> arr;
+    NStr::Split(str,"-",arr);
+    if (arr.size() == 2)
+    {
+        span = true;
+        start =  NStr::StringToInt(arr.front(), NStr::fConvErr_NoThrow);
+        stop =  NStr::StringToInt(arr.back(), NStr::fConvErr_NoThrow);
+    }
+    starts.push_back(start);
+    stops.push_back(stop);
+    spans.push_back(span);
 }
 
+bool CFindITSParser :: IsLengthTooLarge(const string& str, int max_length, 
+                                        int i,
+                                        const vector<int>& starts,
+                                        const vector<int>& stops,
+                                        const vector<bool>& spans,
+                                        int bioseq_length)
+{
+    if (spans[i])
+    {
+        int start = starts[i];
+        int end = stops[i];
+        int length = end - start + 1;
+        return length > max_length;
+    }
+    if (str == "No end")
+    {
+        int start = 1;
+        for (int j = i - 1; j >= 0; j--)
+        {
+            if (spans[j])
+            {
+                start = stops[j] + 1;
+                break;
+            }
+        }
+        int end = bioseq_length;
+        int length = end - start + 1;
+        return length > max_length;
+    }
+    if (str == "No start")
+    {
+        int start = 1;
+        int end = bioseq_length;
+        for (int j = i + 1; j < spans.size(); j++)
+        {
+            if (spans[j])
+            {
+                end = starts[j] - 1;
+                break;
+            }
+        }
+        int length = end - start + 1;
+        return length > max_length;
+    }
+    return false;
+}
 
-CRef <CSeq_feat> CFindITSParser :: x_CreateMiscRna(const string &accession, const string &comment, CBioseq_Handle bsh)
+CRef <CSeq_feat> CFindITSParser :: x_CreateMiscRna(const string &comment, CBioseq_Handle bsh)
 {
     CRef <CSeq_feat> new_mrna (new CSeq_feat());
     new_mrna->SetData().SetRna().SetType(CRNA_ref::eType_miscRNA);
@@ -160,6 +291,26 @@ CRef <CSeq_feat> CFindITSParser :: x_CreateMiscRna(const string &accession, cons
     return new_mrna;
 }
 
+CRef <CSeq_feat> CFindITSParser :: x_CreateRRna(const string &comment, CBioseq_Handle bsh)
+{
+    CRef <CSeq_feat> new_rrna (new CSeq_feat());
+    new_rrna->SetData().SetRna().SetType(CRNA_ref::eType_rRNA);
+    string remainder;
+    new_rrna->SetData().SetRna().SetRnaProductName(comment, remainder);
+  
+    CRef<CSeq_loc> loc(new CSeq_loc());
+    loc->SetInt().SetFrom(0);
+    loc->SetInt().SetTo(bsh.GetBioseqLength()-1);
+    loc->SetInt().SetStrand(eNa_strand_plus);
+    loc->SetPartialStart(true, eExtreme_Positional); 
+    loc->SetPartialStop(true, eExtreme_Positional); 
+    loc->SetId(*bsh.GetSeqId());
+    new_rrna->SetLocation(*loc);
+    
+    new_rrna->SetPartial(true);
+    return new_rrna;
+}
+
 CBioseq_Handle CFindITSParser :: x_GetBioseqHandleFromIdGuesser(const string &id_str, objects::CSeq_entry_Handle tse)
 {
     CRef<edit::CStringConstraint> constraint(new edit::CStringConstraint(id_str, edit::CStringConstraint::eMatchType_Equals));
diff --git a/c++/src/objtools/edit/seq_entry_edit.cpp b/c++/src/objtools/edit/seq_entry_edit.cpp
index 1efc86b..2f100f5 100644
--- a/c++/src/objtools/edit/seq_entry_edit.cpp
+++ b/c++/src/objtools/edit/seq_entry_edit.cpp
@@ -1,4 +1,4 @@
-/*  $Id: seq_entry_edit.cpp 500378 2016-05-04 13:49:57Z ivanov $
+/*  $Id: seq_entry_edit.cpp 519211 2016-11-14 16:04:20Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -60,7 +60,6 @@
 #include <objtools/edit/seq_entry_edit.hpp>
 #include <objtools/edit/loc_edit.hpp>
 
-#include <objtools/edit/gene_utils.hpp>
 #include <objtools/edit/autodef_options.hpp>
 
 #include <set>
@@ -1751,6 +1750,8 @@ void ConvertRawToDeltaByNs(CSeq_inst& inst,
                 s_AddLiteral(inst, element);
             }
             s_AddGap(inst, n_len, is_unknown, is_assembly_gap, gap_type, linkage, linkage_evidence);
+        } else {
+            s_AddLiteral(inst, element);
         }
     } else {
         s_AddLiteral(inst, element);
@@ -2283,7 +2284,7 @@ void TrimSeqData(CBioseq_Handle bsh,
     // There should be sequence data
     if ( !(bsh.CanGetInst() && bsh.GetInst().IsSetSeq_data()) ) {
         return;
-    }
+        }
 
     // Copy residues to buffer
     CSeqVector vec(bsh, CBioseq_Handle::eCoding_Iupac);
@@ -2296,13 +2297,13 @@ void TrimSeqData(CBioseq_Handle bsh,
         TSeqPos start = cut.GetFrom();
         TSeqPos length = cut.GetTo() - start + 1;
         seq_string.erase(start, length);
-    }
+            }
 
     // Update sequence length and sequence data
     inst->SetLength(seq_string.size());
     inst->SetSeq_data().SetIupacna(*new CIUPACna(seq_string));
     CSeqportUtil::Pack(&inst->SetSeq_data());
-}
+    }
 
 
 static void s_GetTrimCoordinates(CBioseq_Handle bsh,
@@ -3201,7 +3202,7 @@ string GetTargetedLocusName(const CSeq_feat& feat)
 string GetTargetedLocusName(const CSeq_feat& cds, CScope& scope)
 {
     string tls = kEmptyStr;
-    CConstRef <CSeq_feat> gene_for_feat = GetGeneForFeature(cds, scope);
+    CConstRef <CSeq_feat> gene_for_feat = sequence::GetGeneForFeature(cds, scope);
     if (gene_for_feat) {
         tls = GetTargetedLocusName(*gene_for_feat);
     }
diff --git a/c++/src/objtools/edit/string_constraint.cpp b/c++/src/objtools/edit/string_constraint.cpp
index baab6ac..c77a260 100644
--- a/c++/src/objtools/edit/string_constraint.cpp
+++ b/c++/src/objtools/edit/string_constraint.cpp
@@ -1,4 +1,4 @@
-/*  $Id: string_constraint.cpp 460632 2015-03-02 14:41:06Z asztalos $
+/*  $Id: string_constraint.cpp 518211 2016-11-01 15:04:31Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -106,38 +106,30 @@ bool CStringConstraint::DoesTextMatch (const string& text)
         NStr::ToLower(tmp);
     }
     
-    switch (m_MatchType) {
+    vector<string> tokens;
+    if (m_MatchType == eMatchType_Equals)
+        tokens.push_back(match);
+    else
+        NStr::Split(match, ",; ", tokens);
+    ITERATE(vector<string>, it, tokens) {
+        switch (m_MatchType) {
         case eMatchType_Contains: 
-            if (NStr::Find(tmp, match) != string::npos) {
-                rval = true;
-            }
+            rval |= (NStr::Find(tmp, *it) != string::npos);
             break;
         case eMatchType_Equals:
-            if (NStr::Equal(tmp, match)) {
-                rval = true;
-            }
+            rval |= NStr::Equal(tmp, *it);
             break;
         case eMatchType_StartsWith:
-            if (NStr::StartsWith(tmp, match)) {
-                rval = true;
-            }
+            rval |= NStr::StartsWith(tmp, *it);
             break;
         case eMatchType_EndsWith:
-            if (NStr::EndsWith(tmp, match)) {
-                rval = true;
-            }
+            rval |= NStr::EndsWith(tmp, *it);
             break;
         case eMatchType_IsOneOf:
-            {
-                vector<string> tokens;
-                NStr::Tokenize(match, ",; ", tokens);
-                ITERATE(vector<string>, it, tokens) {
-                    if (NStr::Equal(*it, tmp)) {
-                        rval = true;
-                        break;
-                    }
-                }
-            }
+            rval |= (IsInRange(*it, tmp) || NStr::Equal(*it, tmp));
+            break;
+        }
+        if (rval)
             break;
     }
     if (m_NotPresent) {
@@ -146,6 +138,32 @@ bool CStringConstraint::DoesTextMatch (const string& text)
     return rval;    
 }
 
+bool CStringConstraint::IsInRange(const string& str, const string &tmp)
+{
+    bool range(false);
+    if (NStr::Find(str, "-") != NPOS)
+    {
+        string first, last;
+        NStr::SplitInTwo(str, "-", first, last);
+        int start = NStr::StringToInt(first, NStr::fConvErr_NoThrow | NStr::fAllowLeadingSymbols);
+        int end = NStr::StringToInt(last, NStr::fConvErr_NoThrow | NStr::fAllowLeadingSymbols);
+        NStr::ReplaceInPlace(first, NStr::IntToString(start), kEmptyStr);
+        NStr::ReplaceInPlace(last, NStr::IntToString(end), kEmptyStr);
+        if (first == last && start <= end)
+        {
+            for ( ; start <= end; ++start)
+            {
+                string match = first + NStr::IntToString(start);
+                if (NStr::Equal(match, tmp)) 
+                {
+                    range = true;
+                    break;
+                }
+            }
+        }
+    }
+    return range;
+}
 
 bool CStringConstraint::DoesListMatch(const vector<string>& vals)
 {
diff --git a/c++/src/objtools/edit/struc_comm_field.cpp b/c++/src/objtools/edit/struc_comm_field.cpp
index c2993aa..86485fb 100644
--- a/c++/src/objtools/edit/struc_comm_field.cpp
+++ b/c++/src/objtools/edit/struc_comm_field.cpp
@@ -1,4 +1,4 @@
-/*  $Id: struc_comm_field.cpp 493879 2016-03-02 14:17:26Z ivanov $
+/*  $Id: struc_comm_field.cpp 492413 2016-02-17 15:49:17Z bollin $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/format/Makefile.xformat.lib b/c++/src/objtools/format/Makefile.xformat.lib
index 72ebee8..2c2fa6a 100644
--- a/c++/src/objtools/format/Makefile.xformat.lib
+++ b/c++/src/objtools/format/Makefile.xformat.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.xformat.lib 472056 2015-07-06 19:29:12Z gotvyans $
+# $Id: Makefile.xformat.lib 501626 2016-05-17 17:32:10Z kornbluh $
 
 # Build library "xformat"
 ###############################
@@ -20,7 +20,7 @@ SRC = accession_item basecount_item comment_item contig_item date_item \
 
 DLL_LIB = xalnmgr xconnect
 
-WATCHERS = ludwigf dicuccio kornbluh
+WATCHERS = ludwigf dicuccio
 
 
 USES_LIBRARIES =  \
diff --git a/c++/src/objtools/format/comment_item.cpp b/c++/src/objtools/format/comment_item.cpp
index d9fe9c8..5b07639 100644
--- a/c++/src/objtools/format/comment_item.cpp
+++ b/c++/src/objtools/format/comment_item.cpp
@@ -1,4 +1,4 @@
-/*  $Id: comment_item.cpp 495721 2016-03-21 14:22:49Z ivanov $
+/*  $Id: comment_item.cpp 506085 2016-07-01 14:25:26Z gotvyans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -73,8 +73,8 @@ bool CCommentItem::sm_FirstComment = true;
 
 static const string kRefSeq = "REFSEQ";
 static const string kRefSeqInformation = "REFSEQ INFORMATION";
-static const string kRefSeqLink = "<a href=\"http://www.ncbi.nlm.nih.gov/RefSeq/\">REFSEQ</a>";
-static const string kRefSeqInformationLink = "<a href=\"http://www.ncbi.nlm.nih.gov/RefSeq/\">REFSEQ INFORMATION</a>";
+static const string kRefSeqLink = "<a href=\"https://www.ncbi.nlm.nih.gov/RefSeq/\">REFSEQ</a>";
+static const string kRefSeqInformationLink = "<a href=\"https://www.ncbi.nlm.nih.gov/RefSeq/\">REFSEQ INFORMATION</a>";
 
 /////////////////////////////////////////////////////////////////////////////
 //
@@ -359,16 +359,12 @@ string CCommentItem::GetStringForBankIt(const CUser_object& uo, bool dump_mode)
 }
 
 
-
-static void s_GetAssemblyInfo(const CUser_object& uo,
-                              string& s,
-                              CCommentItem::ECommentFormat format,
-                              CScope &scope )
+static 
+void s_GetAssemblyInfo(const CBioseqContext& ctx, string& s, const CUser_object& uo)
 {
     s.clear();
 
-    const bool is_html = (format == CCommentItem::eFormat_Html);
-
+    const bool is_html = ctx.Config().DoHTML();
     vector<string> assembly_pieces;
 
     if ( uo.HasField("Assembly") ) {
@@ -436,11 +432,19 @@ static void s_GetAssemblyInfo(const CUser_object& uo,
                 // } catch(...) {
                 //     // do nothing, we know there's an error because new_gi is zero
                 // }
+#ifdef NEW_HTML_FMT
+                if (IsValidAccession(accession)) {
+                    ctx.Config().GetHTMLFormatter().FormatGeneralId(oss, accession);
+                } else {
+                    oss << accession;                    
+                }
+#else
                 if( IsValidAccession(accession) ) {
                     NcbiId(oss, accession, is_html);
                 } else {
                     oss << accession;                    
                 }
+#endif
 
                 if( from > 0 && to > 0 ) {
                     oss << " (range: " << from << "-" << to << ")";
@@ -516,12 +520,12 @@ CCommentItem::TRefTrackStatus CCommentItem::GetRefTrackStatus
 }
 
 
-string CCommentItem::GetStringForRefTrack
-(const CUser_object& uo,
- const CBioseq_Handle& bsh,
- ECommentFormat format,
- EGenomeBuildComment eGenomeBuildComment )
+string CCommentItem::GetStringForRefTrack(const CBioseqContext& ctx, const CUser_object& uo,
+    const CBioseq_Handle& bsh,
+    EGenomeBuildComment eGenomeBuildComment )
 {
+    bool is_html = ctx.Config().DoHTML();
+
     if ( !uo.IsSetType()  ||  !uo.GetType().IsStr()  ||
          uo.GetType().GetStr() != "RefGeneTracking") {
         return kEmptyStr;
@@ -598,10 +602,10 @@ string CCommentItem::GetStringForRefTrack
 
     CNcbiOstrstream oss;
     if (status == eRefTrackStatus_Pipeline) {
-        oss << ( format == eFormat_Html ? kRefSeqInformationLink : kRefSeqInformation ) << ":";
+        oss << (is_html ? kRefSeqInformationLink : kRefSeqInformation) << ":";
     } else {
         oss << status_str << ' ' 
-            << ( format == eFormat_Html ? kRefSeqLink : kRefSeq ) << ":";
+            << (is_html ? kRefSeqLink : kRefSeq) << ":";
     }
     switch ( status ) {
     case eRefTrackStatus_Inferred:
@@ -614,11 +618,11 @@ string CCommentItem::GetStringForRefTrack
                 oss << " Features on this sequence have been produced for build "
                     << build_num << " of the NCBI's genome annotation"
                     << " [see ";
-                if( format == eFormat_Html ) {
+                if (is_html) {
                     oss << "<a href=\"" << strDocLink << "\">" ;
                 }
                 oss << "documentation";
-                if( format == eFormat_Html ) {
+                if (is_html) {
                     oss << "</a>";
                 }
                 oss << "].";
@@ -675,8 +679,17 @@ string CCommentItem::GetStringForRefTrack
 
     if ( !identical_to.empty() ) {
         oss << " The reference sequence is identical to ";
-        const bool add_link = (format == eFormat_Html && identical_to_priority != eIdenticalToPriority_Name);
+        const bool add_link = (is_html && identical_to_priority != eIdenticalToPriority_Name);
+#ifdef NEW_HTML_FMT
+        if (add_link) {
+            ctx.Config().GetHTMLFormatter().FormatGeneralId(oss, identical_to);
+        }
+        else {
+            oss << identical_to;
+        }
+#else
         NcbiId( oss, identical_to, add_link );
+#endif
 
         if( ! identical_to_start.empty() && ! identical_to_end.empty() ) {
             oss << " (range: " << identical_to_start << "-" << 
@@ -688,11 +701,11 @@ string CCommentItem::GetStringForRefTrack
     {{
          /// add our assembly info
          string s;
-         s_GetAssemblyInfo(uo, s, format, bsh.GetScope());
+         s_GetAssemblyInfo(ctx, s, uo);
          oss << s;
      }}
 
-    const static string kRefSeqGeneLink = "<a href=\"http://www.ncbi.nlm.nih.gov/refseq/rsg/\">RefSeqGene</a>";
+    const static string kRefSeqGeneLink = "<a href=\"https://www.ncbi.nlm.nih.gov/refseq/rsg/\">RefSeqGene</a>";
     const static string kRefSeqGene = "RefSeqGene";
 
     /// check for a concomitant RefSeqGene item
@@ -706,7 +719,7 @@ string CCommentItem::GetStringForRefTrack
                 const string& status = f->GetData().GetStr();
                 if (status == "Reference Standard") {
                     oss << "~This sequence is a reference standard in the " 
-                        << ( format == eFormat_Html ? kRefSeqGeneLink : kRefSeqGene )
+                        << (is_html ? kRefSeqGeneLink : kRefSeqGene)
                         << " project.";
                 }
             }
@@ -1122,6 +1135,7 @@ string CCommentItem::GetStringForHTGS(CBioseqContext& ctx)
     return comment;
 }
 
+#ifndef NEW_HTML_FMT
 static
 string s_HtmlWrapModelEvidenceName( const SModelEvidance& me )
 {
@@ -1149,18 +1163,22 @@ string s_HtmlWrapTranscriptName( const string& name )
 {
     return "<a href=\"" + strLinkBaseNuc + name + "\">" + name + "</a>";
 }
+#endif
 
-string CCommentItem::GetStringForModelEvidance
-(const SModelEvidance& me,
- ECommentFormat format)
+string CCommentItem::GetStringForModelEvidance(const CBioseqContext& ctx, const SModelEvidance& me)
 {
-    const bool bHtml = (format == eFormat_Html);
+    const bool bHtml = ctx.Config().DoHTML();
 
     const string *refseq = (bHtml ? &kRefSeqLink : &kRefSeq);
 
     CNcbiOstrstream text;
 
+#ifdef NEW_HTML_FMT
+    string me_name;
+    ctx.Config().GetHTMLFormatter().FormatModelEvidence(me_name, me);
+#else
     const string me_name = ( bHtml ? s_HtmlWrapModelEvidenceName(me) : me.name );
+#endif
 
     text << "MODEL " << *refseq << ":  " << "This record is predicted by "
          << "automated computational analysis. This record is derived from "
@@ -1176,7 +1194,12 @@ string CCommentItem::GetStringForModelEvidance
         int count = 0;
         string prefix = "";
         FOR_EACH_STRING_IN_LIST (str, me.assembly) {
+#ifdef NEW_HTML_FMT
+            string tr_name;
+            ctx.Config().GetHTMLFormatter().FormatTranscript(tr_name, *str);
+#else
             const string tr_name = ( bHtml ? s_HtmlWrapTranscriptName(*str) : *str);
+#endif
             text << prefix << tr_name;
             count++;
             if (num_assm == count + 1) {
@@ -1206,7 +1229,7 @@ string CCommentItem::GetStringForModelEvidance
     }
 
     const char *documentation_str = ( bHtml ? 
-        "<a href=\"http://www.ncbi.nlm.nih.gov/genome/annotation_euk/process/\">Documentation</a>" : 
+        "<a href=\"https://www.ncbi.nlm.nih.gov/genome/annotation_euk/process/\">Documentation</a>" : 
         "Documentation" );
 
     text << ".~Also see:~"
@@ -1272,7 +1295,7 @@ static bool s_GetEncodeValues
 
 string CCommentItem::GetStringForEncode(CBioseqContext& ctx)
 {
-    const static string kEncodeProjLink = "http://www.nhgri.nih.gov/10005107";
+    const static string kEncodeProjLink = "https://www.nhgri.nih.gov/10005107";
 
     const bool bHtml = ctx.Config().DoHTML();
 
@@ -1322,7 +1345,7 @@ string CCommentItem::GetStringForAuthorizedAccess(CBioseqContext& ctx)
         str << "</a>";
         str << " to Study ";
         str << "<a href=\""  
-            << "http://www.ncbi.nlm.nih.gov/projects/gap/cgi-bin/study.cgi?study_id="
+            << "https://www.ncbi.nlm.nih.gov/projects/gap/cgi-bin/study.cgi?study_id="
             << sAuthorizedAccess << "\">";
         str << sAuthorizedAccess;
         str << "</a>";
@@ -1526,7 +1549,7 @@ void CCommentItem::x_GatherInfo(CBioseqContext& ctx)
 
 // returns the data_str, but wrapped in appropriate <a href...>...</a> if applicable
 static
-string s_HtmlizeStructuredCommentData( const bool is_html, const string &label_str, const string &data_str, const char* provider )
+string s_HtmlizeStructuredCommentData( const bool is_html, const string &label_str, const string &data_str, const char* provider, const char* status )
 {
     if( ! is_html ) {
         return data_str;
@@ -1543,7 +1566,7 @@ string s_HtmlizeStructuredCommentData( const bool is_html, const string &label_s
                << data_str
                << "\">" << data_str << "</a>";
         return CNcbiOstrstreamToString(result);
-    } else if ( NStr::Equal (label_str, "Annotation Version") && NStr::Equal (provider, "NCBI") ) {
+    } else if ( NStr::Equal (label_str, "Annotation Version") && NStr::Equal (provider, "NCBI") && NStr::Equal (status, "Full annotation") ) {
         string fst;
         string snd;
         NStr::Replace( data_str, " Annotation Release ", "/", fst );
@@ -1575,6 +1598,7 @@ void s_GetStrForStructuredComment(
     const char* prefix = "##Metadata-START##";
     const char* suffix = "##Metadata-END##";
     const char* provider = "";
+    const char* status = "";
 
     bool fieldOverThreshold = false;
 
@@ -1593,6 +1617,8 @@ void s_GetStrForStructuredComment(
             } else {
                 if ( label == "Annotation Provider" ) {
                     provider = (*it_for_len)->GetData().GetStr().c_str();
+                } else if ( label == "Annotation Status" ) {
+                    status = (*it_for_len)->GetData().GetStr().c_str();
                 }
                 const string::size_type label_len = label.length();
                 if( (label_len > longest_label_len) && (label_len <= kFieldLenThreshold) ) {
@@ -1642,7 +1668,7 @@ void s_GetStrForStructuredComment(
             next_line.resize( max( next_line.size(), longest_label_len), ' ' );
         }
         next_line.append( " :: " );
-        next_line.append( s_HtmlizeStructuredCommentData( is_html, (*it)->GetLabel().GetStr(), (*it)->GetData().GetStr(), provider ) );
+        next_line.append( s_HtmlizeStructuredCommentData( is_html, (*it)->GetLabel().GetStr(), (*it)->GetData().GetStr(), provider, status ) );
         next_line.append( "\n" );
 
         ExpandTildes(next_line, eTilde_comment);
@@ -1957,11 +1983,7 @@ void CGenomeAnnotComment::x_GatherInfo(CBioseqContext& ctx)
         }
 
         string s;
-        s_GetAssemblyInfo(uo, s,
-                          ctx.Config().DoHTML() ?
-                          CCommentItem::eFormat_Html :
-                          CCommentItem::eFormat_Text,
-                              ctx.GetScope() );
+        s_GetAssemblyInfo(ctx, s, uo);
         text << s;
         break;
     }
@@ -2021,7 +2043,11 @@ string s_CreateHistCommentString
             text << ",";
         }
         text << " gi:";
+#ifdef NEW_HTML_FMT
+        ctx.Config().GetHTMLFormatter().FormatGeneralId(text, NStr::NumericToString(gis[count]));
+#else
         NcbiId(text, gis[count], ctx.Config().DoHTML());
+#endif
     }
     text << '.' << '\n';
 
diff --git a/c++/src/objtools/format/context.cpp b/c++/src/objtools/format/context.cpp
index e37b4b7..ea1dfa7 100644
--- a/c++/src/objtools/format/context.cpp
+++ b/c++/src/objtools/format/context.cpp
@@ -1,4 +1,4 @@
-/*  $Id: context.cpp 495721 2016-03-21 14:22:49Z ivanov $
+/*  $Id: context.cpp 515538 2016-10-03 16:03:11Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -251,7 +251,7 @@ void CBioseqContext::x_Init(const CBioseq_Handle& seq, const CSeq_loc* user_loc)
     m_HasOperon = x_HasOperon();
 
     if (IsRefSeq()) {
-        m_FFCtx.GetConfig().SetRefSeqConventions();
+        m_FFCtx.SetConfig().SetRefSeqConventions();
     }
 
     SAnnotSelector sel = SetAnnotSelector();
@@ -285,8 +285,8 @@ void CBioseqContext::x_SetLocation(const CSeq_loc* user_loc)
             if (loc->IsWhole()) {
                 loc.Reset();
             } else if (loc->IsInt()) {
-                CSeq_loc::TRange range = loc->GetTotalRange();
-                if (range.GetFrom() == 0  &&  range.GetTo() == m_Handle.GetInst_Length() - 1) {
+                CSeq_loc::TRange range = loc->GetTotalRange();               
+                if (!IsReverse(loc->GetStrand()) && range.GetFrom() == 0 && range.GetTo() == m_Handle.GetInst_Length() - 1) {
                     loc.Reset();
                 }
             }
@@ -925,6 +925,8 @@ bool CBioseqContext::x_IsDeltaLitOnly(void) const
         if ( ext.IsDelta() ) {
             ITERATE (CDelta_ext::Tdata, it, ext.GetDelta().Get()) {
                 if ( (*it)->IsLoc() ) {
+                    const CSeq_loc& loc = (*it)->GetLoc();
+                    if (loc.IsNull()) continue;
                     return false;
                 }
             }
diff --git a/c++/src/objtools/format/dbsource_item.cpp b/c++/src/objtools/format/dbsource_item.cpp
index 50a35bc..f908a19 100644
--- a/c++/src/objtools/format/dbsource_item.cpp
+++ b/c++/src/objtools/format/dbsource_item.cpp
@@ -1,4 +1,4 @@
-/*  $Id: dbsource_item.cpp 472056 2015-07-06 19:29:12Z gotvyans $
+/*  $Id: dbsource_item.cpp 506085 2016-07-01 14:25:26Z gotvyans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -609,13 +609,18 @@ string CDBSourceItem::x_FormatDBSourceID(const CSeq_id_Handle& idh)
                     choice != CSeq_id::e_Swissprot) {
                     acc += '.' + NStr::IntToString(tsid->GetVersion());
                 }
-                if( is_html ) {
+#ifdef NEW_HTML_FMT
+                s += comma + sep + "accession ";
+                GetContext()->Config().GetHTMLFormatter().FormatNucId(s, *idh.GetSeqId(), GetContext()->GetScope().GetGi(idh), acc);
+#else
+                if (is_html) {
                     const TIntId gi = GetContext()->GetScope().GetGi(idh);
                     s += comma + sep + "accession <a href=\"" + strLinkBaseNuc +
                         NStr::NumericToString(gi) + "\">" + acc + "</a>";
                 } else {
                     s += comma + sep + "accession " + acc;
                 }
+#endif
                 sep = " ";
             }
             /**
diff --git a/c++/src/objtools/format/feature_item.cpp b/c++/src/objtools/format/feature_item.cpp
index 12e1b30..2d9b93a 100644
--- a/c++/src/objtools/format/feature_item.cpp
+++ b/c++/src/objtools/format/feature_item.cpp
@@ -1,4 +1,4 @@
-/*  $Id: feature_item.cpp 498880 2016-04-20 13:36:23Z ivanov $
+/*  $Id: feature_item.cpp 514605 2016-09-22 18:44:07Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -65,6 +65,7 @@
 #include <objects/seqfeat/PCRReactionSet.hpp>
 #include <objects/seqfeat/Code_break.hpp>
 #include <objects/seqfeat/Delta_item.hpp>
+#include <objects/seqfeat/Gb_qual.hpp>
 #include <objects/seqfeat/Gene_nomenclature.hpp>
 #include <objects/seqfeat/Genetic_code.hpp>
 #include <objects/seqfeat/Genetic_code_table.hpp>
@@ -996,7 +997,8 @@ string CFeatureItem::GetKey(void) const
             if ( subtype == CSeqFeatData::eSubtype_preprotein         ||
                  subtype == CSeqFeatData::eSubtype_mat_peptide_aa     ||
                 subtype == CSeqFeatData::eSubtype_sig_peptide_aa     ||
-                subtype == CSeqFeatData::eSubtype_transit_peptide_aa ) {
+                subtype == CSeqFeatData::eSubtype_transit_peptide_aa     ||
+                subtype == CSeqFeatData::eSubtype_propeptide ) {
                 return "Precursor";
             } 
         }
@@ -2324,11 +2326,14 @@ void CFeatureItem::x_AddQualProteinId(
 
             case CSeq_id::e_Gi:
                 if( seqid.GetGi() > ZERO_GI ) {
-                    if ( eLastRegularChoice == CSeq_id::e_not_set ) {
-                        // use as protein_id if it's the first usable one
-                        x_AddQual( eFQ_protein_id, new CFlatSeqIdQVal( seqid ) );
+                    const CFlatFileConfig& cfg = GetContext()->Config();
+                    if (! cfg.HideGI()) {
+                        if ( eLastRegularChoice == CSeq_id::e_not_set ) {
+                            // use as protein_id if it's the first usable one
+                            x_AddQual( eFQ_protein_id, new CFlatSeqIdQVal( seqid ) );
+                        }
+                        x_AddQual( eFQ_db_xref, new CFlatSeqIdQVal( seqid, true ) );
                     }
-                    x_AddQual( eFQ_db_xref, new CFlatSeqIdQVal( seqid, true ) );
                 }
                 break;
 
@@ -2590,10 +2595,13 @@ void CFeatureItem::x_AddProductIdQuals(
     x_AddQual(slot, new CFlatSeqIdQVal(*best.GetSeqId()));
 
     if( m_Feat.GetData().IsCdregion() || ! GetContext()->IsProt() ) {
+        const CFlatFileConfig& cfg = GetContext()->Config();
         ITERATE( CBioseq_Handle::TId, id_iter, ids ) {
             if( id_iter->IsGi() ) {
-                x_AddQual( eFQ_db_xref,
-                    new CFlatStringQVal("GI:" + NStr::NumericToString(id_iter->GetGi()) ));
+                if (! cfg.HideGI()) {
+                    x_AddQual( eFQ_db_xref,
+                        new CFlatStringQVal("GI:" + NStr::NumericToString(id_iter->GetGi()) ));
+                }
             }
         }
     }
@@ -3197,7 +3205,8 @@ void CFeatureItem::x_AddQualsProt(
     if ( !pseudo  &&  ctx.Config().ShowPeptides() ) {
         if ( processed == CProt_ref::eProcessed_mature          ||
              processed == CProt_ref::eProcessed_signal_peptide  ||
-             processed == CProt_ref::eProcessed_transit_peptide ) {
+             processed == CProt_ref::eProcessed_transit_peptide  ||
+             processed == CProt_ref::eProcessed_propeptide ) {
             CSeqVector pep(m_Feat.GetLocation(), ctx.GetScope());
             pep.SetCoding(CSeq_data::e_Ncbieaa);
             string peptide;
@@ -3497,6 +3506,7 @@ void CFeatureItem::x_ImportQuals(
         DO_IMPORT(product),
         DO_IMPORT(pseudogene),
         DO_IMPORT(rad_map),
+        DO_IMPORT(recombination_class),
         DO_IMPORT(regulatory_class),
         DO_IMPORT(replace),
         DO_IMPORT(ribosomal_slippage),
@@ -3788,30 +3798,6 @@ void CFeatureItem::x_AddRptUnitQual(
 }
 
 
-static bool s_IsValidRptType(const string& type)
-{
-    static const char* const valid_rpt[] = {
-        "centromeric_repeat",
-        "direct",
-        "dispersed",
-        "engineered_foreign_repetitive_element",
-        "flanking",
-        "inverted",
-        "long_terminal_repeat",
-        "non_LTR_retrotransposon_polymeric_tract",
-        "other",
-        "tandem",
-        "telomeric_repeat",
-        "terminal",
-        "X_element_combinatorial_repeat",
-        "Y_prime_element"
-    };
-    typedef CStaticArraySet<string, PNocase> TValidRptTypes;
-    DEFINE_STATIC_ARRAY_MAP(TValidRptTypes, valid_types, valid_rpt);
-
-    return valid_types.find(type) != valid_types.end();
-}
-
 //  ----------------------------------------------------------------------------
 void CFeatureItem::x_AddRptTypeQual(
     const string& rpt_type, 
@@ -3829,7 +3815,7 @@ void CFeatureItem::x_AddRptTypeQual(
     s_SplitCommaSeparatedStringInParens( pieces, value );
 
     ITERATE( vector<string>, it, pieces ) {
-        if ( ! check_qual_syntax || s_IsValidRptType( *it ) ) {
+        if ( ! check_qual_syntax || CGb_qual::IsValidRptTypeValue( *it ) ) {
             x_AddQual( eFQ_rpt_type, new CFlatStringQVal( *it, CFormatQual::eUnquoted ) );
         }
     }
@@ -3838,30 +3824,14 @@ void CFeatureItem::x_AddRptTypeQual(
 
 static bool s_IsValidRegulatoryClass(const string& type)
 {
-    static const char* const kValidClasses[] = {
-        "attenuator",
-        "CAAT_signal",
-        "enhancer",
-        "enhancer_blocking_element",
-        "GC_signal",
-        "imprinting_control_region",
-        "insulator",
-        "locus_control_region",
-        "minus_10_signal",
-        "minus_35_signal",
-        "other",
-        "polyA_signal_sequence",
-        "promoter",
-        "response_element",
-        "ribosome_binding_site",
-        "silencer",
-        "TATA_box",
-        "terminator"
-    };
-    typedef CStaticArraySet<string, PNocase> TValidRegClass;
-    DEFINE_STATIC_ARRAY_MAP(TValidRegClass, valid_types, kValidClasses);
+    vector<string> valid_types = CSeqFeatData::GetRegulatoryClassList();
+
+    FOR_EACH_STRING_IN_VECTOR (itr, valid_types) {
+        string str = *itr;
+        if (NStr::Equal (str, type)) return true;
+    }
 
-    return valid_types.find(type) != valid_types.end();
+    return false;
 }
 
 //  ----------------------------------------------------------------------------
@@ -3879,7 +3849,17 @@ void CFeatureItem::x_AddRegulatoryClassQual(
         x_AddQual( eFQ_regulatory_class, new CFlatStringQVal(regulatory_class));
     } else {
         x_AddQual( eFQ_regulatory_class, new CFlatStringQVal("other"));
-        x_AddQual( eFQ_seqfeat_note, new CFlatStringQVal(regulatory_class));
+        string tmp = regulatory_class;
+        /*
+        if (NStr::StartsWith(tmp, "other:")) {
+            NStr::TrimPrefixInPlace(tmp, "other:");
+            NStr::TruncateSpacesInPlace(tmp);
+        }
+        */
+        if (NStr::StartsWith(tmp, "other")) {
+          return;
+        }
+        x_AddQual( eFQ_seqfeat_note, new CFlatStringQVal(tmp));
     }
 }
 
@@ -3899,6 +3879,7 @@ void CFeatureItem::x_FormatQuals(CFlatFeature& ff) const
 #define DO_QUAL(x) x_FormatQual(eFQ_##x, #x, qvec)
     DO_QUAL(ncRNA_class);
     DO_QUAL(regulatory_class);
+    DO_QUAL(recombination_class);
 
     DO_QUAL(partial);
     DO_QUAL(gene);
@@ -4636,6 +4617,7 @@ static const TQualPair sc_GbToFeatQualMap[] = {
     { eFQ_pseudogene, CSeqFeatData::eQual_pseudogene },
     { eFQ_region, CSeqFeatData::eQual_note },
     { eFQ_region_name, CSeqFeatData::eQual_region_name },
+    { eFQ_recombination_class, CSeqFeatData::eQual_recombination_class },
     { eFQ_regulatory_class, CSeqFeatData::eQual_regulatory_class },
     { eFQ_replace, CSeqFeatData::eQual_replace },
     { eFQ_ribosomal_slippage, CSeqFeatData::eQual_ribosomal_slippage },
@@ -5009,10 +4991,10 @@ void CFeatureItem::x_AddFTableCdregionQuals(
              id->IsOther() ||
              (id->IsLocal()  &&  !ctx.Config().SuppressLocalId()) ) {
             id_str = id->GetSeqIdString(true);
-        } else if ( id->IsGi() ) {
+        } else if ( id->IsGi() || id->IsGeneral() ) {
             id_str = id->AsFastaString();
         }
-        if (! cfg.HideProteinID()) {
+        if (! cfg.HideProteinID() && !NStr::IsBlank(id_str)) {
             x_AddFTableQual("protein_id", id_str);
         }
     }
diff --git a/c++/src/objtools/format/flat_file_config.cpp b/c++/src/objtools/format/flat_file_config.cpp
index e5e055e..e39cda6 100644
--- a/c++/src/objtools/format/flat_file_config.cpp
+++ b/c++/src/objtools/format/flat_file_config.cpp
@@ -1,4 +1,4 @@
-/*  $Id: flat_file_config.cpp 500529 2016-05-05 14:28:05Z ivanov $
+/*  $Id: flat_file_config.cpp 507550 2016-07-19 22:30:02Z kans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -58,6 +58,8 @@
 #include <objtools/format/items/wgs_item.hpp>
 #include <objtools/format/flat_expt.hpp>
 
+#include <objmgr/util/objutil.hpp>
+
 BEGIN_NCBI_SCOPE
 BEGIN_SCOPE(objects)
 
@@ -557,7 +559,8 @@ void CFlatFileConfig::AddArgumentDescriptions(CArgDescriptions& args)
          // custom (default: 0)
          arg_desc->AddDefaultKey("custom", "Custom",
                                  "Custom flat file output bits.  The value is the bitwise OR (logical addition) of:\n"
-                                 "         1 - hide protein_id and transcript_id",
+                                 "         1 - hide protein_id and transcript_id\n"
+                                 "         2 - hide GI number",
 
                                  CArgDescriptions::eInteger, "0");
 
@@ -587,7 +590,13 @@ void CFlatFileConfig::AddArgumentDescriptions(CArgDescriptions& args)
          arg_desc->AddOptionalKey("depth", "Depth",
                                   "Exploration depth", CArgDescriptions::eInteger);
 
-         arg_desc->AddFlag("show-flags",
+         arg_desc->AddOptionalKey("max_search_segments", "MaxSearchSegments",
+                                  "Max number of empty segments to search", CArgDescriptions::eInteger);
+
+          arg_desc->AddOptionalKey("max_search_time", "MaxSearchTime",
+                                  "Max time to search for first annotation", CArgDescriptions::eDouble);
+
+        arg_desc->AddFlag("show-flags",
                            "Describe the current flag set in ENUM terms");
 
          // view (default: nucleotide)
@@ -865,5 +874,47 @@ void CFlatFileConfig::FromArguments(const CArgs& args)
     SetCustom(custom);
 }
 
+#ifdef NEW_HTML_FMT
+void CHTMLEmptyFormatter::FormatProteinId(string& str, const CSeq_id& seq_id, const string& prot_id) const
+{
+    str = prot_id;
+}
+
+void CHTMLEmptyFormatter::FormatNucId(string& str, const CSeq_id& seq_id, TIntId gi, const string& acc_id) const
+{
+    str = acc_id;
+}
+
+void CHTMLEmptyFormatter::FormatLocation(string& str, const CSeq_loc& loc, TIntId gi, const string& visible_text) const
+{
+    str = visible_text;
+}
+
+void CHTMLEmptyFormatter::FormatModelEvidence(string& str, const SModelEvidance& me) const
+{
+    str = me.name;
+}
+
+void CHTMLEmptyFormatter::FormatNucSearch(CNcbiOstream& os, const string& id) const
+{
+    os << id;
+}
+
+void CHTMLEmptyFormatter::FormatTaxid(string& str, const int taxid, const string& taxname) const
+{
+    str = taxname;
+}
+
+void CHTMLEmptyFormatter::FormatTranscript(string& str, const string& name) const
+{
+    str = name;
+}
+
+void CHTMLEmptyFormatter::FormatGeneralId(CNcbiOstream& os, const string& id) const
+{
+    os << id;
+}
+#endif
+
 END_SCOPE(objects)
 END_NCBI_SCOPE
diff --git a/c++/src/objtools/format/flat_file_generator.cpp b/c++/src/objtools/format/flat_file_generator.cpp
index 830d148..c758d2c 100644
--- a/c++/src/objtools/format/flat_file_generator.cpp
+++ b/c++/src/objtools/format/flat_file_generator.cpp
@@ -1,4 +1,4 @@
-/*  $Id: flat_file_generator.cpp 498882 2016-04-20 13:37:11Z ivanov $
+/*  $Id: flat_file_generator.cpp 511755 2016-08-24 13:57:06Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -153,6 +153,18 @@ void CFlatFileGenerator::Generate
         }
     }
 
+    m_Ctx->SetSGS(false);
+    CConstRef<CSeq_entry> topent = entry.GetTopLevelEntry().GetCompleteSeq_entry();
+    if (topent && topent->IsSet()) {
+        const CBioseq_set& topset = topent->GetSet();
+        VISIT_ALL_SEQSETS_WITHIN_SEQSET (itr, topset) {
+            const CBioseq_set& bss = *itr;
+            if (bss.GetClass() == CBioseq_set::eClass_small_genome_set) {
+                    m_Ctx->SetSGS(true);
+            }
+        }
+    }
+
     CRef<CFlatItemOStream> pItemOS( & item_os );
     // If there is a ICancel callback, wrap the item_os so
     // that every call checks it.
@@ -383,7 +395,7 @@ void CFlatFileGenerator::Generate
     location->Assign(loc);
     m_Ctx->SetLocation(location);
 
-    CFlatFileConfig& cfg = m_Ctx->GetConfig();
+    CFlatFileConfig& cfg = m_Ctx->SetConfig();
     if (cfg.IsStyleNormal()) {
         cfg.SetStyleMaster();
     }
diff --git a/c++/src/objtools/format/flat_qual_slots.cpp b/c++/src/objtools/format/flat_qual_slots.cpp
index dc2cce0..b5087de 100644
--- a/c++/src/objtools/format/flat_qual_slots.cpp
+++ b/c++/src/objtools/format/flat_qual_slots.cpp
@@ -1,4 +1,4 @@
-/*  $Id: flat_qual_slots.cpp 449759 2014-10-20 19:44:53Z kans $
+/*  $Id: flat_qual_slots.cpp 514605 2016-09-22 18:44:07Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -142,6 +142,7 @@ GetStringOfFeatQual(EFeatureQualifier eFeatureQualifier)
         TYPICAL_FQ(rad_map),
         TYPICAL_FQ(region),
         TYPICAL_FQ(region_name),
+        TYPICAL_FQ(recombination_class),
         TYPICAL_FQ(regulatory_class),
         TYPICAL_FQ(replace),
         TYPICAL_FQ(ribosomal_slippage),
diff --git a/c++/src/objtools/format/flat_seqloc.cpp b/c++/src/objtools/format/flat_seqloc.cpp
index de5e5d8..e290408 100644
--- a/c++/src/objtools/format/flat_seqloc.cpp
+++ b/c++/src/objtools/format/flat_seqloc.cpp
@@ -1,4 +1,4 @@
-/*  $Id: flat_seqloc.cpp 500211 2016-05-03 13:44:08Z ivanov $
+/*  $Id: flat_seqloc.cpp 499994 2016-04-29 18:39:01Z kans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/format/gather_items.cpp b/c++/src/objtools/format/gather_items.cpp
index 51d4a9f..755d229 100644
--- a/c++/src/objtools/format/gather_items.cpp
+++ b/c++/src/objtools/format/gather_items.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gather_items.cpp 500529 2016-05-05 14:28:05Z ivanov $
+/*  $Id: gather_items.cpp 520380 2016-11-28 14:03:14Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -106,6 +106,7 @@
 #include <objtools/format/context.hpp>
 #include <objtools/error_codes.hpp>
 #include <objmgr/util/objutil.hpp>
+#include <objmgr/util/seq_loc_util.hpp>
 
 #include <connect/ncbi_socket.hpp>
 
@@ -1055,7 +1056,7 @@ void CFlatGatherer::x_IdComments(CBioseqContext& ctx,
                 {
                     SModelEvidance me;
                     if ( GetModelEvidance(ctx.GetHandle(), me) ) {
-                        string str = CCommentItem::GetStringForModelEvidance(me, format);
+                        string str = CCommentItem::GetStringForModelEvidance(ctx, me);
                         if ( !str.empty() ) {
                             CRef<CCommentItem> item(new CCommentItem(str, ctx));
                             item->SetNeedPeriod(false);
@@ -1140,10 +1141,7 @@ void CFlatGatherer::x_RefSeqComments(CBioseqContext& ctx,
         // RefTrack
         {{
             if ( !did_ref_track ) {
-                CCommentItem::ECommentFormat format = ctx.Config().DoHTML() ?
-                    CCommentItem::eFormat_Html : CCommentItem::eFormat_Text;
-                string str = 
-                    CCommentItem::GetStringForRefTrack(uo, ctx.GetHandle(), format, 
+                string str = CCommentItem::GetStringForRefTrack(ctx, uo, ctx.GetHandle(),
                     ( /* eGenomeAnnotComment == eGenomeAnnotComment_Yes ?
                       CCommentItem::eGenomeBuildComment_Yes : */
                       CCommentItem::eGenomeBuildComment_No ) );
@@ -1311,10 +1309,76 @@ void CFlatGatherer::x_NameComments(CBioseqContext& ctx) const
     }
 }
 
+static int s_StrucCommOrder(const string&str) {
+    if (NStr::StartsWith(str, "##Taxonomic-Update-Statistics")) return 1;
+    if (NStr::StartsWith(str, "##FluData")) return 2;
+    if (NStr::StartsWith(str, "##MIGS")) return 3;
+    if (NStr::StartsWith(str, "##Assembly-Data")) return 4;
+    if (NStr::StartsWith(str, "##Genome-Assembly-Data")) return 5;
+    if (NStr::StartsWith(str, "##Genome-Annotation-Data")) return 6;
+    if (NStr::StartsWith(str, "##Evidence-Data")) return 7;
+    if (NStr::StartsWith(str, "##RefSeq-Attributes")) return 8;
+    return 1000;
+}
+
+static bool s_SeqDescCompare(const CRef<CSeqdesc>& desc1, const CRef<CSeqdesc>& desc2)
+{
+    CSeqdesc::E_Choice chs1, chs2;
+
+    chs1 = desc1->Which();
+    chs2 = desc2->Which();
+
+    if (chs1 == CSeqdesc::e_User && chs2 == CSeqdesc::e_User) {
+        const CUser_object& uop1 = desc1->GetUser();
+        const CUser_object& uop2 = desc2->GetUser();
+        const CUser_object::TType &typ1 = uop1.GetType();
+        const CUser_object::TType &typ2 = uop2.GetType();
+        if (typ1.IsStr() && typ2.IsStr()) {
+            const string& str1 = typ1.GetStr();
+            const string& str2 = typ2.GetStr();
+            bool issc1 = (bool) (str1 == "StructuredComment");
+            bool issc2 = (bool) (str2 == "StructuredComment");
+            if (issc1 && issc2) {
+                CConstRef<CUser_field> fld1 = uop1.GetFieldRef("StructuredCommentPrefix");
+                CConstRef<CUser_field> fld2 = uop2.GetFieldRef("StructuredCommentPrefix");
+                if (fld1 && fld2 && fld1->IsSetData() && fld2->IsSetData() && fld1->GetData().IsStr()&& fld2->GetData().IsStr()) {
+                    const string& str1 = fld1->GetData().GetStr();
+                    const string& str2 = fld2->GetData().GetStr();
+                    int val1 = s_StrucCommOrder(str1);
+                    int val2 = s_StrucCommOrder(str2);
+                    if (val1 != val2) {
+                        return (val1 < val2);
+                    }
+                    return (NStr::CompareCase(str1, str2) < 0);
+                }
+            } else if (issc1) {
+                return true;
+            } else if (issc2) {
+                return false;
+            } else {
+                return (NStr::CompareCase(str1, str2) < 0);
+            }
+        }
+    }
+
+    return false;
+}
+
 void CFlatGatherer::x_StructuredComments(CBioseqContext& ctx) const
 {
+    vector<CRef<CSeqdesc>> vdesc;
     for (CSeqdesc_CI it(ctx.GetHandle(), CSeqdesc::e_User); it; ++it) {
         const CSeqdesc & desc = *it;
+        if (desc.IsUser()) {
+            CRef<CSeqdesc> dsc(new CSeqdesc);
+            dsc->Assign(desc);
+            vdesc.push_back(dsc);
+        }
+    }
+    stable_sort( vdesc.begin(), vdesc.end(), s_SeqDescCompare );
+    for (size_t ii = 0; ii < vdesc.size(); ii++) {
+        CRef<CSeqdesc>& dsc = vdesc[ii];
+        const CSeqdesc & desc = *dsc;
         if (m_FirstGenAnnotSCAD && desc.IsUser()) {
             const CUser_object& usr = desc.GetUser();
             const CUser_object& fst = *m_FirstGenAnnotSCAD;
@@ -1322,7 +1386,7 @@ void CFlatGatherer::x_StructuredComments(CBioseqContext& ctx) const
                 m_FirstGenAnnotSCAD.Reset();
             }
         }
-        x_AddComment(new CCommentItem(*it, ctx));
+        x_AddComment(new CCommentItem(*dsc, ctx));
     }
     if ( m_FirstGenAnnotSCAD ) {
         x_AddComment(new CCommentItem(*m_FirstGenAnnotSCAD, ctx));
@@ -1631,8 +1695,9 @@ void CFlatGatherer::x_CollectSourceFeatures
       .SetLimitTSE(ctx.GetHandle().GetTopLevelEntry());
 
     for ( CFeat_CI fi(bh, range, as); fi; ++fi ) {
+        TSeqPos start = fi->GetLocation().GetTotalRange().GetFrom();
         TSeqPos stop = fi->GetLocation().GetTotalRange().GetTo();
-        if ( stop >= range.GetFrom()  &&  stop  <= range.GetTo() ) {
+        if ( start <= range.GetFrom()  &&  stop  >= range.GetTo() ) {
             CRef<CSourceFeatureItem> sf(new CSourceFeatureItem(*fi, ctx, m_Feat_Tree));
             srcs.push_back(sf);
         }
@@ -1648,14 +1713,24 @@ void CFlatGatherer::x_CollectBioSourcesOnBioseq
 {
     const CFlatFileConfig& cfg = ctx.Config();
 
+    if ( ctx.IsProt() ) {
+        // collect biosources features on bioseq
+        if ( !ctx.DoContigStyle()  ||  cfg.ShowContigSources() ) {
+            x_CollectSourceFeatures(bh, range, ctx, srcs);
+            if (! srcs.empty()) return;
+        }
+    }
+
     // collect biosources descriptors on bioseq
     // if ( !cfg.IsFormatFTable()  ||  cfg.IsModeDump() ) {
         x_CollectSourceDescriptors(bh, ctx, srcs);
     // }
 
-    // collect biosources features on bioseq
-    if ( !ctx.DoContigStyle()  ||  cfg.ShowContigSources() ) {
-        x_CollectSourceFeatures(bh, range, ctx, srcs);
+    if ( ! ctx.IsProt() ) {
+        // collect biosources features on bioseq
+        if ( !ctx.DoContigStyle()  ||  cfg.ShowContigSources() ) {
+            x_CollectSourceFeatures(bh, range, ctx, srcs);
+        }
     }
 }
 
@@ -1666,18 +1741,19 @@ void CFlatGatherer::x_CollectBioSources(TSourceFeatSet& srcs) const
     CScope* scope = &ctx.GetScope();
     const CFlatFileConfig& cfg = ctx.Config();
 
-    x_CollectBioSourcesOnBioseq(ctx.GetHandle(),
-                                ctx.GetLocation().GetTotalRange(),
-                                ctx,
-                                srcs);
-    
-    // if protein with no sources, get sources applicable to DNA location of CDS
-    if ( srcs.empty()  &&  ctx.IsProt() ) {
+    // if protein, get sources applicable to DNA location of CDS
+    if ( ctx.IsProt() ) {
         const CSeq_feat* cds = GetCDSForProduct(ctx.GetHandle());
         if ( cds != 0 ) {
             const CSeq_loc& cds_loc = cds->GetLocation();
+            CRef<CSeq_loc> cleaned_location( new CSeq_loc );
+            cleaned_location->Assign( cds_loc );
+            if (cleaned_location->IsSetStrand()  &&  IsReverse(cleaned_location->GetStrand())) {
+                CRef<CSeq_loc> rev_loc(SeqLocRevCmpl(*cleaned_location, scope));
+                cleaned_location->Assign(*rev_loc);
+            }
             CBioseq_Handle bioseq_h;
-            ITERATE( CSeq_loc, cds_loc_ci, cds_loc ) {
+            ITERATE( CSeq_loc, cds_loc_ci, *cleaned_location ) {
                 bioseq_h = scope->GetBioseqHandle(cds_loc_ci.GetSeq_id());
                 if( bioseq_h ) {
                     break;
@@ -1686,13 +1762,20 @@ void CFlatGatherer::x_CollectBioSources(TSourceFeatSet& srcs) const
             if( bioseq_h ) {
                 x_CollectBioSourcesOnBioseq(
                     bioseq_h,
-                    cds_loc.GetTotalRange(),
+                    cleaned_location->GetTotalRange(),
                     ctx,
                     srcs);
             }
         }
     }
 
+    if ( srcs.empty() ) {
+        x_CollectBioSourcesOnBioseq(ctx.GetHandle(),
+                                    ctx.GetLocation().GetTotalRange(),
+                                    ctx,
+                                    srcs);
+    }
+  
     // if no source found create one (only if not FTable format or Dump mode)
     if ( srcs.empty()  &&  /* ! cfg.IsFormatFTable()  && */  ! cfg.IsModeDump() ) {
         CRef<CBioSource> bsrc(new CBioSource);
@@ -2189,7 +2272,10 @@ static bool s_SeqLocEndsOnBioseq(const CSeq_loc& loc, CBioseqContext& ctx,
     const bool is_small_genome_set = ( ctx.CanGetTLSeqEntryCtx() &&
         ctx.GetTLSeqEntryCtx().GetHasSmallGenomeSet() );
     */
+    /*
     const bool is_small_genome_set = ctx.IsInSGS();
+    */
+    const bool is_small_genome_set = ctx.GetSGS();
 
     // check certain case(s) that let us skip some work
     if( showOutOfBoundsFeats && ! is_part && ! is_small_genome_set ) {
@@ -2978,7 +3064,8 @@ SAnnotSelector s_GetCdsProductSel(CBioseqContext& ctx)
         .IncludeFeatSubtype(CSeqFeatData::eSubtype_mat_peptide_aa)
         .IncludeFeatSubtype(CSeqFeatData::eSubtype_sig_peptide_aa)
         .IncludeFeatSubtype(CSeqFeatData::eSubtype_transit_peptide_aa)
-        .IncludeFeatSubtype(CSeqFeatData::eSubtype_preprotein);
+        .IncludeFeatSubtype(CSeqFeatData::eSubtype_preprotein)
+        .IncludeFeatSubtype(CSeqFeatData::eSubtype_propeptide);
     return sel;
 }
 
diff --git a/c++/src/objtools/format/genbank_formatter.cpp b/c++/src/objtools/format/genbank_formatter.cpp
index a8e25e0..d8cc59e 100644
--- a/c++/src/objtools/format/genbank_formatter.cpp
+++ b/c++/src/objtools/format/genbank_formatter.cpp
@@ -1,4 +1,4 @@
-/*  $Id: genbank_formatter.cpp 498243 2016-04-14 15:15:47Z ivanov $
+/*  $Id: genbank_formatter.cpp 510812 2016-08-16 14:54:30Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -473,7 +473,10 @@ void CGenbankFormatter::FormatVersion
     } else {
         version_line << version.GetAccession();
         if ( version.GetGi() > ZERO_GI ) {
-            version_line << "  GI:" << version.GetGi();
+            const CFlatFileConfig& cfg = GetContext().GetConfig();
+            if (! cfg.HideGI()) {
+                version_line << "  GI:" << version.GetGi();
+            }
         }
         string version_line_str = CNcbiOstrstreamToString(version_line);
         if( version.GetContext()->Config().DoHTML() ) {
@@ -641,6 +644,7 @@ void CGenbankFormatter::x_FormatSourceLine
 }
 
 
+#ifndef NEW_HTML_FMT
 static string s_GetHtmlTaxname(const CSourceItem& source)
 {
     CNcbiOstrstream link;
@@ -662,18 +666,23 @@ static string s_GetHtmlTaxname(const CSourceItem& source)
     TryToSanitizeHtml(link_str);
     return link_str;
 }
+#endif
 
 
-void CGenbankFormatter::x_FormatOrganismLine
-(list<string>& l,
- const CSourceItem& source) const
+void CGenbankFormatter::x_FormatOrganismLine(list<string>& l, const CSourceItem& source) const
 {
     // taxname
+#ifdef NEW_HTML_FMT
+    string s;
+    GetContext().GetConfig().GetHTMLFormatter().FormatTaxid(s, source.GetTaxid(), source.GetTaxname());
+    Wrap(l, "ORGANISM", s, eSubp);
+#else
     if (source.GetContext()->Config().DoHTML()) {
         Wrap(l, "ORGANISM", s_GetHtmlTaxname(source), eSubp);
     } else {
         Wrap(l, "ORGANISM", source.GetTaxname(), eSubp);
     }
+#endif
     // lineage
     if (source.GetContext()->Config().DoHTML()) {
         string lineage = source.GetLineage();
@@ -1386,25 +1395,27 @@ bool s_GetLinkFeatureKey(
         return false;
     }
 
+    // assembly of the actual string:
+	strLink.reserve(100); // euristical URL length
+#ifdef NEW_HTML_FMT
+    item.GetContext()->Config().GetHTMLFormatter().FormatLocation(strLink, item.GetFeat().GetLocation(), iGi, strRawKey);
+#else
     // check if this is a protein or nucleotide link
     bool is_prot = false;
     {{
-        CBioseq_Handle bioseq_h;
-        const CSeq_loc & loc = item.GetFeat().GetLocation();
-        ITERATE( CSeq_loc, loc_ci, loc ) {
-            bioseq_h = item.GetContext()->GetScope().GetBioseqHandle( loc_ci.GetSeq_id() );
-            if( bioseq_h ) {
-                break;
+            CBioseq_Handle bioseq_h;
+            const CSeq_loc & loc = item.GetFeat().GetLocation();
+            ITERATE(CSeq_loc, loc_ci, loc) {
+                bioseq_h = item.GetContext()->GetScope().GetBioseqHandle(loc_ci.GetSeq_id());
+                if (bioseq_h) {
+                    break;
+                }
+            }
+            if (bioseq_h) {
+                is_prot = (bioseq_h.GetBioseqMolType() == CSeq_inst::eMol_aa);
             }
-        }
-        if( bioseq_h ) {
-            is_prot = ( bioseq_h.GetBioseqMolType() == CSeq_inst::eMol_aa );
-        }
     }}
 
-    // assembly of the actual string:
-	strLink.reserve(100); // euristical URL length
-
     strLink = "<a href=\"";
 
 	// link base
@@ -1431,6 +1442,7 @@ bool s_GetLinkFeatureKey(
 	strLink += "\">";
     strLink += strRawKey;
     strLink += "</a>";
+#endif
     return true;
 }
 
@@ -1483,7 +1495,11 @@ void CGenbankFormatter::x_SmartWrapQuals(const CFeatureItemBase& feat, const CFl
 		switch ((*it)->GetStyle()) {
 		case CFormatQual::eEmpty:
 			prefix1 += '/';
-			value = qual;
+            if (bHtml) {
+                sanitized = qual;
+            } else {
+                value = qual;
+            }
 			break;
 		case CFormatQual::eQuoted:
 			if (bHtml) sanitized += '"'; else value += '"';
@@ -1569,14 +1585,22 @@ void CGenbankFormatter::FormatFeature
     }
 
 	const string& strKey = feat->GetKey();
+  string fkey = strKey;
+	if (NStr::EqualNocase (fkey, "propeptide")) {
+      if (f.GetContext()->IsProt()) {
+      } else if (f.GetContext()->IsRefSeq()) {
+      } else if (f.GetContext()->Config().IsModeEntrez() || f.GetContext()->Config().IsModeRelease()) {
+	        fkey = "misc_feature";
+	    }
+	}
 	// write <span...> and <script...> in HTML mode
 	if (bHtml && f.GetContext()->Config().IsModeEntrez() && f.GetContext()->Config().ShowSeqSpans()) {
-		x_GetFeatureSpanAndScriptStart(*text_os, strKey, f.GetLoc(), *f.GetContext());
+		x_GetFeatureSpanAndScriptStart(*text_os, fkey, f.GetLoc(), *f.GetContext());
 	}
 
 #if 1
 	list<string>        l;
-    Wrap(l, strKey, feat->GetLoc().GetString(), eFeat );
+    Wrap(l, fkey, feat->GetLoc().GetString(), eFeat );
 
     // In HTML mode, if not taking a "slice" (i.e. -from and -to args )
     // we need to add a link
@@ -1585,12 +1609,12 @@ void CGenbankFormatter::FormatFeature
         // negative padding means we need to remove spaces.
         // const int padding_needed = (int)strDummy.length() - (int)feat->GetKey().length();
 		string strFeatKey;
-		if (s_GetLinkFeatureKey(f, *feat, strKey, strFeatKey, m_uFeatureCount))
+		if (s_GetLinkFeatureKey(f, *feat, fkey, strFeatKey, m_uFeatureCount))
 		{
 			// strFeatKey += string( padding_needed, ' ' );
 			NON_CONST_ITERATE(list<string>, it, l) {
 				// string::size_type dummy_loc = (*it).find(strDummy);
-				NStr::ReplaceInPlace( *it, strKey, strFeatKey );
+				NStr::ReplaceInPlace( *it, fkey, strFeatKey );
 			}
 		}
     }
diff --git a/c++/src/objtools/format/genbank_gather.cpp b/c++/src/objtools/format/genbank_gather.cpp
index 51636ea..4489495 100644
--- a/c++/src/objtools/format/genbank_gather.cpp
+++ b/c++/src/objtools/format/genbank_gather.cpp
@@ -1,4 +1,4 @@
-/*  $Id: genbank_gather.cpp 500529 2016-05-05 14:28:05Z ivanov $
+/*  $Id: genbank_gather.cpp 500338 2016-05-03 23:56:29Z kans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/format/gene_finder.cpp b/c++/src/objtools/format/gene_finder.cpp
index f8c065f..ce40026 100644
--- a/c++/src/objtools/format/gene_finder.cpp
+++ b/c++/src/objtools/format/gene_finder.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gene_finder.cpp 490514 2016-01-26 18:13:55Z kans $
+/*  $Id: gene_finder.cpp 510811 2016-08-16 14:54:08Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -325,6 +325,7 @@ void CGeneFinder::GetAssociatedGeneInfo(
         case CSeqFeatData::eSubtype_sig_peptide_aa:
         case CSeqFeatData::eSubtype_transit_peptide_aa:
         case CSeqFeatData::eSubtype_preprotein:
+        case CSeqFeatData::eSubtype_propeptide:
             also_look_at_parent_CDS = true;
             break;
         default:
diff --git a/c++/src/objtools/format/inst_info_map.cpp b/c++/src/objtools/format/inst_info_map.cpp
index 4d548ee..9f47155 100644
--- a/c++/src/objtools/format/inst_info_map.cpp
+++ b/c++/src/objtools/format/inst_info_map.cpp
@@ -1,4 +1,4 @@
-/* $Id: inst_info_map.cpp 498880 2016-04-20 13:36:23Z ivanov $
+/* $Id: inst_info_map.cpp 506763 2016-07-11 19:47:22Z kans $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -71,7 +71,10 @@ CInstInfoMap::GetInstitutionVoucherInfo(
     static const string  s_nbrc_base("http://www.nbrc.nite.go.jp/NBRC2/NBRCCatalogueDetailServlet?ID=NBRC&CAT=");
     static const string  s_ncimb_base("http://www.ncimb.com/BioloMICS.aspx?Table=NCIMBstrains&ExactMatch=T&Fields=All&Name=NCIMB%20");
     static const string  s_nctc_base("https://www.phe-culturecollections.org.uk/products/bacteria/detail.jsp?collection=nctc&refId=NCTC+");
-    static const string  s_nrrl_base("http://nrrl.ncaur.usda.gov/cgi-bin/usda/prokaryote/report.html?nrrlcodes=“");
+    static const string  s_nrrl_base("http://nrrl.ncaur.usda.gov/cgi-bin/usda/prokaryote/report.html?nrrlcodes=");
+    static const string  s_nrrl_mold("http://nrrl.ncaur.usda.gov/cgi-bin/usda/mold/report.html?nrrlcodes=");
+    static const string  s_nrrl_prok("http://nrrl.ncaur.usda.gov/cgi-bin/usda/prokaryote/report.html?nrrlcodes=");
+    static const string  s_nrrl_yest("http://nrrl.ncaur.usda.gov/cgi-bin/usda/yeast/report.html?nrrlcodes=");
     static const string  s_pcc_base("http://www.crbip.pasteur.fr/fiches/fichecata.jsp?crbip=PCC+");
     static const string  s_pcmb_base("http://www2.bishopmuseum.org/HBS/PCMB/results3.asp?searchterm3=");
     static const string  s_pycc_base("http://pycc.bio-aware.com/BioloMICS.aspx?Table=PYCC%20strains&Name=PYCC%20");
@@ -87,8 +90,8 @@ CInstInfoMap::GetInstitutionVoucherInfo(
     static const string s_colon_pfx(":");
     static const string s_uscr_pfx("_");
     
-    static const string s_kui_pfx("KU_Fish/detail.jsp?record=");
-    static const string s_kuit_pfx("KU_Tissue/detail.jsp?record=");
+    static const string s_kui_pfx("KUI/");
+    static const string s_kuit_pfx("KUIT/");
     static const string s_psu_pfx("PSU:Mamm:");
     static const string s_usnm_pfx("voucher=Birds:");
 
@@ -134,8 +137,8 @@ CInstInfoMap::GetInstitutionVoucherInfo(
         { "JCM",              TVoucherInfoRef(new SVoucherInfo(&s_jcm_base,   false, 0, NULL,   NULL,          NULL,        "Japan Collection of Microorganisms") ) },
         { "KCTC",             TVoucherInfoRef(new SVoucherInfo(&s_kctc_base,  false, 0, NULL,   NULL,          NULL,        "Korean Collection for Type Cultures") ) },
         { "KNWR:Ento",        TVoucherInfoRef(new SVoucherInfo(&s_uam_base,   true,  0, NULL,   &s_colon_pfx,  NULL,        "Kenai National Wildlife Refuge, Entomology Collection") ) },
-        { "KU:I",             TVoucherInfoRef(new SVoucherInfo(&s_ku_base,    false, 0, NULL,   &s_kui_pfx,    NULL,        "University of Kansas, Museum of Natural History, Ichthyology collection") ) },
-        { "KU:IT",            TVoucherInfoRef(new SVoucherInfo(&s_ku_base,    false, 0, NULL,   &s_kuit_pfx,   NULL,        "University of Kansas, Museum of Natural History, Ichthyology tissue collection") ) },
+        { "KU:I",             TVoucherInfoRef(new SVoucherInfo(&s_ku_base,    false, 0, NULL,   &s_kui_pfx,    &s_ku_sfx,   "University of Kansas, Museum of Natural History, Ichthyology collection") ) },
+        { "KU:IT",            TVoucherInfoRef(new SVoucherInfo(&s_ku_base,    false, 0, NULL,   &s_kuit_pfx,   &s_ku_sfx,   "University of Kansas, Museum of Natural History, Ichthyology tissue collection") ) },
         { "KWP:Ento",         TVoucherInfoRef(new SVoucherInfo(&s_uam_base,   true,  0, NULL,   &s_colon_pfx,  NULL,        "Kenelm W. Philip Collection, University of Alaska Museum of the North, Lepidoptera collection") ) },
         { "MAFF",             TVoucherInfoRef(new SVoucherInfo(&s_maff_base,  false, 0, NULL,   NULL,          NULL,        "Genebank, Ministry of Agriculture Forestry and Fisheries") ) },
         { "MCZ:Bird",         TVoucherInfoRef(new SVoucherInfo(&s_mcz_base,   true,  0, NULL,   &s_colon_pfx,  NULL,        "Harvard Museum of Comparative Zoology, Ornithology Collection") ) },
@@ -169,6 +172,9 @@ CInstInfoMap::GetInstitutionVoucherInfo(
         { "NCIMB",            TVoucherInfoRef(new SVoucherInfo(&s_ncimb_base, false, 0, NULL,   NULL,          NULL,        "National Collections of Industrial Food and Marine Bacteria (incorporating the NCFB)") ) },
         { "NCTC",             TVoucherInfoRef(new SVoucherInfo(&s_nctc_base,  false, 0, NULL,   NULL,          NULL,        "National Collection of Type Cultures") ) },
         { "NRRL",             TVoucherInfoRef(new SVoucherInfo(&s_nrrl_base,  false, 0, NULL,   NULL,          NULL,        "Agricultural Research Service Culture Collection") ) },
+        { "NRRL:MOLD",        TVoucherInfoRef(new SVoucherInfo(&s_nrrl_mold,  false, 0, NULL,   NULL,          NULL,        "Agricultural Research Service Culture Collection") ) },
+        { "NRRL:PROK",        TVoucherInfoRef(new SVoucherInfo(&s_nrrl_prok,  false, 0, NULL,   NULL,          NULL,        "Agricultural Research Service Culture Collection") ) },
+        { "NRRL:YEAST",       TVoucherInfoRef(new SVoucherInfo(&s_nrrl_yest,  false, 0, NULL,   NULL,          NULL,        "Agricultural Research Service Culture Collection") ) },
         { "NZAC",             TVoucherInfoRef(new SVoucherInfo(&s_lcr_base,   true,  0, NULL,   &s_uscr_pfx,   NULL,        "New Zealand Arthropod Collection") ) },
         { "PCC",              TVoucherInfoRef(new SVoucherInfo(&s_pcc_base,   false, 0, NULL,   NULL,          NULL,        "Pasteur Culture Collection of Cyanobacteria") ) },
         { "PCMB",             TVoucherInfoRef(new SVoucherInfo(&s_pcmb_base,  false, 0, NULL,   NULL,          NULL,        "The Pacific Center for Molecular Biodiversity") ) },
diff --git a/c++/src/objtools/format/inst_info_map.hpp b/c++/src/objtools/format/inst_info_map.hpp
index 54f0d8a..768d99a 100644
--- a/c++/src/objtools/format/inst_info_map.hpp
+++ b/c++/src/objtools/format/inst_info_map.hpp
@@ -1,4 +1,4 @@
-/* $Id: inst_info_map.hpp 498880 2016-04-20 13:36:23Z ivanov $
+/* $Id: inst_info_map.hpp 498670 2016-04-18 21:03:09Z kans $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/format/item_formatter.cpp b/c++/src/objtools/format/item_formatter.cpp
index 4910096..3e9b1f0 100644
--- a/c++/src/objtools/format/item_formatter.cpp
+++ b/c++/src/objtools/format/item_formatter.cpp
@@ -1,4 +1,4 @@
-/*  $Id: item_formatter.cpp 500529 2016-05-05 14:28:05Z ivanov $
+/*  $Id: item_formatter.cpp 506085 2016-07-01 14:25:26Z gotvyans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -207,6 +207,10 @@ string  CFlatItemFormatter::x_FormatAccession
     acc_line << primary;
 
     if ( ctx.IsWGS() && ! acc.GetWGSAccession().empty() ) {
+#ifdef NEW_HTML_FMT
+        acc_line << separator;
+        ctx.Config().GetHTMLFormatter().FormatNucSearch(acc_line, acc.GetWGSAccession());
+#else
         const bool is_html = ctx.Config().DoHTML();
         if( is_html ) {
             acc_line << separator << "<a href=\"" << strLinkBaseNucSearch << acc.GetWGSAccession() << 
@@ -214,9 +218,14 @@ string  CFlatItemFormatter::x_FormatAccession
         } else {
             acc_line << separator << acc.GetWGSAccession();
         }
+#endif
     }
 
     if ( ctx.IsTSA() && ! acc.GetTSAAccession().empty() ) {
+#ifdef NEW_HTML_FMT
+        acc_line << separator;
+        ctx.Config().GetHTMLFormatter().FormatNucSearch(acc_line, acc.GetTSAAccession());
+#else
         const bool is_html = ctx.Config().DoHTML();
         if( is_html ) {
             acc_line << separator << "<a href=\"" << strLinkBaseNucSearch << acc.GetTSAAccession() << 
@@ -224,6 +233,7 @@ string  CFlatItemFormatter::x_FormatAccession
         } else {
             acc_line << separator << acc.GetTSAAccession();
         }
+#endif
     }
 
     if (!acc.GetExtraAccessions().empty()) {
diff --git a/c++/src/objtools/format/keywords_item.cpp b/c++/src/objtools/format/keywords_item.cpp
index 4c7bf1e..deb689e 100644
--- a/c++/src/objtools/format/keywords_item.cpp
+++ b/c++/src/objtools/format/keywords_item.cpp
@@ -1,4 +1,4 @@
-/*  $Id: keywords_item.cpp 493897 2016-03-02 14:22:41Z ivanov $
+/*  $Id: keywords_item.cpp 493033 2016-02-23 18:51:30Z kans $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/format/locus_item.cpp b/c++/src/objtools/format/locus_item.cpp
index 753466e..6a31601 100644
--- a/c++/src/objtools/format/locus_item.cpp
+++ b/c++/src/objtools/format/locus_item.cpp
@@ -1,4 +1,4 @@
-/*  $Id: locus_item.cpp 497806 2016-04-11 13:57:53Z ivanov $
+/*  $Id: locus_item.cpp 515537 2016-10-03 16:02:52Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -204,6 +204,8 @@ static string s_FastaGetOriginalID (CBioseqContext& ctx)
 
 static bool s_ShouldUseOriginalID (CBioseqContext& ctx)
 {
+    if (ctx.Config().IsFormatLite()) return false;
+
     const CBioseq_Handle& bsh = ctx.GetHandle();
     const CBioseq& seq = *bsh.GetCompleteBioseq();
 
@@ -241,6 +243,7 @@ void CLocusItem::x_SetName(CBioseqContext& ctx)
             string basename = ctx.GetMaster().GetBaseName();
             if (!NStr::IsBlank(basename)) {
                 m_Name = basename;
+                m_FullName = m_Name;
                 s_AddLocusSuffix(m_Name, ctx);
                 return;
             }
@@ -306,6 +309,7 @@ void CLocusItem::x_SetName(CBioseqContext& ctx)
             }
         }
 
+        m_FullName = m_Name;
         if( m_Name.length() > MAX_LOCUS_ACCN_LEN ) {
             m_Name.resize(MAX_LOCUS_ACCN_LEN);
             *m_Name.rbegin() = '>';
@@ -522,6 +526,7 @@ static CTempString x_GetDivisionProc(const CBioseq_Handle& bsh, bool is_prot,
         if (tech == CMolInfo::eTech_unknown  ||
             tech == CMolInfo::eTech_standard ||
             tech == CMolInfo::eTech_htgs_3   ||
+            tech == CMolInfo::eTech_wgs      ||
             tech == CMolInfo::eTech_other) {
             division = "ENV";
         }
diff --git a/c++/src/objtools/format/qualifiers.cpp b/c++/src/objtools/format/qualifiers.cpp
index 9cc29e7..a65aef4 100644
--- a/c++/src/objtools/format/qualifiers.cpp
+++ b/c++/src/objtools/format/qualifiers.cpp
@@ -1,4 +1,4 @@
-/*  $Id: qualifiers.cpp 493626 2016-03-01 13:43:04Z ivanov $
+/*  $Id: qualifiers.cpp 509627 2016-08-08 14:27:18Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -1054,7 +1054,12 @@ void CFlatSeqIdQVal::Format(TFlatQuals& q, const CTempString& name,
         id_str = m_Value->GetSeqIdString(true);
     }
 
-    if ( bHtml && name == "protein_id" ) {
+#ifdef NEW_HTML_FMT
+    if (name == "protein_id") {
+       ctx.Config().GetHTMLFormatter().FormatProteinId(id_str, *m_Value, string(id_str));
+    }
+#else
+    if (bHtml && name == "protein_id") {
         string raw_id_str = id_str;
         string raw_link_str = id_str;
         CBioseq_Handle bsh = ctx.GetScope().GetBioseqHandle( *m_Value );
@@ -1073,6 +1078,7 @@ void CFlatSeqIdQVal::Format(TFlatQuals& q, const CTempString& name,
         id_str += raw_id_str;
         id_str += "</a>";
     }
+#endif
     x_AddFQ(q, name, id_str);
 }
 
@@ -1381,6 +1387,10 @@ void CFlatXrefQVal::Format(TFlatQuals& q, const CTempString& name,
             if (!NStr::StartsWith(id, "HGNC:", NStr::eNocase)) {
                 id = "HGNC:" + id;
             }
+        } else if (NStr::EqualNocase(db, "VGNC")) {
+            if (!NStr::StartsWith(id, "VGNC:", NStr::eNocase)) {
+                id = "VGNC:" + id;
+            }
         } else if (NStr::EqualNocase(db, "MGI")) {
             if (!NStr::StartsWith(id, "MGI:", NStr::eNocase)) {
                 id = "MGI:" + id;
diff --git a/c++/src/objtools/readers/Makefile.in b/c++/src/objtools/readers/Makefile.in
index b83aa91..68f68e1 100644
--- a/c++/src/objtools/readers/Makefile.in
+++ b/c++/src/objtools/readers/Makefile.in
@@ -1,10 +1,10 @@
-# $Id: Makefile.in 170010 2009-09-08 14:24:26Z dicuccio $
+# $Id: Makefile.in 497461 2016-04-06 19:07:29Z foleyjp $
 
 # Meta-makefile ("objtools/readers" project)
 ############################################
 
 LIB_PROJ = xobjread xobjreadex
-SUB_PROJ = app test unit_test
+SUB_PROJ = app test unit_test 
 
 srcdir = @srcdir@
 include @builddir@/Makefile.meta
diff --git a/c++/src/objtools/readers/Makefile.xobjread.lib b/c++/src/objtools/readers/Makefile.xobjread.lib
index dde090c..d6d96b2 100644
--- a/c++/src/objtools/readers/Makefile.xobjread.lib
+++ b/c++/src/objtools/readers/Makefile.xobjread.lib
@@ -1,6 +1,6 @@
-# $Id: Makefile.xobjread.lib 468535 2015-05-26 13:23:32Z ucko $
+# $Id: Makefile.xobjread.lib 515962 2016-10-06 18:16:16Z ivanov $
 
-WATCHERS = jcherry sapojnik bollin ludwigf ucko kornbluh gotvyans
+WATCHERS = jcherry sapojnik bollin ludwigf ucko gotvyans
 
 
 ASN_DEP = submit
@@ -10,20 +10,18 @@ CPPFLAGS = $(ORIG_CPPFLAGS) $(BOOST_INCLUDE)
 LIB = xobjread
 SRC = read_util format_guess_ex \
       acc_pattern agp_read agp_seq_entry agp_util agp_validate_reader aln_reader bed_reader cigar fasta \
-	  fasta_aln_builder getfeature gff_reader reader_data \
+	  fasta_aln_builder getfeature gff_reader track_data reader_data \
       microarray_reader phrap reader_base readfeat rm_reader \
       wiggle_reader gff3_sofa gff3_reader gtf_reader \
       gff2_data gff2_reader \
       gvf_reader \
       vcf_reader \
       best_feat_finder source_mod_parser fasta_exception agp_converter \
-      ucscregion_reader \
+      ucscregion_reader struct_cmt_reader \
       message_listener line_error
 
 
 DLL_LIB = submit seqset $(SEQ_LIBS) general creaders xutil
 
-
-
 USES_LIBRARIES =  \
     creaders submit
diff --git a/c++/src/objtools/readers/Makefile.xobjreadex.lib b/c++/src/objtools/readers/Makefile.xobjreadex.lib
index cdf4eb8..7c3f586 100644
--- a/c++/src/objtools/readers/Makefile.xobjreadex.lib
+++ b/c++/src/objtools/readers/Makefile.xobjreadex.lib
@@ -1,6 +1,6 @@
-# $Id: Makefile.xobjreadex.lib 432036 2014-04-09 17:27:03Z grichenk $
+# $Id: Makefile.xobjreadex.lib 501626 2016-05-17 17:32:10Z kornbluh $
 
-WATCHERS = dicuccio ludwigf kornbluh gotvyans
+WATCHERS = dicuccio ludwigf gotvyans
 
 ASN_DEP = seq seqset
 
diff --git a/c++/src/objtools/readers/agp_util.cpp b/c++/src/objtools/readers/agp_util.cpp
index d09aa5a..6cc4ea7 100644
--- a/c++/src/objtools/readers/agp_util.cpp
+++ b/c++/src/objtools/readers/agp_util.cpp
@@ -1,4 +1,4 @@
-/*  $Id: agp_util.cpp 465403 2015-04-21 14:55:53Z sapojnik $
+/*  $Id: agp_util.cpp 496699 2016-03-30 14:46:49Z sapojnik $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -180,7 +180,7 @@ string CAgpErr::FormatMessage(const string& msg, const string& details)
     // string msg = GetMsg(code);
     if( details.size()==0 ) return msg;
 
-    SIZE_TYPE pos = NStr::Find( string(" ") + msg + " ", " X " );
+    SIZE_TYPE pos = ( string(" ") + msg + " " ).find(" X ");
     if(pos!=NPOS) {
         // Substitute "X" with the real value (e.g. a column name or value)
         return msg.substr(0, pos) + details + msg.substr(pos+1);
@@ -289,7 +289,7 @@ int CAgpRow::FromString(const string& line)
 {
     // Comments
     cols.clear();
-    pcomment = NStr::Find(line, "#");
+    pcomment = line.find("#");
 
     bool tabsStripped=false;
     bool extraTabOrSpace=false;
@@ -300,7 +300,7 @@ int CAgpRow::FromString(const string& line)
             pcomment--;
         }
         if(pcomment==0) return -1; // A comment line; to be skipped.
-        NStr::Tokenize(line.substr(0, pcomment), "\t", cols);
+        NStr::Split(line.substr(0, pcomment), "\t", cols);
     }
     else {
       int pos=line.size();
@@ -313,12 +313,12 @@ int CAgpRow::FromString(const string& line)
         do {
           pos--;
         } while(pos>0 && line[pos-1]==' ');
-        NStr::Tokenize(line.substr(0, pos), "\t", cols);
+        NStr::Split(line.substr(0, pos), "\t", cols);
         m_AgpErr->Msg(CAgpErr::W_ExtraTab);
         extraTabOrSpace=true;
         pcomment=pos;
       }
-      else NStr::Tokenize(line, "\t", cols);
+      else NStr::Split(line, "\t", cols);
     }
 
 
@@ -643,7 +643,7 @@ int CAgpRow::ParseGapCols(bool log_errors)
             }
             else {
                 vector<string> raw_linkage_evidences;
-                NStr::Tokenize(GetLinkageEvidence(), ";", raw_linkage_evidences);
+                NStr::Split(GetLinkageEvidence(), ";", raw_linkage_evidences);
                 bool has_unspecified=false;
                 ITERATE( vector<string>, evid_iter, raw_linkage_evidences ) {
                     int le_flag = str_to_le(*evid_iter);
@@ -1212,16 +1212,21 @@ void CAgpErrEx::PrintLine(CNcbiOstream& ostr,
     const string& filename, int linenum, const string& content)
 {
     string line=content.size()<200 ? content : content.substr(0,160)+"...";
+    string comment;
 
     // Mark the first space that is not inside a EOL comment
-    SIZE_TYPE posComment = NStr::Find(line, "#");
-    SIZE_TYPE posSpace   = NStr::Find(line, " ", 0, posComment);
+    SIZE_TYPE posComment = line.find("#");
+    if(posComment!=NPOS) {
+        comment=line.substr(posComment);
+        line.resize(posComment);
+    }
+    SIZE_TYPE posSpace   = line.find(" ");
     if(posSpace!=NPOS) {
-        SIZE_TYPE posTab     = NStr::Find(line, "\t", 0, posComment);
+        SIZE_TYPE posTab     = line.find("\t");
         if(posTab!=NPOS && posTab>posSpace+1 && posSpace!=0 ) {
             // GCOL-1236: allow spaces in object names, emit a WARNING instead of an ERROR
             // => if there is ANOTHER space not inside the object name, then mark that another space
-            posTab = NStr::Find(line, " ", posTab+1, posComment);
+            posTab = line.find(" ", posTab+1);
             if(posTab!=NPOS) posSpace = posTab;
         }
         posSpace++;
@@ -1229,7 +1234,7 @@ void CAgpErrEx::PrintLine(CNcbiOstream& ostr,
     }
 
     if(filename.size()) ostr << filename << ":";
-    ostr<< linenum  << ":" << line << "\n";
+    ostr<< linenum  << ":" << line << comment << "\n";
 }
 
 void ReplaceUnprintableCharacters(string& text)
@@ -1531,7 +1536,7 @@ string CAgpErrEx::SkipMsg(const string& str, bool skip_other)
     res="";
     for( int i=E_First; i<CODE_Last; i++ ) {
         bool matchesCode = ( str==GetPrintableCode(i) || str==GetPrintableCode(i, true) );
-        if( matchesCode || NStr::Find(GetMsg(i), str) != NPOS) {
+        if( matchesCode || string(GetMsg(i)).find(str) != NPOS) {
             m_MustSkip[i] = !skip_other;
             res += "  ";
             res += GetPrintableCode(i);
diff --git a/c++/src/objtools/readers/aln_reader.cpp b/c++/src/objtools/readers/aln_reader.cpp
index 7e9cd8a..4e6e911 100644
--- a/c++/src/objtools/readers/aln_reader.cpp
+++ b/c++/src/objtools/readers/aln_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: aln_reader.cpp 390760 2013-03-01 19:06:10Z vakatov $
+/*  $Id: aln_reader.cpp 511112 2016-08-18 18:12:19Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -74,6 +74,9 @@ CAlnError::CAlnError(int category, int line_num, string id, string message)
     case 3:
         m_Category = eAlnErr_BadFormat;
         break;
+    case 4:
+        m_Category = eAlnErr_BadChar;
+        break;
     default:
         m_Category = eAlnErr_Unknown;
         break;
@@ -112,13 +115,22 @@ static void ALIGNMENT_CALLBACK s_ReportError(TErrorInfoPtr err_ptr,
 {
     CAlnReader::TErrorList *err_list;
     TErrorInfoPtr           next_err;
-    
+   
+    const int category_BadData = 2;
+    const int category_BadChar = 4;
+
     while (err_ptr != NULL) {    
         if (user_data != NULL) {
             err_list = (CAlnReader::TErrorList *)user_data;
-            (*err_list).push_back (CAlnError(err_ptr->category, err_ptr->line_num, 
+            int category = err_ptr->category;
+            string err_msg = (err_ptr->message == NULL) ? "" : err_ptr->message;
+            if ( (category == category_BadData) &&
+                 (err_msg.find("bad char") != string::npos) ) {
+                category = category_BadChar;
+            }
+            (*err_list).push_back (CAlnError(category, err_ptr->line_num, 
                                              err_ptr->id == NULL ? "" : err_ptr->id, 
-                                             err_ptr->message == NULL ? "" : err_ptr->message));
+                                             err_msg));
         }
         
         string msg = "Error reading alignment file";
@@ -168,12 +180,14 @@ void CAlnReader::Read(bool guess, bool generate_local_ids)
     // read the alignment stream
     TAlignmentFilePtr afp;
     m_Errors.clear();
+
     afp = ReadAlignmentFile2(s_ReadLine, (void *) &m_IS,
                             s_ReportError, &(m_Errors), &info,
                             (generate_local_ids ? eTrue : eFalse));
+
     if (!afp) {
         NCBI_THROW2(CObjReaderParseException, eFormat,
-                   "Error reading alignment", 0);
+                   "Error reading alignment: Invalid input or alphabet", 0);
     }
     
     size_t first_len = strlen (afp->sequences[0]);
diff --git a/c++/src/objtools/readers/bed_reader.cpp b/c++/src/objtools/readers/bed_reader.cpp
index 1ea5a22..2b5aa19 100644
--- a/c++/src/objtools/readers/bed_reader.cpp
+++ b/c++/src/objtools/readers/bed_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: bed_reader.cpp 493621 2016-03-01 13:41:26Z ivanov $
+/*  $Id: bed_reader.cpp 518716 2016-11-07 18:15:34Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -84,6 +84,7 @@
 #include <objtools/readers/read_util.hpp>
 #include <objtools/readers/reader_exception.hpp>
 #include <objtools/readers/line_error.hpp>
+#include <objtools/readers/track_data.hpp>
 #include <objtools/readers/message_listener.hpp>
 #include <objtools/readers/bed_reader.hpp>
 #include <objtools/error_codes.hpp>
@@ -105,6 +106,7 @@ CBedReader::CBedReader(
     CReaderBase(flags, annotName, annotTitle),
     m_currentId(""),
     m_columncount(0),
+    m_CurrentFeatureCount(0),
     m_usescore(false),
     m_CurBatchSize(0),
     m_MaxBatchSize(10000)
@@ -136,8 +138,6 @@ CBedReader::ReadSeqAnnot(
     ILineErrorListener* pEC ) 
 //  ----------------------------------------------------------------------------                
 {
-    const size_t MAX_RECORDS = 100000;
-
     xProgressInit(lr);
 
     CRef<CSeq_annot> annot;
@@ -146,11 +146,12 @@ CBedReader::ReadSeqAnnot(
     annot.Reset(new CSeq_annot);
     desc.Reset(new CAnnot_descr);
     annot->SetDesc(*desc);
-    CSeq_annot::C_Data::TFtable& tbl = annot->SetData().SetFtable();
 
+    m_CurrentFeatureCount = 0;
     string line;
-    int featureCount = 0;
     while (xGetLine(lr, line)) {
+
+        // interact with calling party
         if (IsCanceled()) {
             AutoPtr<CObjReaderLineException> pErr(
                 CObjReaderLineException::Create(
@@ -162,56 +163,41 @@ CBedReader::ReadSeqAnnot(
             return CRef<CSeq_annot>();
         }
         xReportProgress(pEC);
-        if (xIsTrackLine(line)  &&  featureCount) {
+
+        if (xIsTrackLine(line)) {
+            if (!m_CurrentFeatureCount) {
+                xParseTrackLine(line, pEC);
+                continue;
+            }
             xUngetLine(lr);
             break;
         }
         if (xParseBrowserLine(line, annot, pEC)) {
             continue;
         }
-        if (xParseTrackLine(line, pEC)) {
-            continue;
-        }
-
-	    CTempString record_copy = NStr::TruncateSpaces_Unsafe(line);
-
-        //  parse
-        vector<string> fields;
-        NStr::Split( record_copy, " \t", fields, NStr::eMergeDelims );
-        try {
-            xCleanColumnValues(fields);
-        }
-        catch(CObjReaderLineException& err) {
-            ProcessError(err, pEC);
-            continue;
-        }
-        if (xParseFeature(fields, annot, featureCount, pEC)) {
-            ++featureCount;
+        if (xParseFeature(line, annot, pEC)) {
             continue;
         }
-        if (tbl.size() >= MAX_RECORDS) {
-            break;
-        }
     }
     //  Only return a valid object if there was at least one feature
-    if (0 == featureCount) {
+    if (0 == m_CurrentFeatureCount) {
         return CRef<CSeq_annot>();
     }
-    xAddConversionInfo(annot, pEC);
-    xAssignTrackData( annot );
-
-    if(m_columncount >= 3) {
-        CRef<CUser_object> columnCountUser( new CUser_object() );
-        columnCountUser->SetType().SetStr( "NCBI_BED_COLUMN_COUNT" );
-        columnCountUser->AddField("NCBI_BED_COLUMN_COUNT", int ( m_columncount ) );
-    
-        CRef<CAnnotdesc> userDesc( new CAnnotdesc() );
-        userDesc->SetUser().Assign( *columnCountUser );
-        annot->SetDesc().Set().push_back( userDesc );
-    }
+    xPostProcessAnnot(annot, pEC);
     return annot;
 }
 
+//  ----------------------------------------------------------------------------
+void CBedReader::xPostProcessAnnot(
+    CRef<CSeq_annot>& annot,
+    ILineErrorListener *pEC)
+//  ----------------------------------------------------------------------------
+{
+    xAddConversionInfo(annot, pEC);
+    xAssignTrackData(annot);
+    xAssignBedColumnCount(*annot);
+}
+
 //  ----------------------------------------------------------------------------                
 CRef< CSerialObject >
 CBedReader::ReadObject(
@@ -276,10 +262,36 @@ CBedReader::x_AppendAnnot(
 }    
     
 //  ----------------------------------------------------------------------------
+bool
+CBedReader::xParseFeature(
+    const string& line,
+    CRef<CSeq_annot>& pAnnot,
+    ILineErrorListener* pEC)
+//  ----------------------------------------------------------------------------
+{
+	CTempString record_copy = NStr::TruncateSpaces_Unsafe(line);
+
+    //  parse
+    vector<string> fields;
+    NStr::Split( record_copy, " \t", fields, NStr::eMergeDelims );
+    try {
+        xCleanColumnValues(fields);
+    }
+    catch(CObjReaderLineException& err) {
+        ProcessError(err, pEC);
+        return false;
+    }
+    if (xParseFeature(fields, pAnnot, pEC)) {
+        ++m_CurrentFeatureCount;
+        return false;
+    }
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
 bool CBedReader::xParseFeature(
     const vector<string>& fields,
     CRef<CSeq_annot>& annot,
-    unsigned int featureCount,
     ILineErrorListener* pEC)
 //  ----------------------------------------------------------------------------
 {
@@ -302,7 +314,10 @@ bool CBedReader::xParseFeature(
     }
 
     if (m_iFlags & CBedReader::fThreeFeatFormat) {
-        return xParseFeatureThreeFeatFormat(fields, annot, 3*featureCount, pEC);
+        return xParseFeatureThreeFeatFormat(fields, annot, pEC);
+    }
+    else if (m_iFlags & CBedReader::fDirectedFeatureModel) {
+        return xParseFeatureGeneModelFormat(fields, annot, pEC);
     }
     else {
         return xParseFeatureUserFormat(fields, annot, pEC);
@@ -313,10 +328,11 @@ bool CBedReader::xParseFeature(
 bool CBedReader::xParseFeatureThreeFeatFormat(
     const vector<string>& fields,
     CRef<CSeq_annot>& annot,
-    unsigned int baseId,
     ILineErrorListener* pEC)
 //  ----------------------------------------------------------------------------
 {
+     unsigned int baseId = 3*m_CurrentFeatureCount;
+
     if (!xAppendFeatureChrom(fields, annot, baseId, pEC)) {
         return false;
     }
@@ -332,6 +348,29 @@ bool CBedReader::xParseFeatureThreeFeatFormat(
 }
 
 //  ----------------------------------------------------------------------------
+bool CBedReader::xParseFeatureGeneModelFormat(
+    const vector<string>& fields,
+    CRef<CSeq_annot>& annot,
+    ILineErrorListener* pEC)
+//  ----------------------------------------------------------------------------
+{
+     unsigned int baseId = 3*m_CurrentFeatureCount;
+
+   if (!xAppendFeatureGene(fields, annot, baseId, pEC)) {
+        return false;
+    }
+    if (xContainsCdsFeature(fields)  &&  
+            !xAppendFeatureCds(fields, annot, baseId, pEC)) {
+        return false;
+    }
+    if (xContainsRnaFeature(fields)  &&
+            !xAppendFeatureRna(fields, annot, baseId, pEC)) {
+        return false;
+    }
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
 bool CBedReader::xAppendFeatureChrom(
     const vector<string>& fields,
     CRef<CSeq_annot>& annot,
@@ -359,6 +398,33 @@ bool CBedReader::xAppendFeatureChrom(
 }
 
 //  ----------------------------------------------------------------------------
+bool CBedReader::xAppendFeatureGene(
+    const vector<string>& fields,
+    CRef<CSeq_annot>& annot,
+    unsigned int baseId,
+    ILineErrorListener* pEC)
+//  ----------------------------------------------------------------------------
+{
+    CSeq_annot::C_Data::TFtable& ftable = annot->SetData().SetFtable();
+    CRef<CSeq_feat> feature;
+    feature.Reset(new CSeq_feat);
+    try {
+        ////xSetFeatureTitle(feature, fields);
+        xSetFeatureLocationGene(feature, fields);
+        xSetFeatureIdsGene(feature, fields, baseId);
+        xSetFeatureBedData(feature, fields);
+    }
+    catch(CObjReaderLineException& err) {
+        //m_currentId.clear();
+        ProcessError(err, pEC);
+        return false;
+    }
+    ftable.push_back(feature);
+    m_currentId = fields[0];
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
 bool CBedReader::xAppendFeatureThick(
     const vector<string>& fields,
     CRef<CSeq_annot>& annot,
@@ -385,6 +451,32 @@ bool CBedReader::xAppendFeatureThick(
 }
 
 //  ----------------------------------------------------------------------------
+bool CBedReader::xAppendFeatureCds(
+    const vector<string>& fields,
+    CRef<CSeq_annot>& annot,
+    unsigned int baseId,
+    ILineErrorListener* pEC)
+//  ----------------------------------------------------------------------------
+{
+    CSeq_annot::C_Data::TFtable& ftable = annot->SetData().SetFtable();
+    CRef<CSeq_feat> feature;
+    feature.Reset(new CSeq_feat);
+    try {
+        ////xSetFeatureTitle(feature, fields);
+        xSetFeatureLocationCds(feature, fields);
+        xSetFeatureIdsCds(feature, fields, baseId);
+        xSetFeatureBedData(feature, fields);
+    }
+    catch(CObjReaderLineException& err) {
+        //m_currentId.clear();
+        ProcessError(err, pEC);
+        return false;
+    }
+    ftable.push_back(feature);
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
 bool CBedReader::xAppendFeatureBlock(
     const vector<string>& fields,
     CRef<CSeq_annot>& annot,
@@ -396,7 +488,7 @@ bool CBedReader::xAppendFeatureBlock(
     CRef<CSeq_feat> feature;
     feature.Reset(new CSeq_feat);
     try {
-        //xSetFeatureTitle(feature, fields);
+        ////xSetFeatureTitle(feature, fields);
         xSetFeatureLocationBlock(feature, fields);
         xSetFeatureIdsBlock(feature, fields, baseId);
         xSetFeatureBedData(feature, fields);
@@ -409,6 +501,34 @@ bool CBedReader::xAppendFeatureBlock(
     ftable.push_back(feature);
     return true;
 }
+
+//  ----------------------------------------------------------------------------
+bool CBedReader::xAppendFeatureRna(
+    const vector<string>& fields,
+    CRef<CSeq_annot>& annot,
+    unsigned int baseId,
+    ILineErrorListener* pEC)
+//  ----------------------------------------------------------------------------
+{
+    CSeq_annot::C_Data::TFtable& ftable = annot->SetData().SetFtable();
+    CRef<CSeq_feat> feature;
+    feature.Reset(new CSeq_feat);
+    try {
+        //xSetFeatureTitle(feature, fields);
+        xSetFeatureLocationRna(feature, fields);
+        xSetFeatureIdsRna(feature, fields, baseId);
+        xSetFeatureBedData(feature, fields);
+    }
+    catch(CObjReaderLineException& err) {
+        //m_currentId.clear();
+        ProcessError(err, pEC);
+        return false;
+    }
+    ftable.push_back(feature);
+    return true;
+}
+
+
 //  ----------------------------------------------------------------------------
 bool CBedReader::xParseFeatureUserFormat(
     const vector<string>& fields,
@@ -508,6 +628,21 @@ void CBedReader::xSetFeatureLocationChrom(
 }
 
 //  ----------------------------------------------------------------------------
+void CBedReader::xSetFeatureLocationGene(
+    CRef<CSeq_feat>& feature,
+    const vector<string>& fields)
+//  ----------------------------------------------------------------------------
+{
+    x_SetFeatureLocation(feature, fields);
+
+    CRef<CUser_object> pBed(new CUser_object());
+    pBed->SetType().SetStr("BED");
+    pBed->AddField("location", "chrom");
+    CSeq_feat::TExts& exts = feature->SetExts();
+    exts.push_back(pBed);
+}
+
+//  ----------------------------------------------------------------------------
 void CBedReader::xSetFeatureLocationThick(
     CRef<CSeq_feat>& feature,
     const vector<string>& fields)
@@ -530,7 +665,69 @@ void CBedReader::xSetFeatureLocationThick(
         pErr->Throw();
     }
     try {
-        to = NStr::StringToInt(fields[7]);
+        to = NStr::StringToInt(fields[7]) - 1;
+    }
+    catch (std::exception&) {
+        AutoPtr<CObjReaderLineException> pErr(
+            CObjReaderLineException::Create(
+            eDiag_Error,
+            0,
+            "Invalid data line: Bad \"ThickStop\" value.") );
+        pErr->Throw();
+    }
+    if (from == to) {
+        location->SetPnt().SetPoint(from);
+    }
+    else if (from < to) {
+        location->SetInt().SetFrom(from);
+        location->SetInt().SetTo(to);
+    }
+    else if (from > to) {
+        //below: flip commenting to switch from null locations to impossible 
+        // intervals
+        //location->SetInt().SetFrom(from);
+        //location->SetInt().SetTo(to);
+        location->SetNull();
+    }
+
+    if (!location->IsNull()) {
+        location->SetStrand(xGetStrand(fields));
+    }
+    CRef<CSeq_id> id = CReadUtil::AsSeqId(fields[0], m_iFlags, false);
+    location->SetId(*id);
+    feature->SetLocation(*location);
+
+    CRef<CUser_object> pBed(new CUser_object());
+    pBed->SetType().SetStr("BED");
+    pBed->AddField("location", "thick");
+    CSeq_feat::TExts& exts = feature->SetExts();
+    exts.push_back(pBed);
+}
+
+//  ----------------------------------------------------------------------------
+void CBedReader::xSetFeatureLocationCds(
+    CRef<CSeq_feat>& feature,
+    const vector<string>& fields)
+//  ----------------------------------------------------------------------------
+{
+    CRef<CSeq_loc> location(new CSeq_loc);
+    int from, to;
+    from = to = -1;
+
+    //already established: We got at least three columns
+    try {
+        from = NStr::StringToInt(fields[6]);
+    }
+    catch (std::exception&) {
+        AutoPtr<CObjReaderLineException> pErr(
+            CObjReaderLineException::Create(
+            eDiag_Error,
+            0,
+            "Invalid data line: Bad \"ThickStart\" value." ) );
+        pErr->Throw();
+    }
+    try {
+        to = NStr::StringToInt(fields[7]) - 1;
     }
     catch (std::exception&) {
         AutoPtr<CObjReaderLineException> pErr(
@@ -675,6 +872,104 @@ void CBedReader::xSetFeatureLocationBlock(
         CRef<CSeq_interval> pInterval(new CSeq_interval);
         pInterval->SetId(*pId);
         pInterval->SetFrom(blockStarts[i]);
+        pInterval->SetTo(blockStarts[i] + blockSizes[i] - 1);
+        pInterval->SetStrand(strand);
+        if (negative)
+            blocks.insert(blocks.begin(), pInterval);
+        else
+            blocks.push_back(pInterval);
+    }
+
+    CRef<CUser_object> pBed(new CUser_object());
+    pBed->SetType().SetStr("BED");
+    pBed->AddField("location", "block");
+    CSeq_feat::TExts& exts = feature->SetExts();
+    exts.push_back(pBed);
+}
+
+//  ----------------------------------------------------------------------------
+void CBedReader::xSetFeatureLocationRna(
+    CRef<CSeq_feat>& feature,
+    const vector<string>& fields)
+//  ----------------------------------------------------------------------------
+{
+    //already established: there are sufficient columns to do this
+    size_t blockCount = NStr::StringToUInt(fields[9]);
+    vector<size_t> blockSizes;
+    vector<size_t> blockStarts;
+    {{
+        blockSizes.reserve(blockCount);
+        vector<string> vals; 
+        NStr::Split(fields[10], ",", vals);
+        if (vals.back() == "") {
+            vals.erase(vals.end()-1);
+        }
+        if (vals.size() != blockCount) {
+            AutoPtr<CObjReaderLineException> pErr(
+                CObjReaderLineException::Create(
+                eDiag_Error,
+                0,
+                "Invalid data line: Bad value count in \"blockSizes\"." ) );
+            pErr->Throw();
+        }
+        try {
+            for (size_t i=0; i < blockCount; ++i) {
+                blockSizes.push_back(NStr::StringToUInt(vals[i]));
+            }
+        }
+        catch (std::exception&) {
+            AutoPtr<CObjReaderLineException> pErr(
+                CObjReaderLineException::Create(
+                eDiag_Error,
+                0,
+                "Invalid data line: Malformed \"blockSizes\" column." ) );
+            pErr->Throw();
+        }
+    }}
+    {{
+        blockStarts.reserve(blockCount);
+        vector<string> vals; 
+        size_t baseStart = NStr::StringToUInt(fields[1]);
+        NStr::Split(fields[11], ",", vals);
+        if (vals.back() == "") {
+            vals.erase(vals.end()-1);
+        }
+        if (vals.size() != blockCount) {
+            AutoPtr<CObjReaderLineException> pErr(
+                CObjReaderLineException::Create(
+                eDiag_Error,
+                0,
+                "Invalid data line: Bad value count in \"blockStarts\"." ) );
+            pErr->Throw();
+        }
+        try {
+            for (size_t i=0; i < blockCount; ++i) {
+                blockStarts.push_back(baseStart + NStr::StringToUInt(vals[i]));
+            }
+        }
+        catch (std::exception&) {
+            AutoPtr<CObjReaderLineException> pErr(
+                CObjReaderLineException::Create(
+                eDiag_Error,
+                0,
+                "Invalid data line: Malformed \"blockStarts\" column." ) );
+            pErr->Throw();
+        }
+    }}
+
+    CPacked_seqint& location = feature->SetLocation().SetPacked_int();
+    
+    ENa_strand strand = xGetStrand(fields);
+    CRef<CSeq_id> pId = CReadUtil::AsSeqId(fields[0], m_iFlags, false);
+
+    bool negative = fields[5] == "-";
+
+    CPacked_seqint::Tdata& blocks = location.Set();
+
+    for (size_t i=0; i < blockCount; ++i) {
+        CRef<CSeq_interval> pInterval(new CSeq_interval);
+        pInterval->SetId(*pId);
+        pInterval->SetFrom(blockStarts[i]);
         pInterval->SetTo(blockStarts[i] + blockSizes[i]);
         pInterval->SetStrand(strand);
         if (negative)
@@ -718,6 +1013,17 @@ void CBedReader::xSetFeatureIdsChrom(
 }
 
 //  ----------------------------------------------------------------------------
+void CBedReader::xSetFeatureIdsGene(
+    CRef<CSeq_feat>& feature,
+    const vector<string>& fields,
+    unsigned int baseId)
+//  ----------------------------------------------------------------------------
+{
+    baseId++; //0-based to 1-based
+    feature->SetId().SetLocal().SetId(baseId);
+}
+
+//  ----------------------------------------------------------------------------
 void CBedReader::xSetFeatureIdsThick(
     CRef<CSeq_feat>& feature,
     const vector<string>& fields,
@@ -743,6 +1049,31 @@ void CBedReader::xSetFeatureIdsThick(
 }
 
 //  ----------------------------------------------------------------------------
+void CBedReader::xSetFeatureIdsCds(
+    CRef<CSeq_feat>& feature,
+    const vector<string>& fields,
+    unsigned int baseId)
+//  ----------------------------------------------------------------------------
+{
+    baseId++; //0-based to 1-based
+    feature->SetId().SetLocal().SetId(baseId+1);
+
+    //CRef<CFeat_id> pIdChrom(new CFeat_id);
+    //pIdChrom->SetLocal().SetId(baseId);
+    //CRef<CSeqFeatXref> pXrefChrom(new CSeqFeatXref);
+    //pXrefChrom->SetId(*pIdChrom);  
+    //feature->SetXref().push_back(pXrefChrom);
+
+    if (xContainsBlockFeature(fields)) {
+        CRef<CFeat_id> pIdBlock(new CFeat_id);
+        pIdBlock->SetLocal().SetId(baseId+2);
+        CRef<CSeqFeatXref> pXrefBlock(new CSeqFeatXref);
+        pXrefBlock->SetId(*pIdBlock);  
+        feature->SetXref().push_back(pXrefBlock);   
+    }
+}
+
+//  ----------------------------------------------------------------------------
 void CBedReader::xSetFeatureIdsBlock(
     CRef<CSeq_feat>& feature,
     const vector<string>& fields,
@@ -768,6 +1099,31 @@ void CBedReader::xSetFeatureIdsBlock(
 }
 
 //  ----------------------------------------------------------------------------
+void CBedReader::xSetFeatureIdsRna(
+    CRef<CSeq_feat>& feature,
+    const vector<string>& fields,
+    unsigned int baseId)
+//  ----------------------------------------------------------------------------
+{
+    baseId++; //0-based to 1-based
+    feature->SetId().SetLocal().SetId(baseId+2);
+
+    CRef<CFeat_id> pIdChrom(new CFeat_id);
+    pIdChrom->SetLocal().SetId(baseId);
+    CRef<CSeqFeatXref> pXrefChrom(new CSeqFeatXref);
+    pXrefChrom->SetId(*pIdChrom);  
+    feature->SetXref().push_back(pXrefChrom);
+
+    //if (xContainsThickFeature(fields)) {
+    //    CRef<CFeat_id> pIdThick(new CFeat_id);
+    //    pIdThick->SetLocal().SetId(baseId+1);
+    //    CRef<CSeqFeatXref> pXrefBlock(new CSeqFeatXref);
+    //    pXrefBlock->SetId(*pIdThick);  
+    //    feature->SetXref().push_back(pXrefBlock);   
+    //}
+}
+
+//  ----------------------------------------------------------------------------
 void CBedReader::xSetFeatureTitle(
     CRef<CSeq_feat>& feature,
     const vector<string>& fields )
@@ -781,34 +1137,23 @@ void CBedReader::xSetFeatureTitle(
     }
 }
 
+
 //  ----------------------------------------------------------------------------
-void CBedReader::xSetFeatureBedData(
-    CRef<CSeq_feat>& feature,
+void CBedReader::xSetFeatureScore(
+    CRef<CUser_object> pDisplayData,
     const vector<string>& fields )
 //  ----------------------------------------------------------------------------
 {
-    CSeqFeatData& data = feature->SetData();
-	if (fields.size() >= 4  &&  fields[3] != ".") {
-		data.SetRegion() = fields[3];
-	}
-	else {
-		data.SetRegion() = fields[0];
-	}
-    
-    CRef<CUser_object> pDisplayData(new CUser_object());
-    if (fields.size() < 5  ||  fields[4] == ".") {
+    string trackUseScore = m_pTrackDefaults->ValueOf("useScore");
+    if (fields.size() < 5  || trackUseScore == "1") {
+        //record does not carry score information
         return;
     }
 
-    CSeq_feat::TExts& exts = feature->SetExts();
-    pDisplayData->SetType().SetStr("DisplaySettings");
-    exts.push_front(pDisplayData);
-
     int int_score = NStr::StringToInt(fields[4], NStr::fConvErr_NoThrow );
     double d_score = 0;
 
-    if (int_score == 0 && fields[4].compare("0") != 0)
-    {
+    if (int_score == 0 && fields[4].compare("0") != 0) {
         try {
             d_score = NStr::StringToDouble(fields[4]);
         }
@@ -822,8 +1167,7 @@ void CBedReader::xSetFeatureBedData(
         }
     }
 
-    if (d_score < 0 || int_score < 0)
-    {
+    if (d_score < 0 || int_score < 0) {
         AutoPtr<CObjReaderLineException> pErr(
             CObjReaderLineException::Create(
             eDiag_Error,
@@ -831,30 +1175,142 @@ void CBedReader::xSetFeatureBedData(
             "Invalid data line: Bad \"score\" value.") );
         pErr->Throw();
     }
-    else
-    if (d_score > 0)
-    {
+    else if (d_score > 0) {
         pDisplayData->AddField("score", d_score);
     }
-    else
-    {
+    else {
         pDisplayData->AddField("score", int_score);
     }
+}
+
+
+//  ----------------------------------------------------------------------------
+void CBedReader::xSetFeatureColor(
+    CRef<CUser_object> pDisplayData,
+    const vector<string>& fields )
+//  ----------------------------------------------------------------------------
+{
+    //1: if track line itemRgb is set, try that first:
+    string trackItemRgb = m_pTrackDefaults->ValueOf("itemRgb");
+    if (trackItemRgb == "On"  &&  fields.size() >= 9) {
+        string featItemRgb = fields[8];
+        if (featItemRgb != ".") {
+            xSetFeatureColorFromItemRgb(pDisplayData, featItemRgb);
+            return;
+        }
+    }
+
+    //2: if track useScore is set, try that next:
+    string trackUseScore = m_pTrackDefaults->ValueOf("useScore");
+    if (trackUseScore == "1"  && fields.size() >= 5) {
+        string featScore = fields[4];
+        if (featScore != ".") {    
+            xSetFeatureColorFromScore(pDisplayData, featScore);
+            return; 
+        }
+    }
 
-    if (fields.size() < 9) {
+    //3: if track colorByStrand is set, try that next:
+    string trackColorByStrand = m_pTrackDefaults->ValueOf("colorByStrand");
+    if (!trackColorByStrand.empty()  && fields.size() >= 6) {
+        ENa_strand strand = 
+            (fields[5] == "-") ? eNa_strand_minus : eNa_strand_plus;
+        xSetFeatureColorByStrand(pDisplayData, trackColorByStrand, strand);
         return;
     }
+    //4: if none of the track color attributes are set, attempt feature itemRgb:
+    if (fields.size() >= 9) {
+        string featItemRgb = fields[8];
+        if (featItemRgb != ".") {
+            xSetFeatureColorFromItemRgb(pDisplayData, featItemRgb);
+            return;
+        }
+    }
+    
+    //5: if still here, assign default color:
+    xSetFeatureColorDefault(pDisplayData);
+}
+
+//  ----------------------------------------------------------------------------
+void CBedReader::xSetFeatureColorDefault(
+    CRef<CUser_object> pDisplayData)
+//  ----------------------------------------------------------------------------
+{
+    const string colorDefault("0 0 0");
+    pDisplayData->AddField("color", colorDefault);
+}
+
+//  ----------------------------------------------------------------------------
+void CBedReader::xSetFeatureColorByStrand(
+    CRef<CUser_object> pDisplayData,
+    const string& trackColorByStrand,
+    ENa_strand strand)
+//  ----------------------------------------------------------------------------
+{
+    try {
+        string colorPlus, colorMinus;
+        NStr::SplitInTwo(trackColorByStrand, " ", colorPlus, colorMinus);
+        string useColor = (strand == eNa_strand_minus) ? colorMinus : colorPlus;
+        xSetFeatureColorFromItemRgb(pDisplayData, useColor);
+    }
+    catch (std::exception&) {
+        AutoPtr<CObjReaderLineException> pErr(
+            CObjReaderLineException::Create(
+            eDiag_Error,
+            0,
+            "Invalid track line: Bad colorByStrand value.") );
+        pErr->Throw();
+    }
+}
+
+//  ----------------------------------------------------------------------------
+void CBedReader::xSetFeatureColorFromScore(
+    CRef<CUser_object> pDisplayData,
+    const string& featScore )
+//  ----------------------------------------------------------------------------
+{
+    int score = 0;
+    try {
+        score = NStr::StringToInt(featScore);
+    }
+    catch (const std::exception&) {
+        AutoPtr<CObjReaderLineException> pErr(
+            CObjReaderLineException::Create(
+            eDiag_Error,
+            0,
+            "Invalid data line: Bad score value to be used for color.") );
+        pErr->Throw();
+    }
+    if (score < 0  ||  1000 < score) {
+        AutoPtr<CObjReaderLineException> pErr(
+            CObjReaderLineException::Create(
+            eDiag_Error,
+            0,
+            "Invalid data line: Bad score value to be used for color.") );
+        pErr->Throw();
+    }
+    string greyValue  = NStr::IntToString(255 - (score/4));
+    vector<string> srgb{ greyValue, greyValue, greyValue};
+    string rgbValue = NStr::Join(srgb, " ");
+    pDisplayData->AddField("color", rgbValue);
+}
+
+//  ----------------------------------------------------------------------------
+void CBedReader::xSetFeatureColorFromItemRgb(
+    CRef<CUser_object> pDisplayData,
+    const string& itemRgb )
+//  ----------------------------------------------------------------------------
+{
     vector<string> srgb;
-    if (fields[8] == "0"  ||  fields[8] == ".") {
+    if (itemRgb == "0") {
         srgb.push_back("0");
         srgb.push_back("0");
         srgb.push_back("0");
     }
     else {
-        NStr::Split(fields[8], ",", srgb);
+        NStr::Split(itemRgb, ",", srgb);
     }
-    if (srgb.size() != 3)
-    {
+    if (srgb.size() != 3) {
         AutoPtr<CObjReaderLineException> pErr(
             CObjReaderLineException::Create(
             eDiag_Error,
@@ -862,8 +1318,7 @@ void CBedReader::xSetFeatureBedData(
             "Invalid data line: Bad color value.") );
         pErr->Throw();
     }
-    try
-    {
+    try {
         for (int i=0; i < 3; i++)
         {
            int x = NStr::StringToInt(srgb[i]);
@@ -878,8 +1333,7 @@ void CBedReader::xSetFeatureBedData(
 
         }
     }
-    catch(const std::exception&)
-    {
+    catch(const std::exception&) {
         AutoPtr<CObjReaderLineException> pErr(
             CObjReaderLineException::Create(
             eDiag_Error,
@@ -892,6 +1346,30 @@ void CBedReader::xSetFeatureBedData(
 }
 
 //  ----------------------------------------------------------------------------
+void CBedReader::xSetFeatureBedData(
+    CRef<CSeq_feat>& feature,
+    const vector<string>& fields )
+//  ----------------------------------------------------------------------------
+{
+    CSeqFeatData& data = feature->SetData();
+	if (fields.size() >= 4  &&  fields[3] != ".") {
+		data.SetRegion() = fields[3];
+	}
+	else {
+		data.SetRegion() = fields[0];
+	}
+    
+    CRef<CUser_object> pDisplayData(new CUser_object());
+
+    CSeq_feat::TExts& exts = feature->SetExts();
+    pDisplayData->SetType().SetStr("DisplaySettings");
+    exts.push_front(pDisplayData);
+
+    xSetFeatureScore(pDisplayData, fields);
+    xSetFeatureColor(pDisplayData, fields);
+}
+
+//  ----------------------------------------------------------------------------
 void CBedReader::x_SetFeatureLocation(
     CRef<CSeq_feat>& feature,
     const vector<string>& fields )
@@ -972,40 +1450,6 @@ void CBedReader::x_SetFeatureLocation(
 }
 
 //  ----------------------------------------------------------------------------
-void CBedReader::xSetTrackData(
-    CRef<CSeq_annot>& annot,
-    CRef<CUser_object>& trackdata,
-    const string& strKey,
-    const string& strValue)
-//  ----------------------------------------------------------------------------
-{
-    CAnnot_descr& desc = annot->SetDesc();
-
-    if (strKey == "useScore") {
-        m_usescore = (1 == NStr::StringToInt(strValue));
-        trackdata->AddField( strKey, NStr::StringToInt(strValue));
-        return;
-    }
-    if (strKey == "name") {
-        CRef<CAnnotdesc> name(new CAnnotdesc());
-        name->SetName(strValue);
-        desc.Set().push_back(name);
-        return;
-    }
-    if (strKey == "description") {
-        CRef<CAnnotdesc> title(new CAnnotdesc());
-        title->SetTitle(strValue);
-        desc.Set().push_back(title);
-        return;
-    }
-    if (strKey == "visibility") {
-        trackdata->AddField(strKey, NStr::StringToInt(strValue));
-        return;
-    }
-    CReaderBase::xSetTrackData(annot, trackdata, strKey, strValue);
-}
-
-//  ----------------------------------------------------------------------------
 bool 
 CBedReader::ReadTrackData(
     ILineReader& lr,
@@ -1172,6 +1616,37 @@ CBedReader::xContainsThickFeature(
 
 //  ----------------------------------------------------------------------------
 bool
+CBedReader::xContainsCdsFeature(
+    const vector<string>& fields) const
+//  ----------------------------------------------------------------------------
+{
+    if (fields.size() < 8) {
+        return false;
+    }
+
+    int start = -1, from = -1, to = -1;
+    try {
+        start = NStr::StringToInt(fields[1]);
+        from = NStr::StringToInt(fields[6]);
+        to = NStr::StringToInt(fields[7]);
+    }
+    catch (std::exception&) {
+        AutoPtr<CObjReaderLineException> pErr(
+            CObjReaderLineException::Create(
+            eDiag_Error,
+            0,
+            "Invalid data line: Bad \"Start/ThickStart/ThickStop\" values." ) );
+        pErr->Throw();
+    }
+    if (start == from  &&  from == to) {
+        return false;
+    }
+    return true;
+}
+
+
+//  ----------------------------------------------------------------------------
+bool
 CBedReader::xContainsBlockFeature(
     const vector<string>& fields) const
 //  ----------------------------------------------------------------------------
@@ -1182,6 +1657,16 @@ CBedReader::xContainsBlockFeature(
 
 //  ----------------------------------------------------------------------------
 bool
+CBedReader::xContainsRnaFeature(
+    const vector<string>& fields) const
+//  ----------------------------------------------------------------------------
+{
+    return (fields.size() >= 12);
+}
+
+
+//  ----------------------------------------------------------------------------
+bool
 CBedReader::xReadBedDataRaw(
     ILineReader& lr,
     CRawBedTrack& rawdata,
@@ -1254,5 +1739,23 @@ CBedReader::xCleanColumnValues(
     }
 }
 
+//  ----------------------------------------------------------------------------
+void 
+CBedReader::xAssignBedColumnCount(
+    CSeq_annot& annot)
+//  ----------------------------------------------------------------------------
+{
+    if(m_columncount < 3) {
+        return;
+    }
+    CRef<CUser_object> columnCountUser( new CUser_object() );
+    columnCountUser->SetType().SetStr( "NCBI_BED_COLUMN_COUNT" );
+    columnCountUser->AddField("NCBI_BED_COLUMN_COUNT", int ( m_columncount ) );
+    
+    CRef<CAnnotdesc> userDesc( new CAnnotdesc() );
+    userDesc->SetUser().Assign( *columnCountUser );
+    annot.SetDesc().Set().push_back( userDesc );
+}                   
+
 END_objects_SCOPE
 END_NCBI_SCOPE
diff --git a/c++/src/objtools/readers/fasta.cpp b/c++/src/objtools/readers/fasta.cpp
index 1df1a90..baa852e 100644
--- a/c++/src/objtools/readers/fasta.cpp
+++ b/c++/src/objtools/readers/fasta.cpp
@@ -1,4 +1,4 @@
-/*  $Id: fasta.cpp 499434 2016-04-26 14:13:36Z ivanov $
+/*  $Id: fasta.cpp 520111 2016-11-22 19:00:06Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -534,26 +534,38 @@ void CFastaReader::SetIDGenerator(CSeqIdGenerator& gen)
     m_IDGenerator.Reset(&gen);
 }
 
-void CFastaReader::ParseDefLine(const TStr& s, ILineErrorListener * pMessageListener)
+// This method does not use CRef<CSeq_interval> to access range 
+// information for reasons of efficiency - RW-26
+void CFastaReader::ParseDefLine(const TStr& defLine,
+                                const SDefLineParseInfo& info,
+                                const TIgnoredProblems& ignoredErrors,
+                                list<CRef<CSeq_id>>& ids,
+                                bool& hasRange,
+                                TSeqPos& rangeStart,
+                                TSeqPos& rangeEnd,
+                                TSeqTitles& seqTitles, 
+                                ILineErrorListener * pMessageListener) 
 {
-    size_t start = 1, pos, len = s.length(), range_len = 0, title_start;
-    TSeqPos range_start, range_end;
+    size_t start = 1, pos, len = defLine.length(), title_start;
+    size_t range_len = 0;
+    const TFlags& fFastaFlags = info.fFastaFlags;
+    const size_t& lineNumber = info.lineNumber;
 
     // ignore spaces between '>' and the sequence ID
     for( ; start < len; ++start ) {
-        if( ! isspace(s[start]) ) {
+        if( ! isspace(defLine[start]) ) {
             break;
         }
     }
 
     do {
         bool has_id = true;
-        if (TestFlag(fNoParseID)) {
+        if ((fFastaFlags & fNoParseID)) {
             title_start = start;
         } else {
             // This loop finds the end of the sequence ID
             for ( pos = start;  pos < len;  ++pos) {
-                unsigned char c = s[pos];
+                unsigned char c = defLine[pos];
                 
                 if (c <= ' ' ) { // assumes ASCII
                     break;
@@ -573,7 +585,7 @@ void CFastaReader::ParseDefLine(const TStr& s, ILineErrorListener * pMessageList
                     const static size_t kMaxCharsToLookAt = 30; 
                     // we give up much sooner than the length of the string, if the string is long.
                     // also note that we give up *before* the end so even if pos
-                    // reaches bracket_give_up_pos, we can still say s[pos] without worrying
+                    // reaches bracket_give_up_pos, we can still say defLine[pos] without worrying
                     // about array-out-of-bounds issues.
                     const size_t bracket_give_up_pos = min(len - 1, kMaxCharsToLookAt);
                     // keep track of the first space we find, because that becomes the end of the seqid
@@ -582,7 +594,7 @@ void CFastaReader::ParseDefLine(const TStr& s, ILineErrorListener * pMessageList
 
                     // find the end of the key
                     for( ; pos < bracket_give_up_pos ; ++pos ) {
-                        const unsigned char c = s[pos];
+                        const unsigned char c = defLine[pos];
                         if( c == '=' ) {
                             break;
                         } else if( c <= ' ' ) {
@@ -596,7 +608,7 @@ void CFastaReader::ParseDefLine(const TStr& s, ILineErrorListener * pMessageList
                         }
                     }
 
-                    if( s[pos] == '=' ) {
+                    if( defLine[pos] == '=' ) {
                         // this seems to be a FASTA mod, so consider the left square bracket
                         // to be the end of the seqid
                         pos = left_bracket_pos;
@@ -616,22 +628,26 @@ void CFastaReader::ParseDefLine(const TStr& s, ILineErrorListener * pMessageList
                 }
             }
 
-            range_len = ParseRange(TStr(s.data() + start, pos - start),
-                                   range_start, range_end, pMessageListener);
-            has_id = ParseIDs(TStr(s.data() + start, pos - start - range_len), pMessageListener);
-            if (has_id  &&  TestFlag(fAllSeqIds)  &&  s[pos] == '\1') {
+            range_len = ParseRange(TStr(defLine.data() + start, pos - start),
+                                   rangeStart, rangeEnd, pMessageListener);
+            has_id = ParseIDs(TStr(defLine.data() + start, pos - start - range_len), 
+                              info,
+                              ignoredErrors,
+                              ids, 
+                              pMessageListener);
+            if (has_id  &&  (fFastaFlags & fAllSeqIds)  &&  defLine[pos] == '\1') {
                 start = pos + 1;
                 continue;
             }
             title_start = pos;
             // trim leading whitespace from title (is this appropriate?)
             while (title_start < len
-                   &&  isspace((unsigned char) s[title_start])) {
+                   &&  isspace((unsigned char) defLine[title_start])) {
                 ++title_start;
             }
         }
         for (pos = title_start + 1;  pos < len;  ++pos) {
-            if ((unsigned char) s[pos] < ' ') {
+            if ((unsigned char) defLine[pos] < ' ') {
                 break;
             }
         }
@@ -642,14 +658,39 @@ void CFastaReader::ParseDefLine(const TStr& s, ILineErrorListener * pMessageList
         }
         if (title_start < min(pos, len)) {
             // we parse the titles after we know what molecule this is
-            m_CurrentSeqTitles.push_back(
+            seqTitles.push_back(
                 SLineTextAndLoc(
-                s.substr(title_start, pos - title_start), LineNumber()));
+                defLine.substr(title_start, pos - title_start), lineNumber));
         }
         start = pos + 1;
-    } while (TestFlag(fAllSeqIds)  &&  start < len  &&  s[start - 1] == '\1'
+    } while ( (fFastaFlags & fAllSeqIds)  &&  start < len  &&  defLine[start - 1] == '\1'
              &&  !range_len);
 
+
+    hasRange = (range_len>0);
+}
+
+
+void CFastaReader::ParseDefLine(const TStr& s, ILineErrorListener * pMessageListener)
+{
+    TSeqPos range_start, range_end;
+    bool has_range;
+    SDefLineParseInfo parseInfo;
+    parseInfo.fBaseFlags = m_iFlags;
+    parseInfo.fFastaFlags = GetFlags();
+    parseInfo.maxIdLength = m_MaxIDLength;
+    parseInfo.lineNumber = LineNumber();
+
+    ParseDefLine(s,
+                 parseInfo,
+                 m_ignorable,
+                 SetIDs(), 
+                 has_range,
+                 range_start,
+                 range_end,
+                 m_CurrentSeqTitles, 
+                 pMessageListener);
+
     if (GetIDs().empty()) {
         // No [usable] IDs
         if (TestFlag(fRequireID)) {
@@ -676,7 +717,7 @@ void CFastaReader::ParseDefLine(const TStr& s, ILineErrorListener * pMessageList
 
     m_BestID = FindBestChoice(GetIDs(), CSeq_id::BestRank);
 
-    if (range_len) {
+    if (has_range) {
         // generate a new ID, and record its relation to the given one(s).
         SetIDs().clear();
         GenerateID();
@@ -728,6 +769,115 @@ void CFastaReader::ParseDefLine(const TStr& s, ILineErrorListener * pMessageList
     }
 }
 
+
+bool CFastaReader::ParseIDs(
+    const TStr& s, 
+    const SDefLineParseInfo& info,
+    const TIgnoredProblems& ignoredErrors,
+    list<CRef<CSeq_id>>& ids, 
+    ILineErrorListener * pMessageListener) 
+{
+    // if user wants all ids to be purely local, no problem
+    if( info.fBaseFlags & CReaderBase::fAllIdsAsLocal )
+    {
+        ids.push_back(Ref(new CSeq_id(CSeq_id::e_Local, s)));
+        return true;
+    }
+
+    size_t count = 0;
+    // be generous overall, and give raw local IDs the benefit of the
+    // doubt for now
+    CSeq_id::TParseFlags flags
+        = CSeq_id::fParse_PartialOK | CSeq_id::fParse_AnyLocal;
+    if ( info.fFastaFlags & fParseRawID ) {
+        flags |= CSeq_id::fParse_RawText;
+    }
+
+    const bool ignoreError
+        = (find(ignoredErrors.cbegin(), ignoredErrors.cend(), ILineError::eProblem_GeneralParsingError) 
+           != ignoredErrors.cend()); 
+
+    try {
+        if (s.find(',') != TStr::npos && s.find('|') == TStr::npos)
+        {
+            string temp = NStr::Replace(s, ",", "_");
+            count = CSeq_id::ParseIDs(ids, temp, flags);
+
+            const string errMessage = 
+                "CFastaReader: Near line " + NStr::NumericToString(info.lineNumber) 
+                + ", the sequence contains 'comma' symbol and replaced with 'underscore' "
+                + "symbol. Please find and correct the sequence id.";
+
+            if (!ignoreError) {
+                PostWarning(pMessageListener, 
+                            info.lineNumber,
+                            errMessage,
+                            CObjReaderParseException::eFormat);
+
+            }
+        }
+        else
+        {
+            count = CSeq_id::ParseIDs(ids, s, flags);
+        }
+    } catch (CSeqIdException&) {
+        // swap(ids, old_ids);
+    }
+
+    // numerics become local, if requested
+    if( info.fBaseFlags & CReaderBase::fNumericIdsAsLocal ) {
+        NON_CONST_ITERATE(CBioseq::TId, id_it, ids) {
+            CSeq_id & id = **id_it;
+            if( id.IsGi() ) {
+                const TGi gi = id.GetGi();
+                id.SetLocal().SetStr( NStr::NumericToString(gi) );
+            }
+        }
+    }
+    // recheck raw local IDs
+    if (count == 1  &&  ids.back()->IsLocal())
+    {
+        string temp;
+        ids.back()->GetLabel(&temp, 0, CSeq_id::eContent);
+        if (!IsValidLocalID(temp, info.fFastaFlags))
+        {
+            ids.clear();
+            return false;
+        }
+    }
+    // check if ID was too long, use only 
+    if( count == 1)
+    {
+      CTempString check;
+      size_t last = s.rfind('|');
+      check = (last == CTempString::npos) ? s : s.substr(last + 1);
+      if (check.length() > info.maxIdLength) { 
+
+        // before throwing an ID-too-long error, check if what we
+        // think is a "sequence ID" is actually sequence data
+        if (ExcessiveSeqDataInTitle(s, info.fFastaFlags)) {
+            return false;
+        }
+
+        const string errMessage =
+            "CFastaReader: Near line " + NStr::NumericToString(info.lineNumber)
+            + ", the sequence ID is too long.  Its length is " + NStr::NumericToString(s.length())
+            + " but the max length allowed is "+  NStr::NumericToString(info.maxIdLength)
+            + ".  Please find and correct all sequence IDs that are too long.";
+
+
+        if (!ignoreError) {
+            PostError(pMessageListener, 
+                      info.lineNumber,
+                      errMessage,
+                      CObjReaderParseException::eIDTooLong);
+        }
+      }
+    }
+    return count > 0;
+}
+
+
 bool CFastaReader::ParseIDs(
     const TStr& s, ILineErrorListener * pMessageListener)
 {
@@ -788,8 +938,13 @@ bool CFastaReader::ParseIDs(
             return false;
         }
     }
-    // check if ID was too long
-    if( count == 1 && s.length() > m_MaxIDLength ){ 
+    // check if ID was too long, use only 
+    if( count == 1)
+    {
+      CTempString check;
+      size_t last = s.rfind('|');
+      check = (last == CTempString::npos) ? s : s.substr(last + 1);
+      if (check.length() > m_MaxIDLength ) { 
 
         // before throwing an ID-too-long error, check if what we
         // think is a "sequence ID" is actually sequence data
@@ -805,6 +960,7 @@ bool CFastaReader::ParseIDs(
             << " but the max length allowed is " << m_MaxIDLength 
             << ".  Please find and correct all sequence IDs that are too long.",
             CObjReaderParseException::eIDTooLong);
+      }
     }
     return count > 0;
 }
@@ -870,13 +1026,19 @@ void CFastaReader::ParseTitle(
     x_ApplyAllMods(*m_CurrentSeq, lineInfo.m_iLineNum, pMessageListener);
 }
 
-bool CFastaReader::IsValidLocalID(const TStr& s)
+bool CFastaReader::IsValidLocalID(const TStr& s) const
 {
-    if (TestFlag(fQuickIDCheck)) { // just check first character
-        return CSeq_id::IsValidLocalID(s.substr(0, 1));
-    } else {
-        return CSeq_id::IsValidLocalID(s);
+    return IsValidLocalID(s, GetFlags());
+}
+
+bool CFastaReader::IsValidLocalID(const TStr& idString, 
+    const TFlags fFastaFlags)
+{
+    if ( fFastaFlags & fQuickIDCheck) { // check only the first character
+        return CSeq_id::IsValidLocalID(idString.substr(0,1));
     }
+
+    return CSeq_id::IsValidLocalID(idString);
 }
 
 void CFastaReader::GenerateID(void)
@@ -1596,17 +1758,67 @@ void CFastaReader::AssignMolType(ILineErrorListener * pMessageListener)
     } 
 }
 
+bool 
+CFastaReader::ExcessiveSeqDataInTitle(const string& title, TFlags fFastaFlags) 
+{
+    if (fFastaFlags & fAssumeProt) {
+        return false;
+    }
+
+    // Check for nuc or aa sequence at the end of the title
+    const size_t kWarnNumNucCharsAtEnd = 20;
+    const size_t kWarnNumAminoAcidCharsAtEnd = 50;
+
+    // Check for nuc sequence
+    if (title.length() > kWarnNumNucCharsAtEnd) {
+        size_t numNucChars = 0;
+        for (auto rit=title.crbegin(); rit!=title.crend(); ++rit) {
+            if (!s_ASCII_IsUnAmbigNuc(*rit)) {
+                break;
+            }
+            ++numNucChars;
+        }
+        if (numNucChars > kWarnNumNucCharsAtEnd) {
+            return true;
+        }
+    }
+
+    // Check for Aa sequence
+    if (title.length() > kWarnNumAminoAcidCharsAtEnd) {
+        size_t numAaChars = 0;
+        for (auto rit=title.crbegin(); rit!=title.crend(); ++rit) {
+            const auto ch = *rit;
+            if ( !(ch >= 'A' && ch <= 'Z')  &&
+                 !(ch >= 'a' && ch <= 'z') ) {
+                break;
+            }
+            ++numAaChars;
+        }
+        if (numAaChars > kWarnNumAminoAcidCharsAtEnd) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+
 bool
 CFastaReader::CreateWarningsForSeqDataInTitle(
     const TStr& sLineText, 
     TSeqPos iLineNum,
-    ILineErrorListener * pMessageListener)
+    ILineErrorListener * pMessageListener) const
 {
     bool bFoundProblem = false;
 
     // check for nuc or aa sequences at the end of the title
     const static size_t kWarnNumNucCharsAtEnd = 20;
     const static size_t kWarnAminoAcidCharsAtEnd = 50;
+
+    if (TestFlag(fAssumeProt))
+    {
+    }
+    else
     if( sLineText.length() > kWarnNumNucCharsAtEnd ) {
 
         // find last non-nuc character, within the last kWarnNumNucCharsAtEnd characters
@@ -2143,9 +2355,58 @@ void CFastaReader::SetGapLinkageEvidences(CSeq_gap::EType type, const set<int>&
    }
 }
 
+
+void CFastaReader::PostWarning(ILineErrorListener* pMessageListener, 
+                               const size_t lineNumber,
+                               const string& errMessage, 
+                               const CObjReaderParseException::EErrCode errCode) 
+{
+    unique_ptr<CObjReaderLineException> pLineExpt(
+        CObjReaderLineException::Create(
+        eDiag_Warning,
+        lineNumber,
+        errMessage, 
+        ILineError::eProblem_GeneralParsingError,
+        "", "", "", "",
+        errCode));
+
+
+    if (!pMessageListener) {
+        LOG_POST_X(1, Warning << pLineExpt->Message());
+        return;
+    }
+
+    if (!pMessageListener->PutError(*pLineExpt)) {
+        throw CObjReaderParseException(DIAG_COMPILE_INFO, 0, errCode, errMessage, lineNumber, eDiag_Warning);
+    }
+}
+
+
+void CFastaReader::PostError(ILineErrorListener* pMessageListener,
+                             const size_t lineNumber,
+                             const string& errMessage,
+                             const CObjReaderParseException::EErrCode errCode) 
+{
+
+    unique_ptr<CObjReaderLineException> pLineExpt(
+        CObjReaderLineException::Create(
+        eDiag_Error,
+        lineNumber,
+        errMessage, 
+        ILineError::eProblem_GeneralParsingError,
+        "", "", "", "",
+        errCode));
+
+    if (!pMessageListener || !pMessageListener->PutError(*pLineExpt)) {
+        throw CObjReaderParseException(DIAG_COMPILE_INFO, 0, errCode, errMessage, lineNumber, eDiag_Error);
+    }
+}
+
+
+
 void CFastaReader::PostWarning(
             ILineErrorListener * pMessageListener,
-            EDiagSev _eSeverity, size_t _uLineNum, CTempString _MessageStrmOps, CObjReaderParseException::EErrCode _eErrCode, ILineError::EProblem _eProblem, CTempString _sFeature, CTempString _sQualName, CTempString _sQualValue)
+            EDiagSev _eSeverity, size_t _uLineNum, CTempString _MessageStrmOps, CObjReaderParseException::EErrCode _eErrCode, ILineError::EProblem _eProblem, CTempString _sFeature, CTempString _sQualName, CTempString _sQualValue) const
 {
     if (find(m_ignorable.begin(), m_ignorable.end(), _eProblem) != m_ignorable.end())
         return;
diff --git a/c++/src/objtools/readers/gff2_data.cpp b/c++/src/objtools/readers/gff2_data.cpp
index 9fe671e..027b47c 100644
--- a/c++/src/objtools/readers/gff2_data.cpp
+++ b/c++/src/objtools/readers/gff2_data.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gff2_data.cpp 497078 2016-04-04 14:59:49Z ivanov $
+/*  $Id: gff2_data.cpp 516436 2016-10-13 15:25:49Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -52,6 +52,7 @@
 #include <objects/seqfeat/SeqFeatXref.hpp>
 #include <objects/seqfeat/Code_break.hpp>
 #include <objects/seqfeat/Genetic_code.hpp>
+#include <objects/seqfeat/Variation_ref.hpp>
 
 #include <objtools/readers/read_util.hpp>
 #include <objtools/readers/reader_base.hpp>
@@ -86,7 +87,7 @@ CRef<CCode_break> s_StringToCodeBreak(
 //  ----------------------------------------------------------------------------
 {
     const string cdstr_start = "(pos:";
-    const string cdstr_div = ",aa=";
+    const string cdstr_div = ",aa:";
     const string cdstr_end = ")";
     
     CRef<CCode_break> pCodeBreak;
@@ -932,32 +933,32 @@ bool CGff2Record::x_MigrateAttributes(
         attrs_left.erase(it);
     }
 
-    it = attrs_left.find("product");
-    if (it != attrs_left.end()) {
-        if (!pFeature->IsSetProduct()) {
-            CRef<CSeq_id> pId = CReadUtil::AsSeqId(it->second, flags);
-            CRef<CSeq_loc> pLoc( new CSeq_loc(CSeq_loc::e_Whole));
-            pLoc->SetId(*pId);
-            pFeature->SetProduct(*pLoc);
-        }
-        xMigrateAttributeDefault(
-            attrs_left, "product", pFeature, "product", flags);
-    }
+//    it = attrs_left.find("product");
+//    if (it != attrs_left.end()) {
+//        if (!pFeature->IsSetProduct()) {
+//            CRef<CSeq_id> pId = CReadUtil::AsSeqId(it->second, flags);
+//            CRef<CSeq_loc> pLoc( new CSeq_loc(CSeq_loc::e_Whole));
+//            pLoc->SetId(*pId);
+//            pFeature->SetProduct(*pLoc);
+//        }
+//        xMigrateAttributeDefault(
+//            attrs_left, "product", pFeature, "product", flags);
+//    }
 
-    xMigrateAttributeDefault(
-        attrs_left, "Product", pFeature, "product", flags);
+//    xMigrateAttributeDefault(
+//        attrs_left, "Product", pFeature, "product", flags);
 
-    it = attrs_left.find("protein_id");
-    if (it != attrs_left.end()) {
-        string protId = it->second;
-        CRef<CSeq_id> pId = CReadUtil::AsSeqId(protId, flags);
-        CRef<CSeq_loc> pLoc( new CSeq_loc(CSeq_loc::e_Whole));
-        pLoc->SetId(*pId);
-        pFeature->SetProduct(*pLoc);
+//    it = attrs_left.find("protein_id");
+//    if (it != attrs_left.end()) {
+//        string protId = it->second;
+//        CRef<CSeq_id> pId = CReadUtil::AsSeqId(protId, flags);
+//        CRef<CSeq_loc> pLoc( new CSeq_loc(CSeq_loc::e_Whole));
+//        pLoc->SetId(*pId);
+//        pFeature->SetProduct(*pLoc);
 
-        this->xMigrateAttributeDefault(
-            attrs_left, "protein_id", pFeature, "protein_id", flags);
-    }
+//        this->xMigrateAttributeDefault(
+//            attrs_left, "protein_id", pFeature, "protein_id", flags);
+//    }
 
     it = attrs_left.find("pseudo");
     if (it != attrs_left.end()) {
@@ -965,19 +966,19 @@ bool CGff2Record::x_MigrateAttributes(
         attrs_left.erase(it);
     }
 
-    it = attrs_left.find("transcript_id");
-    if (it != attrs_left.end()) {
-        string transcriptId = it->second;
-        if (!pFeature->IsSetProduct()) {
-            CRef<CSeq_id> pId = CReadUtil::AsSeqId(transcriptId, flags);
-            CRef<CSeq_loc> pLoc( new CSeq_loc(CSeq_loc::e_Whole));
-            pLoc->SetId(*pId);
-            pFeature->SetProduct(*pLoc);
-        }
+//    it = attrs_left.find("transcript_id");
+//    if (it != attrs_left.end()) {
+//        string transcriptId = it->second;
+//        if (!pFeature->IsSetProduct()) {
+//            CRef<CSeq_id> pId = CReadUtil::AsSeqId(transcriptId, flags);
+//            CRef<CSeq_loc> pLoc( new CSeq_loc(CSeq_loc::e_Whole));
+//            pLoc->SetId(*pId);
+//            pFeature->SetProduct(*pLoc);
+//        }
         // mss-362: turn transcript_id attributes into transcript_id quailifiers.
-        xMigrateAttributeSingle(
-            attrs_left, "transcript_id", pFeature, "transcript_id", flags);
-    }
+//        xMigrateAttributeSingle(
+//            attrs_left, "transcript_id", pFeature, "transcript_id", flags);
+//    }
 
     it = attrs_left.find("transl_except");
     if (it != attrs_left.end()) {
@@ -986,8 +987,10 @@ bool CGff2Record::x_MigrateAttributes(
             NStr::Split(it->second, ",", codebreaks, NStr::eMergeDelims);
             for (vector<string>::iterator it1 = codebreaks.begin(); 
                     it1 != codebreaks.end(); ++it1 ) {
+                string breakData = xNormalizedAttributeValue(*it1);
+                CRef<CSeq_id> pBreakId = GetSeqId(flags);
                 CRef<CCode_break> pCodeBreak = s_StringToCodeBreak(
-                    xNormalizedAttributeValue(*it1), *GetSeqId(flags), flags);
+                    breakData, *pBreakId, flags);
                 if (pCodeBreak) {
                     pFeature->SetData().SetCdregion().SetCode_break().push_back(
                         pCodeBreak);
@@ -1242,7 +1245,20 @@ bool CGff2Record::xInitFeatureData(
         }
     }
 
-    CFeatListItem itemtype = SofaTypes().MapSofaTermToFeatListItem( Type());
+    //special cases:
+    if (xInitFeatureDataBond(flags, pFeature)) {
+        return true;
+    }
+    if (xInitFeatureDataNcrna(flags, pFeature)) {
+        return true;
+    }
+    if (xInitFeatureDataSpecialImp(flags, pFeature)) {
+        return true;
+    }
+
+    //regular case:
+    // use 1<->1 SOFA map.
+    CFeatListItem itemtype = SofaTypes().MapSofaTermToFeatListItem(Type());
     switch( itemtype.GetType() ) {
         default: {
             return true;
@@ -1310,7 +1326,136 @@ bool CGff2Record::xInitFeatureData(
             imp.SetKey(key);
             return true;
         }
+        case CSeqFeatData::e_Variation: {
+            CSeqFeatData::TVariation& variation = pFeature->SetData().SetVariation();
+            variation.SetData().SetUnknown();
+            //CSeqFeatData::TImp& imp = pFeature->SetData().SetImp();
+            //CSeqFeatData::ESubtype subType = 
+            //    static_cast<CSeqFeatData::ESubtype>(itemtype.GetSubtype());
+            //if (subType == CSeqFeatData::eSubtype_bad) {
+            //    if (Type() == ".") {
+            //        imp.SetKey("misc_feature");
+            //        return true;
+            //    }
+            //    imp.SetKey(Type());
+            //    return true;
+            //}
+            //const string& key = CSeqFeatData::SubtypeValueToName(
+            //    static_cast<CSeqFeatData::ESubtype>(itemtype.GetSubtype()));
+            //imp.SetKey(key);
+            return true;
+        }
+    }
+}
+
+//  ----------------------------------------------------------------------------
+bool CGff2Record::xInitFeatureDataBond(
+    int flags,
+    CRef<CSeq_feat> pFeature) const
+//  ----------------------------------------------------------------------------
+{
+    string ftype = Type();
+    if (ftype == "cross_link") {
+        pFeature->SetData().SetBond(CSeqFeatData::eBond_xlink);
+        return true;
+    }
+    if (ftype == "disulfide_bond") {
+        pFeature->SetData().SetBond(CSeqFeatData::eBond_disulfide);
+        return true;
+    }
+    return false;
+}
+
+//  ----------------------------------------------------------------------------
+bool CGff2Record::xInitFeatureDataNcrna(
+    int flags,
+    CRef<CSeq_feat> pFeature) const
+//  ----------------------------------------------------------------------------
+{
+    typedef SStaticPair<const char*, const char*>  NCRNA_ENTRY;
+    static const NCRNA_ENTRY ncRnaMap_[] = {
+        { "antisense_RNA", "antisense_RNA" },
+        { "autocatalytically_spliced_intron", "autocatalytically_spliced_intron" },
+        { "guide_RNA", "guide_RNA" },
+        { "hammerhead_ribozyme", "hammerhead_ribozyme" },
+        { "lnc_RNA", "lncRNA" },
+        { "miRNA", "miRNA" },
+        { "ncRNA", "other" },
+        { "piRNA", "piRNA" },
+        { "rasiRNA", "rasiRNA" },
+        { "ribozyme", "ribozyme" },
+        { "RNase_MRP_RNA", "RNase_MRP_RNA" },
+        { "RNase_P_RNA", "RNase_P_RNA" },
+        { "scRNA", "scRNA" },
+        { "siRNA", "siRNA" },
+        { "snoRNA", "snoRNA" },
+        { "snRNA", "snRNA" },
+        { "SRP_RNA", "SRP_RNA" },
+        { "telomerase_RNA", "telomerase_RNA" },
+        { "vault_RNA", "vault_RNA" },
+        { "Y_RNA", "Y_RNA" }
+    };
+    typedef CStaticArrayMap<string, string, PNocase> NCRNA_MAP;
+    DEFINE_STATIC_ARRAY_MAP_WITH_COPY(NCRNA_MAP, ncRnaMap, ncRnaMap_);
+
+    string ftype = Type();
+    if (ftype == "ncRNA") {
+        pFeature->SetData().SetRna().SetType(CRNA_ref::eType_ncRNA);
+        string ncrna_class;
+        if (GetAttribute("ncrna_class", ncrna_class)) {
+            pFeature->SetData().SetRna().SetExt().SetGen().SetClass(ncrna_class);
+        }
+        else {
+            pFeature->SetData().SetRna().SetExt().SetGen().SetClass("other");
+        }
+        return true;
+    }
+    NCRNA_MAP::const_iterator cit = ncRnaMap.find(ftype);
+    if (cit != ncRnaMap.end()) {
+        pFeature->SetData().SetRna().SetType(CRNA_ref::eType_ncRNA);
+        pFeature->SetData().SetRna().SetExt().SetGen().SetClass(cit->second);
+        return true;
+    }
+    return false;
+}
+
+//  ----------------------------------------------------------------------------
+bool CGff2Record::xInitFeatureDataSpecialImp(
+    int flags,
+    CRef<CSeq_feat> pFeature) const
+//  ----------------------------------------------------------------------------
+{
+    typedef SStaticPair<const char*, const char*>  REGULATORY_ENTRY;
+    static const REGULATORY_ENTRY regulatoryMap_[] = {
+        { "attenuator", "attenuator" },
+        { "boundary_element", "insulator" },
+        { "CAAT_signal", "CAAT_signal" },
+        { "enhancer", "enhancer" },
+        { "GC_rich_promoter_region", "GC_signal" },
+        { "insulator", "enhancer_blocking_element" },
+        { "locus_control_region", "locus_control_region" },
+        { "minus_10_signal", "minus_10_signal" },
+        { "minus_35_signal", "minus_35_signal" },
+        { "polyA_signal_sequence", "polyA_signal_sequence" },
+        { "promoter", "promoter" },
+        { "regulatory_region", "other" },
+        { "riboswitch", "riboswitch" },
+        { "Shine_Dalgarno_sequence", "ribosome_binding_site" },
+        { "silencer", "silencer" },
+        { "TATA_box", "TATA_box" },
+        { "terminator", "terminator" },
+    };
+    typedef CStaticArrayMap<string, string, PNocase> REGULATORY_MAP;
+    DEFINE_STATIC_ARRAY_MAP_WITH_COPY(REGULATORY_MAP, regulatoryMap, regulatoryMap_);
+
+    string ftype = Type();
+    REGULATORY_MAP::const_iterator cit = regulatoryMap.find(ftype);
+    if (cit != regulatoryMap.end()) {
+        pFeature->SetData().SetImp().SetKey("regulatory");
+        pFeature->AddQualifier("regulatory_class", cit->second);
+        return true;
     }
+    return false;
 }
 
 END_objects_SCOPE
diff --git a/c++/src/objtools/readers/gff2_reader.cpp b/c++/src/objtools/readers/gff2_reader.cpp
index 30687bf..808007d 100644
--- a/c++/src/objtools/readers/gff2_reader.cpp
+++ b/c++/src/objtools/readers/gff2_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gff2_reader.cpp 497078 2016-04-04 14:59:49Z ivanov $
+/*  $Id: gff2_reader.cpp 520682 2016-11-30 18:52:13Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -96,6 +96,10 @@
 #include <objtools/readers/gff2_data.hpp>
 #include <objtools/error_codes.hpp>
 
+#include <objects/seqalign/Product_pos.hpp>
+#include <objects/seqalign/Spliced_seg.hpp>
+#include <objects/seqalign/Seq_align_set.hpp>
+
 #include <algorithm>
 
 //#include "gff3_data.hpp"
@@ -131,7 +135,9 @@ CGff2Reader::CGff2Reader(
     const string& title):
 //  ----------------------------------------------------------------------------
     CReaderBase(iFlags, name, title),
-    m_pErrors(0)
+    m_pErrors(0),
+    mCurrentFeatureCount(0),
+    mParsingAlignment(false)
 {
 }
 
@@ -176,16 +182,26 @@ CGff2Reader::ReadSeqAnnots(
     }
 }
 
-//  ---------------------------------------------------------------------------                       
-void
-CGff2Reader::ReadSeqAnnotsNew(
-    TAnnots& annots,
+//  ----------------------------------------------------------------------------                
+CRef<CSeq_annot>
+CGff2Reader::ReadSeqAnnot(
     ILineReader& lr,
-    ILineErrorListener* pEC )
-//  ----------------------------------------------------------------------------
+    ILineErrorListener* pEC ) 
+//  ----------------------------------------------------------------------------                
 {
+    CRef<CSeq_annot> pAnnot;
+    pAnnot.Reset(new CSeq_annot);
+
+    mCurrentFeatureCount = 0;
+    mParsingAlignment = false;
+
+    map<string, list<CRef<CSeq_align>>> alignments;
+    list<string> id_list;
+   
+
     string line;
     while (xGetLine(lr, line)) {
+
         if (IsCanceled()) {
             AutoPtr<CObjReaderLineException> pErr(
                 CObjReaderLineException::Create(
@@ -194,39 +210,123 @@ CGff2Reader::ReadSeqAnnotsNew(
                 "Reader stopped by user.",
                 ILineError::eProblem_ProgressInfo));
             ProcessError(*pErr, pEC);
-            annots.clear();
-            return;
+            return pAnnot;
         }
         xReportProgress(pEC);
-
-        try {
-            if ( x_ParseStructuredCommentGff( line, m_CurrentTrackInfo ) ) {
+        if ( xParseStructuredComment(line) ) {
+            continue;
+        }
+        if (xIsTrackLine(line)) {
+            if (!mCurrentFeatureCount) {
+                xParseTrackLine(line, pEC);
                 continue;
             }
-            if ( x_ParseBrowserLineGff( line, m_CurrentBrowserInfo ) ) {
-                continue;
+            xUngetLine(lr);
+            break;
+        }
+        if (xParseBrowserLine(line, pAnnot, pEC)) {
+            continue;
+        }
+
+        if (!xIsCurrentDataType(line)) {
+            xUngetLine(lr);
+            break;
+        }
+
+        if ( CGff2Reader::IsAlignmentData(line) &&
+             x_ParseAlignmentGff(line, id_list, alignments)) {
+            continue;
+        }
+
+        if (xParseFeature(line, pAnnot, pEC)) {
+            continue;
+        }
+    }
+
+
+    if (!mCurrentFeatureCount) {
+        return CRef<CSeq_annot>();
+    }
+
+    if (!alignments.empty()) {
+        x_ProcessAlignmentsGff(id_list, alignments, pAnnot);
+    }
+
+    xPostProcessAnnot(pAnnot, pEC);
+    return pAnnot;
+}
+
+//  ---------------------------------------------------------------------------                       
+void
+CGff2Reader::ReadSeqAnnotsNew(
+    TAnnots& annots,
+    ILineReader& lr,
+    ILineErrorListener* pEC )
+//  ----------------------------------------------------------------------------
+{
+    xProgressInit(lr);
+
+    if (m_iFlags&fGenbankMode) {
+        CRef<CSeq_annot> pAnnot;
+        pAnnot.Reset(new CSeq_annot);
+
+        map<string, list<CRef<CSeq_align>>> alignments;
+        list<string> id_list;
+
+        string line;
+        while (xGetLine(lr, line)) {
+            if (IsCanceled()) {
+                AutoPtr<CObjReaderLineException> pErr(
+                    CObjReaderLineException::Create(
+                    eDiag_Info,
+                    0,
+                    "Reader stopped by user.",
+                    ILineError::eProblem_ProgressInfo));
+                ProcessError(*pErr, pEC);
+                annots.clear();
+                return;
             }
-            if ( x_ParseTrackLineGff( line, m_CurrentTrackInfo ) ) {
-                continue;
+            xReportProgress(pEC);
+
+            try {
+                if (xParseStructuredComment(line)) {
+                    continue;
+                }
+                if (x_ParseBrowserLineGff(line, m_CurrentBrowserInfo)) {
+                    continue;
+                }
+                if ( x_ParseTrackLineGff(line, m_CurrentTrackInfo)) {
+                    continue;
+                }
+
+                if ( CGff2Reader::IsAlignmentData(line) && 
+                     x_ParseAlignmentGff(line, id_list, alignments) ) {
+                    continue;
+                } 
+
+                if ( ! x_ParseDataGff(line, annots, pEC) ) {
+                    continue;
+                }
             }
-            if ( ! x_ParseDataGff(line, annots, pEC) ) {
-                continue;
+            catch( CObjReaderLineException& err ) {
+                err.SetLineNumber( m_uLineNumber );
+                ProcessError(err, pEC);
             }
         }
-        catch( CObjReaderLineException& err ) {
-            err.SetLineNumber( m_uLineNumber );
-            ProcessError(err, pEC);
-        }
+
+        if (!alignments.empty()) {
+            x_ProcessAlignmentsGff(id_list, alignments, pAnnot);
+        }        
+        return;
     }
-    for (TAnnots::iterator it = annots.begin(); it != annots.end(); ++it) {
-        try {
-            xAnnotPostProcess(*it);
-        }
-        catch(CObjReaderLineException& err) {
-            err.SetLineNumber(m_uLineNumber);
-            ProcessError(err, pEC);
-        }
+    
+    //main line code:
+    CRef<CSeq_annot> pAnnot = ReadSeqAnnot(lr, pEC);
+    while (pAnnot) {
+        annots.push_back(pAnnot);
+        pAnnot = ReadSeqAnnot(lr, pEC);
     }
+    return;
 }
 
 //  ----------------------------------------------------------------------------                
@@ -273,6 +373,44 @@ CGff2Reader::ReadObject(
 }
  
 //  ----------------------------------------------------------------------------
+void CGff2Reader::xPostProcessAnnot(
+    CRef<CSeq_annot>& pAnnot,
+    ILineErrorListener *pEC)
+//  ----------------------------------------------------------------------------
+{
+    xAddConversionInfo(pAnnot, pEC);
+    xAssignTrackData(pAnnot);
+    xAssignAnnotId(pAnnot);
+    xGenerateParentChildXrefs(pAnnot);
+}
+
+//  ----------------------------------------------------------------------------
+void CGff2Reader::xAssignAnnotId(
+    CRef<CSeq_annot>& pAnnot,
+    const string& givenId)
+//  ----------------------------------------------------------------------------
+{
+    if (givenId.empty() && pAnnot->GetData().IsAlign()) {
+        return;
+    }
+
+    string annotId(givenId);
+    if (annotId.empty()  &&  pAnnot->GetData().IsFtable()) {
+        const CSeq_annot::TData::TFtable ftable = pAnnot->GetData().GetFtable();
+        if (ftable.empty()) {
+            return;
+        }
+        const CSeq_feat& front = *ftable.front();
+        annotId = front.GetLocation().GetId()->GetSeqIdString(true);
+    }
+
+    CRef< CAnnot_id > pAnnotId(new CAnnot_id);
+    pAnnotId->SetLocal().SetStr(annotId);
+    pAnnot->SetId().push_back(pAnnotId);   
+}
+
+
+//  ----------------------------------------------------------------------------
 void CGff2Reader::x_SetTrackDataToSeqEntry(
     CRef<CSeq_entry>& entry,
     CRef<CUser_object>& trackdata,
@@ -298,9 +436,8 @@ void CGff2Reader::x_SetTrackDataToSeqEntry(
 }
 
 //  ----------------------------------------------------------------------------
-bool CGff2Reader::x_ParseStructuredCommentGff(
-    const string& strLine,
-    CRef< CAnnotdesc >& )
+bool CGff2Reader::xParseStructuredComment(
+    const string& strLine)
 //  ----------------------------------------------------------------------------
 {
     if ( ! NStr::StartsWith( strLine, "##" ) ) {
@@ -316,13 +453,341 @@ bool CGff2Reader::x_ParseDataGff(
     ILineErrorListener* pEC)
 //  ----------------------------------------------------------------------------
 {
-    if ( CGff2Reader::IsAlignmentData(strLine) ) {
-        return x_ParseAlignmentGff(strLine, annots);
+    if (CGff2Reader::IsAlignmentData(strLine)) {
+        if (m_iFlags&fGenbankMode) {
+            return true;
+        }
+        //return x_ParseAlignmentGff(strLine, annots);
+        return true;
     }
     return x_ParseFeatureGff(strLine, annots, pEC);
 }
 
 //  ----------------------------------------------------------------------------
+bool
+CGff2Reader::xParseFeature(
+    const string& line,
+    CRef<CSeq_annot>& pAnnot,
+    ILineErrorListener* pEC)
+//  ----------------------------------------------------------------------------
+{
+    if (CGff2Reader::IsAlignmentData(line)) {
+        return false;
+    }
+
+    //parse record:
+    auto_ptr<CGff2Record> pRecord(x_CreateRecord());
+    try {
+        if (!pRecord->AssignFromGff(line)) {
+			return false;
+		}
+    }
+    catch(CObjReaderLineException& err) {
+        ProcessError(err, pEC);
+        return false;
+    }
+
+    //make sure we are interested:
+    string ftype = pRecord->Type();
+    if (xIsIgnoredFeatureType(ftype)) {
+        string message = string("GFF3 feature type \"") + ftype + 
+            string("\" not supported- ignored.");
+        AutoPtr<CObjReaderLineException> pErr(
+            CObjReaderLineException::Create(
+            eDiag_Warning,
+            0,
+            message,
+            ILineError::eProblem_FeatureNameNotAllowed));
+        ProcessError(*pErr, pEC);
+        return true;
+    }
+
+    //append feature to annot:
+    if (!x_UpdateAnnotFeature(*pRecord, pAnnot, pEC)) {
+        return false;
+    }
+
+    ++mCurrentFeatureCount;
+    mParsingAlignment = false;
+    return true;
+}
+
+
+//  ----------------------------------------------------------------------------
+void CGff2Reader::x_GetAlignmentScores(const CSeq_align& alignment, 
+                                       TScoreValueMap& score_values)
+//  ----------------------------------------------------------------------------
+{
+    // Start with empty scores
+    score_values.clear();
+
+    if (!alignment.IsSetScore()) {
+        return;
+    }
+
+    for (const CRef<CScore>& score : alignment.GetScore()) {
+
+        if (!score->IsSetId() ||
+            !score->GetId().IsStr() ||
+            !score->IsSetValue()) {
+            continue;
+        }
+        const string name = score->GetId().GetStr();
+        const CScore::TValue& value = score->GetValue();
+        score_values[name] = Ref(new CScore::TValue());
+        score_values[name]->Assign(value);
+    }
+}
+
+
+//  ----------------------------------------------------------------------------
+bool s_CompareValues(const CScore::TValue& score_val1, 
+                     const CScore::TValue& score_val2)
+//  ----------------------------------------------------------------------------
+{
+
+    if (score_val1.IsInt() && 
+        score_val2.IsInt() &&
+        score_val1.GetInt() == score_val2.GetInt()) {
+        return true;
+    }
+
+    if (score_val1.IsReal() &&
+        score_val2.IsReal() &&
+        score_val1.GetReal() == score_val2.GetReal()) {
+        return true;
+    }
+
+    return false;
+}
+
+// Result is a set of matching scores
+//  ----------------------------------------------------------------------------
+void CGff2Reader::x_FindMatchingScores(const TScoreValueMap& scores_1,
+                                       const TScoreValueMap& scores_2,
+                                       set<string>& matching_scores) 
+//  ----------------------------------------------------------------------------
+{
+    matching_scores.clear();
+
+    for (const auto& score1 : scores_1) {
+        const string& name = score1.first;
+        const CScore::TValue& value = *(score1.second);
+
+        const auto& it = scores_2.find(name);
+        if (it != scores_2.end() &&
+            s_CompareValues(value, *(it->second))) {
+            matching_scores.insert(name);
+        }
+    }
+}
+
+
+//  ----------------------------------------------------------------------------
+void CGff2Reader::x_ProcessAlignmentsGff(const list<string>& id_list,
+                            const map<string, list<CRef<CSeq_align>>>& alignments,
+                            CRef<CSeq_annot> pAnnot) 
+//  ----------------------------------------------------------------------------
+{
+    if (pAnnot.IsNull()) {
+        pAnnot = Ref(new CSeq_annot());
+    }
+
+    for (const auto id : id_list) {
+        CRef<CSeq_align> pAlign = Ref(new CSeq_align());
+        if (x_MergeAlignments(alignments.at(id), pAlign)) {
+            // if available, add current browser information
+            if ( m_CurrentBrowserInfo ) {
+                pAnnot->SetDesc().Set().push_back( m_CurrentBrowserInfo );
+            }
+
+            pAnnot->SetNameDesc("alignments");
+
+            if ( !m_AnnotTitle.empty() ) {
+                pAnnot->SetTitleDesc(m_AnnotTitle);
+            }
+            // Add alignment
+            pAnnot->SetData().SetAlign().push_back(pAlign);
+        }
+    }
+}
+
+
+//  ----------------------------------------------------------------------------
+bool CGff2Reader::x_ParseAlignmentGff(
+    const string& strLine, 
+    list<string>& id_list, // Add id to alignment
+    map<string, list<CRef<CSeq_align>>>& alignments)
+//  ----------------------------------------------------------------------------
+{
+    unique_ptr<CGff2Record> pRecord(x_CreateRecord());
+    if ( !pRecord->AssignFromGff(strLine) ) {
+        return false;
+    }
+    
+    string id;
+    if ( !pRecord->GetAttribute("ID", id) ) {
+        id = pRecord->Id();
+    }
+
+    if (alignments.find(id) == alignments.end()) {
+       id_list.push_back(id);
+    }
+
+    CRef<CSeq_align> alignment;
+    if (!x_CreateAlignment(*pRecord, alignment)) {
+        return false;
+    }
+
+    alignments[id].push_back(alignment);
+
+    ++mCurrentFeatureCount;
+    mParsingAlignment = true;
+    return true;
+}
+
+
+//  ----------------------------------------------------------------------------
+bool CGff2Reader::x_MergeAlignments(
+        const list<CRef<CSeq_align>>& alignment_list,
+        CRef<CSeq_align>& processed)
+//  ----------------------------------------------------------------------------
+{
+    if (alignment_list.empty()) {
+        return false;
+    }
+
+    if (alignment_list.size() == 1) {
+        processed = alignment_list.front();
+        return true;
+    }
+
+    map<string, size_t> summed_scores;
+    const list<string> summed_score_names {"num_ident", "num_mismatch"};
+
+    // Factor out identical scores
+    list<CRef<CSeq_align>>::const_iterator align_it = alignment_list.begin();
+    TScoreValueMap score_values;
+    x_GetAlignmentScores(**align_it, score_values);
+
+
+    for (const string& score_name : summed_score_names) {
+        if (score_values.find(score_name) != score_values.end()) {
+            summed_scores[score_name] = score_values[score_name]->GetInt();
+        }
+    }
+    ++align_it;
+
+    while (align_it != alignment_list.end() &&
+           !score_values.empty()) {
+        TScoreValueMap new_score_values;
+        x_GetAlignmentScores(**align_it, new_score_values);
+
+        for (const string& score_name : summed_score_names) {
+            if (new_score_values.find(score_name) == new_score_values.end()) {
+                summed_scores.erase(score_name);
+            } else if (summed_scores.find(score_name) != summed_scores.end()) {
+                summed_scores[score_name] += new_score_values[score_name]->GetInt();
+                new_score_values.erase(score_name);
+            }
+        }
+
+        set<string> matching_scores;
+        x_FindMatchingScores(score_values, 
+                             new_score_values, 
+                             matching_scores);
+
+        score_values.clear(); 
+        for (string score_name : matching_scores) {
+            score_values[score_name] = Ref(new CScore::TValue());
+            score_values[score_name]->Assign(*new_score_values[score_name]);
+        }
+        ++align_it;
+    }
+    // At this point, the score_values map should contain the scores that 
+    // do not change over the rows
+
+
+    processed->SetType(CSeq_align::eType_disc);
+
+    for (auto& kv : summed_scores) {
+        CRef<CScore> score = Ref(new CScore());
+        score->SetId().SetStr(kv.first);
+        score->SetValue().SetInt(kv.second);
+        processed->SetScore().push_back(score);
+    }
+
+    for (auto& kv : score_values) {
+        CRef<CScore> score = Ref(new CScore());
+        score->SetId().SetStr(kv.first);
+        score->SetValue().Assign(*(kv.second));
+        processed->SetScore().push_back(score);
+    }
+
+    for (auto current : alignment_list) {
+        CRef<CSeq_align> new_align = Ref(new CSeq_align());
+        new_align->Assign(*current);
+        new_align->ResetScore();
+
+        for (CRef<CScore> score : current->GetScore()) {
+            const string& score_name = score->GetId().GetStr();
+            if (score_values.find(score_name) == score_values.end()) {
+                new_align->SetScore().push_back(score);
+            }
+        }
+        processed->SetSegs().SetDisc().Set().push_back(new_align);
+    }
+
+    return true;
+}
+
+
+//  ----------------------------------------------------------------------------
+bool
+CGff2Reader::xParseAlignment(
+    const string& line,
+    CRef<CSeq_annot>& pAnnot,
+    ILineErrorListener* pEC)
+//  ----------------------------------------------------------------------------
+{
+    if (!CGff2Reader::IsAlignmentData(line)) {
+        return false;
+    }
+
+    //parse record:
+    auto_ptr<CGff2Record> pRecord(x_CreateRecord());
+    try {
+        if ( ! pRecord->AssignFromGff(line) ) {
+            return false;
+        }
+    }
+    catch(CObjReaderLineException& err) {
+        ProcessError(err, pEC);
+        return false;
+    }
+
+    if (!x_UpdateAnnotAlignment(*pRecord, pAnnot, pEC)) {
+        return false;
+    }
+
+    ++mCurrentFeatureCount;
+    mParsingAlignment = true;
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
+bool
+CGff2Reader::xIsCurrentDataType(
+    const string& line)
+//  ----------------------------------------------------------------------------
+{
+    if (CGff2Reader::IsAlignmentData(line)) {
+        return (mParsingAlignment  ||  !mCurrentFeatureCount);
+    }
+    return (!mParsingAlignment  ||  !mCurrentFeatureCount);
+}
+
+//  ----------------------------------------------------------------------------
 bool CGff2Reader::x_ParseFeatureGff(
     const string& strLine,
     TAnnots& annots,
@@ -396,6 +861,8 @@ bool CGff2Reader::x_ParseFeatureGff(
     return true; 
 };
 
+
+
 //  ----------------------------------------------------------------------------
 bool CGff2Reader::x_ParseAlignmentGff(
     const string& strLine,
@@ -549,8 +1016,8 @@ bool CGff2Reader::x_InitAnnot(
     }
 
     // if available, add current track information
-    if ( m_CurrentTrackInfo ) {
-        pAnnot->SetDesc().Set().push_back( m_CurrentTrackInfo );
+    if (m_pTrackDefaults->ContainsData() ) {
+        m_pTrackDefaults->WriteToAnnot(*pAnnot);
     }
 
     if ( !m_AnnotName.empty() ) {
@@ -606,10 +1073,33 @@ bool CGff2Reader::x_UpdateAnnotFeature(
     return true;
 }
 
+
+bool CGff2Reader::x_CreateAlignment(
+        const CGff2Record& gff, 
+        CRef<CSeq_align>& pAlign ) 
+{
+    pAlign = Ref(new CSeq_align());
+    pAlign->SetType(CSeq_align::eType_partial);
+    pAlign->SetDim(2);
+
+    //score
+    if (!xAlignmentSetScore(gff, pAlign)) {
+        return false;
+    }
+
+    if (!xAlignmentSetSegment(gff, pAlign)) {
+        return false;
+    }
+
+    return true;
+}
+
+
 //  ----------------------------------------------------------------------------
 bool CGff2Reader::x_UpdateAnnotAlignment(
     const CGff2Record& gff,
-    CRef< CSeq_annot > pAnnot )
+    CRef< CSeq_annot > pAnnot,
+    ILineErrorListener* pEC)
 //  ----------------------------------------------------------------------------
 {
     CRef<CSeq_align> pAlign( new CSeq_align );
@@ -627,48 +1117,150 @@ bool CGff2Reader::x_UpdateAnnotAlignment(
     return true;
 }
 
+
+
+bool CGff2Reader::xUpdateSplicedAlignment(const CGff2Record& gff,
+                                          CRef<CSeq_align> pAlign) const
+{
+    if (!pAlign->IsSetType()) {
+        pAlign->SetType(CSeq_align::eType_partial);
+    }
+    // Need to set a whole bunch of things
+
+    if (!xUpdateSplicedSegment(gff, pAlign->SetSegs().SetSpliced())) {
+        return false;
+    }
+
+    return true;
+}
+
+
+
+bool CGff2Reader::xUpdateSplicedSegment(
+        const CGff2Record& gff, 
+        CSpliced_seg& segment) const
+{
+    if (segment.IsSetProduct_type()) {
+        segment.SetProduct_type(CSpliced_seg::eProduct_type_transcript);
+    }
+    
+
+    CRef<CSpliced_exon> pExon = Ref(new CSpliced_exon());
+    if (!xSetSplicedExon(gff, pExon)) {
+        return false;
+    }
+
+   segment.SetExons().push_back(pExon);
+
+    return true;
+}
+
+
+
 //  ----------------------------------------------------------------------------
-bool CGff2Reader::xAlignmentSetSegment(
-    const CGff2Record& gff,
-    CRef<CSeq_align> pAlign)
+bool CGff2Reader::xSetSplicedExon(
+        const CGff2Record& gff, 
+        CRef<CSpliced_exon> pExon) const
 //  ----------------------------------------------------------------------------
 {
-    string targetInfo;
     vector<string> targetParts;
+    if (!xGetTargetParts(gff, targetParts)) {
+        return false;
+    }
+
+
+    pExon->SetGenomic_start(gff.SeqStart()-1);
+    pExon->SetGenomic_end(gff.SeqStop()-1);
+    if (gff.IsSetStrand()) {
+        pExon->SetGenomic_strand(gff.Strand());
+    }
+
+
+    const int product_start = NStr::StringToInt(targetParts[1])-1;
+    const int product_end = NStr::StringToInt(targetParts[2])-1;
+
+    // Check to see that product start and product end are
+    // non-negative and that product_end >= product_start
+
+    pExon->SetProduct_start().SetNucpos(product_start);
+    pExon->SetProduct_end().SetNucpos(product_end);
+
+    ENa_strand targetStrand = eNa_strand_plus;
+    if (targetParts[3] == "-") {
+        targetStrand = eNa_strand_minus;
+    }
+    pExon->SetProduct_strand(targetStrand);
+
+    return true;
+}
+
+
+//  ----------------------------------------------------------------------------
+bool CGff2Reader::xGetTargetParts(const CGff2Record& gff, vector<string>& targetParts) const
+//  ----------------------------------------------------------------------------
+{
+    string targetInfo;
     if (!gff.GetAttribute("Target", targetInfo)) {
         return false;
     }
+
     NStr::Split(targetInfo, " ", targetParts);
     if (targetParts.size() != 4) {
         return false;
     }
-    
-    string gapInfo;
-    vector<string> gapParts;
-    if (gff.GetAttribute("Gap", gapInfo)) {
-        NStr::Split(gapInfo, " ", gapParts);
-    }
-    else {
-        gapParts.push_back(string("M") + NStr::NumericToString(gff.SeqStop()-gff.SeqStart()+1));
-    }
-    int gapCount = gapParts.size();
+   
+    return true;
+}
 
-    //meta
-    CSeq_align::TSegs& segs = pAlign->SetSegs();
-    CSeq_align::C_Segs::TDenseg& denseg = segs.SetDenseg();
-    denseg.SetDim(2);
-    denseg.SetNumseg(gapCount);
+//  ----------------------------------------------------------------------------
+bool CGff2Reader::xSetDensegStarts(const vector<string>& gapParts, 
+                                   const bool oppositeStrands,
+                                   const size_t targetStart,
+                                   const CGff2Record& gff,
+                                   CSeq_align::C_Segs::TDenseg& denseg)
+//  ----------------------------------------------------------------------------
+{
 
-    //ids
-    denseg.SetIds().push_back(
-        CReadUtil::AsSeqId(targetParts[0]));
-    denseg.SetIds().push_back(
-        CReadUtil::AsSeqId(gff.Id()));
+    size_t targetOffset = targetStart;
+    const size_t gapCount = gapParts.size();
+    // Gap attribute is always given with respect to the target 
+    // strand. 
+    // The reference start values depend on the relative strandedness.
+    // The target start values do not.
+    if (oppositeStrands) {
+        size_t identOffset = gff.SeqStop();
+        for (size_t i=0; i<gapCount; ++i) {
+            char changeType = gapParts[i][0];
+            int changeSize = NStr::StringToInt(gapParts[i].substr(1));
+            switch (changeType) {
+            default:
+                return false;
+            case 'M': 
+                denseg.SetStarts().push_back(targetOffset);
+                denseg.SetStarts().push_back(identOffset+1-changeSize);
+                targetOffset += changeSize;
+                identOffset -= changeSize;
+                break;
+
+            case 'I':
+                denseg.SetStarts().push_back(targetOffset);
+                denseg.SetStarts().push_back(-1);
+                targetOffset += changeSize;
+                break;
+
+            case 'D':
+                denseg.SetStarts().push_back(-1);
+                denseg.SetStarts().push_back(identOffset+1-changeSize);
+                identOffset -= changeSize;
+                break;
+            }
+        }
+        return true;
+    }
 
-    //starts
-    size_t targetOffset = 0;
+    // No difference in strandedness
     size_t identOffset = gff.SeqStart();
-    for (int i=0; i < gapCount; ++i) {
+    for (size_t i=0; i < gapCount; ++i) {
         char changeType = gapParts[i][0];
         int changeSize = NStr::StringToInt(gapParts[i].substr(1));
         switch (changeType) {
@@ -692,10 +1284,22 @@ bool CGff2Reader::xAlignmentSetSegment(
             break;
         }
     }
-    //lengths
-    for (int i=0; i < gapCount; ++i) {
-        denseg.SetLens().push_back(NStr::StringToInt(CTempString(gapParts[i],1,string::npos)));
+
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
+bool CGff2Reader::xAlignmentSetSegment(
+    const CGff2Record& gff,
+    CRef<CSeq_align> pAlign)
+//  ----------------------------------------------------------------------------
+{
+
+    vector<string> targetParts;
+    if (!xGetTargetParts(gff, targetParts)) {
+        return false;
     }
+
     //strands
     ENa_strand targetStrand = eNa_strand_plus;
     if (targetParts[3] == "-") {
@@ -705,6 +1309,48 @@ bool CGff2Reader::xAlignmentSetSegment(
     if (gff.IsSetStrand()) {
         identStrand = gff.Strand();
     }
+
+
+    string gapInfo;
+    vector<string> gapParts;
+    if (gff.GetAttribute("Gap", gapInfo)) {
+        NStr::Split(gapInfo, " ", gapParts);
+    }
+    else {
+        gapParts.push_back(string("M") + NStr::NumericToString(gff.SeqStop()-gff.SeqStart()+1));
+    }
+
+    bool oppositeStrands = (targetStrand != identStrand);
+
+    int gapCount = gapParts.size();
+
+    //meta
+    CSeq_align::TSegs& segs = pAlign->SetSegs();
+    CSeq_align::C_Segs::TDenseg& denseg = segs.SetDenseg();
+    denseg.SetDim(2);
+    denseg.SetNumseg(gapCount);
+
+    //ids
+    denseg.SetIds().push_back(
+        CReadUtil::AsSeqId(targetParts[0]));
+    denseg.SetIds().push_back(
+        CReadUtil::AsSeqId(gff.Id()));
+
+    size_t targetOffset = NStr::StringToInt(targetParts[1])-1;
+
+    if (!xSetDensegStarts(gapParts, 
+                          oppositeStrands,
+                          targetOffset,
+                          gff,
+                          denseg)) {
+        return false;
+    }
+
+    //lengths
+    for (int i=0; i < gapCount; ++i) {
+        denseg.SetLens().push_back(NStr::StringToInt(CTempString(gapParts[i],1,string::npos)));
+    }
+
     for (int i=0; i < gapCount; ++i) {
         denseg.SetStrands().push_back(targetStrand);
         denseg.SetStrands().push_back(identStrand);
@@ -742,6 +1388,8 @@ bool CGff2Reader::xAlignmentSetScore(
         "merge_aligner",
         "rank",
         "reciprocity",
+        "batch_id",
+        "align_id",
     };
 
     const size_t intCount(sizeof(intScores)/sizeof(string));
@@ -765,6 +1413,8 @@ bool CGff2Reader::xAlignmentSetScore(
         "pct_coverage_hiqual",
 
         //picked up from real data files
+        "inversion_merge_alignmer",
+        "expansion",
     };
 
     const size_t realCount(sizeof(realScores)/sizeof(string));
@@ -826,7 +1476,6 @@ bool CGff2Reader::x_FeatureTrimQualifiers(
 //  ----------------------------------------------------------------------------
 {
     typedef CSeq_feat::TQual TQual;
-    typedef CGff2Record::TAttributes TAttrs;
     //task:
     // for each attribute of the new piece check if we already got a feature 
     //  qualifier
@@ -847,6 +1496,14 @@ bool CGff2Reader::x_FeatureTrimQualifiers(
             it++;
             continue;
         }
+        if (qualKey == "product") {
+            it++;
+            continue;
+        }
+        if (qualKey == "protein_id") {
+            it++;
+            continue;
+        }
         const string& qualVal = (*it)->GetVal();
         string attrVal;
         if (!record.GetAttribute(qualKey, attrVal)) {
@@ -1101,7 +1758,7 @@ bool CGff2Reader::xAddFeatureToAnnot(
 {
     if (IsExon(pFeature)) {
         CRef< CSeq_feat > pParent;    
-        if (!x_GetParentFeature(*pFeature, pParent) ) {
+        if (!xGetParentFeature(*pFeature, pParent) ) {
             pAnnot->SetData().SetFtable().push_back(pFeature) ;
             return true;
         }
@@ -1141,7 +1798,7 @@ bool CGff2Reader::xGetExistingFeature(
 }
 
 //  ----------------------------------------------------------------------------
-bool CGff2Reader::x_GetParentFeature(
+bool CGff2Reader::xGetParentFeature(
     const CSeq_feat& feature,
     CRef< CSeq_feat >& pParent )
 //  ----------------------------------------------------------------------------
@@ -1252,7 +1909,7 @@ bool CGff2Reader::xGenerateParentChildXrefs(
     typedef list<CRef<CSeq_feat> > FTABLE;
     typedef list<string> PARENTS;
 
-    if (!(m_iFlags & CGff2Reader::fGenbankMode)) {
+    if (!pAnnot->IsFtable()) {
         return true;
     }
     FTABLE& ftable = pAnnot->SetData().SetFtable();
@@ -1362,7 +2019,8 @@ bool CGff2Reader::IsAlignmentData(
     if (columns.size() < 9) {
         return false;
     }
-    if (NStr::StartsWith(columns[2], "match")) {
+    if (NStr::StartsWith(columns[2], "match") || 
+        NStr::EndsWith(columns[2], "_match")) {
         return true;
     }
     return false;
diff --git a/c++/src/objtools/readers/gff3_reader.cpp b/c++/src/objtools/readers/gff3_reader.cpp
index 2155acc..fcdb4dc 100644
--- a/c++/src/objtools/readers/gff3_reader.cpp
+++ b/c++/src/objtools/readers/gff3_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gff3_reader.cpp 497078 2016-04-04 14:59:49Z ivanov $
+/*  $Id: gff3_reader.cpp 520685 2016-11-30 18:53:22Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -111,6 +111,46 @@ string CGff3Reader::xNextGenericId()
 }
 
 //  ----------------------------------------------------------------------------
+bool CGff3ReadRecord::AssignFromGff(
+    const string& strRawInput )
+//  ----------------------------------------------------------------------------
+{
+    if (!CGff2Record::AssignFromGff(strRawInput)) {
+        return false;
+    }
+    if (m_strType == "pseudogene") {
+        m_strType = "gene";
+        m_Attributes["pseudo"] = "true";
+        return true;
+    }
+    if (m_strType == "pseudogenic_transcript") {
+        m_strType = "transcript";
+        m_Attributes["pseudo"] = "true";
+        return true;
+    }        
+    if (m_strType == "pseudogenic_tRNA") {
+        m_strType = "tRNA";
+        m_Attributes["pseudo"] = "true";
+        return true;
+    }
+    if (m_strType == "pseudogenic_rRNA") {
+        m_strType = "rRNA";
+        m_Attributes["pseudo"] = "true";
+        return true;
+    }
+    if (m_strType == "pseudogenic_exon") {
+        m_strType = "exon";
+        return true;
+    }
+    if (m_strType == "pseudogenic_CDS") {
+        m_strType = "CDS";
+        m_Attributes["pseudo"] = "true";
+        return true;
+    }
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
 string CGff3ReadRecord::x_NormalizedAttributeKey(
     const string& strRawKey )
 //  ---------------------------------------------------------------------------
@@ -215,7 +255,7 @@ bool CGff3Reader::x_UpdateAnnotFeature(
 }
 
 //  ----------------------------------------------------------------------------
-void CGff3Reader::xVerifyExonLocation(
+bool CGff3Reader::xVerifyExonLocation(
     const string& mrnaId,
     const CGff2Record& exon,
     ILineErrorListener* pEC)
@@ -223,36 +263,25 @@ void CGff3Reader::xVerifyExonLocation(
 {
     map<string,CRef<CSeq_interval> >::const_iterator cit = mMrnaLocs.find(mrnaId);
     if (cit == mMrnaLocs.end()) {
-        AutoPtr<CObjReaderLineException> pErr(
-            CObjReaderLineException::Create(
-            eDiag_Error,
-            0,
-            "Bad data line: Exon record referring to non-existing mRNA parent.",
-            ILineError::eProblem_FeatureBadStartAndOrStop));
-        ProcessError(*pErr, pEC);
-        return; // can not continue without cit being valid, regardless of ProcessError() 
+        return false;
     }
     const CSeq_interval& containingInt = cit->second.GetObject();
     const CRef<CSeq_loc> pContainedLoc = exon.GetSeqLoc(m_iFlags);
     const CSeq_interval& containedInt = pContainedLoc->GetInt();
-    bool failed = (containedInt.GetFrom() < containingInt.GetFrom())  ||
-        (containedInt.GetTo() > containingInt.GetTo());
-    if (failed) {
-        AutoPtr<CObjReaderLineException> pErr(
-            CObjReaderLineException::Create(
-            eDiag_Error,
-            0,
-            "Bad data line: Exon record that lies outside its parent location.",
-            ILineError::eProblem_FeatureBadStartAndOrStop));
-        ProcessError(*pErr, pEC);
+    if (containedInt.GetFrom() < containingInt.GetFrom()) {
+        return false;
+    }
+    if (containedInt.GetTo() > containingInt.GetTo()) {
+        return false;
     }
+    return true;
 }
 
 //  ----------------------------------------------------------------------------
 bool CGff3Reader::xUpdateAnnotExon(
     const CGff2Record& record,
-    CRef<CSeq_feat>,
-    CRef<CSeq_annot>,
+    CRef<CSeq_feat> pFeature,
+    CRef<CSeq_annot> pAnnot,
     ILineErrorListener* pEC)
 //  ----------------------------------------------------------------------------
 {
@@ -261,10 +290,32 @@ bool CGff3Reader::xUpdateAnnotExon(
         for (list<string>::const_iterator it = parents.begin(); it != parents.end(); 
                 ++it) {
             const string& parentId = *it; 
-            xVerifyExonLocation(parentId, record, pEC);
+            if (!xVerifyExonLocation(parentId, record, pEC)) {
+                //create a free agent "exon" feature
+                if (!record.InitializeFeature(m_iFlags, pFeature)) {
+                    return false;
+                }
+                CRef<CSeq_feat> pParent;
+                if (!xGetParentFeature(*pFeature, pParent)  ||  
+                        !pParent->GetData().IsGene()) {
+                    AutoPtr<CObjReaderLineException> pErr(
+                        CObjReaderLineException::Create(
+                        eDiag_Error,
+                        0,
+                        "Bad data line: Exon record referring to non-existing mRNA or gene parent.",
+                        ILineError::eProblem_FeatureBadStartAndOrStop));
+                    ProcessError(*pErr, pEC);
+                    return false;
+                }
+                if (! xAddFeatureToAnnot(pFeature, pAnnot)) {
+                    return false;
+                }
+                return true;
+            }
             IdToFeatureMap::iterator fit = m_MapIdToFeature.find(parentId);
             if (fit != m_MapIdToFeature.end()) {
-                if (!record.UpdateFeature(m_iFlags, fit->second)) {
+                CRef<CSeq_feat> pParent = fit->second;
+                if (!record.UpdateFeature(m_iFlags, pParent)) {
                     return false;
                 }
             }
@@ -273,6 +324,7 @@ bool CGff3Reader::xUpdateAnnotExon(
     return true;
 }
 
+
 //  ----------------------------------------------------------------------------
 bool CGff3Reader::xUpdateAnnotCds(
     const CGff2Record& record,
@@ -324,14 +376,23 @@ bool CGff3Reader::xUpdateAnnotCds(
         //update parent location:
         IdToFeatureMap::iterator featIt = m_MapIdToFeature.find(parentId);
         if (featIt != m_MapIdToFeature.end()) {
-            if (!record.UpdateFeature(m_iFlags, featIt->second)) {
+            CRef<CSeq_feat> pParent = featIt->second;
+            if (!record.UpdateFeature(m_iFlags, pParent)) {
                 return false;
             }
+            //rw-143:
+            // if parent type is miscRNA then change it to mRNA:
+            if (pParent->GetData().IsRna()  &&  
+                    pParent->GetData().GetRna().GetType()  ==  CRNA_ref::eType_other) {
+                pParent->SetData().SetRna().SetType(CRNA_ref::eType_mRNA);
+            }
         }
 
         //generate applicable CDS ID:
-        string siblingId("cds:");
-        siblingId += parentId;
+        string siblingId("cds");
+        if (!record.GetAttribute("ID", siblingId)  ||  IsInGenbankMode()) {
+            siblingId = string("cds:") + parentId;
+        }
         impliedCdsFeats[siblingId] = parentId;
     }
     // deal with unparented cds
@@ -469,11 +530,25 @@ bool CGff3Reader::xUpdateAnnotGeneric(
     if (featType == "stop_codon_read_through"  ||  featType == "selenocysteine") {
         string cdsParent;
         if (!record.GetAttribute("Parent", cdsParent)) {
-            cerr << "BAD!" << endl;
+            AutoPtr<CObjReaderLineException> pErr(
+                CObjReaderLineException::Create(
+                eDiag_Error,
+                0,
+                "Bad data line: Unassigned code break.",
+                ILineError::eProblem_GeneralParsingError) );
+            ProcessError(*pErr, pEC);
+            return false;
         }
         IdToFeatureMap::iterator it = m_MapIdToFeature.find(cdsParent);
         if (it == m_MapIdToFeature.end()) {
-            cerr << "BAD!" << endl;
+            AutoPtr<CObjReaderLineException> pErr(
+                CObjReaderLineException::Create(
+                eDiag_Error,
+                0,
+                "Bad data line: Code break assigned to missing feature.",
+                ILineError::eProblem_GeneralParsingError) );
+            ProcessError(*pErr, pEC);
+            return false;
         }
 
         CRef<CCode_break> pCodeBreak(new CCode_break); 
@@ -487,8 +562,6 @@ bool CGff3Reader::xUpdateAnnotGeneric(
         }
         pCodeBreak->SetAa().SetNcbieaa(
             (featType == "selenocysteine") ? 'U' : 'X');
-
-
         CRef<CSeq_feat> pCds = it->second;
         CCdregion& cdRegion = pCds->SetData().SetCdregion();
         list< CRef< CCode_break > >& codeBreaks = cdRegion.SetCode_break();
@@ -627,40 +700,22 @@ bool CGff3Reader::xReadInit()
 
 //  ----------------------------------------------------------------------------
 bool CGff3Reader::xIsIgnoredFeatureType(
-    const string& ftype)
+    const string& featureType)
 //  ----------------------------------------------------------------------------
 {
-    vector<string>::const_iterator cit;
-
-    static vector<string> ignoredTypesAlways;
-    if (ignoredTypesAlways.empty()) {
-        ignoredTypesAlways.push_back("protein");
-    }
-    static vector<string> ignoredTypesGenbank;
-    if (ignoredTypesGenbank.empty()) {
-        ignoredTypesGenbank.push_back("replicon");
-        ignoredTypesGenbank.push_back("chromosome");
-        ignoredTypesGenbank.push_back("dna_chromosome");
-        ignoredTypesGenbank.push_back("rna_chromosome");
-        ignoredTypesGenbank.push_back("apicoplast_chromosome");
-        ignoredTypesGenbank.push_back("chloroplast_chromosome");
-        ignoredTypesGenbank.push_back("chromoplast_chromosome");
-        ignoredTypesGenbank.push_back("cyanelle_chromosome");
-        ignoredTypesGenbank.push_back("leucoplast_chromosome");
-        ignoredTypesGenbank.push_back("macronuclear_chromosome");
-        ignoredTypesGenbank.push_back("micronuclear_chromosome");
-        ignoredTypesGenbank.push_back("mitochondrial_chromosome");
-        ignoredTypesGenbank.push_back("nuclear_chromosome");
-        ignoredTypesGenbank.push_back("nucleomorphic_chromosome");
-        ignoredTypesGenbank.push_back("contig");
-        ignoredTypesGenbank.push_back("supercontig");
-        ignoredTypesGenbank.push_back("ultracontig");
-        ignoredTypesGenbank.push_back("partial_genomic_sequence_assembly");
-        ignoredTypesGenbank.push_back("sequence_assembly");
-        ignoredTypesGenbank.push_back("assembly");
-    }
-
-    cit = std::find(ignoredTypesAlways.begin(), ignoredTypesAlways.end(), ftype);
+    typedef CStaticArraySet<string, PNocase> STRINGARRAY;
+
+    string ftype(featureType);
+    NStr::ToLower(ftype);
+    if (SofaTypes().IsStringSofaAlias(ftype)) {
+        ftype = SofaTypes().MapSofaAliasToSofaTerm(ftype);
+    }
+
+    static const char* const ignoredTypesAlways_[] = {
+        "protein"
+    };
+    DEFINE_STATIC_ARRAY_MAP(STRINGARRAY, ignoredTypesAlways, ignoredTypesAlways_);    
+    STRINGARRAY::const_iterator cit = ignoredTypesAlways.find(ftype);
     if (cit != ignoredTypesAlways.end()) {
         return true;
     }
@@ -669,10 +724,75 @@ bool CGff3Reader::xIsIgnoredFeatureType(
     }
 
     /* -genbank mode:*/
-    cit = std::find(ignoredTypesGenbank.begin(), ignoredTypesGenbank.end(), ftype);
+    static const char* const specialTypesGenbank_[] = {
+        "antisense_RNA",
+        "autocatalytically_spliced_intron",
+        "guide_RNA",
+        "hammerhead_ribozyme",
+        "lnc_RNA",
+        "miRNA",
+        "piRNA",
+        "rasiRNA",
+        "ribozyme",
+        "RNase_MRP_RNA",
+        "RNase_P_RNA",
+        "scRNA",
+        "selenocysteine",
+        "siRNA",
+        "snoRNA",
+        "snRNA",
+        "SRP_RNA",
+        "stop_codon_read_through",
+        "telomerase_RNA",
+        "vault_RNA",
+        "Y_RNA"
+    };
+    DEFINE_STATIC_ARRAY_MAP(STRINGARRAY, specialTypesGenbank, specialTypesGenbank_);    
+
+    static const char* const ignoredTypesGenbank_[] = {
+        "apicoplast_chromosome",
+        "assembly",
+        "cDNA_match",
+        "chloroplast_chromosome",
+        "chromoplast_chromosome",
+        "chromosome",
+        "contig",
+        "cyanelle_chromosome",
+        "dna_chromosome",
+        "EST_match",
+        "expressed_sequence_match",
+        "intron",
+        "leucoplast_chromosome",
+        "macronuclear_chromosome",
+        "match",
+        "match_part",
+        "micronuclear_chromosome",
+        "mitochondrial_chromosome",
+        "nuclear_chromosome",
+        "nucleomorphic_chromosome",
+        "nucleotide_motif",
+        "nucleotide_to_protein_match",
+        "partial_genomic_sequence_assembly",
+        "protein_match",
+        "replicon",
+        "rna_chromosome",
+        "sequence_assembly",
+        "supercontig",
+        "translated_nucleotide_match",
+        "ultracontig",
+    };
+    DEFINE_STATIC_ARRAY_MAP(STRINGARRAY, ignoredTypesGenbank, ignoredTypesGenbank_);    
+
+    cit = specialTypesGenbank.find(ftype);
+    if (cit != specialTypesGenbank.end()) {
+        return false;
+    }
+
+    cit = ignoredTypesGenbank.find(ftype);
     if (cit != ignoredTypesGenbank.end()) {
         return true;
     }
+
     CSeqFeatData::ESubtype iGenbankType = SofaTypes().MapSofaTermToGenbankType(ftype);
     if (iGenbankType == CSeqFeatData::eSubtype_bad) {
         return true;
diff --git a/c++/src/objtools/readers/gff3_sofa.cpp b/c++/src/objtools/readers/gff3_sofa.cpp
index b3061c6..e130ef3 100644
--- a/c++/src/objtools/readers/gff3_sofa.cpp
+++ b/c++/src/objtools/readers/gff3_sofa.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gff3_sofa.cpp 496421 2016-03-28 15:14:58Z ivanov $
+/*  $Id: gff3_sofa.cpp 520685 2016-11-30 18:53:22Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -42,8 +42,11 @@ BEGIN_NCBI_SCOPE
 
 BEGIN_objects_SCOPE // namespace ncbi::objects::
 
+#define GT( a, b ) CFeatListItem( CSeqFeatData::a, CSeqFeatData::b, "", "" )
+
 //  --------------------------------------------------------------------------
 CSafeStatic<TLookupSofaToGenbank> CGff3SofaTypes::m_Lookup;
+CSafeStatic<TAliasToTerm> CGff3SofaTypes::m_Aliases;
 //  --------------------------------------------------------------------------
 
 //  --------------------------------------------------------------------------
@@ -68,6 +71,13 @@ CGff3SofaTypes::CGff3SofaTypes()
     for (SOFAITER cit = entries.begin(); cit != entries.end(); ++cit) {
         lookup[cit->second.m_name] = cit->first;
     }
+    //overrides:
+    lookup["primary_transcript"] = GT(e_Imp, eSubtype_preRNA);
+    lookup["sequence_alteration"] = GT(e_Variation, eSubtype_variation_ref);
+    lookup["signal_peptide"] = GT(e_Imp, eSubtype_sig_peptide);
+
+    TAliasToTerm& aliases = *m_Aliases;
+    aliases["satellite"] = "satellite_DNA";
 };
 
 //  --------------------------------------------------------------------------
@@ -101,5 +111,27 @@ CFeatListItem CGff3SofaTypes::MapSofaTermToFeatListItem(
     return cit->second;
 }
 
+//  ---------------------------------------------------------------------------
+bool CGff3SofaTypes::IsStringSofaAlias(
+    const string& str)
+//  ---------------------------------------------------------------------------
+{
+    return (m_Aliases->find(str) != m_Aliases->end());
+}
+
+//  ---------------------------------------------------------------------------
+string CGff3SofaTypes::MapSofaAliasToSofaTerm(
+    const string& alias)
+//  ---------------------------------------------------------------------------
+{
+    TAliasToTermCit cit = m_Aliases->find(alias);
+    if (cit == m_Aliases->end()) {
+        return "";
+    }
+    return cit->second;
+}
+
+#undef GT
+
 END_objects_SCOPE
 END_NCBI_SCOPE
diff --git a/c++/src/objtools/readers/gff_reader.cpp b/c++/src/objtools/readers/gff_reader.cpp
index db0b855..c881351 100644
--- a/c++/src/objtools/readers/gff_reader.cpp
+++ b/c++/src/objtools/readers/gff_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gff_reader.cpp 493622 2016-03-01 13:41:45Z ivanov $
+/*  $Id: gff_reader.cpp 491626 2016-02-08 14:58:45Z ludwigf $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/readers/gtf_reader.cpp b/c++/src/objtools/readers/gtf_reader.cpp
index 334475f..3587959 100644
--- a/c++/src/objtools/readers/gtf_reader.cpp
+++ b/c++/src/objtools/readers/gtf_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: gtf_reader.cpp 497078 2016-04-04 14:59:49Z ivanov $
+/*  $Id: gtf_reader.cpp 515629 2016-10-04 17:46:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -236,10 +236,13 @@ CGtfReader::ReadSeqAnnots(
         }
         xReportProgress(pEC);
         try {
+            if (xIsTrackTerminator(line)) {
+                continue;
+            }
             if (x_ParseBrowserLineGff(line, m_CurrentBrowserInfo)) {
                 continue;
             }
-            if (x_ParseTrackLineGff(line, m_CurrentTrackInfo)) {
+            if (xParseTrackLine(line, pEC)) {
                 continue;
             }
             if (x_ParseFeatureGff(line, annots, pEC)) {
@@ -840,7 +843,7 @@ bool CGtfReader::x_CreateParentGene(
     if ( ! x_CreateFeatureId( gff, "gene", pFeature ) ) {
         return false;
     }
-    if ( ! x_FeatureSetQualifiers( gff, pFeature ) ) {
+    if ( ! xFeatureSetQualifiersGene( gff, pFeature ) ) {
         return false;
     }
     m_GeneMap[ s_GeneKey( gff ) ] = pFeature;
@@ -861,6 +864,37 @@ bool CGtfReader::x_MergeParentGene(
     return true;
 }
 
+//  ----------------------------------------------------------------------------
+bool CGtfReader::xFeatureSetQualifiersGene(
+    const CGff2Record& record,
+    CRef< CSeq_feat > pFeature )
+//  ----------------------------------------------------------------------------
+{
+    //
+    //  Create GB qualifiers for the record attributes:
+    //
+    CRef< CGb_qual > pQual(0);
+    const CGff2Record::TAttributes& attrs = record.Attributes();
+    CGff2Record::TAttrCit it = attrs.begin();
+    for (/*NOOP*/; it != attrs.end(); ++it) {
+        // gtf genes don't get transcript_id
+        if (it->first == "transcript_id") {
+            continue;
+        }
+        // special case some well-known attributes
+        if (x_ProcessQualifierSpecialCase(it, pFeature)) {
+            continue;
+        }
+
+        // turn everything else into a qualifier
+        pQual.Reset(new CGb_qual);
+        pQual->SetQual(it->first);
+        pQual->SetVal(it->second);
+        pFeature->SetQual().push_back(pQual);
+    } 
+    return true;
+}
+
 //  -----------------------------------------------------------------------------
 bool CGtfReader::x_CreateParentCds(
     const CGff2Record& gff,
@@ -1020,10 +1054,6 @@ bool CGtfReader::x_FeatureSetDataMRNA(
     if (record.GetAttribute("product", strValue)) {
         rna.SetExt().SetName(strValue);
     }
-    if (record.GetAttribute("transcript_id", strValue)) {
-        pFeature->SetProduct().SetWhole(
-            *CReadUtil::AsSeqId(strValue, m_iFlags & fAllIdsAsLocal));
-    }
 
     return true;
 }
@@ -1039,21 +1069,17 @@ bool CGtfReader::x_FeatureSetDataCDS(
     }
 
     CCdregion& cdr = pFeature->SetData().SetCdregion();
-
     string strValue;
     if ( record.GetAttribute( "protein_id", strValue ) ) {
-        pFeature->SetProduct().SetWhole(
-            *CReadUtil::AsSeqId(strValue,m_iFlags));
+        CRef<CSeq_id> pId = CReadUtil::AsSeqId(strValue,m_iFlags);
+        if (pId->IsGenbank()) {
+            pFeature->SetProduct().SetWhole(*pId);
+        }
     }
     if ( record.GetAttribute( "ribosomal_slippage", strValue ) ) {
         pFeature->SetExcept( true );
         pFeature->SetExcept_text( "ribosomal slippage" );
     }
-    if ( record.GetAttribute( "product", strValue ) ) {
-        CRef< CSeqFeatXref > pXref( new CSeqFeatXref );
-        pXref->SetData().SetProt().SetName().push_back( strValue );
-        pFeature->SetXref().push_back( pXref );
-    }
     if ( record.GetAttribute( "transl_table", strValue ) ) {
         CRef< CGenetic_code::C_E > pGc( new CGenetic_code::C_E );
         pGc->SetId( NStr::StringToUInt( strValue ) );
@@ -1063,79 +1089,6 @@ bool CGtfReader::x_FeatureSetDataCDS(
 }
 
 //  ----------------------------------------------------------------------------
-bool CGtfReader::x_FeatureSetQualifiers(
-    const CGff2Record& record,
-    CRef< CSeq_feat > pFeature)
-//  ----------------------------------------------------------------------------
-{
-    if (this->m_iFlags & fGenbankMode) {
-        // mss-399: Strip gene_id and transcript_id qualifiers in their 
-        //  entirety.
-        return CGff2Reader::x_FeatureSetQualifiers(record, pFeature);
-    }
-    else {
-        // mss-399: Keep gene_id and transcript_id as qualifiers without any 
-        //  further processing
-        return CGff2Reader::x_FeatureSetQualifiers(record, pFeature);
-    }
-}
-
-//  ----------------------------------------------------------------------------
-bool CGtfReader::x_SkipAttribute(
-    const CGff2Record& record,
-    const string& strKey ) const
-//  ----------------------------------------------------------------------------
-{
-    if ( strKey == "exon_number" ) {
-        return true;
-    }
-
-    if ( record.Type() == "CDS" ) {
-        if ( strKey == "protein_id" ) {
-            return true;
-        }
-        if ( strKey == "ribosomal_slippage" ) {
-            return true;
-        }
-        if ( strKey == "product" ) {
-            return true;
-        }
-        if ( strKey == "transl_table" ) {
-            return true;
-        }
-        if ( strKey == "gene_id" ) {
-            return true;
-        }
-        if ( strKey == "transcript_id" ) { // ! implied by parent mRNA
-            return true;
-        }
-    }
-
-    if ( record.Type() == "exon" ) {
-        if ( strKey == "product" ) {
-            return true;
-        }
-        if ( strKey == "gene_id" ) {
-            return true;
-        }
-        if ( strKey == "transcript_id" ) {
-            return true;
-        }
-    }
-
-    if ( record.Type() == "gene" ) {
-        if ( strKey == "gene_synonym" ) {
-            return true;
-        }
-        if ( strKey == "gene_id" ) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-//  ----------------------------------------------------------------------------
 bool CGtfReader::x_CdsIsPartial(
     const CGff2Record& record )
 //  ----------------------------------------------------------------------------
@@ -1192,35 +1145,10 @@ bool CGtfReader::x_ProcessQualifierSpecialCase(
         pFeature->SetPartial( true );
         return true;
     }
-    if (0 == NStr::CompareNocase(it->first, "gene_id")) {
-        if (m_iFlags | fGenbankMode) {
-            // mss-399:
-            //  in genbank mode, drop gene_id altogether
-            return true;
-        }
-        else {
-            // mss-399:
-            //  in regular mode, retain gene_id as a qualifier but do nothing
-            //  else with it.
-            return false;
-        }
-    }
-    if (0 == NStr::CompareNocase(it->first, "transcript_id")) {
-        if (m_iFlags | fGenbankMode) {
-            // mss-399:
-            //  in genbank mode, drop transcript_id altogether
-            return true;
-        }
-        else {
-            // mss-399:
-            //  in regular mode, retain transcript_id as a qualifier but do 
-            //  nothing else with it.
-            return false;
-        }
-    }
-    //if (0 == NStr::CompareNocase(it->first, "transcript_id") &&
-    //    pFeature->GetData().IsGene()) {
-    //    return true;
+    //if (0 == NStr::CompareNocase(it->first, "protein_id")) {
+    //    if (pFeature->IsSetProduct()) {
+    //        return true;
+    //    }
     //}
 
     return false;
diff --git a/c++/src/objtools/readers/gvf_reader.cpp b/c++/src/objtools/readers/gvf_reader.cpp
index 7d24ae0..e08048e 100644
--- a/c++/src/objtools/readers/gvf_reader.cpp
+++ b/c++/src/objtools/readers/gvf_reader.cpp
@@ -1,4 +1,4 @@
- /*  $Id: gvf_reader.cpp 489339 2016-01-12 15:46:54Z ludwigf $
+ /*  $Id: gvf_reader.cpp 515629 2016-10-04 17:46:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -89,6 +89,7 @@
 
 #include <objtools/readers/read_util.hpp>
 #include <objtools/readers/reader_exception.hpp>
+#include <objtools/readers/track_data.hpp>
 #include <objtools/readers/line_error.hpp>
 #include <objtools/readers/message_listener.hpp>
 #include <objtools/readers/gff3_sofa.hpp>
@@ -131,6 +132,21 @@ bool CGvfReadRecord::AssignFromGff(
         return false;
     }
     // GVF specific fixup goes here ...
+    TAttrIt idIt = m_Attributes.find("ID");
+    if (idIt == m_Attributes.end()) {
+        string errMessage(
+            "Required attribute ID missing. Import aborted.");
+        xTraceError(eDiag_Critical, errMessage);
+        return false;
+    }
+    TAttrIt variantSeqIt = m_Attributes.find("Variant_seq");
+    TAttrIt referenceSeqIt = m_Attributes.find("Reference_seq");
+    if (variantSeqIt == m_Attributes.end()  ||  referenceSeqIt == m_Attributes.end()) {
+        string errMessage(
+            "Required attribute Reference_seq and/or Variant_seq missing. Import aborted.");
+        xTraceError(eDiag_Critical, errMessage);
+        return false;
+    }
     return true;
 }
 
@@ -190,7 +206,7 @@ void CGvfReadRecord::xTraceError(
         severity,
         mLineNumber,
         msg) );
-    if (!mpMessageListener->PutError(*pErr)) {
+    if (!mpMessageListener  ||  !mpMessageListener->PutError(*pErr)) {
         pErr->Throw();
     }
 }
@@ -212,25 +228,37 @@ CGvfReader::~CGvfReader()
 }
 
 //  ----------------------------------------------------------------------------
-bool CGvfReader::x_ParseFeatureGff(
-    const string& strLine,
-    TAnnots& annots,
-    ILineErrorListener* pMessageListener)
+bool
+CGvfReader::xParseFeature(
+    const string& line,
+    CRef<CSeq_annot>& pAnnot,
+    ILineErrorListener* pEC)
 //  ----------------------------------------------------------------------------
 {
-    //
-    //  Parse the record and determine which ID the given feature will pertain 
-    //  to:
-    //
     CGvfReadRecord record(m_uLineNumber);
-    if ( ! record.AssignFromGff( strLine ) ) {
+    if (!record.AssignFromGff(line)) {
+        return false;
+    }
+    if (!x_MergeRecord(record, pAnnot, pEC)) {
         return false;
     }
+    ++mCurrentFeatureCount;
+    return true;
+}
 
-    CRef<CSeq_annot> pAnnot = x_GetAnnotById( annots, record.Id() );
-    return x_MergeRecord( record, pAnnot, pMessageListener );
-//    return x_UpdateAnnot( record, pAnnot ); 
-};
+//  ----------------------------------------------------------------------------
+void CGvfReader::xPostProcessAnnot(
+    CRef<CSeq_annot>& pAnnot,
+    ILineErrorListener *pEC)
+//  ----------------------------------------------------------------------------
+{
+    xAddConversionInfo(pAnnot, pEC);
+    xAssignTrackData(pAnnot);
+    xAssignAnnotId(pAnnot);
+    if (m_Pragmas) {
+        pAnnot->SetDesc().Set().push_back(m_Pragmas);
+    }
+}
 
 //  ----------------------------------------------------------------------------
 CRef<CSeq_annot> CGvfReader::x_GetAnnotById(
@@ -268,8 +296,8 @@ CRef<CSeq_annot> CGvfReader::x_GetAnnotById(
     }
 
     // if available, add current track information
-    if ( m_CurrentTrackInfo ) {
-        pNewAnnot->SetDesc().Set().push_back( m_CurrentTrackInfo );
+    if (m_pTrackDefaults->ContainsData()) {
+        xAssignTrackData(pNewAnnot);
     }
 
     if ( !m_AnnotName.empty() ) {
@@ -324,6 +352,214 @@ bool CGvfReader::x_FeatureSetLocation(
     }
 }
 
+
+//  ----------------------------------------------------------------------------
+bool CGvfReader::x_SetLocation(
+        const CGff2Record& record, 
+        CRef<CSeq_loc> pLocation)
+//  ----------------------------------------------------------------------------
+{
+
+    if (record.SeqStart() < record.SeqStop()) {
+        return x_SetLocationInterval(record, pLocation);
+    }
+    else { // record.SeqStart() == record.SeqStop()
+        return x_SetLocationPoint(record, pLocation);
+    }
+}
+
+
+
+//  ----------------------------------------------------------------------------
+bool CGvfReader::x_SetLocationInterval(
+    const CGff2Record& record,
+    CRef<CSeq_loc> pLocation)
+//  ----------------------------------------------------------------------------
+{
+    CRef< CSeq_id > pId = CReadUtil::AsSeqId(record.Id(), m_iFlags);
+
+    pLocation->SetInt().SetId(*pId);
+    pLocation->SetInt().SetFrom(record.SeqStart());
+    pLocation->SetInt().SetTo(record.SeqStop());
+    if (record.IsSetStrand()) {
+        pLocation->SetInt().SetStrand( record.Strand() );
+    }
+
+
+    //  deal with fuzzy range indicators / lower end:
+    string strRange;
+    list<string> range_borders;
+    size_t lower, upper;
+    if (record.GetAttribute( "Start_range", strRange ) )
+    {
+        NStr::Split( strRange, ",", range_borders, 0 );
+        if ( range_borders.size() != 2 ) {
+            AutoPtr<CObjReaderLineException> pErr(
+                CObjReaderLineException::Create(
+                eDiag_Error,
+                0,
+                string("CGvfReader::x_SetLocation: Bad \"Start_range\" attribute") +
+                    " (Start_range=" + strRange + ").",
+                ILineError::eProblem_QualifierBadValue) );
+        pErr->Throw();
+        }
+        try {
+            if ( range_borders.back() == "." ) {
+                lower = upper = NStr::StringToUInt( range_borders.front() );
+                pLocation->SetInt().SetFuzz_from().SetLim( CInt_fuzz::eLim_gt );
+            }
+            else if ( range_borders.front() == "." ) { 
+                lower = upper = NStr::StringToUInt( range_borders.back() );
+                pLocation->SetInt().SetFuzz_from().SetLim( CInt_fuzz::eLim_lt );
+            }
+            else {
+                lower = NStr::StringToUInt( range_borders.front() );
+                upper = NStr::StringToUInt( range_borders.back() );
+                pLocation->SetInt().SetFuzz_from().SetRange().SetMin( lower-1 );
+                pLocation->SetInt().SetFuzz_from().SetRange().SetMax( upper-1 );
+            }        
+        }
+        catch ( std::exception& ) {
+            AutoPtr<CObjReaderLineException> pErr(
+                CObjReaderLineException::Create(
+                eDiag_Error,
+                0,
+                string("CGvfReader::x_SetLocation: Bad \"Start_range\" attribute") +
+                    " (Start_range=" + strRange + ").",
+                ILineError::eProblem_QualifierBadValue) );
+        pErr->Throw();
+        }
+    }
+
+    //  deal with fuzzy range indicators / upper end:
+    range_borders.clear();
+    if (record.GetAttribute( "End_range", strRange ) )
+    {
+        NStr::Split( strRange, ",", range_borders, 0 );
+        if ( range_borders.size() != 2 ) {
+            AutoPtr<CObjReaderLineException> pErr(
+                CObjReaderLineException::Create(
+                eDiag_Error,
+                0,
+                string("CGvfReader::x_SetLocation: Bad \"End_range\" attribute") +
+                    " (End_range=" + strRange + ").",
+                ILineError::eProblem_QualifierBadValue) );
+        pErr->Throw();
+        }
+        try {
+            if ( range_borders.back() == "." ) {
+                lower = upper = NStr::StringToUInt( range_borders.front() );
+                pLocation->SetInt().SetFuzz_to().SetLim( CInt_fuzz::eLim_gt );
+            }
+            else if ( range_borders.front() == "." ) { 
+                lower = upper = NStr::StringToUInt( range_borders.back() );
+                pLocation->SetInt().SetFuzz_to().SetLim( CInt_fuzz::eLim_lt );
+            }
+            else {
+                lower = NStr::StringToUInt( range_borders.front() );
+                upper = NStr::StringToUInt( range_borders.back() );
+                pLocation->SetInt().SetFuzz_to().SetRange().SetMin( lower-1 );
+                pLocation->SetInt().SetFuzz_to().SetRange().SetMax( upper-1 );
+            }        
+        }
+        catch (std::exception&) {
+            AutoPtr<CObjReaderLineException> pErr(
+                CObjReaderLineException::Create(
+                eDiag_Error,
+                0,
+                string("CGvfReader::x_SetLocation: Bad \"End_range\" attribute") +
+                    " (End_range=" + strRange + ").",
+                ILineError::eProblem_QualifierBadValue) );
+pErr->Throw();
+        }
+    }
+
+    return true;
+}
+
+
+//  ----------------------------------------------------------------------------
+bool CGvfReader::x_SetLocationPoint(
+    const CGff2Record& record,
+    CRef<CSeq_loc> pLocation)
+//  ----------------------------------------------------------------------------
+{
+    CRef< CSeq_id > pId = CReadUtil::AsSeqId(record.Id(), m_iFlags);
+    pLocation->SetPnt().SetId(*pId);
+    if (record.Type() == "insertion") {
+        //for insertions, GVF uses insert-after logic while NCBI uses insert-before
+        pLocation->SetPnt().SetPoint(record.SeqStart()+1);
+    }
+    else {
+        pLocation->SetPnt().SetPoint(record.SeqStart());
+    }
+    if (record.IsSetStrand()) {
+        pLocation->SetStrand(record.Strand());
+    }
+
+    string strRangeLower, strRangeUpper;
+    bool hasLower = record.GetAttribute("Start_range", strRangeLower);
+    bool hasUpper = record.GetAttribute("End_range", strRangeUpper);
+    if (hasLower  &&  hasUpper  &&  strRangeLower != strRangeUpper) {
+        AutoPtr<CObjReaderLineException> pErr(
+            CObjReaderLineException::Create(
+            eDiag_Error,
+            0,
+            string("CGvfReader::x_SetLocation: Bad range attribute:") +
+                " Conflicting fuzz ranges for single point location.",
+            ILineError::eProblem_QualifierBadValue) );
+    pErr->Throw();
+    }
+    if (!hasLower  &&  !hasUpper) {
+        return true;
+    }
+    if (!hasLower) {
+        strRangeLower = strRangeUpper;
+    }
+
+    list<string> bounds;
+    size_t lower, upper;
+    NStr::Split( strRangeLower, ",", bounds, 0 );
+    if (bounds.size() != 2) {
+        AutoPtr<CObjReaderLineException> pErr(
+            CObjReaderLineException::Create(
+            eDiag_Error,
+            0,
+            string("CGvfReader::x_SetLocation: Bad \"XXX_range\" attribute") +
+                " (XXX_range=" + strRangeLower + ").",
+            ILineError::eProblem_QualifierBadValue) );
+pErr->Throw();
+    }
+    try {
+        if (bounds.back() == ".") {
+            lower = upper = NStr::StringToUInt(bounds.front());
+            pLocation->SetPnt().SetFuzz().SetLim(CInt_fuzz::eLim_gt);
+        }
+        else if (bounds.front() == ".") { 
+            lower = upper = NStr::StringToUInt(bounds.back());
+            pLocation->SetPnt().SetFuzz().SetLim( CInt_fuzz::eLim_lt );
+        }
+        else {
+            lower = NStr::StringToUInt(bounds.front());
+            upper = NStr::StringToUInt(bounds.back());
+            pLocation->SetPnt().SetFuzz().SetRange().SetMin(lower-1);
+            pLocation->SetPnt().SetFuzz().SetRange().SetMax(upper-1);
+        }        
+    }
+    catch ( ... ) {
+        AutoPtr<CObjReaderLineException> pErr(
+            CObjReaderLineException::Create(
+            eDiag_Error,
+            0,
+            string("CGvfReader::x_SetLocation: Bad \"XXX_range\" attribute") +
+                " (XXX_range=" + strRangeLower + ").",
+            ILineError::eProblem_QualifierBadValue) );
+pErr->Throw();
+    }
+    return true;
+}
+
+
 //  ----------------------------------------------------------------------------
 bool CGvfReader::xFeatureSetLocationInterval(
     const CGff2Record& record,
@@ -516,6 +752,25 @@ pErr->Throw();
 }
 
 //  ----------------------------------------------------------------------------
+bool CGvfReader::x_IsDbvarCall(const string& nameAttr) const
+//  ----------------------------------------------------------------------------
+{
+    return (nameAttr.find("ssv") != string::npos);
+}
+
+//  ----------------------------------------------------------------------------
+bool CGvfReader::x_GetNameAttribute(const CGvfReadRecord& record, string& name) const
+//  ----------------------------------------------------------------------------
+{
+    if ( record.GetAttribute( "Name", name ) ) {
+        return true;
+    }
+
+    return false;
+}
+
+
+//  ----------------------------------------------------------------------------
 bool CGvfReader::x_FeatureSetVariation(
     const CGvfReadRecord& record,
     CRef< CSeq_feat > pFeature )
@@ -525,21 +780,75 @@ bool CGvfReader::x_FeatureSetVariation(
     string strType = record.Type();
     NStr::ToLower( strType );
 
+    string nameAttr;
+    x_GetNameAttribute(record, nameAttr);
+
     if ( strType == "snv" ) {
         if (!xVariationMakeSNV( record, pVariation )) {
             return false;
         }
     }
-    else if (strType == "insertion") {
+    else if (strType == "insertion" || 
+             strType == "alu_insertion" ||
+             strType == "line1_insertion" || 
+             strType == "sva_insertion" ||
+             strType == "mobile_element_insertion" ||
+             strType == "mobile_sequence_insertion" || 
+             strType == "novel_sequence_insertion") {
         if (!xVariationMakeInsertions( record, pVariation )) {
             return false;
         }
     }
-    else if (strType == "deletion") {
+    else if (strType == "deletion" || 
+             strType == "alu_deletion" || 
+             strType == "line1_deletion" ||
+             strType == "sva_deletion" || 
+             strType == "herv_deletion" ||
+             (strType == "mobile_element_deletion" && 
+              x_IsDbvarCall(nameAttr))) {
         if (!xVariationMakeDeletions( record, pVariation )) {
             return false;
         }
     }
+    else if (strType == "indel") {
+        if (!xVariationMakeIndels( record, pVariation )) {
+            return false;
+        }
+    }
+    else if (strType == "inversion") {
+        if (!xVariationMakeInversions( record, pVariation )) {
+            return false;
+        }
+
+    }
+    else if (strType == "tandem_duplication") {
+        if (!xVariationMakeEversions( record, pVariation )) {
+            return false;
+        }
+    }
+    else if (strType == "translocation" ||
+             strType == "interchromosomal_translocation" ||
+             strType == "intrachromosomal_translocation") {
+
+        if (!xVariationMakeTranslocations( record, pVariation )) {
+            return false;
+        }
+    }
+    else if (strType == "complex" ||
+             strType == "complex_substitution" ||
+             strType == "complex_chromosomal_rearrangement" ||
+             strType == "complex_sequence_alteration") { 
+        if (!xVariationMakeComplex( record, pVariation )){
+            return false;
+        }
+    }
+    else if (strType == "unknown" ||
+             strType == "other" ||
+             strType == "sequence_alteration") {
+        if (!xVariationMakeUnknown( record, pVariation )){
+            return false;
+        }
+    }
     else {
         if (!xVariationMakeCNV( record, pVariation )) {
             return false;
@@ -553,12 +862,11 @@ bool CGvfReader::x_FeatureSetVariation(
 }
   
 //  ----------------------------------------------------------------------------
-bool CGvfReader::x_ParseStructuredCommentGff(
-    const string& strLine,
-    CRef< CAnnotdesc >& pAnnotDesc )
+bool CGvfReader::xParseStructuredComment(
+    const string& strLine)
 //  ----------------------------------------------------------------------------
 {
-    if ( !CGff2Reader::x_ParseStructuredCommentGff( strLine, pAnnotDesc ) ) {
+    if ( !CGff2Reader::xParseStructuredComment( strLine) ) {
         return false;
     }
     if ( ! m_Pragmas ) {
@@ -634,7 +942,6 @@ bool CGvfReader::xVariationSetInsertions(
                pAllele );
         }
     }
-//    pVariation->SetInsertion();
     return true;
 }
 
@@ -655,19 +962,27 @@ bool CGvfReader::xVariationMakeCNV(
         return false;
     }
 
+    string nameAttr;
+    x_GetNameAttribute(record, nameAttr);
+
     string strType = record.Type();
     NStr::ToLower( strType );
-    if ( strType == "cnv" || strType == "copy_number_variation" ) {
+    if ( strType == "cnv" || 
+        strType == "copy_number_variation" ) {
         pVariation->SetCNV();
         return true;
     }
-    if ( strType == "gain" || strType == "copy_number_gain" ) {
+    if ( strType == "gain" || 
+         strType == "copy_number_gain" ||
+         strType == "duplication" ) {
         pVariation->SetGain();
         return true;
     }
-    if ( strType == "loss" || strType == "copy_number_loss" ) {
+    if ( strType == "loss" || 
+         strType == "copy_number_loss" ||
+         (strType == "mobile_element_deletion" && !x_IsDbvarCall(nameAttr)) ) {
         pVariation->SetLoss();
-        return pVariation;
+        return true;
     }
     if ( strType == "loss_of_heterozygosity" ) {
         pVariation->SetLoss();
@@ -677,20 +992,7 @@ bool CGvfReader::xVariationMakeCNV(
         pVariation->SetConsequence().push_back( pConsequence );
         return true;
     }
-    if ( strType == "complex"  || strType == "complex_substitution"  ||
-        strType == "complex_sequence_alteration" ) {
-        pVariation->SetComplex();
-        return true;
-    }
-    if ( strType == "inversion" ) {
-        //pVariation->SetInversion( feature.GetLocation() );
-        return false;
-    }
-    if ( strType == "unknown" || strType == "other" || 
-        strType == "sequence_alteration" ) {
-        pVariation->SetUnknown();
-        return true;
-    }
+
     AutoPtr<CObjReaderLineException> pErr(
         CObjReaderLineException::Create(
         eDiag_Error,
@@ -700,11 +1002,12 @@ bool CGvfReader::xVariationMakeCNV(
 pErr->Throw();
     return false;
 }
-  
+
+
 //  ----------------------------------------------------------------------------
-bool CGvfReader::xVariationMakeSNV(
-    const CGvfReadRecord& record,
-    CRef<CVariation_ref> pVariation)
+bool CGvfReader::xVariationSetCommon(
+        const CGvfReadRecord& record,
+        CRef<CVariation_ref> pVariation)
 //  ----------------------------------------------------------------------------
 {
     pVariation->SetData().SetSet().SetType( 
@@ -722,66 +1025,164 @@ bool CGvfReader::xVariationMakeSNV(
     if ( ! xVariationSetProperties( record, pVariation ) ) {
         return false;
     }
-    if ( ! xVariationSetSnvs( record, pVariation ) ) {
+
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
+bool CGvfReader::xVariationMakeInversions(
+    const CGvfReadRecord& record,
+    CRef<CVariation_ref> pVariation)
+//  ----------------------------------------------------------------------------
+{
+    if ( ! xVariationSetCommon( record, pVariation ) ) {
         return false;
     }
+
+    CRef<CSeq_loc> null = Ref(new CSeq_loc());
+    null->SetNull();
+
+    pVariation->SetInversion(*null);
+   
     return true;
 }
 
+
 //  ----------------------------------------------------------------------------
-bool CGvfReader::xVariationMakeInsertions(
+bool CGvfReader::xVariationMakeEversions(
     const CGvfReadRecord& record,
-    CRef<CVariation_ref> pVariation )
+    CRef<CVariation_ref> pVariation)
 //  ----------------------------------------------------------------------------
 {
-    pVariation->SetData().SetSet().SetType( 
-        CVariation_ref::C_Data::C_Set::eData_set_type_package );
+    if ( ! xVariationSetCommon( record, pVariation ) ) {
+        return false;
+    }
 
-    if ( ! xVariationSetId( record, pVariation ) ) {
+    CRef<CSeq_loc> null = Ref(new CSeq_loc());
+    null->SetNull();
+
+    pVariation->SetEversion(*null);
+   
+    return true;
+}
+
+
+//  ----------------------------------------------------------------------------
+bool CGvfReader::xVariationMakeTranslocations(
+    const CGvfReadRecord& record,
+    CRef<CVariation_ref> pVariation)
+//  ----------------------------------------------------------------------------
+{
+    if ( ! xVariationSetCommon( record, pVariation ) ) {
         return false;
     }
-    if ( ! xVariationSetParent( record, pVariation ) ) {
+
+    CRef<CSeq_loc> null = Ref(new CSeq_loc());
+    null->SetNull();
+
+    pVariation->SetTranslocation(*null);
+   
+    return true;
+}
+
+
+//  ----------------------------------------------------------------------------
+bool CGvfReader::xVariationMakeComplex(
+    const CGvfReadRecord& record,
+    CRef<CVariation_ref> pVariation)
+//  ----------------------------------------------------------------------------
+{
+    if ( ! xVariationSetCommon( record, pVariation ) ) {
         return false;
     }
-    if ( ! xVariationSetName( record, pVariation ) ) {
+
+    pVariation->SetComplex();
+   
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
+bool CGvfReader::xVariationMakeUnknown(
+    const CGvfReadRecord& record,
+    CRef<CVariation_ref> pVariation)
+//  ----------------------------------------------------------------------------
+{
+    if ( ! xVariationSetCommon( record, pVariation ) ) {
         return false;
     }
-    if ( ! xVariationSetProperties( record, pVariation ) ) {
+
+    pVariation->SetUnknown();
+   
+    return true;
+}
+
+
+//  ----------------------------------------------------------------------------
+bool CGvfReader::xVariationMakeSNV(
+    const CGvfReadRecord& record,
+    CRef<CVariation_ref> pVariation)
+//  ----------------------------------------------------------------------------
+{
+    if ( ! xVariationSetCommon( record, pVariation ) ) {
         return false;
     }
-    if ( ! xVariationSetInsertions( record, pVariation ) ) {
+
+    if ( ! xVariationSetSnvs( record, pVariation ) ) {
         return false;
     }
     return true;
 }
 
 //  ----------------------------------------------------------------------------
-bool CGvfReader::xVariationMakeDeletions(
+bool CGvfReader::xVariationMakeInsertions(
     const CGvfReadRecord& record,
     CRef<CVariation_ref> pVariation )
 //  ----------------------------------------------------------------------------
 {
-    pVariation->SetData().SetSet().SetType( 
-        CVariation_ref::C_Data::C_Set::eData_set_type_package );
 
-    if ( ! xVariationSetId( record, pVariation ) ) {
+    if ( ! xVariationSetCommon( record, pVariation ) ) {
         return false;
     }
-    if ( ! xVariationSetParent( record, pVariation ) ) {
+
+    if ( ! xVariationSetInsertions( record, pVariation ) ) {
         return false;
     }
-    if ( ! xVariationSetName( record, pVariation ) ) {
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
+bool CGvfReader::xVariationMakeDeletions(
+    const CGvfReadRecord& record,
+    CRef<CVariation_ref> pVariation )
+//  ----------------------------------------------------------------------------
+{
+    if ( ! xVariationSetCommon( record, pVariation ) ) {
         return false;
     }
-    if ( ! xVariationSetProperties( record, pVariation ) ) {
+
+    if ( ! xVariationSetDeletions( record, pVariation ) ) {
         return false;
     }
-    if ( ! xVariationSetDeletions( record, pVariation ) ) {
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
+bool CGvfReader::xVariationMakeIndels(
+    const CGvfReadRecord& record,
+    CRef<CVariation_ref> pVariation )
+//  ----------------------------------------------------------------------------
+{
+    if ( ! xVariationSetCommon( record, pVariation ) ) {
         return false;
     }
+
+    pVariation->SetDeletionInsertion("", CVariation_ref::eSeqType_na);
+    pVariation->SetData().SetInstance().SetType(CVariation_inst::eType_delins);
+
     return true;
 }
 
+
 //  ---------------------------------------------------------------------------
 bool CGvfReader::xVariationSetId(
     const CGvfReadRecord& record,
@@ -810,6 +1211,7 @@ bool CGvfReader::xVariationSetParent(
     return true;
 }
 
+
 //  ---------------------------------------------------------------------------
 bool CGvfReader::xVariationSetName(
     const CGvfReadRecord& record,
@@ -862,56 +1264,59 @@ bool CGvfReader::xVariationSetDeletions(
 {
     string strReference;
     CRef<CVariation_ref> pReference(new CVariation_ref);
-    if (record.GetAttribute("Reference_seq", strReference)) {
-        pReference->SetData().SetInstance().SetType(
-            CVariation_inst::eType_identity);
-        CRef<CDelta_item> pDelta(new CDelta_item);
-        pDelta->SetSeq().SetLiteral().SetLength(strReference.size());
-        pDelta->SetSeq().SetLiteral().SetSeq_data().SetIupacna().Set(
-            strReference);
-        pReference->SetData().SetInstance().SetDelta().push_back(pDelta);
-        pReference->SetData().SetInstance().SetObservation(
-            CVariation_inst::eObservation_asserted);
-        pVariation->SetData().SetSet().SetVariations().push_back(
-            pReference );
+    if (!record.GetAttribute("Reference_seq", strReference)) {
+        return false;
     }
+    pReference->SetData().SetInstance().SetType(
+        CVariation_inst::eType_identity);
+    CRef<CDelta_item> pDelta(new CDelta_item);
+    pDelta->SetSeq().SetLiteral().SetLength(strReference.size());
+    pDelta->SetSeq().SetLiteral().SetSeq_data().SetIupacna().Set(
+        strReference);
+    pReference->SetData().SetInstance().SetDelta().push_back(pDelta);
+    pReference->SetData().SetInstance().SetObservation(
+        CVariation_inst::eObservation_asserted);
+    pVariation->SetData().SetSet().SetVariations().push_back(
+        pReference );
+
     string strAlleles;
-    if ( record.GetAttribute( "Variant_seq", strAlleles ) ) {
-        list<string> alleles;
-        NStr::Split( strAlleles, ",", alleles, 0 );
-        alleles.sort();
-        alleles.unique();
-        for ( list<string>::const_iterator cit = alleles.begin(); 
-            cit != alleles.end(); ++cit )
-        {
-            string allele(*cit); 
-            if (allele == strReference) {
-                pReference->SetVariant_prop().SetAllele_state(
-                    (alleles.size() == 1) ?
-                        CVariantProperties::eAllele_state_homozygous :
-                        CVariantProperties::eAllele_state_heterozygous);
-                pReference->SetData().SetInstance().SetObservation(
-                    CVariation_inst::eObservation_asserted |
-                    CVariation_inst::eObservation_variant);
-                continue;
-            }
-            CRef<CVariation_ref> pAllele(new CVariation_ref);
-            pAllele->SetVariant_prop().SetAllele_state(
+    if (!record.GetAttribute( "Variant_seq", strAlleles)) {
+        return false;
+    }
+    list<string> alleles;
+    NStr::Split( strAlleles, ",", alleles, 0 );
+    alleles.sort();
+    alleles.unique();
+    for ( list<string>::const_iterator cit = alleles.begin(); 
+        cit != alleles.end(); ++cit )
+    {
+        string allele(*cit); 
+        if (allele == strReference) {
+            pReference->SetVariant_prop().SetAllele_state(
                 (alleles.size() == 1) ?
-                CVariantProperties::eAllele_state_homozygous :
-                CVariantProperties::eAllele_state_heterozygous);
-            CRef<CDelta_item> pDelta(new CDelta_item);
-            pDelta->SetSeq().SetThis();
-            pDelta->SetAction(CDelta_item::eAction_del_at);
-            pAllele->SetData().SetInstance().SetDelta().push_back(pDelta);
+                    CVariantProperties::eAllele_state_homozygous :
+                    CVariantProperties::eAllele_state_heterozygous);
+            pReference->SetData().SetInstance().SetObservation(
+                CVariation_inst::eObservation_asserted |
+                CVariation_inst::eObservation_variant);
+            continue;
+        }
+        CRef<CVariation_ref> pAllele(new CVariation_ref);
+        pAllele->SetVariant_prop().SetAllele_state(
+            (alleles.size() == 1) ?
+            CVariantProperties::eAllele_state_homozygous :
+            CVariantProperties::eAllele_state_heterozygous);
+        CRef<CDelta_item> pDelta(new CDelta_item);
+        pDelta->SetSeq().SetThis();
+        pDelta->SetAction(CDelta_item::eAction_del_at);
+        pAllele->SetData().SetInstance().SetDelta().push_back(pDelta);
 
-            pAllele->SetData().SetInstance().SetType(CVariation_inst::eType_del);
-            pAllele->SetData().SetInstance().SetObservation( 
-                CVariation_inst::eObservation_variant );
+        pAllele->SetData().SetInstance().SetType(CVariation_inst::eType_del);
+        pAllele->SetData().SetInstance().SetObservation( 
+            CVariation_inst::eObservation_variant );
             
-            pVariation->SetData().SetSet().SetVariations().push_back(
-               pAllele );
-        }
+        pVariation->SetData().SetSet().SetVariations().push_back(
+            pAllele );
     }
     return true;
 }
diff --git a/c++/src/objtools/readers/idmapper_config.cpp b/c++/src/objtools/readers/idmapper_config.cpp
index 31b28a3..945fb93 100644
--- a/c++/src/objtools/readers/idmapper_config.cpp
+++ b/c++/src/objtools/readers/idmapper_config.cpp
@@ -1,4 +1,4 @@
-/*  $Id: idmapper_config.cpp 486243 2015-12-02 16:47:28Z grichenk $
+/*  $Id: idmapper_config.cpp 501592 2016-05-17 15:27:30Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -188,7 +188,7 @@ CIdMapperConfig::SetCurrentContext(
 //  ============================================================================
 {
     vector<string> columns;
-    NStr::Tokenize( strLine, " \t[]|:", columns, NStr::fSplit_MergeDelimiters);
+    NStr::Split( strLine, " \t[]|:", columns, NStr::fSplit_MergeDelimiters);
     
     //sanity check: only a single columns remaining
     if ( columns.size() != 1 ) {
@@ -205,7 +205,7 @@ CIdMapperConfig::AddMapEntry(
 //  ============================================================================
 {
     vector<string> columns;
-    NStr::Tokenize( strLine, " \t", columns, NStr::eMergeDelims );
+    NStr::Split(strLine, " \t", columns, NStr::fSplit_MergeDelims);
     
     //sanity check: two or three columns. If three columns, the last better be
     //integer
diff --git a/c++/src/objtools/readers/microarray_reader.cpp b/c++/src/objtools/readers/microarray_reader.cpp
index d6fa9a2..5c9e8c2 100644
--- a/c++/src/objtools/readers/microarray_reader.cpp
+++ b/c++/src/objtools/readers/microarray_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: microarray_reader.cpp 493622 2016-03-01 13:41:45Z ivanov $
+/*  $Id: microarray_reader.cpp 515629 2016-10-04 17:46:33Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -349,54 +349,6 @@ bool CMicroArrayReader::xParseTrackLine(
     
     return true;
 }
-//  ----------------------------------------------------------------------------
-void CMicroArrayReader::xSetTrackData(
-    CRef<CSeq_annot>& annot,
-    CRef<CUser_object>& trackdata,
-    const string& strKey,
-    const string& strValue )
-//  ----------------------------------------------------------------------------
-{
-    CAnnot_descr& desc = annot->SetDesc();
-
-    if (strKey == "useScore") {
-        m_usescore = (1 == NStr::StringToInt(strValue));
-        trackdata->AddField(strKey, NStr::StringToInt(strValue));
-        return;
-    }
-    if (strKey == "name") {
-        CRef<CAnnotdesc> name(new CAnnotdesc());
-        name->SetName(strValue);
-        desc.Set().push_back(name);
-        return;
-    }
-    if (strKey == "description") {
-        CRef<CAnnotdesc> title(new CAnnotdesc());
-        title->SetTitle(strValue);
-        desc.Set().push_back(title);
-        return;
-    }
-    if (strKey == "visibility") {
-        trackdata->AddField(strKey, NStr::StringToInt(strValue));
-        return;
-    }
-    if (strKey == "expNames") {
-        trackdata->AddField(strKey, strValue);
-        m_strExpNames = strValue;
-        return;
-    }
-    if (strKey == "expScale") {
-        trackdata->AddField(strKey, NStr::StringToInt(strValue));
-        m_iExpScale = NStr::StringToInt(strValue);
-        return;
-    }
-    if (strKey == "expStep") {
-        trackdata->AddField(strKey, NStr::StringToInt(strValue));
-        m_iExpStep = NStr::StringToInt(strValue);
-        return;
-    }
-    CReaderBase::xSetTrackData(annot, trackdata, strKey, strValue);
-}
 
 //  ----------------------------------------------------------------------------
 void
diff --git a/c++/src/objtools/readers/read_util.cpp b/c++/src/objtools/readers/read_util.cpp
index f89400a..e409ee1 100644
--- a/c++/src/objtools/readers/read_util.cpp
+++ b/c++/src/objtools/readers/read_util.cpp
@@ -1,4 +1,4 @@
-/*  $Id: read_util.cpp 496064 2016-03-23 15:33:38Z ivanov $
+/*  $Id: read_util.cpp 494824 2016-03-10 19:12:03Z ludwigf $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/objtools/readers/reader_base.cpp b/c++/src/objtools/readers/reader_base.cpp
index d9382bb..a23916c 100644
--- a/c++/src/objtools/readers/reader_base.cpp
+++ b/c++/src/objtools/readers/reader_base.cpp
@@ -1,4 +1,4 @@
-/*  $Id: reader_base.cpp 493622 2016-03-01 13:41:45Z ivanov $
+/*  $Id: reader_base.cpp 515630 2016-10-04 17:46:56Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -84,6 +84,7 @@
 #include <objtools/readers/reader_exception.hpp>
 #include <objtools/readers/line_error.hpp>
 #include <objtools/readers/message_listener.hpp>
+#include <objtools/readers/track_data.hpp>
 #include <objtools/readers/reader_base.hpp>
 #include <objtools/readers/bed_reader.hpp>
 #include <objtools/readers/microarray_reader.hpp>
@@ -437,29 +438,7 @@ void CReaderBase::xAssignTrackData(
     if (!m_AnnotTitle.empty()) {
         annot->SetTitleDesc(m_AnnotTitle);
     }
-    if (!m_pTrackDefaults->ContainsData()) {
-        return;
-    }
-    CAnnot_descr& desc = annot->SetDesc();
-    CRef<CUser_object> trackdata( new CUser_object() );
-    trackdata->SetType().SetStr( "Track Data" );
-   
-    if ( !m_pTrackDefaults->Description().empty() ) {
-        annot->SetTitleDesc(m_pTrackDefaults->Description());
-    }
-    if ( !m_pTrackDefaults->Name().empty() ) {
-        annot->SetNameDesc(m_pTrackDefaults->Name());
-    }
-    map<string,string>::const_iterator cit = m_pTrackDefaults->Values().begin();
-    while ( cit != m_pTrackDefaults->Values().end() ) {
-        trackdata->AddField( cit->first, cit->second );
-        ++cit;
-    }
-    if ( trackdata->CanGetData() && ! trackdata->GetData().empty() ) {
-        CRef<CAnnotdesc> user( new CAnnotdesc() );
-        user->SetUser( *trackdata );
-        desc.Set().push_back( user );
-    }
+    m_pTrackDefaults->WriteToAnnot(*annot);
 }
 
 //  ----------------------------------------------------------------------------
@@ -487,17 +466,6 @@ bool CReaderBase::xParseBrowserLine(
 }
 
 //  ----------------------------------------------------------------------------
-void CReaderBase::xSetTrackData(
-    CRef<CSeq_annot>& annot,
-    CRef<CUser_object>& trackdata,
-    const string& strKey,
-    const string& strValue )
-//  ----------------------------------------------------------------------------
-{
-    trackdata->AddField( strKey, strValue );
-}
-
-//  ----------------------------------------------------------------------------
 bool CReaderBase::xParseComment(
     const CTempString& record,
     CRef<CSeq_annot>& annot ) /* throws CObjReaderLineException */
@@ -510,6 +478,14 @@ bool CReaderBase::xParseComment(
 }
  
 //  ----------------------------------------------------------------------------
+void CReaderBase::xPostProcessAnnot(
+    CRef<CSeq_annot>& annot,
+    ILineErrorListener *pMessageListener)
+//  ----------------------------------------------------------------------------
+{
+}
+
+//  ----------------------------------------------------------------------------
 void CReaderBase::xAddConversionInfo(
     CRef<CSeq_annot >& annot,
     ILineErrorListener *pMessageListener)
@@ -657,6 +633,9 @@ bool CReaderBase::xIsTrackLine(
     const CTempString& strLine)
 //  ----------------------------------------------------------------------------
 {
+    if (strLine == "track") {
+        return true;
+    }
     if (NStr::StartsWith(strLine, "track ")) {
         return true;
     }
@@ -664,6 +643,14 @@ bool CReaderBase::xIsTrackLine(
 }
 
 //  ----------------------------------------------------------------------------
+bool CReaderBase::xIsTrackTerminator(
+    const CTempString& strLine)
+//  ----------------------------------------------------------------------------
+{
+    return (NStr::TruncateSpaces(strLine) == "###");
+}
+
+//  ----------------------------------------------------------------------------
 bool CReaderBase::xIsBrowserLine(
     const CTempString& strLine)
 //  ----------------------------------------------------------------------------
diff --git a/c++/src/objtools/readers/reader_data.cpp b/c++/src/objtools/readers/reader_data.cpp
index aaa9f25..a1ee7f4 100644
--- a/c++/src/objtools/readers/reader_data.cpp
+++ b/c++/src/objtools/readers/reader_data.cpp
@@ -1,4 +1,4 @@
-/*  $Id: reader_data.cpp 441980 2014-07-29 17:37:08Z ludwigf $
+/*  $Id: reader_data.cpp 503674 2016-06-07 13:47:01Z ludwigf $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -72,55 +72,5 @@ CBrowserData::Values() const
     return m_Data;
 }
 
-//  ----------------------------------------------------------------------------
-bool CTrackData::IsTrackData(
-    const LineData& linedata )
-//  ----------------------------------------------------------------------------
-{
-    return ( !linedata.empty() && linedata[0] == "track" );
-}
-
-//  ----------------------------------------------------------------------------
-bool CTrackData::ParseLine(
-    const LineData& linedata )
-//  ----------------------------------------------------------------------------
-{
-    if ( !IsTrackData(linedata) ) {
-        return false;
-    }
-    m_strType = m_strName = m_strDescription = "";
-    m_Data.clear();
-
-    LineData::const_iterator cit = linedata.begin();
-    for ( cit++; cit != linedata.end(); ++cit ) {
-        string key, value;
-        NStr::SplitInTwo( *cit, "=", key, value );
-        value = NStr::Replace(value, "\"", " ");
-        NStr::TruncateSpacesInPlace(value);
-        if ( key == "type" ) {
-            m_strType = value;
-            //continue;
-        }
-        if ( key == "name" ) {
-            m_strName = value;
-            //continue;
-        }
-        if ( key == "description" ) {
-            m_strDescription = value;
-            //continue;
-        }
-        m_Data[ key ] = value;
-    }
-    return true;
-}
-
-//  ----------------------------------------------------------------------------
-const CTrackData::TrackData&
-CTrackData::Values() const
-//  ----------------------------------------------------------------------------
-{
-    return m_Data;
-}
-
 END_SCOPE(objects)
 END_NCBI_SCOPE
diff --git a/c++/src/objtools/readers/reader_data.hpp b/c++/src/objtools/readers/reader_data.hpp
index 5933176..48758c4 100644
--- a/c++/src/objtools/readers/reader_data.hpp
+++ b/c++/src/objtools/readers/reader_data.hpp
@@ -1,4 +1,4 @@
-/*  $Id: reader_data.hpp 441980 2014-07-29 17:37:08Z ludwigf $
+/*  $Id: reader_data.hpp 503674 2016-06-07 13:47:01Z ludwigf $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -57,33 +57,6 @@ protected:
     BrowserData m_Data;
 };
 
-//  ============================================================================
-class CTrackData
-//  ============================================================================
-{
-public:
-    typedef std::vector< std::string > LineData;
-    typedef std::map< std::string, std::string > TrackData;
-public:
-    CTrackData() {};
-    ~CTrackData() {};
-    bool ParseLine(
-        const LineData& );
-    static bool IsTrackData(
-        const LineData& );
-    const TrackData& Values() const;
-    string Type() const { return m_strType; };
-    string Description() const { return m_strDescription; };
-    string Name() const { return m_strName; };
-    bool ContainsData() const { return !m_Data.empty(); };
-
-protected:
-    TrackData m_Data;
-    string m_strType;
-    string m_strDescription;
-    string m_strName;
-};
-
 END_SCOPE(objects)
 END_NCBI_SCOPE
 
diff --git a/c++/src/objtools/readers/readfeat.cpp b/c++/src/objtools/readers/readfeat.cpp
index db40982..cbd4f2f 100644
--- a/c++/src/objtools/readers/readfeat.cpp
+++ b/c++/src/objtools/readers/readfeat.cpp
@@ -96,12 +96,12 @@
 
 #define NCBI_USE_ERRCODE_X   Objtools_Rd_Feature
 
-#define FTBL_PROGRESS(_sSeqid, _uLineNum) \
+#define FTBL_PROGRESS(listener, _sSeqid, _uLineNum)                        \
     do {                                                                   \
         const Uint8 uLineNum = (_uLineNum);                                \
         CNcbiOstrstream err_strm;                                          \
         err_strm << "Seq-id " << (_sSeqid) << ", line " << uLineNum;       \
-        pMessageListener->PutProgress(CNcbiOstrstreamToString(err_strm));  \
+        listener->PutProgress(CNcbiOstrstreamToString(err_strm));  \
     } while(false)
 
 BEGIN_NCBI_SCOPE
@@ -276,24 +276,20 @@ public:
     };
 
     // constructor
-    CFeature_table_reader_imp(void);
+    CFeature_table_reader_imp(ILineReader* reader, unsigned int line_num, ILineErrorListener* pMessageListener);
     // destructor
     ~CFeature_table_reader_imp(void);
 
     // read 5-column feature table and return Seq-annot
-    CRef<CSeq_annot> ReadSequinFeatureTable (ILineReader& reader,
-                                             const string& seqid,
+    CRef<CSeq_annot> ReadSequinFeatureTable (const string& seqid,
                                              const string& annotname,
                                              const CFeature_table_reader::TFlags flags, 
-                                             ILineErrorListener* pMessageListener,
                                              ITableFilter *filter);
 
     // create single feature from key
     CRef<CSeq_feat> CreateSeqFeat (const string& feat,
                                    CSeq_loc& location,
                                    const CFeature_table_reader::TFlags flags, 
-                                   ILineErrorListener* pMessageListener,
-                                   unsigned int line,
                                    const string &seq_id,
                                    ITableFilter *filter);
 
@@ -303,8 +299,6 @@ public:
                       const string& qual,
                       const string& val,
                       const CFeature_table_reader::TFlags flags,
-                      ILineErrorListener* pMessageListener,
-                      int line,
                       const string &seq_id );
 
     static bool ParseInitialFeatureLine (
@@ -318,41 +312,36 @@ private:
     CFeature_table_reader_imp(const CFeature_table_reader_imp& value);
     CFeature_table_reader_imp& operator=(const CFeature_table_reader_imp& value);
 
+    void x_InitId(const string& seq_id);
     // returns true if parsed (otherwise, out_offset is left unchanged)
     bool x_TryToParseOffset(const CTempString & sLine, Int4 & out_offset );
 
     bool x_ParseFeatureTableLine (const string& line, Int4* startP, Int4* stopP,
                                   bool* partial5P, bool* partial3P, bool* ispointP, bool* isminusP,
-                                  string& featP, string& qualP, string& valP, Int4 offset,
-                                  ILineErrorListener *pMessageListener, int line_num, const string &seq_id );
+                                  string& featP, string& qualP, string& valP, Int4 offset);
 
     bool x_IsWebComment(CTempString line);
 
-    bool x_AddIntervalToFeature (CTempString strFeatureName, CRef<CSeq_feat> sfp, CSeq_loc_mix& mix,
+    bool x_AddIntervalToFeature (CTempString strFeatureName, CRef<CSeq_feat>& sfp,
                                  Int4 start, Int4 stop,
-                                 bool partial5, bool partial3, bool ispoint, bool isminus,
-                                 ILineErrorListener *pMessageListener, int line_num, const string& seqid);
+                                 bool partial5, bool partial3, bool ispoint, bool isminus);
 
     bool x_AddQualifierToFeature (CRef<CSeq_feat> sfp,
         const string &feat_name,
         const string& qual, const string& val,
-        const CFeature_table_reader::TFlags flags,
-        ILineErrorListener *pMessageListener, int line_num, const string &seq_id );
+        const CFeature_table_reader::TFlags flags);
 
     bool x_AddQualifierToGene     (CSeqFeatData& sfdata,
                                    EQual qtype, const string& val);
     bool x_AddQualifierToCdregion (CRef<CSeq_feat> sfp, CSeqFeatData& sfdata,
-                                   EQual qtype, const string& val,
-                                   ILineErrorListener *pMessageListener, int line_num, const string &seq_id );
+                                   EQual qtype, const string& val);
     bool x_AddQualifierToRna      (CRef<CSeq_feat> sfp,
-                                   EQual qtype, const string& val,
-                                   ILineErrorListener *pMessageListener, int line_num, const string &seq_id );
+                                   EQual qtype, const string& val);
     bool x_AddQualifierToImp      (CRef<CSeq_feat> sfp, CSeqFeatData& sfdata,
                                    EQual qtype, const string& qual, const string& val);
     bool x_AddQualifierToBioSrc   (CSeqFeatData& sfdata,
                                    const string &feat_name,
-                                   EOrgRef rtype, const string& val,
-                                   ILineErrorListener *pMessageListener, int line, const string &seq_id );
+                                   EOrgRef rtype, const string& val);
     bool x_AddQualifierToBioSrc   (CSeqFeatData& sfdata,
                                    CSubSource::ESubtype stype, const string& val);
     bool x_AddQualifierToBioSrc   (CSeqFeatData& sfdata,
@@ -394,23 +383,17 @@ private:
     void x_CreateGenesFromCDSs(
         CRef<CSeq_annot> sap,
         TChoiceToFeatMap & choiceToFeatMap, // an input param, but might get more items added
-        const CFeature_table_reader::TFlags flags,
-        ILineErrorListener *pMessageListener,
-        const string& seqid );
+        const CFeature_table_reader::TFlags flags);
 
     bool x_StringIsJustQuotes (const string& str);
 
     int x_ParseTrnaString (const string& val);
 
-    bool x_ParseTrnaExtString(
-        CTrna_ext & ext_trna, const string & str, const CSeq_id *seq_id );
+    bool x_ParseTrnaExtString(CTrna_ext & ext_trna, const string & str);
     SIZE_TYPE x_MatchingParenPos( const string &str, SIZE_TYPE open_paren_pos );
 
     long x_StringToLongNoThrow (
         CTempString strToConvert,
-        ILineErrorListener *pMessageListener, 
-        const std::string& strSeqId,
-        unsigned int uLine,
         CTempString strFeatureName,
         CTempString strQualifierName,
         // user can override the default problem types that are set on error
@@ -419,40 +402,42 @@ private:
 
     bool x_SetupSeqFeat (CRef<CSeq_feat> sfp, const string& feat,
                          const CFeature_table_reader::TFlags flags, 
-                         unsigned int line,
-                         const string &seq_id,
-                         ILineErrorListener* pMessageListener,
                          ITableFilter *filter);
 
     void  x_ProcessMsg (
-        ILineErrorListener* pMessageListener,
         ILineError::EProblem eProblem,
         EDiagSev eSeverity,
-        const std::string& strSeqId,
-        unsigned int uLine,
         const std::string & strFeatureName = kEmptyStr,
         const std::string & strQualifierName = kEmptyStr,
         const std::string & strQualifierValue = kEmptyStr,
         const ILineError::TVecOfLines & vecOfOtherLines =
             ILineError::TVecOfLines() );
 
+    void  x_ProcessMsg(
+        int line_num,
+        ILineError::EProblem eProblem,
+        EDiagSev eSeverity,
+        const std::string & strFeatureName = kEmptyStr,
+        const std::string & strQualifierName = kEmptyStr,
+        const std::string & strQualifierValue = kEmptyStr,
+        const ILineError::TVecOfLines & vecOfOtherLines =
+        ILineError::TVecOfLines());
+
     void x_TokenizeStrict( const string &line, vector<string> &out_tokens );
     void x_TokenizeLenient( const string &line, vector<string> &out_tokens );
+    void x_FinishFeature(CRef<CSeq_feat>& feat);
+    void x_ResetFeat(CRef<CSeq_feat>& feat, bool & curr_feat_intervals_done);
+    void x_UpdatePointStrand(CSeq_feat& feat, CSeq_interval::TStrand strand) const;
+    void x_GetPointStrand(const CSeq_feat& feat, CSeq_interval::TStrand& strand) const;
+
+    bool m_need_check_strand;
+    string m_real_seqid;
+    unsigned int m_line_num;
+    CRef<CSeq_id> m_seq_id;
+    ILineErrorListener* m_pMessageListener;
+    ILineReader* m_reader;
 };
 
-auto_ptr<CFeature_table_reader_imp> CFeature_table_reader::sm_Implementation;
-
-void CFeature_table_reader::x_InitImplementation()
-{
-    DEFINE_STATIC_FAST_MUTEX(s_Implementation_mutex);
-
-    CFastMutexGuard   LOCK(s_Implementation_mutex);
-    if ( !sm_Implementation.get() ) {
-        sm_Implementation.reset(new CFeature_table_reader_imp());
-    }
-}
-
-
 typedef SStaticPair<const char *, CFeature_table_reader_imp::EQual> TQualKey;
 
 static const TQualKey qual_key_to_subtype [] = {
@@ -801,7 +786,8 @@ DEFINE_STATIC_ARRAY_MAP(TSingleSet, sc_SingleKeys, single_key_list);
 
 
 // constructor
-CFeature_table_reader_imp::CFeature_table_reader_imp(void)
+CFeature_table_reader_imp::CFeature_table_reader_imp(ILineReader* reader, unsigned int line_num, ILineErrorListener* pMessageListener)
+    : m_reader(reader), m_line_num(line_num), m_pMessageListener(pMessageListener)
 {
 }
 
@@ -867,11 +853,7 @@ bool CFeature_table_reader_imp::x_ParseFeatureTableLine (
     string& featP,
     string& qualP,
     string& valP,
-    Int4 offset,
-
-    ILineErrorListener *pMessageListener, 
-    int line_num, 
-    const string &seq_id
+    Int4 offset
 )
 
 {
@@ -929,7 +911,7 @@ bool CFeature_table_reader_imp::x_ParseFeatureTableLine (
           ispoint = true;
           start [len - 1] = '\0';
         }
-        startv = x_StringToLongNoThrow(start, pMessageListener, seq_id, line_num, feat, qual,
+        startv = x_StringToLongNoThrow(start, feat, qual,
             ILineError::eProblem_BadFeatureInterval);
     }
 
@@ -938,7 +920,7 @@ bool CFeature_table_reader_imp::x_ParseFeatureTableLine (
             partial3 = true;
             stop.erase (0, 1);
         }
-        stopv = x_StringToLongNoThrow (stop, pMessageListener, seq_id, line_num, feat, qual,
+        stopv = x_StringToLongNoThrow (stop, feat, qual,
             ILineError::eProblem_BadFeatureInterval);
     }
 
@@ -1135,10 +1117,7 @@ bool CFeature_table_reader_imp::x_AddQualifierToGene (
 bool CFeature_table_reader_imp::x_AddQualifierToCdregion (
     CRef<CSeq_feat> sfp,
     CSeqFeatData& sfdata,
-    EQual qtype, const string& val,
-    ILineErrorListener *pMessageListener, 
-    int line, 
-    const string &seq_id 
+    EQual qtype, const string& val
 )
 
 {
@@ -1146,8 +1125,7 @@ bool CFeature_table_reader_imp::x_AddQualifierToCdregion (
     switch (qtype) {
         case eQual_codon_start:
             {
-                int frame = x_StringToLongNoThrow (val, pMessageListener,
-                    seq_id, line, kCdsFeatName, "codon_start");
+                int frame = x_StringToLongNoThrow (val, kCdsFeatName, "codon_start");
                 switch (frame) {
                     case 0:
                         crp.SetFrame (CCdregion::eFrame_not_set);
@@ -1314,8 +1292,7 @@ int CFeature_table_reader_imp::x_ParseTrnaString (
 }
 
 bool
-CFeature_table_reader_imp::x_ParseTrnaExtString(
-    CTrna_ext & ext_trna, const string & str, const CSeq_id *seq_id )
+CFeature_table_reader_imp::x_ParseTrnaExtString(CTrna_ext & ext_trna, const string & str)
 {
     if (NStr::IsBlank (str)) return false;
 
@@ -1342,7 +1319,7 @@ CFeature_table_reader_imp::x_ParseTrnaExtString(
                 }
             }
             CGetSeqLocFromStringHelper helper;
-            CRef<CSeq_loc> anticodon = GetSeqLocFromString (pos_str, seq_id, & helper);
+            CRef<CSeq_loc> anticodon = GetSeqLocFromString (pos_str, m_seq_id, & helper);
             if (anticodon == NULL) {
                 ext_trna.ResetAa();
                 return false;
@@ -1402,9 +1379,6 @@ SIZE_TYPE CFeature_table_reader_imp::x_MatchingParenPos(
 
 long CFeature_table_reader_imp::x_StringToLongNoThrow (
     CTempString strToConvert,
-    ILineErrorListener *pMessageListener, 
-    const std::string& strSeqId,
-    unsigned int uLine,
     CTempString strFeatureName,
     CTempString strQualifierName,
     ILineError::EProblem eProblem
@@ -1424,10 +1398,10 @@ long CFeature_table_reader_imp::x_StringToLongNoThrow (
                     problem = eProblem;
                 }
 
-                x_ProcessMsg( pMessageListener, 
+                x_ProcessMsg( 
                     problem,
                     eDiag_Warning,
-                    strSeqId, uLine, strFeatureName, strQualifierName, strToConvert );
+                    strFeatureName, strQualifierName, strToConvert );
                 return result;
             } catch( ... ) { } // fall-thru to usual handling
         }
@@ -1438,10 +1412,10 @@ long CFeature_table_reader_imp::x_StringToLongNoThrow (
             problem = eProblem;
         }
 
-        x_ProcessMsg( pMessageListener,
+        x_ProcessMsg(
             problem,
             eDiag_Warning,
-            strSeqId, uLine, strFeatureName, strQualifierName, strToConvert );
+            strFeatureName, strQualifierName, strToConvert );
         // we have no idea, so just return zero
         return 0;
     }
@@ -1451,10 +1425,7 @@ long CFeature_table_reader_imp::x_StringToLongNoThrow (
 bool CFeature_table_reader_imp::x_AddQualifierToRna (
     CRef<CSeq_feat> sfp,
     EQual qtype,
-    const string& val,
-    ILineErrorListener *pMessageListener, 
-    int line_num, 
-    const string &seq_id
+    const string& val
 )
 {
     CSeqFeatData& sfdata = sfp->SetData();
@@ -1529,9 +1500,8 @@ bool CFeature_table_reader_imp::x_AddQualifierToRna (
                             taa.SetNcbieaa(aaval);
                         }
                         else {
-                            x_ProcessMsg(pMessageListener,
+                            x_ProcessMsg(
                                 ILineError::eProblem_QualifierBadValue, eDiag_Warning,
-                                seq_id, line_num,
                                 "tRNA", "product", val);
                         }
                         return true;
@@ -1541,11 +1511,9 @@ bool CFeature_table_reader_imp::x_AddQualifierToRna (
                     {
                         CRNA_ref::TExt& tex = rrp.SetExt ();
                         CRNA_ref::C_Ext::TTRNA & ext_trna = tex.SetTRNA();
-                        CRef<CSeq_id> seq_id_obj( new CSeq_id(seq_id) );
-                        if( ! x_ParseTrnaExtString(ext_trna, val, &*seq_id_obj) ) {
-                            x_ProcessMsg( pMessageListener, 
+                        if( ! x_ParseTrnaExtString(ext_trna, val) ) {
+                            x_ProcessMsg(
                                 ILineError::eProblem_QualifierBadValue, eDiag_Error,
-                                seq_id, line_num,
                                 "tRNA", "anticodon", val );
                         }
                         return true;
@@ -1685,12 +1653,8 @@ bool CFeature_table_reader_imp::x_AddQualifierToBioSrc (
     CSeqFeatData& sfdata,
     const string &feat_name,
     EOrgRef rtype,
-    const string& val,
-    ILineErrorListener *pMessageListener, 
-    int line, 	
-    const string &seq_id 
+    const string& val
 )
-
 {
     CBioSource& bsp = sfdata.SetBiosrc ();
 
@@ -1708,9 +1672,8 @@ bool CFeature_table_reader_imp::x_AddQualifierToBioSrc (
                     CBioSource::EGenome gtype = g_iter->second;
                     bsp.SetGenome (gtype);
                 } else {
-                    x_ProcessMsg( pMessageListener, 
+                    x_ProcessMsg(
                         ILineError::eProblem_QualifierBadValue, eDiag_Error,
-                        seq_id, line,
                         feat_name, "organelle", val );
                 }
                 return true;
@@ -1733,7 +1696,7 @@ bool CFeature_table_reader_imp::x_AddQualifierToBioSrc (
             {
                 CBioSource::TOrg& orp = bsp.SetOrg ();
                 COrg_ref::TOrgname& onp = orp.SetOrgname ();
-                int code = x_StringToLongNoThrow (val, pMessageListener, seq_id, line, feat_name, "gcode");
+                int code = x_StringToLongNoThrow (val, feat_name, "gcode");
                 onp.SetGcode (code);
                 return true;
             }
@@ -1741,7 +1704,7 @@ bool CFeature_table_reader_imp::x_AddQualifierToBioSrc (
             {
                 CBioSource::TOrg& orp = bsp.SetOrg ();
                 COrg_ref::TOrgname& onp = orp.SetOrgname ();
-                int code = x_StringToLongNoThrow (val, pMessageListener, seq_id, line, feat_name, "mgcode");
+                int code = x_StringToLongNoThrow (val, feat_name, "mgcode");
                 onp.SetMgcode (code);
                 return true;
             }
@@ -1921,9 +1884,7 @@ bool CFeature_table_reader_imp::x_AddGeneOntologyToFeature (
 void CFeature_table_reader_imp::x_CreateGenesFromCDSs(
     CRef<CSeq_annot> sap,
     TChoiceToFeatMap & choiceToFeatMap,
-    const CFeature_table_reader::TFlags flags,
-    ILineErrorListener *pMessageListener,
-    const string& seq_id )
+    const CFeature_table_reader::TFlags flags)
 {
     // load cds_equal_range to hold the CDSs
     typedef TChoiceToFeatMap::iterator TChoiceCI;
@@ -2037,9 +1998,9 @@ void CFeature_table_reader_imp::x_CreateGenesFromCDSs(
                 if( (flags & CFeature_table_reader::fCreateGenesFromCDSs) != 0 &&
                     gene_line_num < 1 )
                 {
-                    x_ProcessMsg( pMessageListener, 
+                    x_ProcessMsg(
+                        cds_line_num,
                         ILineError::eProblem_CreatedGeneFromMultipleFeats, eDiag_Error,
-                        seq_id, cds_line_num,
                         kCdsFeatName );
                 }
 
@@ -2057,9 +2018,9 @@ void CFeature_table_reader_imp::x_CreateGenesFromCDSs(
                         if( gene_line_num > 0 ) {
                             gene_lines.push_back(gene_line_num);
                         }
-                        x_ProcessMsg( pMessageListener, 
+                        x_ProcessMsg( 
+                            cds_line_num,
                             ILineError::eProblem_FeatMustBeInXrefdGene, eDiag_Error,
-                            seq_id, cds_line_num,
                             kCdsFeatName, 
                             kEmptyStr, kEmptyStr,
                             gene_lines );
@@ -2131,10 +2092,7 @@ bool CFeature_table_reader_imp::x_AddQualifierToFeature (
     const string &feat_name,
     const string& qual,
     const string& val,
-    const CFeature_table_reader::TFlags flags,
-    ILineErrorListener *pMessageListener, 
-    int line, 	
-    const string &seq_id 
+    const CFeature_table_reader::TFlags flags
 )
 
 {
@@ -2146,9 +2104,8 @@ bool CFeature_table_reader_imp::x_AddQualifierToFeature (
     if( (flags & CFeature_table_reader::fReportDiscouragedKey) != 0 ) {
         if( CSeqFeatData::IsDiscouragedQual(qual_type) ) {
             x_ProcessMsg(
-                pMessageListener,
                 ILineError::eProblem_DiscouragedQualifierName,
-                eDiag_Warning, seq_id, line, feat_name, qual);
+                eDiag_Warning, feat_name, qual);
         }
     }
 
@@ -2157,7 +2114,7 @@ bool CFeature_table_reader_imp::x_AddQualifierToFeature (
         TOrgRefMap::const_iterator o_iter = sm_OrgRefKeys.find (qual.c_str ());
         if (o_iter != sm_OrgRefKeys.end ()) {
             EOrgRef rtype = o_iter->second;
-            if (x_AddQualifierToBioSrc (sfdata, feat_name, rtype, val, pMessageListener, line, seq_id)) return true;
+            if (x_AddQualifierToBioSrc (sfdata, feat_name, rtype, val)) return true;
 
         } else {
 
@@ -2189,10 +2146,10 @@ bool CFeature_table_reader_imp::x_AddQualifierToFeature (
                     if (x_AddQualifierToGene (sfdata, qtype, val)) return true;
                     break;
                 case CSeqFeatData::e_Cdregion:
-                    if (x_AddQualifierToCdregion (sfp, sfdata, qtype, val, pMessageListener, line, seq_id)) return true;
+                    if (x_AddQualifierToCdregion (sfp, sfdata, qtype, val)) return true;
                     break;
                 case CSeqFeatData::e_Rna:
-                    if (x_AddQualifierToRna (sfp, qtype, val, pMessageListener, line, seq_id)) return true;
+                    if (x_AddQualifierToRna (sfp, qtype, val)) return true;
                     break;
                 case CSeqFeatData::e_Imp:
                     if (x_AddQualifierToImp (sfp, sfdata, qtype, qual, val)) return true;
@@ -2224,7 +2181,7 @@ bool CFeature_table_reader_imp::x_AddQualifierToFeature (
                 case CSeqFeatData::e_Pub:
                     if( qtype == eQual_PubMed ) {
                         CRef<CPub> new_pub( new CPub );
-                        new_pub->SetPmid( CPubMedId( x_StringToLongNoThrow(val, pMessageListener, seq_id, line, feat_name, qual) ) );
+                        new_pub->SetPmid( CPubMedId( x_StringToLongNoThrow(val, feat_name, qual) ) );
                         sfdata.SetPub().SetPub().Set().push_back( new_pub );
                         return true;
                     }
@@ -2293,9 +2250,8 @@ bool CFeature_table_reader_imp::x_AddQualifierToFeature (
                             x_AddGBQualToFeature(sfp, qual, val);
                         }
                         else {
-                            x_ProcessMsg(pMessageListener,
+                            x_ProcessMsg(
                                 ILineError::eProblem_QualifierBadValue, eDiag_Error,
-                                seq_id, line,
                                 feat_name, qual, val);
                         }
                         return true;
@@ -2436,10 +2392,8 @@ bool CFeature_table_reader_imp::x_AddQualifierToFeature (
                 case eQual_regulatory_class:
                     // This should've been handled up in x_AddQualifierToImp
                     // so it's always a bad value to be here
-                    x_ProcessMsg(
-                        pMessageListener,
+                    x_ProcessMsg(                        
                         ILineError::eProblem_QualifierBadValue, eDiag_Error,
-                        seq_id, line,
                         feat_name, qual, val );
                     return true;
                 default:
@@ -2505,17 +2459,13 @@ bool CFeature_table_reader_imp::x_IsWebComment(CTempString line)
 
 bool CFeature_table_reader_imp::x_AddIntervalToFeature(
     CTempString strFeatureName,
-    CRef<CSeq_feat> sfp,
-    CSeq_loc_mix& mix,
+    CRef<CSeq_feat>& sfp,
     Int4 start,
     Int4 stop,
     bool partial5,
     bool partial3,
     bool ispoint,
-    bool isminus,
-    ILineErrorListener *pMessageListener, 
-    int line_num, 
-    const string& seqid
+    bool isminus
 )
 
 {
@@ -2530,19 +2480,23 @@ bool CFeature_table_reader_imp::x_AddIntervalToFeature(
     }
 
     // construct loc, which will be added to the mix
-    CRef<CSeq_id> seq_id ( new CSeq_id(seqid) );
+    CSeq_loc_mix::Tdata & mix_set = sfp->SetLocation().SetMix();
     CRef<CSeq_loc> loc(new CSeq_loc);
     if (ispoint || start == stop ) {
         // a point of some kind
-        CRef<CSeq_point> pPoint( new CSeq_point(*seq_id, start, strand) );
+        if (mix_set.empty())
+           m_need_check_strand = true;
+        else
+           x_GetPointStrand(*sfp, strand);
+
+        CRef<CSeq_point> pPoint( new CSeq_point(*m_seq_id, start, strand) );
         if( ispoint ) {
             // between two bases
             pPoint->SetRightOf (true);
             // warning if stop is not start plus one
             if( stop != (start+1) ) {
-                x_ProcessMsg( pMessageListener, 
+                x_ProcessMsg( 
                     ILineError::eProblem_BadFeatureInterval, eDiag_Warning,
-                    seqid, line_num,
                     strFeatureName );
             }
         } else {
@@ -2551,7 +2505,7 @@ bool CFeature_table_reader_imp::x_AddIntervalToFeature(
         loc->SetPnt( *pPoint );
     } else {
         // interval
-        CRef<CSeq_interval> pIval( new CSeq_interval(*seq_id, start, stop, strand) );
+        CRef<CSeq_interval> pIval( new CSeq_interval(*m_seq_id, start, stop, strand) );
         if (partial5) {
             pIval->SetPartialStart (true, eExtreme_Biological);
         }
@@ -2559,18 +2513,22 @@ bool CFeature_table_reader_imp::x_AddIntervalToFeature(
             pIval->SetPartialStop (true, eExtreme_Biological);
         }
         loc->SetInt(*pIval);
+        if (m_need_check_strand)
+        {
+            x_UpdatePointStrand(*sfp, strand);
+            m_need_check_strand = false;
+        }
     }
 
     // check for internal partials
-    CSeq_loc_mix::Tdata & mix_set = mix.Set();
     if( ! mix_set.empty() ) {
         const CSeq_loc & last_loc = *mix_set.back();
         if( last_loc.IsPartialStop(eExtreme_Biological) ||
             loc->IsPartialStart(eExtreme_Biological) ) 
         {
             // internal partials
-            x_ProcessMsg(pMessageListener, ILineError::eProblem_InternalPartialsInFeatLocation,
-                eDiag_Warning, seqid, line_num, strFeatureName );
+            x_ProcessMsg(ILineError::eProblem_InternalPartialsInFeatLocation,
+                eDiag_Warning, strFeatureName );
         }
     }
 
@@ -2589,9 +2547,6 @@ bool CFeature_table_reader_imp::x_SetupSeqFeat (
     CRef<CSeq_feat> sfp,
     const string& feat,
     const CFeature_table_reader::TFlags flags,
-    unsigned int line,
-    const std::string &seq_id,
-    ILineErrorListener* pMessageListener,
     ITableFilter *filter
 )
 
@@ -2602,9 +2557,9 @@ bool CFeature_table_reader_imp::x_SetupSeqFeat (
     if( NULL != filter ) {
         ITableFilter::EAction action = filter->GetFeatAction(feat);
         if( action != ITableFilter::eAction_Okay ) {
-            x_ProcessMsg( pMessageListener, 
+            x_ProcessMsg( 
                 ILineError::eProblem_FeatureNameNotAllowed,
-                eDiag_Warning, seq_id, line, feat );
+                eDiag_Warning, feat );
             if( action == ITableFilter::eAction_Disallowed ) {
                 return false;
             }
@@ -2698,9 +2653,8 @@ bool CFeature_table_reader_imp::x_SetupSeqFeat (
         if( (flags & CFeature_table_reader::fReportDiscouragedKey) != 0 ) {
             if( CSeqFeatData::IsDiscouragedSubtype(sbtyp) ) {
                 x_ProcessMsg(
-                    pMessageListener,
                     ILineError::eProblem_DiscouragedFeatureName,
-                    eDiag_Warning, seq_id, line, feat);
+                    eDiag_Warning, feat);
             }
         }
 
@@ -2710,7 +2664,7 @@ bool CFeature_table_reader_imp::x_SetupSeqFeat (
     // unrecognized feature key
 
     if ((flags & CFeature_table_reader::fReportBadKey) != 0) {
-        x_ProcessMsg(pMessageListener, ILineError::eProblem_UnrecognizedFeatureName, eDiag_Warning, seq_id, line, feat );
+        x_ProcessMsg(ILineError::eProblem_UnrecognizedFeatureName, eDiag_Warning, feat );
     }
 
     if ((flags & CFeature_table_reader::fTranslateBadKey) != 0) {
@@ -2719,7 +2673,7 @@ bool CFeature_table_reader_imp::x_SetupSeqFeat (
         CSeqFeatData& sfdata = sfp->SetData ();
         CImp_feat_Base& imp = sfdata.SetImp ();
         imp.SetKey ("misc_feature");
-        x_AddQualifierToFeature (sfp, kEmptyStr, "standard_name", feat, flags, pMessageListener, line, seq_id);
+        x_AddQualifierToFeature (sfp, kEmptyStr, "standard_name", feat, flags);
 
         return true;
 
@@ -2736,13 +2690,23 @@ bool CFeature_table_reader_imp::x_SetupSeqFeat (
     return false;
 }
 
+void CFeature_table_reader_imp::x_ProcessMsg(
+    ILineError::EProblem eProblem,
+    EDiagSev eSeverity,
+    const std::string & strFeatureName,
+    const std::string & strQualifierName,
+    const std::string & strQualifierValue,
+    const ILineError::TVecOfLines & vecOfOtherLines)
+{
+    x_ProcessMsg(m_reader ? m_reader->GetLineNumber() : m_line_num,
+        eProblem, eSeverity, strFeatureName, strQualifierName, strQualifierValue, vecOfOtherLines);
+}
+
 
 void CFeature_table_reader_imp::x_ProcessMsg(
-    ILineErrorListener* pMessageListener,
+    int line_num,
     ILineError::EProblem eProblem,
     EDiagSev eSeverity,
-    const std::string& strSeqId,
-    unsigned int uLine,
     const std::string & strFeatureName,
     const std::string & strQualifierName,
     const std::string & strQualifierValue,
@@ -2750,37 +2714,95 @@ void CFeature_table_reader_imp::x_ProcessMsg(
 {
     AutoPtr<CObjReaderLineException> pErr ( 
         CObjReaderLineException::Create(
-        eSeverity, uLine, "", eProblem, strSeqId, strFeatureName, 
+        eSeverity, line_num, "", eProblem, m_real_seqid, strFeatureName,
         strQualifierName, strQualifierValue));
     ITERATE( ILineError::TVecOfLines, line_it, vecOfOtherLines ) {
         pErr->AddOtherLine(*line_it);
     }
-    if (pMessageListener == 0) {
+    if (m_pMessageListener == 0) {
         pErr->Throw();
     }
 
-    if ( ! pMessageListener->PutError(*pErr) ) {
+    if (!m_pMessageListener->PutError(*pErr)) {
         pErr->Throw();
     }
 }
 
-namespace {
-    // helper for CFeature_table_reader_imp::ReadSequinFeatureTable,
-    // just so we don't forget a step when we reset the feature
-    // 
-    void s_ResetFeat( CRef<CSeq_feat> & sfp, bool & curr_feat_intervals_done ) {
-        sfp.Reset (new CSeq_feat);
-        sfp->ResetLocation ();
-        curr_feat_intervals_done = false;
+
+// helper for CFeature_table_reader_imp::ReadSequinFeatureTable,
+// just so we don't forget a step when we reset the feature
+// 
+void CFeature_table_reader_imp::x_ResetFeat(CRef<CSeq_feat> & sfp, bool & curr_feat_intervals_done)
+{
+    m_need_check_strand = false;
+    sfp.Reset(new CSeq_feat);
+    //sfp->ResetLocation();
+    curr_feat_intervals_done = false;
+}
+
+void CFeature_table_reader_imp::x_GetPointStrand(const CSeq_feat& feat, CSeq_interval::TStrand& strand) const
+{
+    if (feat.IsSetLocation() && feat.GetLocation().IsMix())
+    {
+        const CSeq_loc& last = *feat.GetLocation().GetMix().Get().back();
+        if (last.IsInt() && last.GetInt().IsSetStrand())
+        {
+            strand = last.GetInt().GetStrand();
+        }
+        else
+        if (last.IsPnt() && last.GetPnt().IsSetStrand())
+        {
+            strand = last.GetPnt().GetStrand();
+        }
+    }
+}
+
+void CFeature_table_reader_imp::x_UpdatePointStrand(CSeq_feat& feat, CSeq_interval::TStrand strand) const
+{
+    if (feat.IsSetLocation() && feat.GetLocation().IsMix())
+    {
+        NON_CONST_REVERSE_ITERATE(CSeq_loc_mix::Tdata, it, feat.SetLocation().SetMix().Set())
+        {
+            if ((**it).IsPnt())
+            {
+                (**it).SetPnt().SetStrand(strand);
+            }
+        }
+    }    
+}
+
+void CFeature_table_reader_imp::x_FinishFeature(CRef<CSeq_feat>& feat)
+{
+    if (feat.Empty())
+        return;
+
+    if (feat->IsSetLocation())
+    {
+        // demote single interval seqlocmix to seqlocint
+        if (feat->GetLocation().IsMix())
+        {
+            switch (feat->GetLocation().GetMix().Get().size())
+            {
+            case 0:
+                feat->SetLocation().SetNull();
+                break;
+            case 1:
+            {
+                CRef<CSeq_loc> keep_loc = *feat->SetLocation().SetMix().Set().begin();
+                feat->SetLocation(*keep_loc);
+            }
+            break;
+            default:
+                break;
+            }
+        }
     }
 }
-                                             
+
 CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
-    ILineReader& reader,
     const string& seqid,
     const string& annotname,
     const CFeature_table_reader::TFlags flags,
-    ILineErrorListener* pMessageListener,
     ITableFilter *filter
 )
 {
@@ -2795,17 +2817,7 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
         ( (flags & CFeature_table_reader::fIgnoreWebComments) != 0 );
 
     // if sequence ID is a list, use just one sequence ID string    
-    string real_seqid = seqid;
-    if (!NStr::IsBlank(real_seqid)) {
-        //try {
-        //    CSeq_id seq_id (seqid);
-        //} catch (...) {
-            CBioseq::TId ids;
-            CSeq_id::ParseIDs(ids, seqid);
-            real_seqid.clear();
-            ids.front()->GetLabel(&real_seqid, CSeq_id::eFasta);
-        //}
-    }
+    x_InitId(seqid);
 
     // Use this to efficiently find the best CDS for a prot feature
     // (only add CDS's for it to work right)
@@ -2833,22 +2845,22 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
       descr.Set().push_back (annot);
     }
 
-    while ( !reader.AtEOF() ) {
+    while ( !m_reader->AtEOF() ) {
 
         // since reader's UngetLine doesn't actually push back
         // into the reader's underlying stream, we try to
         // be careful to detect the most common case of
         // "there's another feature next"
-        if( reader.PeekChar() == '>' ) {
+        if( m_reader->PeekChar() == '>' ) {
             break;
         }
 
-        CTempString line = *++reader;
+        CTempString line = *++(*m_reader);
 
-        if( reader.GetLineNumber() % 10000 == 0 &&
-            reader.GetLineNumber() > 0 )
+        if( m_reader->GetLineNumber() % 10000 == 0 &&
+            m_reader->GetLineNumber() > 0 )
         {
-            FTBL_PROGRESS(real_seqid, reader.GetLineNumber());
+            FTBL_PROGRESS(m_pMessageListener, m_real_seqid, m_reader->GetLineNumber());
         }
 
         // skip empty lines.
@@ -2860,7 +2872,7 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
         // if next line is a new feature table, return current sap
         string dummy1, dummy2;
         if( ParseInitialFeatureLine(line, dummy1, dummy2) ) {
-            reader.UngetLine(); // we'll get this feature line the next time around
+            m_reader->UngetLine(); // we'll get this feature line the next time around
             break;
         } 
 
@@ -2871,10 +2883,9 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
                 // okay, known command
             } else {
                 // warn for unknown square-bracket commands
-                x_ProcessMsg( pMessageListener,
+                x_ProcessMsg( 
                     ILineError::eProblem_UnrecognizedSquareBracketCommand,
-                    eDiag_Warning,
-                    seqid, reader.GetLineNumber() );
+                    eDiag_Warning);
             }
 
         } else if ( s_LineIndicatesOrder(line) ) {
@@ -2887,8 +2898,7 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
             }
 
         } else if (x_ParseFeatureTableLine (line, &start, &stop, &partial5, &partial3,
-                                            &ispoint, &isminus, feat, qual, val, offset,
-                                            pMessageListener, reader.GetLineNumber(), real_seqid)) {
+                                            &ispoint, &isminus, feat, qual, val, offset)) {
 
             // process line in feature table
 
@@ -2898,17 +2908,13 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
 
                 // process start - stop - feature line
 
-                s_ResetFeat( sfp, curr_feat_intervals_done );
+                x_FinishFeature(sfp);
+                x_ResetFeat( sfp, curr_feat_intervals_done );
 
-                if (x_SetupSeqFeat (sfp, feat, flags, reader.GetLineNumber(), real_seqid, pMessageListener, filter)) {
+                if (x_SetupSeqFeat (sfp, feat, flags, filter)) {
 
                     ftable.push_back (sfp);
 
-                    // now create location
-
-                    CRef<CSeq_loc> location (new CSeq_loc);
-                    sfp->SetLocation (*location);
-
                     // figure out type of feat, and store in map for later use
                     CSeqFeatData::E_Choice eChoice = CSeqFeatData::e_not_set;
                     if( sfp->CanGetData() ) {
@@ -2917,7 +2923,7 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
                     choiceToFeatMap.insert(
                         TChoiceToFeatMap::value_type(
                         eChoice, 
-                        SFeatAndLineNum(sfp, reader.GetLineNumber())));
+                        SFeatAndLineNum(sfp, m_reader->GetLineNumber())));
 
                     // if new feature is a CDS, remember it for later lookups
                     if( eChoice == CSeqFeatData::e_Cdregion ) {
@@ -2925,9 +2931,8 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
                     }
 
                     // and add first interval
-                    x_AddIntervalToFeature (curr_feat_name, sfp, location->SetMix(), 
-                        start, stop, partial5, partial3, ispoint, isminus, 
-                        pMessageListener, reader.GetLineNumber(), real_seqid );
+                    x_AddIntervalToFeature (curr_feat_name, sfp,
+                        start, stop, partial5, partial3, ispoint, isminus);
 
                     ignore_until_next_feature_key = false;
 
@@ -2949,24 +2954,18 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
 
                 if( curr_feat_intervals_done ) {
                     // the feat intervals were done, so it's an error for there to be more intervals
-                    x_ProcessMsg(pMessageListener, ILineError::eProblem_NoFeatureProvidedOnIntervals,
-                            eDiag_Error,
-                            real_seqid,
-                            reader.GetLineNumber() );
+                    x_ProcessMsg(ILineError::eProblem_NoFeatureProvidedOnIntervals, eDiag_Error);
                     // this feature is in bad shape, so we ignore the rest of it
                     ignore_until_next_feature_key = true;
-                    s_ResetFeat(sfp, curr_feat_intervals_done);
+                    x_ResetFeat(sfp, curr_feat_intervals_done);
                 } else if (sfp  &&  sfp->IsSetLocation()  &&  sfp->GetLocation().IsMix()) {
                     // process start - stop multiple interval line
-                    x_AddIntervalToFeature (curr_feat_name, sfp, sfp->SetLocation().SetMix(), 
-                                            start, stop, partial5, partial3, ispoint, isminus, 
-                                            pMessageListener, reader.GetLineNumber(), real_seqid);
+                    x_AddIntervalToFeature (curr_feat_name, sfp,
+                                            start, stop, partial5, partial3, ispoint, isminus);
                 } else {
                     if ((flags & CFeature_table_reader::fReportBadKey) != 0) {
-                        x_ProcessMsg(pMessageListener, ILineError::eProblem_NoFeatureProvidedOnIntervals,
-                            eDiag_Warning,
-                            real_seqid,
-                            reader.GetLineNumber() );
+                        x_ProcessMsg(ILineError::eProblem_NoFeatureProvidedOnIntervals,
+                            eDiag_Warning);
                     }
                 }
 
@@ -2980,20 +2979,19 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
 
                 if ( !sfp ) {
                     if ((flags & CFeature_table_reader::fReportBadKey) != 0) {
-                        x_ProcessMsg(pMessageListener, 
+                        x_ProcessMsg( 
                             ILineError::eProblem_QualifierWithoutFeature, 
                             eDiag_Warning,
-                            real_seqid,
-                            reader.GetLineNumber(), kEmptyStr, qual, val );
+                            kEmptyStr, qual, val );
                     }
-                } else if ( !x_AddQualifierToFeature (sfp, curr_feat_name, qual, val, flags, pMessageListener, reader.GetLineNumber(), real_seqid) ) {
+                } else if ( !x_AddQualifierToFeature (sfp, curr_feat_name, qual, val, flags) ) {
 
                     // unrecognized qualifier key
 
                     if ((flags & CFeature_table_reader::fReportBadKey) != 0) {
-                        x_ProcessMsg(pMessageListener,
+                        x_ProcessMsg(
                             ILineError::eProblem_UnrecognizedQualifierName, 
-                            eDiag_Warning, real_seqid, reader.GetLineNumber(), curr_feat_name, qual, val );
+                            eDiag_Warning, curr_feat_name, qual, val );
                     }
 
                     if ((flags & CFeature_table_reader::fKeepBadKey) != 0) {
@@ -3010,16 +3008,15 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
                 // check for the few qualifiers that do not need a value
                 if ( !sfp ) {
                     if ((flags & CFeature_table_reader::fReportBadKey) != 0) {
-                        x_ProcessMsg(pMessageListener, 
+                        x_ProcessMsg(
                             ILineError::eProblem_QualifierWithoutFeature, eDiag_Warning,
-                            real_seqid, reader.GetLineNumber(),
                             kEmptyStr, qual );
                     }
                 } else {
                     TSingleSet::const_iterator s_iter = sc_SingleKeys.find (qual.c_str ());
                     if (s_iter != sc_SingleKeys.end ()) {
 
-                        x_AddQualifierToFeature (sfp, curr_feat_name, qual, val, flags, pMessageListener, reader.GetLineNumber(), real_seqid);
+                        x_AddQualifierToFeature (sfp, curr_feat_name, qual, val, flags);
                     }
                 }
             } else if (! feat.empty ()) {
@@ -3031,9 +3028,8 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
                 curr_feat_intervals_done = true;
 
                 if ((flags & CFeature_table_reader::fReportBadKey) != 0) {
-                    x_ProcessMsg( pMessageListener, 
+                    x_ProcessMsg( 
                         ILineError::eProblem_FeatureBadStartAndOrStop, eDiag_Warning,
-                        real_seqid, reader.GetLineNumber(),
                         feat );
                 }
             }
@@ -3043,7 +3039,7 @@ CRef<CSeq_annot> CFeature_table_reader_imp::ReadSequinFeatureTable (
     if ((flags & CFeature_table_reader::fCreateGenesFromCDSs) != 0 ||
         (flags & CFeature_table_reader::fCDSsMustBeInTheirGenes) != 0 ) 
     {
-        x_CreateGenesFromCDSs(sap, choiceToFeatMap, flags, pMessageListener, seqid);
+        x_CreateGenesFromCDSs(sap, choiceToFeatMap, flags);
     }
 
     return sap;
@@ -3054,8 +3050,6 @@ CRef<CSeq_feat> CFeature_table_reader_imp::CreateSeqFeat (
     const string& feat,
     CSeq_loc& location,
     const CFeature_table_reader::TFlags flags,
-    ILineErrorListener* pMessageListener,
-    unsigned int line,
     const string &seq_id,
     ITableFilter *filter
 )
@@ -3065,7 +3059,7 @@ CRef<CSeq_feat> CFeature_table_reader_imp::CreateSeqFeat (
 
     sfp->ResetLocation ();
 
-    if ( ! x_SetupSeqFeat (sfp, feat, flags, line, seq_id, pMessageListener, filter) ) {
+    if ( ! x_SetupSeqFeat (sfp, feat, flags, filter) ) {
 
         // bad feature, make dummy
 
@@ -3083,6 +3077,16 @@ CRef<CSeq_feat> CFeature_table_reader_imp::CreateSeqFeat (
     return sfp;
 }
 
+void CFeature_table_reader_imp::x_InitId(const string& seq_id)
+{
+    if (!NStr::IsBlank(seq_id)) {
+        CBioseq::TId ids;
+        CSeq_id::ParseIDs(ids, seq_id);
+        m_real_seqid.clear();
+        ids.front()->GetLabel(&m_real_seqid, CSeq_id::eFasta);
+        m_seq_id = ids.front();
+    }
+}
 
 void CFeature_table_reader_imp::AddFeatQual (
     CRef<CSeq_feat> sfp,
@@ -3090,14 +3094,14 @@ void CFeature_table_reader_imp::AddFeatQual (
     const string& qual,
     const string& val,
     const CFeature_table_reader::TFlags flags,
-    ILineErrorListener* pMessageListener,
-    int line, 	
-    const string &seq_id )
+    const string &seq_id1 )
 
 {
+    x_InitId(seq_id1);
+
     if ((! qual.empty ()) && (! val.empty ())) {
 
-        if (! x_AddQualifierToFeature (sfp, feat_name, qual, val, flags, pMessageListener, line, seq_id)) {
+        if (! x_AddQualifierToFeature (sfp, feat_name, qual, val, flags)) {
 
             // unrecognized qualifier key
 
@@ -3117,7 +3121,7 @@ void CFeature_table_reader_imp::AddFeatQual (
         TSingleSet::const_iterator s_iter = sc_SingleKeys.find (qual.c_str ());
         if (s_iter != sc_SingleKeys.end ()) {
 
-            x_AddQualifierToFeature (sfp, feat_name, qual, val, flags, pMessageListener, line, seq_id);
+            x_AddQualifierToFeature (sfp, feat_name, qual, val, flags);
 
         }
     }
@@ -3218,30 +3222,8 @@ CRef<CSeq_annot> CFeature_table_reader::ReadSequinFeatureTable (
 )
 {
     // just read features from 5-column table
-
-    CRef<CSeq_annot> sap = x_GetImplementation().ReadSequinFeatureTable 
-      (reader, seqid, annotname, flags, pMessageListener, filter);
-
-    // go through all features and demote single interval seqlocmix to seqlocint
-    for (CTypeIterator<CSeq_feat> fi(*sap); fi; ++fi) {
-        CSeq_feat& feat = *fi;
-        CSeq_loc& location = feat.SetLocation ();
-        if (location.IsMix ()) {
-            CSeq_loc_mix& mx = location.SetMix ();
-            CSeq_loc &keep_loc(*mx.Set ().front ());
-            CRef<CSeq_loc> guard_loc(&keep_loc);            
-            switch (mx.Get ().size ()) {
-                case 0:
-                    location.SetNull ();
-                    break;
-                case 1:
-                    feat.SetLocation (*mx.Set ().front ());
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
+    CFeature_table_reader_imp impl(&reader, 0, pMessageListener);
+    CRef<CSeq_annot> sap = impl.ReadSequinFeatureTable(seqid, annotname, flags, filter);
 
     return sap;
 }
@@ -3275,7 +3257,7 @@ CRef<CSeq_annot> CFeature_table_reader::ReadSequinFeatureTable (
         CTempString line = *++reader;
 
         if( ParseInitialFeatureLine(line, seqid, annotname) ) {
-            FTBL_PROGRESS( seqid, reader.GetLineNumber() );
+            FTBL_PROGRESS(pMessageListener, seqid, reader.GetLineNumber());
         }
     }
 
@@ -3374,8 +3356,8 @@ CRef<CSeq_feat> CFeature_table_reader::CreateSeqFeat (
 )
 
 {
-    return x_GetImplementation ().CreateSeqFeat (feat, location, flags, pMessageListener, line, 
-        (seq_id ? *seq_id : string() ), filter);
+    CFeature_table_reader_imp impl(0, line, pMessageListener);
+    return impl.CreateSeqFeat (feat, location, flags, (seq_id ? *seq_id : string() ), filter);
 }
 
 
@@ -3391,7 +3373,8 @@ void CFeature_table_reader::AddFeatQual (
 )
 
 {
-    x_GetImplementation ().AddFeatQual ( sfp, feat_name, qual, val, flags, pMessageListener, line, seq_id ) ;
+    CFeature_table_reader_imp impl(0, line, pMessageListener);
+    impl.AddFeatQual ( sfp, feat_name, qual, val, flags, seq_id ) ;
 }
 
 bool
@@ -3400,7 +3383,7 @@ CFeature_table_reader::ParseInitialFeatureLine (
     string & out_seqid,
     string & out_annotname )
 {
-    return x_GetImplementation ().ParseInitialFeatureLine ( line_arg, out_seqid, out_annotname );
+     return CFeature_table_reader_imp::ParseInitialFeatureLine(line_arg, out_seqid, out_annotname);
 }
 
 
diff --git a/c++/src/objtools/readers/source_mod_parser.cpp b/c++/src/objtools/readers/source_mod_parser.cpp
index c872057..90e2d55 100644
--- a/c++/src/objtools/readers/source_mod_parser.cpp
+++ b/c++/src/objtools/readers/source_mod_parser.cpp
@@ -1,4 +1,4 @@
-/*  $Id: source_mod_parser.cpp 499427 2016-04-26 14:11:26Z ivanov $
+/*  $Id: source_mod_parser.cpp 520374 2016-11-28 13:29:07Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -497,6 +497,7 @@ void CSourceModParser::x_ApplyMods(CAutoInitDesc<CBioSource>& bsrc,
                                    CTempString organism)
 {
     const SMod* mod = NULL;
+    bool reset_taxid = false;
 
     // org[anism]
     if (organism.empty())
@@ -520,6 +521,7 @@ void CSourceModParser::x_ApplyMods(CAutoInitDesc<CBioSource>& bsrc,
                 bsrc->ResetSubtype();
             }
             bsrc->SetOrg().SetTaxname(organism);
+            reset_taxid = true;
         }
     }
 
@@ -584,6 +586,7 @@ void CSourceModParser::x_ApplyMods(CAutoInitDesc<CBioSource>& bsrc,
                 org_mod->SetSubtype(it->second);
                 org_mod->SetSubname(mod->value);
                 bsrc->SetOrg().SetOrgname().SetMod().push_back(org_mod);
+                reset_taxid = true;
             }
         }
     }}
@@ -603,6 +606,7 @@ void CSourceModParser::x_ApplyMods(CAutoInitDesc<CBioSource>& bsrc,
                 org_mod->SetSubtype(it->value);
                 org_mod->SetSubname(mod->value);
                 bsrc->SetOrg().SetOrgname().SetMod().push_back(org_mod);
+                reset_taxid = true;
             }
         }
     }}
@@ -774,6 +778,9 @@ void CSourceModParser::x_ApplyMods(CAutoInitDesc<CBioSource>& bsrc,
             bsrc->SetIs_focus();
         }
     }
+
+    if (reset_taxid && bsrc->IsSetOrgname() && bsrc->GetOrg().GetTaxId() != 0)
+       bsrc->SetOrg().SetTaxId(0);
 }
 
 typedef SStaticPair<const char*, CMolInfo::TTech> TTechMapEntry;
@@ -1364,6 +1371,7 @@ void CSourceModParser::AddMods(const CTempString& name, const CTempString& value
     SMod newmod;
     newmod.key = name;
     newmod.value = value;
+    newmod.used = false;
 
     m_Mods.insert(newmod);
 }
diff --git a/c++/src/objtools/readers/struct_cmt_reader.cpp b/c++/src/objtools/readers/struct_cmt_reader.cpp
new file mode 100644
index 0000000..86e3794
--- /dev/null
+++ b/c++/src/objtools/readers/struct_cmt_reader.cpp
@@ -0,0 +1,130 @@
+/*  $Id: struct_cmt_reader.cpp 515962 2016-10-06 18:16:16Z ivanov $
+* ===========================================================================
+*
+*                            PUBLIC DOMAIN NOTICE
+*               National Center for Biotechnology Information
+*
+*  This software/database is a "United States Government Work" under the
+*  terms of the United States Copyright Act.  It was written as part of
+*  the author's official duties as a United States Government employee and
+*  thus cannot be copyrighted.  This software/database is freely available
+*  to the public for use. The National Library of Medicine and the U.S.
+*  Government have not placed any restriction on its use or reproduction.
+*
+*  Although all reasonable efforts have been taken to ensure the accuracy
+*  and reliability of the software and data, the NLM and the U.S.
+*  Government do not and cannot warrant the performance or results that
+*  may be obtained by using this software or data. The NLM and the U.S.
+*  Government disclaim all warranties, express or implied, including
+*  warranties of performance, merchantability or fitness for any particular
+*  purpose.
+*
+*  Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* Author:  Sergiy Gotvyanskyy, NCBI
+*
+* File Description:
+*   Reader for structured comments for sequences
+*
+* ===========================================================================
+*/
+
+#include <ncbi_pch.hpp>
+
+#include <objtools/readers/struct_cmt_reader.hpp>
+
+#include <objects/seq/Seqdesc.hpp>
+#include <objects/seq/Seq_descr.hpp>
+#include <objects/general/User_object.hpp>
+#include <objects/general/Object_id.hpp>
+#include <objects/seqloc/Seq_id.hpp>
+
+#include <util/line_reader.hpp>
+
+#include <common/test_assert.h>  /* This header must go last */
+
+BEGIN_NCBI_SCOPE
+USING_SCOPE(objects);
+
+CStructuredCommentsReader::CStructuredCommentsReader(ILineErrorListener* logger) : m_logger(logger)
+{
+}
+
+CStructuredCommentsReader::~CStructuredCommentsReader()
+{
+}
+
+CUser_object* CStructuredCommentsReader::FindStructuredComment(CSeq_descr& descr)
+{
+    NON_CONST_ITERATE(CSeq_descr::Tdata, it, descr.Set())
+    {
+        if ((**it).IsUser())
+        {
+            if ((**it).GetUser().GetType().GetStr().compare("StructuredComment") == 0)
+                return &((**it).SetUser());
+        }
+    }
+    return 0;
+}
+
+objects::CUser_object* CStructuredCommentsReader::_AddStructuredComment(objects::CUser_object* user_obj, TStructComment& cmt, const CTempString& name, const CTempString& value)
+{
+    if (name.compare("StructuredCommentPrefix") == 0)
+        user_obj = 0; // reset user obj so to create a new one
+    else
+    {
+        //if (user_obj == 0)
+        //    user_obj = FindStructuredComment(cmt.m_descs);
+    }
+
+    if (user_obj == 0)
+    {
+        // create new user object
+        CRef<CSeqdesc> user_desc(new CSeqdesc);
+        user_obj = &(user_desc->SetUser());
+        user_obj->SetType().SetStr("StructuredComment");
+        cmt.m_descs.push_back(user_desc);
+    }
+    user_obj->AddField(name, value);
+    // create next user object
+    if (name.compare("StructuredCommentSuffix") == 0)
+        return 0;
+    else
+        return user_obj;
+}
+
+void CStructuredCommentsReader::_BuildStructuredComment(TStructComment& cmt, const vector<string>& cols, const vector<CTempString>& values)
+{
+    cmt.m_descs.reserve(values.size() - 1);
+    objects::CUser_object* user = 0;
+
+    for (size_t i = 1; i<values.size(); i++)
+    {
+        if (!values[i].empty())
+        {
+            // create new user object
+            user = _AddStructuredComment(user, cmt, cols[i], values[i]);
+        }
+    }
+}
+
+void CStructuredCommentsReader::_LoadHeaderLine(ILineReader& reader, vector<string>& cols)
+{
+    cols.clear();
+
+    while (!reader.AtEOF() && cols.empty())
+    {
+        reader.ReadLine();
+        // First line is a collumn definitions
+        CTempString current = reader.GetCurrentLine();
+        if (NStr::StartsWith(current, '#'))
+            continue;
+
+        NStr::Split(current, "\t", cols);
+    }
+}
+
+END_NCBI_SCOPE
+
diff --git a/c++/src/objtools/readers/track_data.cpp b/c++/src/objtools/readers/track_data.cpp
new file mode 100644
index 0000000..59f2e67
--- /dev/null
+++ b/c++/src/objtools/readers/track_data.cpp
@@ -0,0 +1,144 @@
+/*  $Id: track_data.cpp 515629 2016-10-04 17:46:33Z ivanov $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *               National Center for Biotechnology Information
+ *
+ *  This software/database is a "United States Government Work" under the
+ *  terms of the United States Copyright Act.  It was written as part of
+ *  the author's official duties as a United States Government employee and
+ *  thus cannot be copyrighted.  This software/database is freely available
+ *  to the public for use. The National Library of Medicine and the U.S.
+ *  Government have not placed any restriction on its use or reproduction.
+ *
+ *  Although all reasonable efforts have been taken to ensure the accuracy
+ *  and reliability of the software and data, the NLM and the U.S.
+ *  Government do not and cannot warrant the performance or results that
+ *  may be obtained by using this software or data. The NLM and the U.S.
+ *  Government disclaim all warranties, express or implied, including
+ *  warranties of performance, merchantability or fitness for any particular
+ *  purpose.
+ *
+ *  Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * Author:  Frank Ludwig
+ *
+ * File Description:
+ *   WIGGLE transient data structures
+ *
+ */
+
+#include <ncbi_pch.hpp>
+#include <corelib/ncbistd.hpp>
+#include <corelib/ncbiapp.hpp>
+
+#include <objects/general/Object_id.hpp>
+#include <objects/general/User_object.hpp>
+#include <objects/general/User_field.hpp>
+#include <objects/general/Dbtag.hpp>
+
+#include <objects/seq/Seq_annot.hpp>
+#include <objects/seq/Annotdesc.hpp>
+#include <objects/seq/Annot_descr.hpp>
+#include <objects/seq/Seq_descr.hpp>
+#include <objtools/readers/track_data.hpp>
+
+BEGIN_NCBI_SCOPE
+BEGIN_SCOPE(objects) // namespace ncbi::objects::
+
+//  ----------------------------------------------------------------------------
+CTrackData::CTrackData()
+//  ----------------------------------------------------------------------------
+{
+}
+
+
+//  ----------------------------------------------------------------------------
+bool CTrackData::IsTrackData(
+    const LineData& linedata )
+//  ----------------------------------------------------------------------------
+{
+    return ( !linedata.empty() && linedata[0] == "track" );
+}
+
+//  ----------------------------------------------------------------------------
+bool CTrackData::ParseLine(
+    const LineData& linedata )
+//  ----------------------------------------------------------------------------
+{
+    if ( !IsTrackData(linedata) ) {
+        return false;
+    }
+    string s = mData["name"];
+    mData.clear();
+
+    LineData::const_iterator cit = linedata.begin();
+    for ( cit++; cit != linedata.end(); ++cit ) {
+        string key, value;
+        NStr::SplitInTwo( *cit, "=", key, value );
+        value = NStr::Replace(value, "\"", " ");
+        NStr::TruncateSpacesInPlace(value);
+        mData[key] = value;
+    }
+    return true;
+}
+
+//  ----------------------------------------------------------------------------
+int CTrackData::Offset() const 
+//  ----------------------------------------------------------------------------
+{ 
+    string offset = ValueOf("offset");
+    if (offset.empty()) {
+        return 0;
+    }
+    return NStr::StringToInt(offset); 
+};
+
+//  ----------------------------------------------------------------------------
+string CTrackData::ValueOf(
+    const string& key) const
+//  ----------------------------------------------------------------------------
+{
+    auto valueIt = mData.find(key);
+    if (valueIt != mData.end()) {
+        return valueIt->second;
+    }
+    return "";
+}
+
+//  -----------------------------------------------------------------------------
+bool
+CTrackData::WriteToAnnot(
+    CSeq_annot& annot)
+//  -----------------------------------------------------------------------------
+{
+    if (!ContainsData()) {
+        return false;
+    }
+    CAnnot_descr& desc = annot.SetDesc();
+    CRef<CUser_object> pTrackdata(new CUser_object());
+    pTrackdata->SetType().SetStr("Track Data");
+   
+    if (!Description().empty()) {
+        annot.SetTitleDesc(Description());
+    }
+    if (!Name().empty()) {
+        annot.SetNameDesc(Name());
+    }
+    map<const string,string>::const_iterator cit = Values().begin();
+    while ( cit != Values().end() ) {
+        pTrackdata->AddField( cit->first, cit->second );
+        ++cit;
+    }
+    if ( pTrackdata->CanGetData() && ! pTrackdata->GetData().empty() ) {
+        CRef<CAnnotdesc> user(new CAnnotdesc());
+        user->SetUser(*pTrackdata);
+        desc.Set().push_back(user);
+    }
+    return true;
+}
+
+END_SCOPE(objects)
+END_NCBI_SCOPE
diff --git a/c++/src/objtools/readers/vcf_reader.cpp b/c++/src/objtools/readers/vcf_reader.cpp
index 1031688..2cb5655 100644
--- a/c++/src/objtools/readers/vcf_reader.cpp
+++ b/c++/src/objtools/readers/vcf_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: vcf_reader.cpp 493624 2016-03-01 13:42:25Z ivanov $
+/*  $Id: vcf_reader.cpp 503929 2016-06-09 14:30:25Z foleyjp $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -169,7 +169,8 @@ ESpecNumber SpecNumber(
 //  ----------------------------------------------------------------------------
 CVcfReader::CVcfReader(
     int flags ):
-    CReaderBase(flags)
+    CReaderBase(flags),
+    m_MetaHandled(false)
 //  ----------------------------------------------------------------------------
 {
 }
@@ -193,8 +194,6 @@ CVcfReader::ReadSeqAnnot(
         return CRef<CSeq_annot>();
     }
     CRef< CSeq_annot > annot( new CSeq_annot );
-    CRef< CAnnot_descr > desc( new CAnnot_descr );
-    annot->SetDesc( *desc );
     annot->SetData().SetFtable();
     if (!m_Meta) {
         m_Meta.Reset( new CAnnotdesc );
@@ -245,7 +244,7 @@ CVcfReader::ReadSeqAnnot(
         ProcessWarning(*pErr, pEC);
     }
     xAssignTrackData(annot);
-    xAssignVcfMeta(annot);
+    xAssignVcfMeta(annot, pEC);
     return annot;
 }
 
@@ -270,6 +269,10 @@ CVcfReader::xProcessMetaLine(
 //  ----------------------------------------------------------------------------
 {
     if ( ! NStr::StartsWith( line, "##" ) ) {
+        if ( !m_MetaDirectives.empty() && !m_MetaHandled ) {
+            m_Meta->SetUser().AddField("meta-information", m_MetaDirectives);
+        }
+        m_MetaHandled = true;
         return false;
     }
     m_MetaDirectives.push_back(line.substr(2));
@@ -486,7 +489,6 @@ CVcfReader::xProcessHeaderLine(
     if ( ! NStr::StartsWith( line, "#CHROM" ) ) {
         return false;
     }
-    m_Meta->SetUser().AddField("meta-information", m_MetaDirectives);
 
     //
     //  Per spec:
@@ -517,11 +519,26 @@ CVcfReader::xProcessHeaderLine(
 //  ----------------------------------------------------------------------------
 bool
 CVcfReader::xAssignVcfMeta(
-    CRef<CSeq_annot> pAnnot )
+    CRef<CSeq_annot> pAnnot,
+    ILineErrorListener* pEC)
 //  ----------------------------------------------------------------------------
 {
-    if (m_Meta) {
+    if (m_Meta &&
+        m_Meta->IsUser() &&
+        m_Meta->GetUser().IsSetData()) {
+        if (!pAnnot->IsSetDesc()) {
+            CRef< CAnnot_descr > desc( new CAnnot_descr );
+            pAnnot->SetDesc(*desc);
+        }
         pAnnot->SetDesc().Set().push_back( m_Meta );
+    } else { // VCF input ought to include a header
+        AutoPtr<CObjReaderLineException> pErr(
+            CObjReaderLineException::Create(
+            eDiag_Warning,
+            0,
+            "CVcfReader::xAssignVcfMeta: Missing VCF header data.",
+            ILineError::eProblem_GeneralParsingError) );
+        ProcessWarning(*pErr, pEC);
     }
     return true;
 }
diff --git a/c++/src/objtools/readers/wiggle_reader.cpp b/c++/src/objtools/readers/wiggle_reader.cpp
index 6d2b1a8..a594466 100644
--- a/c++/src/objtools/readers/wiggle_reader.cpp
+++ b/c++/src/objtools/readers/wiggle_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: wiggle_reader.cpp 472933 2015-07-15 13:13:48Z ludwigf $
+/*  $Id: wiggle_reader.cpp 503674 2016-06-07 13:47:01Z ludwigf $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -54,6 +54,7 @@
 #include <objtools/readers/read_util.hpp>
 #include <objtools/readers/line_error.hpp>
 #include <objtools/readers/message_listener.hpp>
+#include <objtools/readers/track_data.hpp>
 #include <objtools/readers/reader_base.hpp>
 #include <objtools/readers/wiggle_reader.hpp>
 
diff --git a/c++/src/objtools/seqmasks_io/mask_bdb_reader.cpp b/c++/src/objtools/seqmasks_io/mask_bdb_reader.cpp
index 5fb96db..c4c7720 100644
--- a/c++/src/objtools/seqmasks_io/mask_bdb_reader.cpp
+++ b/c++/src/objtools/seqmasks_io/mask_bdb_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: mask_bdb_reader.cpp 169629 2009-09-01 17:23:02Z morgulis $
+/*  $Id: mask_bdb_reader.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -30,11 +30,6 @@
  *
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: mask_bdb_reader.cpp 169629 2009-09-01 17:23:02Z morgulis $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbidbg.hpp>
 #include <objtools/readers/fasta.hpp>
diff --git a/c++/src/objtools/seqmasks_io/mask_cmdline_args.cpp b/c++/src/objtools/seqmasks_io/mask_cmdline_args.cpp
index 7dd6f60..22325ae 100644
--- a/c++/src/objtools/seqmasks_io/mask_cmdline_args.cpp
+++ b/c++/src/objtools/seqmasks_io/mask_cmdline_args.cpp
@@ -1,4 +1,4 @@
-/*  $Id: mask_cmdline_args.cpp 123978 2008-04-08 16:50:21Z camacho $
+/*  $Id: mask_cmdline_args.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -31,11 +31,6 @@
  *  
  */
 
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = 
-    "$Id: mask_cmdline_args.cpp 123978 2008-04-08 16:50:21Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/seqmasks_io/mask_cmdline_args.hpp>
 
diff --git a/c++/src/objtools/seqmasks_io/mask_fasta_reader.cpp b/c++/src/objtools/seqmasks_io/mask_fasta_reader.cpp
index 2a7e058..a5db295 100644
--- a/c++/src/objtools/seqmasks_io/mask_fasta_reader.cpp
+++ b/c++/src/objtools/seqmasks_io/mask_fasta_reader.cpp
@@ -1,4 +1,4 @@
-/*  $Id: mask_fasta_reader.cpp 148871 2009-01-05 16:51:12Z camacho $
+/*  $Id: mask_fasta_reader.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  *   CMaskFastaReader class member and method definitions.
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: mask_fasta_reader.cpp 148871 2009-01-05 16:51:12Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <corelib/ncbidbg.hpp>
 #include <objects/seq/Bioseq.hpp>
diff --git a/c++/src/objtools/seqmasks_io/mask_writer.cpp b/c++/src/objtools/seqmasks_io/mask_writer.cpp
index 8fdebc4..1bd1496 100644
--- a/c++/src/objtools/seqmasks_io/mask_writer.cpp
+++ b/c++/src/objtools/seqmasks_io/mask_writer.cpp
@@ -1,4 +1,4 @@
-/*  $Id: mask_writer.cpp 389772 2013-02-20 20:48:34Z camacho $
+/*  $Id: mask_writer.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  *   CMaskWriter class member and method definitions.
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: mask_writer.cpp 389772 2013-02-20 20:48:34Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objects/seq/Seqdesc.hpp>
 #include <objects/seq/Seq_descr.hpp>
diff --git a/c++/src/objtools/seqmasks_io/mask_writer_blastdb_maskinfo.cpp b/c++/src/objtools/seqmasks_io/mask_writer_blastdb_maskinfo.cpp
index 02184f6..5931713 100644
--- a/c++/src/objtools/seqmasks_io/mask_writer_blastdb_maskinfo.cpp
+++ b/c++/src/objtools/seqmasks_io/mask_writer_blastdb_maskinfo.cpp
@@ -1,4 +1,4 @@
-/*  $Id: mask_writer_blastdb_maskinfo.cpp 255510 2011-02-24 17:19:39Z camacho $
+/*  $Id: mask_writer_blastdb_maskinfo.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  *   CMaskWriterBlastDbMaskInfo class member and method definitions.
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: mask_writer_blastdb_maskinfo.cpp 255510 2011-02-24 17:19:39Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/seqmasks_io/mask_writer_blastdb_maskinfo.hpp>
 #include <objtools/seqmasks_io/mask_writer_int.hpp>
diff --git a/c++/src/objtools/seqmasks_io/mask_writer_fasta.cpp b/c++/src/objtools/seqmasks_io/mask_writer_fasta.cpp
index 3200d97..ffd5e2f 100644
--- a/c++/src/objtools/seqmasks_io/mask_writer_fasta.cpp
+++ b/c++/src/objtools/seqmasks_io/mask_writer_fasta.cpp
@@ -1,4 +1,4 @@
-/*  $Id: mask_writer_fasta.cpp 389772 2013-02-20 20:48:34Z camacho $
+/*  $Id: mask_writer_fasta.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  *   CMaskWriterFasta class member and method definitions.
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: mask_writer_fasta.cpp 389772 2013-02-20 20:48:34Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objects/seq/Bioseq.hpp>
 #include <objects/seq/Seq_inst.hpp>
diff --git a/c++/src/objtools/seqmasks_io/mask_writer_int.cpp b/c++/src/objtools/seqmasks_io/mask_writer_int.cpp
index c2249a1..02e7350 100644
--- a/c++/src/objtools/seqmasks_io/mask_writer_int.cpp
+++ b/c++/src/objtools/seqmasks_io/mask_writer_int.cpp
@@ -1,4 +1,4 @@
-/*  $Id: mask_writer_int.cpp 389772 2013-02-20 20:48:34Z camacho $
+/*  $Id: mask_writer_int.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  *   CMaskWriterInt class member and method definitions.
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: mask_writer_int.cpp 389772 2013-02-20 20:48:34Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/seqmasks_io/mask_writer_int.hpp>
 #include <objects/seqloc/Seq_loc.hpp>
diff --git a/c++/src/objtools/seqmasks_io/mask_writer_seqloc.cpp b/c++/src/objtools/seqmasks_io/mask_writer_seqloc.cpp
index 11a7298..6665030 100644
--- a/c++/src/objtools/seqmasks_io/mask_writer_seqloc.cpp
+++ b/c++/src/objtools/seqmasks_io/mask_writer_seqloc.cpp
@@ -1,4 +1,4 @@
-/*  $Id: mask_writer_seqloc.cpp 183173 2010-02-12 18:29:18Z camacho $
+/*  $Id: mask_writer_seqloc.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  *   CMaskWriterSeqLoc class member and method definitions.
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: mask_writer_seqloc.cpp 183173 2010-02-12 18:29:18Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/seqmasks_io/mask_writer_seqloc.hpp>
 #include <objects/seqloc/Seq_loc.hpp>
diff --git a/c++/src/objtools/seqmasks_io/mask_writer_tab.cpp b/c++/src/objtools/seqmasks_io/mask_writer_tab.cpp
index d2bdfb6..79eb3bf 100644
--- a/c++/src/objtools/seqmasks_io/mask_writer_tab.cpp
+++ b/c++/src/objtools/seqmasks_io/mask_writer_tab.cpp
@@ -1,4 +1,4 @@
-/*  $Id: mask_writer_tab.cpp 389772 2013-02-20 20:48:34Z camacho $
+/*  $Id: mask_writer_tab.cpp 500404 2016-05-04 14:59:01Z camacho $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -29,11 +29,6 @@
  *   CMaskWriterTabular class member and method definitions.
  *
  */
-
-#ifndef SKIP_DOXYGEN_PROCESSING
-static char const rcsid[] = "$Id: mask_writer_tab.cpp 389772 2013-02-20 20:48:34Z camacho $";
-#endif /* SKIP_DOXYGEN_PROCESSING */
-
 #include <ncbi_pch.hpp>
 #include <objtools/seqmasks_io/mask_writer_tab.hpp>
 #include <objects/seqloc/Seq_loc.hpp>
diff --git a/c++/src/serial/aliasinfo.cpp b/c++/src/serial/aliasinfo.cpp
index e79e259..4a96123 100644
--- a/c++/src/serial/aliasinfo.cpp
+++ b/c++/src/serial/aliasinfo.cpp
@@ -1,4 +1,4 @@
-/*  $Id: aliasinfo.cpp 405847 2013-07-09 13:56:53Z gouriano $
+/*  $Id: aliasinfo.cpp 498023 2016-04-12 18:53:26Z grichenk $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -228,4 +228,14 @@ template class NCBI_XSERIAL_EXPORT CStringAliasBase<string>;
 template class NCBI_XSERIAL_EXPORT CAliasBase< vector<char> >;
 template class NCBI_XSERIAL_EXPORT CStringAliasBase< vector<char> >;
 
+#ifdef NCBI_INT8_GI
+template class NCBI_XSERIAL_EXPORT CAliasBase<TIntId>;
+template class NCBI_XSERIAL_EXPORT CStdAliasBase<TIntId>;
+#endif
+
+#ifdef NCBI_STRICT_GI
+template class NCBI_XSERIAL_EXPORT CAliasBase<CStrictId64>;
+template class NCBI_XSERIAL_EXPORT CStdAliasBase<CStrictId64>;
+#endif
+
 END_NCBI_SCOPE
diff --git a/c++/src/serial/choice.cpp b/c++/src/serial/choice.cpp
index 4c6a2d0..dddaaa0 100644
--- a/c++/src/serial/choice.cpp
+++ b/c++/src/serial/choice.cpp
@@ -1,4 +1,4 @@
-/*  $Id: choice.cpp 497436 2016-04-06 17:56:51Z ivanov $
+/*  $Id: choice.cpp 497217 2016-04-05 11:37:33Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/serial/classinfo.cpp b/c++/src/serial/classinfo.cpp
index 4b9d7c1..00260e6 100644
--- a/c++/src/serial/classinfo.cpp
+++ b/c++/src/serial/classinfo.cpp
@@ -1,4 +1,4 @@
-/*  $Id: classinfo.cpp 497436 2016-04-06 17:56:51Z ivanov $
+/*  $Id: classinfo.cpp 497217 2016-04-05 11:37:33Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/serial/datatool/aliasstr.cpp b/c++/src/serial/datatool/aliasstr.cpp
index 4654c7a..6e326dc 100644
--- a/c++/src/serial/datatool/aliasstr.cpp
+++ b/c++/src/serial/datatool/aliasstr.cpp
@@ -1,4 +1,4 @@
-/*  $Id: aliasstr.cpp 412225 2013-09-05 15:31:52Z gouriano $
+/*  $Id: aliasstr.cpp 507796 2016-07-21 17:25:37Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -31,6 +31,7 @@
 
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiutil.hpp>
+#include "datatool.hpp"
 #include "exceptions.hpp"
 #include "type.hpp"
 #include "aliasstr.hpp"
@@ -324,6 +325,7 @@ void CAliasTypeStrings::GenerateCode(CClassContext& ctx) const
                 "    SET_FULL_ALIAS;\n"
                 "\n";
         }
+        methods <<  "    info->CodeVersion(" << DATATOOL_VERSION << ");\n";
         methods <<
             "}\n"
             "END_ALIAS_INFO\n"
diff --git a/c++/src/serial/datatool/choiceptrstr.cpp b/c++/src/serial/datatool/choiceptrstr.cpp
index 11f3378..06308e5 100644
--- a/c++/src/serial/datatool/choiceptrstr.cpp
+++ b/c++/src/serial/datatool/choiceptrstr.cpp
@@ -1,4 +1,4 @@
-/*  $Id: choiceptrstr.cpp 412225 2013-09-05 15:31:52Z gouriano $
+/*  $Id: choiceptrstr.cpp 507796 2016-07-21 17:25:37Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -33,6 +33,7 @@
 #include <ncbi_pch.hpp>
 #include <corelib/ncbistd.hpp>
 #include <serial/serialdef.hpp>
+#include "datatool.hpp"
 #include "choiceptrstr.hpp"
 #include "code.hpp"
 #include "namespace.hpp"
@@ -161,6 +162,7 @@ void CChoicePtrTypeStrings::GenerateClassCode(CClassCode& code,
                 "    ADD_NAMED_SUB_CLASS(\""<<i->externalName<<"\", "<<i->type->GetCType(code.GetNamespace())<<");\n";
         }
     }
+    code.Methods() <<  "    info->CodeVersion(" << DATATOOL_VERSION << ");\n";
     code.Methods() <<
         "}\n"
         "END_CLASS_INFO\n"
diff --git a/c++/src/serial/datatool/choicestr.cpp b/c++/src/serial/datatool/choicestr.cpp
index 2aa4533..5970b57 100644
--- a/c++/src/serial/datatool/choicestr.cpp
+++ b/c++/src/serial/datatool/choicestr.cpp
@@ -1,4 +1,4 @@
-/*  $Id: choicestr.cpp 477153 2015-08-26 18:45:21Z vasilche $
+/*  $Id: choicestr.cpp 507796 2016-07-21 17:25:37Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -32,6 +32,7 @@
 
 #include <ncbi_pch.hpp>
 #include <corelib/ncbiutil.hpp>
+#include "datatool.hpp"
 #include "exceptions.hpp"
 #include "type.hpp"
 #include "blocktype.hpp"
@@ -1603,6 +1604,7 @@ void CChoiceTypeStrings::GenerateClassCode(CClassCode& code,
             methods << ";\n";
         }
     }
+    methods <<  "    info->CodeVersion(" << DATATOOL_VERSION << ");\n";
     methods <<
         "}\n"
         "END_CHOICE_INFO\n"
diff --git a/c++/src/serial/datatool/classstr.cpp b/c++/src/serial/datatool/classstr.cpp
index bdc2ead..3d8d8b9 100644
--- a/c++/src/serial/datatool/classstr.cpp
+++ b/c++/src/serial/datatool/classstr.cpp
@@ -1,4 +1,4 @@
-/*  $Id: classstr.cpp 461337 2015-03-09 18:00:58Z gouriano $
+/*  $Id: classstr.cpp 507796 2016-07-21 17:25:37Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -30,6 +30,7 @@
 */
 
 #include <ncbi_pch.hpp>
+#include "datatool.hpp"
 #include "exceptions.hpp"
 #include "type.hpp"
 #include "blocktype.hpp"
@@ -1467,6 +1468,7 @@ void CClassTypeStrings::GenerateClassCode(CClassCode& code,
             methods << "    info->RandomOrder();\n";
         }
     }
+    methods <<  "    info->CodeVersion(" << DATATOOL_VERSION << ");\n";
     methods <<
         "}\n"
         "END_CLASS_INFO\n"
diff --git a/c++/src/serial/datatool/datatool.cpp b/c++/src/serial/datatool/datatool.cpp
index b381b54..74d69db 100644
--- a/c++/src/serial/datatool/datatool.cpp
+++ b/c++/src/serial/datatool/datatool.cpp
@@ -1,4 +1,4 @@
-/*  $Id: datatool.cpp 485907 2015-11-30 14:26:20Z gouriano $
+/*  $Id: datatool.cpp 507796 2016-07-21 17:25:37Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -88,7 +88,7 @@ int CDataTool::Run(void)
 
 CDataTool::CDataTool(void)
 {
-    SetVersion( CVersionInfo(2,14,0) );
+    SetVersion( CVersionInfo(DATATOOL_VERSION_MAJOR,DATATOOL_VERSION_MINOR,DATATOOL_VERSION_PATCH) );
 }
 
 void CDataTool::Init(void)
diff --git a/c++/src/serial/datatool/datatool.hpp b/c++/src/serial/datatool/datatool.hpp
index 30b0b05..ccfaeaf 100644
--- a/c++/src/serial/datatool/datatool.hpp
+++ b/c++/src/serial/datatool/datatool.hpp
@@ -1,7 +1,7 @@
 #ifndef DATATOOL__HPP
 #define DATATOOL__HPP
 
-/*  $Id: datatool.hpp 461580 2015-03-11 13:15:39Z gouriano $
+/*  $Id: datatool.hpp 507796 2016-07-21 17:25:37Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -40,6 +40,11 @@
 
 BEGIN_NCBI_SCOPE
 
+#define DATATOOL_VERSION_MAJOR  2
+#define DATATOOL_VERSION_MINOR 16
+#define DATATOOL_VERSION_PATCH  0
+const size_t DATATOOL_VERSION = DATATOOL_VERSION_MAJOR*10000 + DATATOOL_VERSION_MINOR*100 + DATATOOL_VERSION_PATCH; 
+
 class CArgs;
 class CFileSet;
 
diff --git a/c++/src/serial/datatool/dtdaux.cpp b/c++/src/serial/datatool/dtdaux.cpp
index 2f0ec35..fa524ac 100644
--- a/c++/src/serial/datatool/dtdaux.cpp
+++ b/c++/src/serial/datatool/dtdaux.cpp
@@ -1,4 +1,4 @@
-/*  $Id: dtdaux.cpp 406003 2013-07-10 13:17:43Z gouriano $
+/*  $Id: dtdaux.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -449,7 +449,7 @@ string DTDElement::CreateEmbeddedName(int depth) const
     list<string>::const_iterator i;
     for ( i = m_Refs.begin(); i != m_Refs.end(); ++i) {
         tmp = i->substr(0,depth);
-        tmp[0] = toupper((unsigned char) tmp[0]);
+        tmp[0] = (char)toupper((unsigned char) tmp[0]);
         name += tmp;
     }
     if (m_Type == eAny) {
diff --git a/c++/src/serial/datatool/dtdparser.cpp b/c++/src/serial/datatool/dtdparser.cpp
index ec62bc8..859f5d0 100644
--- a/c++/src/serial/datatool/dtdparser.cpp
+++ b/c++/src/serial/datatool/dtdparser.cpp
@@ -1,4 +1,4 @@
-/*  $Id: dtdparser.cpp 466898 2015-05-07 13:36:43Z gouriano $
+/*  $Id: dtdparser.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -562,7 +562,7 @@ string DTDParser::CreateEmbeddedName(const DTDElement& node, int depth) const
             if (!refname.empty()) {
                 string::size_type name = refname.find(':');
                 name = (name != string::npos && (name+1) < refname.size()) ? (name+1) : 0;
-                new_var += toupper((unsigned char) refname[name]);;
+                new_var += (char)toupper((unsigned char) refname[name]);;
 // try to avoid very long names
                 if (new_var.size() > 8) {
                     break;
@@ -732,7 +732,7 @@ bool DTDParser::PopEntityLexer(void)
 }
 
 AbstractLexer* DTDParser::CreateEntityLexer(
-    CNcbiIstream& in, const string& name, bool autoDelete /*=true*/)
+    CNcbiIstream& in, const string& name, bool /*autoDelete*/ /*=true*/)
 {
     return new DTDEntityLexer(in,name);
 }
@@ -1251,16 +1251,16 @@ CDataType* DTDParser::TypesBlock(
                 if (uniseq2 || (optional && refseq)) {
                     refname.insert(0,"E");
                 }
-                AutoPtr<CDataMemberContainerType> container(new CDataSequenceType());
+                AutoPtr<CDataMemberContainerType> type_container(new CDataSequenceType());
                 AutoPtr<CDataMember> member(new CDataMember(refname, type));
-                container->SetSourceLine(type->GetSourceLine());
+                type_container->SetSourceLine(type->GetSourceLine());
                 if (optional) {
                     member->SetOptional();
                 }
                 member->SetNotag();
                 member->SetNoPrefix();
-                container->AddMember(member);
-                type.reset(container.release());
+                type_container->AddMember(member);
+                type.reset(type_container.release());
             }
             else if (uniseq2 && setnil) {
 // the idea is to make it implicit
diff --git a/c++/src/serial/datatool/enumtype.cpp b/c++/src/serial/datatool/enumtype.cpp
index 7cc913f..673a105 100644
--- a/c++/src/serial/datatool/enumtype.cpp
+++ b/c++/src/serial/datatool/enumtype.cpp
@@ -1,4 +1,4 @@
-/*  $Id: enumtype.cpp 485707 2015-11-25 13:58:19Z gouriano $
+/*  $Id: enumtype.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -120,8 +120,7 @@ void CEnumDataType::PrintSpecDumpExtra(CNcbiOstream& out, int indent) const
 // XML schema generator submitted by
 // Marc Dumontier, Blueprint initiative, dumontier at mshri.on.ca
 // modified by Andrei Gourianov, gouriano at ncbi
-void CEnumDataType::PrintXMLSchema(CNcbiOstream& out,
-    int indent, bool contents_only) const
+void CEnumDataType::PrintXMLSchema(CNcbiOstream& out, int indent, bool /*contents_only*/) const
 {
     string tag(XmlTagName());
     string use("required");
@@ -237,7 +236,7 @@ void CEnumDataType::PrintXMLSchema(CNcbiOstream& out,
     m_LastComments.PrintDTD(out, CComments::eMultiline);
 }
 
-void CEnumDataType::PrintDTDElement(CNcbiOstream& out, bool contents_only) const
+void CEnumDataType::PrintDTDElement(CNcbiOstream& out, bool /*contents_only*/) const
 {
     string tag(XmlTagName());
     string content(GetXMLContents());
diff --git a/c++/src/serial/datatool/exceptions.hpp b/c++/src/serial/datatool/exceptions.hpp
index a023fee..f46ce39 100644
--- a/c++/src/serial/datatool/exceptions.hpp
+++ b/c++/src/serial/datatool/exceptions.hpp
@@ -1,7 +1,7 @@
 #ifndef DATATOOL_EXCEPTIONS_HPP
 #define DATATOOL_EXCEPTIONS_HPP
 
-/*  $Id: exceptions.hpp 122761 2008-03-25 16:45:09Z gouriano $
+/*  $Id: exceptions.hpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -74,6 +74,7 @@ class CNotFoundException : public CDatatoolException
 {
 public:
     enum EErrCode {
+        eInvalid = CException::eInvalid,
         eType,
         eModule
     };
@@ -107,9 +108,8 @@ public:
                      EErrCode err_code, const string& message,
                      const list<CDataType*>& types, 
                      EDiagSev severity = eDiag_Error) THROWS_NONE
-        : CNotFoundException(info, prev_exception,
-            (CNotFoundException::EErrCode) CException::eInvalid,
-            message), m_Types(types)
+        : CNotFoundException(info, prev_exception, CNotFoundException::eInvalid, message),
+          m_Types(types)
     NCBI_EXCEPTION_DEFAULT_IMPLEMENTATION(CAmbiguiousTypes, CNotFoundException);
 
 public:
diff --git a/c++/src/serial/datatool/filecode.cpp b/c++/src/serial/datatool/filecode.cpp
index 088e679..585911e 100644
--- a/c++/src/serial/datatool/filecode.cpp
+++ b/c++/src/serial/datatool/filecode.cpp
@@ -1,4 +1,4 @@
-/*  $Id: filecode.cpp 485907 2015-11-30 14:26:20Z gouriano $
+/*  $Id: filecode.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -127,7 +127,7 @@ string CFileCode::GetDefineBase(void) const
     ITERATE ( string, i, GetFileBaseName() ) {
         char c = *i;
         if ( c >= 'a' && c <= 'z' )
-            c = c + ('A' - 'a');
+            c = (char)(c + ('A' - 'a'));
         else if ( (c < 'A' || c > 'Z') &&
                   (c < '0' || c > '9') )
             c = '_';
diff --git a/c++/src/serial/datatool/fileutil.cpp b/c++/src/serial/datatool/fileutil.cpp
index e8ea2a8..6739fd1 100644
--- a/c++/src/serial/datatool/fileutil.cpp
+++ b/c++/src/serial/datatool/fileutil.cpp
@@ -1,4 +1,4 @@
-/*  $Id: fileutil.cpp 435421 2014-05-15 19:29:47Z ucko $
+/*  $Id: fileutil.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -288,7 +288,8 @@ string GetStdPath(const string& path)
 {
     string stdpath = path;
     // Replace each native separator character with the 'standard' one.
-    SIZE_TYPE ibeg = NStr::StartsWith(path, "http://", NStr::eNocase) ? 7 : 0;
+    SIZE_TYPE ibeg = NStr::StartsWith(path, "http://", NStr::eNocase) ? 7 : 
+                    (NStr::StartsWith(path, "https://", NStr::eNocase) ? 8 : 0);
     for (SIZE_TYPE i=ibeg ; i < stdpath.size(); i++) {
 #ifdef NCBI_OS_MSWIN
         if ( i==1 && IsDiskSeparator(stdpath[i]) ) {
@@ -307,8 +308,8 @@ string GetStdPath(const string& path)
 class SSubString
 {
 public:
-    SSubString(const string& value, size_t order)
-        : value(value), order(order)
+    SSubString(const string& val, size_t ord)
+        : value(val), order(ord)
         {
         }
 
diff --git a/c++/src/serial/datatool/module.cpp b/c++/src/serial/datatool/module.cpp
index a7b705b..fb1a994 100644
--- a/c++/src/serial/datatool/module.cpp
+++ b/c++/src/serial/datatool/module.cpp
@@ -1,4 +1,4 @@
-/*  $Id: module.cpp 485707 2015-11-25 13:58:19Z gouriano $
+/*  $Id: module.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -597,7 +597,7 @@ string CDataTypeModule::ToAsnName(const string& name)
         unsigned char u = (unsigned char)(*i);
         if (first) {
             if (isalpha(u)) {
-                asn += toupper(u);
+                asn += (char)toupper(u);
             } else {
                 asn += 'A';
                 if (isdigit(u)) {
@@ -626,7 +626,7 @@ string CDataTypeModule::ToAsnName(const string& name)
 string CDataTypeModule::ToAsnId(const string& name)
 {
     string asn(name);
-    asn[0] = tolower((unsigned char)asn[0]);
+    asn[0] = (char)tolower((unsigned char)asn[0]);
     return asn;
 }
 
diff --git a/c++/src/serial/datatool/parser.cpp b/c++/src/serial/datatool/parser.cpp
index c46036a..b2d3a17 100644
--- a/c++/src/serial/datatool/parser.cpp
+++ b/c++/src/serial/datatool/parser.cpp
@@ -1,4 +1,4 @@
-/*  $Id: parser.cpp 467208 2015-05-11 17:01:47Z gouriano $
+/*  $Id: parser.cpp 507796 2016-07-21 17:25:37Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -236,7 +236,7 @@ CDataType* ASNParser::x_Type(void)
         if ( CheckSymbol('{') )
             return EnumeratedBlock(new CBigIntEnumDataType());
         else
-            return new CBigIntDataType();
+            return new CBigIntDataType(true);
     case K_ENUMERATED:
         Consume();
         return EnumeratedBlock(new CEnumDataType());
diff --git a/c++/src/serial/datatool/srcutil.cpp b/c++/src/serial/datatool/srcutil.cpp
index 326bd04..3261713 100644
--- a/c++/src/serial/datatool/srcutil.cpp
+++ b/c++/src/serial/datatool/srcutil.cpp
@@ -1,4 +1,4 @@
-/*  $Id: srcutil.cpp 462658 2015-03-20 13:05:49Z gouriano $
+/*  $Id: srcutil.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -44,7 +44,7 @@ string Identifier(const string& typeName, bool capitalize)
     string::const_iterator i = typeName.begin();
     if ( i != typeName.end() ) {
         if (isalnum((unsigned char)(*i))) {
-            s += capitalize? toupper((unsigned char)(*i)): *i;
+            s += capitalize? (char)toupper((unsigned char)(*i)) : *i;
         } else {
             string ent(NStr::HtmlEntity((unsigned char)(*i)));
             if (*i != '_' && !ent.empty()) {
diff --git a/c++/src/serial/datatool/statictype.cpp b/c++/src/serial/datatool/statictype.cpp
index 38556b3..460d92b 100644
--- a/c++/src/serial/datatool/statictype.cpp
+++ b/c++/src/serial/datatool/statictype.cpp
@@ -1,4 +1,4 @@
-/*  $Id: statictype.cpp 485707 2015-11-25 13:58:19Z gouriano $
+/*  $Id: statictype.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -61,7 +61,7 @@ void CStaticDataType::PrintASN(CNcbiOstream& out, int /*indent*/) const
 // Marc Dumontier, Blueprint initiative, dumontier at mshri.on.ca
 // modified by Andrei Gourianov, gouriano at ncbi
 void CStaticDataType::PrintXMLSchema(CNcbiOstream& out,
-    int indent, bool contents_only) const
+    int indent, bool /*contents_only*/) const
 {
     string tag( XmlTagName());
     string xsdk("element"), use, form;
@@ -560,7 +560,11 @@ AutoPtr<CTypeStrings> CStringDataType::GetFullCType(void) const
     bool full_ns = !type.empty();
     if ( type.empty() )
         type = GetDefaultCType();
-    return AutoPtr<CTypeStrings>(new CStringTypeStrings(type,Comments(),full_ns));
+    AutoPtr<CTypeStrings> a = AutoPtr<CTypeStrings>(new CStringTypeStrings(type,Comments(),full_ns));
+    if (m_Type == eStringTypeUTF8) {
+        a->SetSpecialRef("CStringUTF8, ()");
+    }
+    return a;
 }
 
 const char* CStringDataType::GetDefaultCType(void) const
@@ -852,6 +856,14 @@ const char* CBigIntDataType::GetDefaultCType(void) const
     return "Int8";
 }
 
+AutoPtr<CTypeStrings> CBigIntDataType::GetFullCType(void) const
+{
+    AutoPtr<CTypeStrings> a = CParent::GetFullCType();
+    if (m_bAsnBigInt) {
+        a->SetSpecialRef("BigInt, ()");
+    }
+    return a;
+}
 
 bool CAnyContentDataType::CheckValue(const CDataValue& /* value */) const
 {
diff --git a/c++/src/serial/datatool/statictype.hpp b/c++/src/serial/datatool/statictype.hpp
index b12c2ce..65515e7 100644
--- a/c++/src/serial/datatool/statictype.hpp
+++ b/c++/src/serial/datatool/statictype.hpp
@@ -1,7 +1,7 @@
 #ifndef STATICTYPE_HPP
 #define STATICTYPE_HPP
 
-/*  $Id: statictype.hpp 485707 2015-11-25 13:58:19Z gouriano $
+/*  $Id: statictype.hpp 507796 2016-07-21 17:25:37Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -204,16 +204,21 @@ public:
 class CBigIntDataType : public CIntDataType {
     typedef CIntDataType CParent;
 public:
+    CBigIntDataType(bool bAsnBigInt = false) : m_bAsnBigInt(bAsnBigInt) {
+    }
     bool CheckValue(const CDataValue& value) const;
     TObjectPtr CreateDefault(const CDataValue& value) const;
     virtual string GetDefaultString(const CDataValue& value) const;
 
     CTypeRef GetTypeInfo(void);
+    virtual AutoPtr<CTypeStrings> GetFullCType(void) const;
     virtual const char* GetDefaultCType(void) const;
     virtual const char* GetASNKeyword(void) const;
     virtual const char* GetDEFKeyword(void) const;
     virtual const char* GetXMLContents(void) const;
     virtual string GetSchemaTypeString(void) const;
+protected:
+    bool m_bAsnBigInt;
 };
 
 class CAnyContentDataType : public CStaticDataType {
diff --git a/c++/src/serial/datatool/stdstr.cpp b/c++/src/serial/datatool/stdstr.cpp
index d354014..6c266ba 100644
--- a/c++/src/serial/datatool/stdstr.cpp
+++ b/c++/src/serial/datatool/stdstr.cpp
@@ -1,4 +1,4 @@
-/*  $Id: stdstr.cpp 395047 2013-04-09 13:58:30Z gouriano $
+/*  $Id: stdstr.cpp 507796 2016-07-21 17:25:37Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -79,15 +79,10 @@ string CStdTypeStrings::GetPrefixedCType(const CNamespace& ns,
     return GetCType(ns);
 }
 
-bool CStdTypeStrings::HaveSpecialRef(void) const
-{
-    return NStr::EndsWith(m_CType, "CStringUTF8");
-}
-
 string CStdTypeStrings::GetRef(const CNamespace& ns) const
 {
     if (HaveSpecialRef()) {
-        return "CStringUTF8, ()";
+        return CTypeStrings::GetRef(ns);
     }
     return "STD, ("+GetCType(ns)+')';
 }
diff --git a/c++/src/serial/datatool/stdstr.hpp b/c++/src/serial/datatool/stdstr.hpp
index e6397be..11888c0 100644
--- a/c++/src/serial/datatool/stdstr.hpp
+++ b/c++/src/serial/datatool/stdstr.hpp
@@ -1,7 +1,7 @@
 #ifndef STDSTR_HPP
 #define STDSTR_HPP
 
-/*  $Id: stdstr.hpp 395047 2013-04-09 13:58:30Z gouriano $
+/*  $Id: stdstr.hpp 507796 2016-07-21 17:25:37Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -48,7 +48,6 @@ public:
     string GetCType(const CNamespace& ns) const;
     string GetPrefixedCType(const CNamespace& ns,
                             const string& methodPrefix) const;
-    virtual bool HaveSpecialRef(void) const;
     string GetRef(const CNamespace& ns) const;
     string GetInitializer(void) const;
 
diff --git a/c++/src/serial/datatool/traversal_code_generator.cpp b/c++/src/serial/datatool/traversal_code_generator.cpp
index 69c4cee..a98dc8b 100644
--- a/c++/src/serial/datatool/traversal_code_generator.cpp
+++ b/c++/src/serial/datatool/traversal_code_generator.cpp
@@ -1,4 +1,4 @@
-/*  $Id: traversal_code_generator.cpp 443700 2014-08-18 18:10:33Z vasilche $
+/*  $Id: traversal_code_generator.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -69,7 +69,7 @@ public:
     bool Call( CTraversalNode& node, const CTraversalNode::TNodeVec &node_path, ECallType is_cyclic ) {
 
         // print indentation
-        const int depth = node_path.size() - 1;
+        const size_t depth = node_path.size() - 1;
         m_Ostream << string( depth * 2, ' ' );
 
         if( node.GetType() == CTraversalNode::eType_Reference ) {
@@ -101,7 +101,7 @@ public:
     CGenerateIncludesCallback( CNcbiOstream& ostream ) 
         : m_Ostream(ostream) { }
 
-    bool Call( CTraversalNode& node, const CTraversalNode::TNodeVec &node_path, ECallType is_cyclic ) {
+    bool Call( CTraversalNode& node, const CTraversalNode::TNodeVec& /*node_path*/, ECallType /*is_cyclic*/ ) {
 
         // We can't generate an include for an unknown type
         if( node.IsTemplate() ) {
@@ -173,7 +173,7 @@ public:
     CGenerateCodeCallback( const string &class_name, CNcbiOstream& ostream, CTraversalNode::EGenerateMode generate_mode ) 
         : m_Ostream(ostream), m_ClassName(class_name), m_GenerateMode(generate_mode) { }
 
-    bool Call( CTraversalNode& node, const CTraversalNode::TNodeVec &node_path, ECallType is_cyclic ) {
+    bool Call( CTraversalNode& node, const CTraversalNode::TNodeVec& /*node_path*/, ECallType /*is_cyclic*/ ) {
 
         // skip functions we've already output
         if( m_NodesSeen.find( node.Ref() ) != m_NodesSeen.end() ) {
@@ -205,7 +205,7 @@ public:
     CAddToNodeSetCallback( CTraversalNode::TNodeSet &set_to_add_to )
         : m_SetToAddTo(set_to_add_to) { }
 
-    bool Call( CTraversalNode& node, const CTraversalNode::TNodeVec &node_path, ECallType is_cyclic ) {
+    bool Call( CTraversalNode& node, const CTraversalNode::TNodeVec& /*node_path*/, ECallType /*is_cyclic*/ ) {
         // we've already seen this node, so don't traverse its "children" again
         if( m_SetToAddTo.find( node.Ref() ) != m_SetToAddTo.end() ) {
             return false;
@@ -227,7 +227,7 @@ public:
     CGenerateStoredArgVariablesCallback( CNcbiOstream& ostream )
         : m_Ostream(ostream) { }
 
-    bool Call( CTraversalNode& node, const CTraversalNode::TNodeVec &node_path, ECallType is_cyclic ) {
+    bool Call( CTraversalNode& node, const CTraversalNode::TNodeVec& /*node_path*/, ECallType /*is_cyclic*/ ) {
         if( node.GetDoStoreArg() ) {
             const string arg_var = node.GetStoredArgVariable();
             if( m_Args_seen.find(arg_var) == m_Args_seen.end() ) {
@@ -251,7 +251,7 @@ public:
     CGenerateStoredArgInitializerCallback( CNcbiOstream& ostream ) 
         : m_Ostream(ostream) { }
 
-    bool Call( CTraversalNode& node, const CTraversalNode::TNodeVec &node_path, ECallType is_cyclic ) {
+    bool Call( CTraversalNode& node, const CTraversalNode::TNodeVec& /*node_path*/, ECallType /*is_cyclic*/ ) {
         if( node.GetDoStoreArg() ) {
             const string arg_var = node.GetStoredArgVariable();
             if( m_Args_seen.find(arg_var) == m_Args_seen.end() ) {
@@ -558,7 +558,7 @@ void CTraversalCodeGenerator::x_GetIncludeGuard( string& include_guard_define, c
 void CTraversalCodeGenerator::x_GenerateSourceFile(
     const std::vector<std::string> & output_class_namespace,
     const string &output_class_name,
-    const string &headerFileName,
+    const string &/*headerFileName*/,
     CNcbiOstream& traversal_source_file,
     vector< CRef<CTraversalNode> > &rootTraversalNodes,
     const std::vector<std::string> &source_includes )
@@ -627,7 +627,7 @@ std::string CTraversalCodeGenerator::x_MemberVarNameToArg(const std::string &mem
     // remove initial m_ and make first letter lowercase
     _ASSERT( NStr::StartsWith(member_var_name, "m_") );
     string result = member_var_name.substr(2);
-    result[0] = tolower(result[0]);
+    result[0] = (char)tolower(result[0]);
     return result;
 }
 
diff --git a/c++/src/serial/datatool/traversal_node.cpp b/c++/src/serial/datatool/traversal_node.cpp
index 5aedc3c..687137c 100644
--- a/c++/src/serial/datatool/traversal_node.cpp
+++ b/c++/src/serial/datatool/traversal_node.cpp
@@ -1,4 +1,4 @@
-/*  $Id: traversal_node.cpp 404668 2013-06-26 12:55:17Z kornbluh $
+/*  $Id: traversal_node.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -259,7 +259,7 @@ void CTraversalNode::GenerateCode( const string &func_class_name, CNcbiOstream&
                 traversal_output_file << "  switch( arg0.Which() ) {" << endl;
                 ITERATE( TNodeCallSet, child_iter, m_Callees ) {
                     string case_name = (*child_iter)->GetVarName();
-                    case_name[0] = toupper(case_name[0]);
+                    case_name[0] = (char)toupper(case_name[0]);
                     NStr::ReplaceInPlace( case_name, "-", "_" );
                     traversal_output_file << "  case " << m_InputClassName << "::e_" << case_name << ":" << endl;;
                     string argString = string("arg0.Set") + case_name + "()";
@@ -275,7 +275,7 @@ void CTraversalNode::GenerateCode( const string &func_class_name, CNcbiOstream&
             {
                 ITERATE( TNodeCallSet, child_iter, m_Callees ) {
                     string case_name = (*child_iter)->GetVarName();
-                    case_name[0] = toupper(case_name[0]);
+                    case_name[0] = (char)toupper(case_name[0]);
                     NStr::ReplaceInPlace( case_name, "-", "_" );
                     traversal_output_file << "  if( arg0.IsSet" << case_name << "() ) {" << endl;;
                     string argString = string("arg0.Set") + case_name + "()";
@@ -290,7 +290,7 @@ void CTraversalNode::GenerateCode( const string &func_class_name, CNcbiOstream&
                 CRef<CNodeCall> child_call = *m_Callees.begin();
                 string case_name = child_call->GetVarName();
                 CRef<CTraversalNode> child = child_call->GetNode();
-                case_name[0] = toupper(case_name[0]);
+                case_name[0] = (char)toupper(case_name[0]);
                 NStr::ReplaceInPlace( case_name, "-", "_" );
 
                 // some reference functions pass their argument directly and others
@@ -318,7 +318,7 @@ void CTraversalNode::GenerateCode( const string &func_class_name, CNcbiOstream&
                 CRef<CNodeCall> child_call = *m_Callees.begin();
                 string case_name = child_call->GetVarName();
                 CRef<CTraversalNode> child = child_call->GetNode();
-                case_name[0] = toupper(case_name[0]);
+                case_name[0] = (char)toupper(case_name[0]);
                 NStr::ReplaceInPlace( case_name, "-", "_" );
                 const char *input_class_prefix = ( m_IsTemplate ? "typename " : kEmptyCStr );
                 traversal_output_file << "  NON_CONST_ITERATE( " << input_class_prefix << m_InputClassName << ", iter, arg0 ) { " << endl;
@@ -632,7 +632,7 @@ void CTraversalNode::x_TemplatizeType( string &type_name )
     }
 
     NStr::ToLower( result );
-    result[0] = toupper(result[0]);
+    result[0] = (char)toupper(result[0]);
 
     type_name.swap( result );
 }
@@ -643,7 +643,7 @@ bool CTraversalNode::x_IsSeqFeat(void)
 }
 
 void 
-CTraversalNode::x_MergeNames( string &result, const string &name1, const string &name2 )
+CTraversalNode::x_MergeNames(string &result, const string& /*name1*/, const string& /*name2*/)
 {
     // the other names are ignored, but maybe in the future, we'll use them
     if( ! NStr::EndsWith(result, "_ETC" ) ) {
diff --git a/c++/src/serial/datatool/traversal_pattern_match_callback.cpp b/c++/src/serial/datatool/traversal_pattern_match_callback.cpp
index c050d88..be93bb9 100644
--- a/c++/src/serial/datatool/traversal_pattern_match_callback.cpp
+++ b/c++/src/serial/datatool/traversal_pattern_match_callback.cpp
@@ -1,4 +1,4 @@
-/*  $Id: traversal_pattern_match_callback.cpp 348987 2012-01-06 14:04:00Z kornbluh $
+/*  $Id: traversal_pattern_match_callback.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -229,7 +229,7 @@ CRef<CTraversalNode> CTraversalPatternMatchCallback::x_TranslateArgToNode(
     const CTraversalSpecFileParser::TPattern &extra_arg_pattern )
 {
     // how many levels do we have to climb up to find the extra_arg_pattern?
-    const int levels_to_climb = ( main_pattern.size() - extra_arg_pattern.size() );
+    const int levels_to_climb = (int)(main_pattern.size() - extra_arg_pattern.size());
 
     // climb up
     int level_up = 0;
diff --git a/c++/src/serial/datatool/traversal_spec_file_parser.cpp b/c++/src/serial/datatool/traversal_spec_file_parser.cpp
index ecdb95b..08fe065 100644
--- a/c++/src/serial/datatool/traversal_spec_file_parser.cpp
+++ b/c++/src/serial/datatool/traversal_spec_file_parser.cpp
@@ -1,4 +1,4 @@
-/*  $Id: traversal_spec_file_parser.cpp 485907 2015-11-30 14:26:20Z gouriano $
+/*  $Id: traversal_spec_file_parser.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -256,7 +256,7 @@ void CTraversalSpecFileParser::CDescFileNode::ConvertToMemberMacro(void)
     // transform the member_arg to match how it should be used
     NStr::ReplaceInPlace( member_arg, "-", "_" );
     NStr::ToLower( member_arg );
-    member_arg[0] = toupper(member_arg[0]);
+    member_arg[0] = (char)toupper(member_arg[0]);
 }
 
 bool CTraversalSpecFileParser::CTokenizer::GetNextNoThrow( string& out_next_token )
@@ -617,14 +617,13 @@ void CTraversalSpecFileParser::x_ParseMemberMacro( CTokenizer &tokenizer )
     // membermacro parses similar to "use" clauses, so we use the use-clause
     // parser and then just adjust its output.
 
-    const int old_desc_file_nodes = m_DescFileNodes.size();
+    const int old_desc_file_nodes = (int)m_DescFileNodes.size();
     x_ParseUseClause(tokenizer);
 
     std::vector< CRef<CDescFileNode> >::iterator desc_node_iter = m_DescFileNodes.begin();
     desc_node_iter += old_desc_file_nodes;
     for( ; desc_node_iter != m_DescFileNodes.end(); ++desc_node_iter ) {
         CDescFileNode &file_node = **desc_node_iter;
-        
         file_node.ConvertToMemberMacro();
     }
 }
diff --git a/c++/src/serial/datatool/type.cpp b/c++/src/serial/datatool/type.cpp
index ad0c83e..f14fef2 100644
--- a/c++/src/serial/datatool/type.cpp
+++ b/c++/src/serial/datatool/type.cpp
@@ -1,4 +1,4 @@
-/*  $Id: type.cpp 462658 2015-03-20 13:05:49Z gouriano $
+/*  $Id: type.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -196,7 +196,7 @@ void CDataType::PrintSpecDump(CNcbiOstream& out, int indent) const
     }
 }
 
-void CDataType::PrintSpecDumpExtra(CNcbiOstream& out, int indent) const
+void CDataType::PrintSpecDumpExtra(CNcbiOstream& /*out*/, int /*indent*/) const
 {
 }
 
@@ -951,10 +951,10 @@ string CDataType::GetFullName(void) const
                     special = !member->GetType()->IsUniSeq();
                 }
             } else if (IsUniSeq()) {
-                const CDataType* parent = GetParentType();
-                special = parent->GetDataMember() != 0;
-                if (!special && parent->IsContainer()) {
-                    cont = dynamic_cast<const CDataMemberContainerType*>(parent);
+                const CDataType* parent_type = GetParentType();
+                special = parent_type->GetDataMember() != 0;
+                if (!special && parent_type->IsContainer()) {
+                    cont = dynamic_cast<const CDataMemberContainerType*>(parent_type);
                     special = cont->GetMembers().size() == 1;
                 }
             }
diff --git a/c++/src/serial/datatool/typestr.cpp b/c++/src/serial/datatool/typestr.cpp
index c6d7f2b..ccaab2d 100644
--- a/c++/src/serial/datatool/typestr.cpp
+++ b/c++/src/serial/datatool/typestr.cpp
@@ -1,4 +1,4 @@
-/*  $Id: typestr.cpp 395047 2013-04-09 13:58:30Z gouriano $
+/*  $Id: typestr.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -128,7 +128,12 @@ string CTypeStrings::GetDefaultCode(const string& var) const
 
 bool CTypeStrings::HaveSpecialRef(void) const
 {
-    return false;
+    return !m_SpecialRef.empty();
+}
+
+string CTypeStrings::GetRef(const CNamespace& /*ns*/) const
+{
+    return m_SpecialRef;
 }
 
 bool CTypeStrings::CanBeKey(void) const
diff --git a/c++/src/serial/datatool/typestr.hpp b/c++/src/serial/datatool/typestr.hpp
index 6d50ef5..58392f0 100644
--- a/c++/src/serial/datatool/typestr.hpp
+++ b/c++/src/serial/datatool/typestr.hpp
@@ -1,7 +1,7 @@
 #ifndef TYPESTR_HPP
 #define TYPESTR_HPP
 
-/*  $Id: typestr.hpp 395047 2013-04-09 13:58:30Z gouriano $
+/*  $Id: typestr.hpp 507796 2016-07-21 17:25:37Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -92,7 +92,7 @@ public:
     virtual string GetPrefixedCType(const CNamespace& ns,
                                     const string& methodPrefix) const = 0;
     virtual bool HaveSpecialRef(void) const;
-    virtual string GetRef(const CNamespace& ns) const = 0;
+    virtual string GetRef(const CNamespace& ns) const;
 
     // for external types
     virtual const CNamespace& GetNamespace(void) const;
@@ -141,10 +141,14 @@ public:
     }
     virtual void SetStorageType(const string& storage);
     virtual string GetStorageType(const CNamespace& ns) const;
+    void SetSpecialRef(const string& ref) {
+        m_SpecialRef = ref;
+    }
 
 private:
     string m_ModuleName;
     string m_NamespaceName;
+    string m_SpecialRef;
     const CDataType* m_DataType;
     CComments m_Comments;
 };
diff --git a/c++/src/serial/datatool/wsdlparser.cpp b/c++/src/serial/datatool/wsdlparser.cpp
index b721462..f92603c 100644
--- a/c++/src/serial/datatool/wsdlparser.cpp
+++ b/c++/src/serial/datatool/wsdlparser.cpp
@@ -1,4 +1,4 @@
-/*  $Id: wsdlparser.cpp 466898 2015-05-07 13:36:43Z gouriano $
+/*  $Id: wsdlparser.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -83,14 +83,14 @@ void WSDLParser::BuildDataTree(
                 !i->second.IsEmbedded() && !i->second.GetName().empty();
             if (valid) {
                 for (j=i, ++j; j != m_MapElement.end(); ++j) {
-                   DTDElement::EType type = j->second.GetType();
+                    DTDElement::EType tp = j->second.GetType();
                     valid =
-                        type != DTDElement::eUnknown &&
-                        type != DTDElement::eUnknownGroup &&
-                        type != DTDElement::eWsdlUnsupportedEndpoint &&
+                        tp != DTDElement::eUnknown &&
+                        tp != DTDElement::eUnknownGroup &&
+                        tp != DTDElement::eWsdlUnsupportedEndpoint &&
                         !j->second.IsEmbedded();
                     if (valid &&
-                        NStr::CompareNocase(i->second.GetName(),j->second.GetName()) ==0 &&
+                        NStr::CompareNocase(i->second.GetName(),j->second.GetName()) == 0 &&
                         i->second.GetNamespaceName() != j->second.GetNamespaceName()) {
                         clashes[i->second.GetName()].insert(i->second.GetNamespaceName());
                         clashes[j->second.GetName()].insert(j->second.GetNamespaceName());
@@ -446,7 +446,7 @@ void WSDLParser::ParseOperation(DTDElement& node)
     }
 }
 
-void WSDLParser::ParseBody(DTDElement& node)
+void WSDLParser::ParseBody(DTDElement& /*node*/)
 {
     TToken tok = GetRawAttributeSet();
     if (tok == K_CLOSING) {
@@ -646,8 +646,10 @@ string WSDLParser::CreateWsdlName(const string& name, DTDElement::EType type)
 
 string WSDLParser::CreateEmbeddedName(DTDElement& node, DTDElement::EType type)
 {
-    return CreateWsdlName( CreateTmpEmbeddedName(
-        node.GetName(), node.GetContent().size()),type);
+    return CreateWsdlName( 
+               CreateTmpEmbeddedName( node.GetName(), (int)node.GetContent().size() ),
+               type
+           );
 }
 
 DTDElement& WSDLParser::EmbeddedElement(DTDElement& node,
@@ -706,7 +708,7 @@ void WSDLParser::ParseService(void)
 }
 
 AbstractLexer* WSDLParser::CreateEntityLexer(
-    CNcbiIstream& in, const string& name, bool autoDelete /*=true*/)
+    CNcbiIstream& in, const string& name, bool /*autoDelete*/ /*=true*/)
 {
     WSDLEntityLexer* l = new WSDLEntityLexer(in,name);
     l->UseXSDLexer(m_ParsingTypes);
diff --git a/c++/src/serial/datatool/wsdlstr.cpp b/c++/src/serial/datatool/wsdlstr.cpp
index e6b44e2..ec15ef0 100644
--- a/c++/src/serial/datatool/wsdlstr.cpp
+++ b/c++/src/serial/datatool/wsdlstr.cpp
@@ -1,4 +1,4 @@
-/*  $Id: wsdlstr.cpp 345396 2011-11-25 17:44:33Z gouriano $
+/*  $Id: wsdlstr.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -163,9 +163,9 @@ bool x_IsNullDataType(CWsdlTypeStrings::TMembers::const_iterator i)
 }
 
 void CWsdlTypeStrings::GenerateClassCode(
-    CClassCode& code, CNcbiOstream& setters,
-    const string& methodPrefix, bool haveUserClass,
-    const string& classPrefix) const
+    CClassCode& code, CNcbiOstream& /*setters*/,
+    const string& methodPrefix, bool /*haveUserClass*/,
+    const string& /*classPrefix*/) const
 {
     string ncbiNamespace =
         code.GetNamespace().GetNamespaceRef(CNamespace::KNCBINamespace);
diff --git a/c++/src/serial/datatool/xsdlexer.cpp b/c++/src/serial/datatool/xsdlexer.cpp
index 3faaad4..ae6a7c1 100644
--- a/c++/src/serial/datatool/xsdlexer.cpp
+++ b/c++/src/serial/datatool/xsdlexer.cpp
@@ -1,4 +1,4 @@
-/*  $Id: xsdlexer.cpp 453174 2014-12-01 18:07:21Z gouriano $
+/*  $Id: xsdlexer.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -181,11 +181,11 @@ TToken XSDLexer::LookupLexeme(void)
     if (c == 0) {
         return T_EOF;
     }
-    if (!isalpha((unsigned char) c)) {
+    if (!isalpha((unsigned char)c)) {
         LexerError("Name must begin with an alphabetic character (alpha)");
     }
     StartToken();
-    for (char c = Char(); c != 0; c = Char()) {
+    for (c = Char(); c != 0; c = Char()) {
         bool space = isspace((unsigned char)c) != 0;
         if (!att && space) {
             for (size_t sp_count=1;; ++sp_count) {
diff --git a/c++/src/serial/datatool/xsdparser.cpp b/c++/src/serial/datatool/xsdparser.cpp
index 634aacf..12121fc 100644
--- a/c++/src/serial/datatool/xsdparser.cpp
+++ b/c++/src/serial/datatool/xsdparser.cpp
@@ -1,4 +1,4 @@
-/*  $Id: xsdparser.cpp 486439 2015-12-04 15:06:23Z gouriano $
+/*  $Id: xsdparser.cpp 514363 2016-09-21 15:20:35Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -698,7 +698,7 @@ bool XSDParser::ParseContent(DTDElement& node, bool extended /*=false*/)
     bool hasContents= false;
     TToken tok;
     for ( tok=GetNextToken(); ; tok=GetNextToken()) {
-        emb= node.GetContent().size();
+        emb = (int)node.GetContent().size();
         if (tok != T_EOF &&
             tok != K_ENDOFTAG &&
             tok != K_ANNOTATION) {
@@ -747,7 +747,7 @@ bool XSDParser::ParseContent(DTDElement& node, bool extended /*=false*/)
             }
             break;
         case K_SEQUENCE:
-            emb= node.GetContent().size();
+            emb = (int)node.GetContent().size();
             if (emb != 0 && extended) {
                 node.SetTypeIfUnknown(DTDElement::eSequence);
                 if (node.GetType() != DTDElement::eSequence) {
@@ -1562,7 +1562,7 @@ bool XSDParser::PopEntityLexer(void)
 }
 
 AbstractLexer* XSDParser::CreateEntityLexer(
-    CNcbiIstream& in, const string& name, bool autoDelete /*=true*/)
+    CNcbiIstream& in, const string& name, bool /*autoDelete*/ /*=true*/)
 {
     return new XSDEntityLexer(in,name);
 }
diff --git a/c++/src/serial/enumerated.cpp b/c++/src/serial/enumerated.cpp
index b0fe8d8..a9c295a 100644
--- a/c++/src/serial/enumerated.cpp
+++ b/c++/src/serial/enumerated.cpp
@@ -1,4 +1,4 @@
-/*  $Id: enumerated.cpp 471296 2015-06-25 12:36:15Z gouriano $
+/*  $Id: enumerated.cpp 500790 2016-05-09 11:30:33Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -113,7 +113,7 @@ TEnumValueType CEnumeratedTypeValues::FindValue(const CTempString& name) const
     TNameToValue::const_iterator i = m.find(name);
     if ( i == m.end() ) {
         string name_alt = string(name);
-        name_alt[0] = toupper((unsigned char)name_alt[0]);
+        name_alt[0] = (char)toupper((unsigned char)name_alt[0]);
         i = m.find(name_alt);
         if ( i == m.end() ) {
             NCBI_THROW(CSerialException,eInvalidData,
diff --git a/c++/src/serial/exception.cpp b/c++/src/serial/exception.cpp
index 903a7d8..90e02c3 100644
--- a/c++/src/serial/exception.cpp
+++ b/c++/src/serial/exception.cpp
@@ -1,4 +1,4 @@
-/*  $Id: exception.cpp 457136 2015-01-20 19:45:17Z gouriano $
+/*  $Id: exception.cpp 500790 2016-05-09 11:30:33Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -105,7 +105,7 @@ CNcbiOstream& operator<<(CNcbiOstream& out, SPrintIdentifier s)
                 c = '_';
             }
             if ( capitalize ) {
-                c = toupper((unsigned char)c);
+                c = (char)toupper((unsigned char)c);
                 capitalize = false;
             }
             out << c;
diff --git a/c++/src/serial/member.cpp b/c++/src/serial/member.cpp
index 8277d71..2bb405f 100644
--- a/c++/src/serial/member.cpp
+++ b/c++/src/serial/member.cpp
@@ -1,4 +1,4 @@
-/*  $Id: member.cpp 478484 2015-09-09 17:35:39Z gouriano $
+/*  $Id: member.cpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -1121,7 +1121,9 @@ void CMemberInfoFunctions::WriteLongMember(CObjectOStream& out,
 void CMemberInfoFunctions::CopySimpleMember(CObjectStreamCopier& copier,
                                             const CMemberInfo* memberInfo)
 {
+    copier.In().SetMemberDefault(0);
     copier.CopyObject(memberInfo->GetTypeInfo());
+    copier.In().SetMemberDefault(0);
 }
 
 void CMemberInfoFunctions::CopyWithDefaultMemberX(CObjectStreamCopier& copier,
@@ -1151,7 +1153,9 @@ void CMemberInfoFunctions::CopyMissingOptionalMember(CObjectStreamCopier& /*copi
 void CMemberInfoFunctions::SkipSimpleMember(CObjectIStream& in,
                                             const CMemberInfo* memberInfo)
 {
+    in.SetMemberDefault(0);
     in.SkipObject(memberInfo->GetTypeInfo());
+    in.SetMemberDefault(0);
 }
 
 void CMemberInfoFunctions::SkipWithDefaultMemberX(CObjectIStream& in,
diff --git a/c++/src/serial/memberid.cpp b/c++/src/serial/memberid.cpp
index 59c5f2c..e22c799 100644
--- a/c++/src/serial/memberid.cpp
+++ b/c++/src/serial/memberid.cpp
@@ -1,4 +1,4 @@
-/*  $Id: memberid.cpp 412224 2013-09-05 15:30:00Z gouriano $
+/*  $Id: memberid.cpp 500790 2016-05-09 11:30:33Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -47,7 +47,7 @@ CMemberId::CMemberId(void)
 {
 }
 
-CMemberId::CMemberId(TTag tag, bool explicitTag)
+CMemberId::CMemberId(TTag tag, bool /*explicitTag*/)
     : m_Tag(tag),
     m_TagClass(CAsnBinaryDefs::eContextSpecific),
     m_TagType(CAsnBinaryDefs::eAutomatic),
@@ -67,7 +67,7 @@ CMemberId::CMemberId(const string& name)
 {
 }
 
-CMemberId::CMemberId(const string& name, TTag tag, bool explicitTag)
+CMemberId::CMemberId(const string& name, TTag tag, bool /*explicitTag*/)
     : m_Name(name), m_Tag(tag),
     m_TagClass(CAsnBinaryDefs::eContextSpecific),
     m_TagType(CAsnBinaryDefs::eAutomatic),
@@ -88,7 +88,7 @@ CMemberId::CMemberId(const char* name)
     _ASSERT(name);
 }
 
-CMemberId::CMemberId(const char* name, TTag tag, bool explicitTag)
+CMemberId::CMemberId(const char* name, TTag tag, bool /*explicitTag*/)
     : m_Name(name), m_Tag(tag),
     m_TagClass(CAsnBinaryDefs::eContextSpecific),
     m_TagType(CAsnBinaryDefs::eAutomatic),
diff --git a/c++/src/serial/objectio.cpp b/c++/src/serial/objectio.cpp
index 7cb8805..686448f 100644
--- a/c++/src/serial/objectio.cpp
+++ b/c++/src/serial/objectio.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objectio.cpp 107919 2007-07-30 18:51:04Z vasilche $
+/*  $Id: objectio.cpp 500790 2016-05-09 11:30:33Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -39,6 +39,7 @@
 
 BEGIN_NCBI_SCOPE
 
+
 // readers
 void CObjectInfo::ReadContainer(CObjectIStream& in,
                                 CReadContainerElementHook& hook)
@@ -154,7 +155,6 @@ void CIStreamClassMemberIterator::BeginClassMember(void)
             GetStream().BeginClassMember(m_ClassType.GetClassTypeInfo(),
                                          m_MemberIndex + 1);
     }
-
     if ( *this )
         GetStream().SetTopMemberId(GetMemberInfo()->GetId());
 }
@@ -412,13 +412,9 @@ void CIStreamContainerIterator::CopyElement(CObjectStreamCopier& copier,
                                             COStreamContainer& out)
 {
     BeginElementData();
-
     out.GetStream().BeginContainerElement(m_ElementTypeInfo);
-
     copier.CopyObject(m_ElementTypeInfo);
-
     out.GetStream().EndContainerElement();
-
     NextElement();
 }
 
@@ -486,20 +482,17 @@ COStreamContainer::~COStreamContainer(void)
 void COStreamContainer::WriteElement(const CConstObjectInfo& element)
 {
     GetStream().BeginContainerElement(m_ElementTypeInfo);
-
     GetStream().WriteSeparateObject(element);
-
     GetStream().EndContainerElement();
 }
 
 void COStreamContainer::WriteElement(CObjectStreamCopier& copier,
-                                     CObjectIStream& in)
+                                     CObjectIStream& /*in*/)
 {
     GetStream().BeginContainerElement(m_ElementTypeInfo);
-
     copier.CopyObject(m_ElementTypeInfo);
-
     GetStream().EndContainerElement();
 }
 
+
 END_NCBI_SCOPE
diff --git a/c++/src/serial/objhook.cpp b/c++/src/serial/objhook.cpp
index b758499..ebf0f80 100644
--- a/c++/src/serial/objhook.cpp
+++ b/c++/src/serial/objhook.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objhook.cpp 358154 2012-03-29 15:05:12Z gouriano $
+/*  $Id: objhook.cpp 502193 2016-05-23 12:28:12Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -124,6 +124,11 @@ void CSkipClassMemberHook::SkipMissingClassMember(CObjectIStream& stream,
     member.GetMemberInfo()->DefaultSkipMissingMember(stream);
 }
 
+void CSkipClassMemberHook::DefaultRead(CObjectIStream& in,
+                                       const CObjectInfo& object)
+{
+    object.GetTypeInfo()->DefaultReadData(in, object.GetObjectPtr());
+}
 void CSkipClassMemberHook::DefaultSkip(CObjectIStream& in,
                                        const CObjectTypeInfoMI& object)
 {
@@ -133,6 +138,16 @@ void CSkipClassMemberHook::DefaultSkip(CObjectIStream& in,
 CSkipChoiceVariantHook::~CSkipChoiceVariantHook(void)
 {
 }
+void CSkipChoiceVariantHook::DefaultRead(CObjectIStream& in,
+                                       const CObjectInfo& object)
+{
+    object.GetTypeInfo()->DefaultReadData(in, object.GetObjectPtr());
+}
+void CSkipChoiceVariantHook::DefaultSkip(CObjectIStream& stream,
+                                         const CObjectTypeInfoCV& variant)
+{
+    stream.SkipObject(variant.GetVariantType());
+}
 
 CCopyObjectHook::~CCopyObjectHook(void)
 {
@@ -160,7 +175,7 @@ void CReadObjectHook::DefaultRead(CObjectIStream& in,
 }
 
 void CReadObjectHook::DefaultSkip(CObjectIStream& in,
-                                  const CObjectInfo& object)
+                                  const CObjectTypeInfo& object)
 {
     object.GetTypeInfo()->DefaultSkipData(in);
 }
@@ -178,9 +193,9 @@ void CReadClassMemberHook::ResetMember(const CObjectInfoMI& object,
 }
 
 void CReadClassMemberHook::DefaultSkip(CObjectIStream& in,
-                                       const CObjectInfoMI& object)
+                                       const CObjectTypeInfoMI& object)
 {
-    in.SkipObject(object.GetMember());
+    in.SkipObject(object.GetMemberType());
 }
 
 void CReadChoiceVariantHook::DefaultRead(CObjectIStream& in,
@@ -188,6 +203,11 @@ void CReadChoiceVariantHook::DefaultRead(CObjectIStream& in,
 {
     in.ReadChoiceVariant(object);
 }
+void CReadChoiceVariantHook::DefaultSkip(CObjectIStream& in,
+                                         const CObjectTypeInfoCV& object)
+{
+    in.SkipObject(object.GetVariantType());
+}
 
 void CWriteObjectHook::DefaultWrite(CObjectOStream& out,
                                     const CConstObjectInfo& object)
@@ -201,12 +221,25 @@ void CWriteClassMemberHook::DefaultWrite(CObjectOStream& out,
     out.WriteClassMember(member);
 }
 
+void CWriteClassMemberHook::CustomWrite(CObjectOStream& out,
+    const CConstObjectInfoMI& member, const CConstObjectInfo& custom_object)
+{
+    const CMemberInfo* memberInfo = member.GetMemberInfo();
+    out.WriteClassMember(memberInfo->GetId(), memberInfo->GetTypeInfo(), custom_object.GetObjectPtr());
+}
+
 void CWriteChoiceVariantHook::DefaultWrite(CObjectOStream& out,
                                            const CConstObjectInfoCV& variant)
 {
     out.WriteChoiceVariant(variant);
 }
 
+void CWriteChoiceVariantHook::CustomWrite(CObjectOStream& out,
+    const CConstObjectInfoCV& variant, const CConstObjectInfo& custom_object)
+{
+    out.WriteExternalObject(custom_object.GetObjectPtr(), variant.GetVariantInfo()->GetTypeInfo());
+}
+
 void CCopyObjectHook::DefaultCopy(CObjectStreamCopier& copier,
                                   const CObjectTypeInfo& type)
 {
diff --git a/c++/src/serial/objistr.cpp b/c++/src/serial/objistr.cpp
index f88acc5..37102d2 100644
--- a/c++/src/serial/objistr.cpp
+++ b/c++/src/serial/objistr.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objistr.cpp 446573 2014-09-16 19:07:04Z grichenk $
+/*  $Id: objistr.cpp 500790 2016-05-09 11:30:33Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -791,17 +791,17 @@ string CObjectIStream::GetPosition(void) const
 }
 
 void CObjectIStream::ThrowError1(const CDiagCompileInfo& diag_info, 
-                                 TFailFlags fail, const char* message)
+                                 TFailFlags flags, const char* message)
 {
-    ThrowError1(diag_info,fail,string(message));
+    ThrowError1(diag_info, flags, string(message));
 }
 
 void CObjectIStream::ThrowError1(const CDiagCompileInfo& diag_info, 
-                                 TFailFlags fail, const string& message)
+                                 TFailFlags flags, const string& message)
 {
     CSerialException::EErrCode err;
-    SetFailFlags(fail, message.c_str());
-    switch(fail)
+    SetFailFlags(flags, message.c_str());
+    switch (flags)
     {
     case fNoError:
         CNcbiDiag(diag_info, eDiag_Trace) << ErrCode(NCBI_ERRCODE_X, 6)
diff --git a/c++/src/serial/objistrasn.cpp b/c++/src/serial/objistrasn.cpp
index a6b0c4b..69b2402 100644
--- a/c++/src/serial/objistrasn.cpp
+++ b/c++/src/serial/objistrasn.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objistrasn.cpp 481847 2015-10-16 15:34:27Z gouriano $
+/*  $Id: objistrasn.cpp 501579 2016-05-17 14:01:10Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -371,7 +371,7 @@ TMemberIndex CObjectIStreamAsn::GetAltItemIndex(
     if (!id.empty()) {
         const CItemsInfo& info = classType->GetItems();
         string id_alt = string(id);
-        id_alt[0] = toupper((unsigned char)id_alt[0]);
+        id_alt[0] = (char)toupper((unsigned char)id_alt[0]);
         if (pos != kInvalidMember) {
             idx = info.Find(CTempString(id_alt),pos);
         } else {
@@ -598,7 +598,7 @@ void CObjectIStreamAsn::ReadBitString(CBitString& obj)
         Uint1 byte;
         ITERATE( string, i, data) {
             byte = *i;
-            for (Uint1 mask= 0x8; mask != 0; mask >>= 1) {
+            for (Uint1 mask= 0x8; mask != 0; mask = Uint1(mask >> 1)) {
                 obj.push_back( (byte & mask) != 0 );
             }
         }
@@ -656,7 +656,7 @@ void CObjectIStreamAsn::ReadBitString(CBitString& obj)
         ITERATE( string, i, data) {
             byte = *i;
             if (byte) {
-                for (Uint1 mask= 0x8; mask != 0; mask >>= 1, ++len) {
+                for (Uint1 mask=0x8; mask != 0; mask = Uint1(mask >> 1), ++len) {
                     if ((byte & mask) != 0) {
                         obj.set_bit(len);
                     }
@@ -668,9 +668,9 @@ void CObjectIStreamAsn::ReadBitString(CBitString& obj)
         if (c > 0) {
             for (c= GetHexChar(); c >= 0; c= GetHexChar()) {
                 obj.resize( 4 + obj.size());
-                byte = c;
+                byte = (Uint1)c;
                 if (byte) {
-                    for (Uint1 mask= 0x8; mask != 0; mask >>= 1, ++len) {
+                    for (Uint1 mask= 0x8; mask != 0; mask = Uint1(mask >> 1), ++len) {
                         if ((byte & mask) != 0) {
                             obj.set_bit(len);
                         }
@@ -870,7 +870,7 @@ inline
 void CObjectIStreamAsn::AppendStringData(string& s,
                                          size_t count,
                                          EFixNonPrint fix_method,
-                                         size_t line)
+                                         size_t /*line*/)
 {
     const char* data = m_Input.GetCurrentPos();
     if ( fix_method != eFNP_Allow ) {
@@ -908,7 +908,7 @@ void CObjectIStreamAsn::AppendLongStringData(string& s,
     if ( s.empty() ) {
         s.reserve(count*2);
     }
-    else if ( s.capacity() < (s.size()+1)*1.1 ) {
+    else if ( s.capacity() < double(s.size()+1)*1.1 ) {
         s.reserve(s.size()*2);
     }
     AppendStringData(s, count, fix_method, line);
@@ -1088,7 +1088,7 @@ void CObjectIStreamAsn::SkipString(EStringType type)
                 SkipEndOfLine(c);
                 break;
             case '\"':
-                if ( m_Input.PeekChar(i + 1) == '\"' ) {
+                if ( m_Input.PeekCharNoEOF(i + 1) == '\"' ) {
                     // double quote -> one quote
                     m_Input.SkipChars(i + 2);
                     i = 0;
@@ -1484,13 +1484,13 @@ size_t CObjectIStreamAsn::ReadBytes(ByteBlock& block,
         }
         int c2 = GetHexChar();
         if ( c2 < 0 ) {
-            *dst++ = c1 << 4;
+            *dst++ = char(c1 << 4);
             count++;
             block.EndOfBlock();
             return count;
         }
         else {
-            *dst++ = (c1 << 4) | c2;
+            *dst++ = char((c1 << 4) | c2);
             count++;
         }
     }
diff --git a/c++/src/serial/objistrasnb.cpp b/c++/src/serial/objistrasnb.cpp
index 1765c97..0727895 100644
--- a/c++/src/serial/objistrasnb.cpp
+++ b/c++/src/serial/objistrasnb.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objistrasnb.cpp 461337 2015-03-09 18:00:58Z gouriano $
+/*  $Id: objistrasnb.cpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -568,7 +568,7 @@ char CObjectIStreamAsnBinary::ReadChar(void)
 
 Int4 CObjectIStreamAsnBinary::ReadInt4(void)
 {
-    ExpectSysTag(eInteger);
+    ExpectIntegerTag();
     Int4 data;
     ReadStdSigned(*this, data);
     return data;
@@ -576,7 +576,7 @@ Int4 CObjectIStreamAsnBinary::ReadInt4(void)
 
 Uint4 CObjectIStreamAsnBinary::ReadUint4(void)
 {
-    ExpectSysTag(eInteger);
+    ExpectIntegerTag();
     Uint4 data;
     ReadStdUnsigned(*this, data);
     return data;
@@ -584,16 +584,7 @@ Uint4 CObjectIStreamAsnBinary::ReadUint4(void)
 
 Int8 CObjectIStreamAsnBinary::ReadInt8(void)
 {
-    if (m_SkipNextTag) {
-        m_SkipNextTag = false;
-    } else {
-        TByte next = PeekTagByte();
-        if (next == MakeTagByte(eUniversal, ePrimitive, eInteger)) {
-            ExpectSysTag(eInteger);
-        } else {
-            ExpectSysTag(eApplication, ePrimitive, eInteger);
-        }
-    }
+    ExpectIntegerTag();
     Uint8 data;
     ReadStdSigned(*this, data);
     return data;
@@ -601,16 +592,7 @@ Int8 CObjectIStreamAsnBinary::ReadInt8(void)
 
 Uint8 CObjectIStreamAsnBinary::ReadUint8(void)
 {
-    if (m_SkipNextTag) {
-        m_SkipNextTag = false;
-    } else {
-        TByte next = PeekTagByte();
-        if (next == MakeTagByte(eUniversal, ePrimitive, eInteger)) {
-            ExpectSysTag(eInteger);
-        } else {
-            ExpectSysTag(eApplication, ePrimitive, eInteger);
-        }
-    }
+    ExpectIntegerTag();
     Uint8 data;
     ReadStdUnsigned(*this, data);
     return data;
@@ -1541,7 +1523,7 @@ void CObjectIStreamAsnBinary::SkipAnyContent(void)
             }
         }
         else {
-            TByte byte = PeekAnyTagFirstByte();
+            byte = PeekAnyTagFirstByte();
             if ( GetTagConstructed(byte) && PeekIndefiniteLength() ) {
                 ExpectIndefiniteLength();
                 ++depth;
@@ -1744,7 +1726,7 @@ void CObjectIStreamAsnBinary::ReadBitString(CBitString& obj)
             }
 #else
             if (byte) {
-                for (Uint1 mask= 0x80; mask != 0; mask >>= 1, ++len) {
+                for (Uint1 mask= 0x80; mask != 0; mask = Uint1(mask >> 1), ++len) {
                     if ((byte & mask) != 0 ) {
                         obj.set_bit(len);
                     }
@@ -2004,7 +1986,7 @@ CObjectIStreamAsnBinary::ReadEnum(const CEnumeratedTypeValues& values)
     TEnumValueType value;
     if ( values.IsInteger() ) {
         // allow any integer
-        ExpectSysTag(eInteger);
+        ExpectIntegerTag();
         ReadStdSigned(*this, value);
     }
     else {
@@ -2054,13 +2036,13 @@ void CObjectIStreamAsnBinary::SkipChar(void)
 
 void CObjectIStreamAsnBinary::SkipSNumber(void)
 {
-    ExpectSysTag(eInteger);
+    ExpectIntegerTag();
     SkipTagData();
 }
 
 void CObjectIStreamAsnBinary::SkipUNumber(void)
 {
-    ExpectSysTag(eInteger);
+    ExpectIntegerTag();
     SkipTagData();
 }
 
diff --git a/c++/src/serial/objistrjson.cpp b/c++/src/serial/objistrjson.cpp
index a732e43..213abcd 100644
--- a/c++/src/serial/objistrjson.cpp
+++ b/c++/src/serial/objistrjson.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objistrjson.cpp 480247 2015-09-29 14:08:47Z gouriano $
+/*  $Id: objistrjson.cpp 501456 2016-05-16 15:12:46Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -238,11 +238,11 @@ char CObjectIStreamJson::ReadEncodedChar(
 
     if (enc_in != enc_out && enc_out != eEncoding_Unknown) {
         int c = ReadEscapedChar(encoded);
-        TUnicodeSymbol chU = ReadUtf8Char(c);
-        Uint1 ch = CUtf8::SymbolToChar( chU, enc_out);
+        TUnicodeSymbol chU = ReadUtf8Char((char)c);
+        Uint1 ch = CUtf8::SymbolToChar(chU, enc_out);
         return ch & 0xFF;
     }
-    return ReadEscapedChar(encoded);
+    return (char)ReadEscapedChar(encoded);
 }
 
 TUnicodeSymbol CObjectIStreamJson::ReadUtf8Char(char c)
@@ -275,7 +275,7 @@ string CObjectIStreamJson::x_ReadString(EStringType type)
         }
         str += char(c);
         // pre-allocate memory for long strings
-        if ( str.size() > 128  &&  double(str.capacity())/(str.size()+1.0) < 1.1 ) {
+        if ( str.size() > 128  &&  (double)str.capacity()/((double)str.size()+1.0) < 1.1 ) {
             str.reserve(str.size()*2);
         }
     }
@@ -296,7 +296,7 @@ string CObjectIStreamJson::x_ReadData(EStringType type /*= eStringTypeVisible*/)
         }
         str += char(c);
         // pre-allocate memory for long strings
-        if ( str.size() > 128  &&  double(str.capacity())/(str.size()+1.0) < 1.1 ) {
+        if ( str.size() > 128  &&  (double)str.capacity()/((double)str.size()+1.0) < 1.1 ) {
             str.reserve(str.size()*2);
         }
     }
@@ -492,7 +492,7 @@ void CObjectIStreamJson::ReadString(string& s,
     s = ReadValue(type);
 }
 
-void CObjectIStreamJson::SkipString(EStringType type /*= eStringTypeVisible*/)
+void CObjectIStreamJson::SkipString(EStringType /*type*/)
 {
     x_SkipData();
 }
@@ -668,7 +668,7 @@ void CObjectIStreamJson::SkipClassSequential(const CClassTypeInfo* classType)
 #endif
 
 // container
-void CObjectIStreamJson::BeginContainer(const CContainerTypeInfo* containerType)
+void CObjectIStreamJson::BeginContainer(const CContainerTypeInfo* /*containerType*/)
 {
     StartBlock('[');
 }
@@ -678,7 +678,7 @@ void CObjectIStreamJson::EndContainer(void)
     EndBlock(']');
 }
 
-bool CObjectIStreamJson::BeginContainerElement(TTypeInfo elementType)
+bool CObjectIStreamJson::BeginContainerElement(TTypeInfo /*elementType*/)
 {
     return NextElement();
 }
@@ -687,7 +687,7 @@ void CObjectIStreamJson::EndContainerElement(void)
 }
 
 // class
-void CObjectIStreamJson::BeginClass(const CClassTypeInfo* classInfo)
+void CObjectIStreamJson::BeginClass(const CClassTypeInfo* /*classInfo*/)
 {
     StartBlock((GetStackDepth() > 1 && FetchFrameFromTop(1).GetNotag()) ? 0 : '{');
 }
@@ -869,7 +869,7 @@ void CObjectIStreamJson::UndoClassMember(void)
 }
 
 // choice
-void CObjectIStreamJson::BeginChoice(const CChoiceTypeInfo* choiceType)
+void CObjectIStreamJson::BeginChoice(const CChoiceTypeInfo* /*choiceType*/)
 {
     StartBlock((GetStackDepth() > 1 && FetchFrameFromTop(1).GetNotag()) ? 0 : '{');
 }
@@ -908,7 +908,7 @@ void CObjectIStreamJson::EndChoiceVariant(void)
 }
 
 // byte block
-void CObjectIStreamJson::BeginBytes(ByteBlock& block)
+void CObjectIStreamJson::BeginBytes(ByteBlock& /*block*/)
 {
     char c = SkipWhiteSpaceAndGetChar();
     if (c == '\"') {
@@ -920,7 +920,7 @@ void CObjectIStreamJson::BeginBytes(ByteBlock& block)
     }
 }
 
-void CObjectIStreamJson::EndBytes(const ByteBlock& block)
+void CObjectIStreamJson::EndBytes(const ByteBlock& /*block*/)
 {
     Expect(m_Closing);
     m_Closing = 0;
@@ -984,7 +984,7 @@ size_t CObjectIStreamJson::ReadCustomBytes(
         Uint1 mask=0x80;
         switch (m_BinaryFormat) {
         case eArray_Bool:
-            for (; !end_of_data && mask!=0; mask >>= 1) {
+            for (; !end_of_data && mask!=0; mask = Uint1(mask >> 1)) {
                 if (ReadBool()) {
                     c |= mask;
                 }
@@ -994,7 +994,7 @@ size_t CObjectIStreamJson::ReadCustomBytes(
             *dst++ = c;
             break;
         case eArray_01:
-            for (; !end_of_data && mask!=0; mask >>= 1) {
+            for (; !end_of_data && mask!=0; mask = Uint1(mask >> 1)) {
                 if (ReadChar() != '0') {
                     c |= mask;
                 }
@@ -1012,7 +1012,7 @@ size_t CObjectIStreamJson::ReadCustomBytes(
             break;
         case eString_01:
         case eString_01B:
-            for (; !end_of_data && mask!=0; mask >>= 1) {
+            for (; !end_of_data && mask!=0; mask = Uint1(mask >> 1)) {
                 char t = GetChar();
                 end_of_data = t == '\"' || t == 'B';
                 if (!end_of_data && t != '0') {
@@ -1052,7 +1052,7 @@ size_t CObjectIStreamJson::ReadBase64Bytes(
                 break;
             }
             /*if (c != '=')*/ {
-                src_buf[ src_size++ ] = c;
+                src_buf[ src_size++ ] = (char)c;
             }
             m_Input.SkipChar();
         }
@@ -1083,13 +1083,13 @@ size_t CObjectIStreamJson::ReadHexBytes(
         }
         int c2 = GetHexChar();
         if ( c2 < 0 ) {
-            *dst++ = c1 << 4;
+            *dst++ = char(c1 << 4);
             count++;
             block.EndOfBlock();
             return count;
         }
         else {
-            *dst++ = (c1 << 4) | c2;
+            *dst++ = char((c1 << 4) | c2);
             count++;
         }
     }
@@ -1097,15 +1097,15 @@ size_t CObjectIStreamJson::ReadHexBytes(
 }
 
 // char block
-void CObjectIStreamJson::BeginChars(CharBlock& block)
+void CObjectIStreamJson::BeginChars(CharBlock& /*block*/)
 {
 }
-size_t CObjectIStreamJson::ReadChars(CharBlock& block, char* buffer, size_t count)
+size_t CObjectIStreamJson::ReadChars(CharBlock& /*block*/, char* /*buffer*/, size_t /*count*/)
 {
     ThrowError(fNotImplemented, "Not Implemented");
     return 0;
 }
-void CObjectIStreamJson::EndChars(const CharBlock& block)
+void CObjectIStreamJson::EndChars(const CharBlock& /*block*/)
 {
 }
 
diff --git a/c++/src/serial/objistrxml.cpp b/c++/src/serial/objistrxml.cpp
index 0cc55e6..7a8273f 100644
--- a/c++/src/serial/objistrxml.cpp
+++ b/c++/src/serial/objistrxml.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objistrxml.cpp 461579 2015-03-11 13:12:43Z gouriano $
+/*  $Id: objistrxml.cpp 501456 2016-05-16 15:12:46Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -796,7 +796,7 @@ inline bool BAD_CHAR(int x) {
 }
 inline int CObjectIStreamXml::x_VerifyChar(int x) {
     return BAD_CHAR(x) ?
-        ReplaceVisibleChar(x, x_FixCharsMethod(), this, kEmptyStr) : x;
+        ReplaceVisibleChar((char)x, x_FixCharsMethod(), this, kEmptyStr) : x;
 }
 inline
 int CObjectIStreamXml::ReadEncodedChar(char endingChar, EStringType type, bool* encoded)
@@ -824,14 +824,14 @@ int CObjectIStreamXml::x_ReadEncodedChar(char endingChar, EStringType type, bool
         }
         if (enc_out != eEncoding_UTF8) {
             TUnicodeSymbol chU = enc_in == eEncoding_UTF8 ?
-                ReadUtf8Char(c) : CUtf8::CharToSymbol( c, enc_in);
+                ReadUtf8Char((char)c) : CUtf8::CharToSymbol((char)c, enc_in);
             Uint1 ch = CUtf8::SymbolToChar( chU, enc_out);
             return ch & 0xFF;
         }
         if ((c & 0x80) == 0) {
             return c;
         }
-        char ch = c;
+        char ch = (char)c;
         m_Utf8Buf = CUtf8::AsUTF8( CTempString(&ch,1), enc_in);
         m_Utf8Pos = m_Utf8Buf.begin();
         return *m_Utf8Pos & 0xFF;
@@ -953,7 +953,7 @@ char CObjectIStreamXml::ReadChar(void)
     int c = ReadEscapedChar('<');
     if ( c < 0 || m_Input.PeekChar() != '<' )
         ThrowError(fFormatError, "one char tag content expected");
-    return c;
+    return (char)c;
 }
 
 Int4 CObjectIStreamXml::ReadInt4(void)
@@ -1287,12 +1287,12 @@ void CObjectIStreamXml::ReadTagData(string& str, EStringType type)
                 CR = true;
                 continue;
             }
-            if (m_Attlist && !encoded && IsWhiteSpace(c)) {
+            if (m_Attlist && !encoded && IsWhiteSpace((char)c)) {
                 c = ' ';
             }
-            str += char(c);
+            str += (char)c;
             // pre-allocate memory for long strings
-            if ( str.size() > 128  &&  double(str.capacity())/(str.size()+1.0) < 1.1 ) {
+            if ( str.size() > 128  &&  (double)str.capacity()/((double)str.size()+1.0) < 1.1 ) {
                 str.reserve(str.size()*2);
             }
         }
@@ -2494,7 +2494,7 @@ size_t CObjectIStreamXml::ReadBytes(ByteBlock& block,
                     break;
                 }
                 /*if (c != '=')*/ {
-                    src_buf[ src_size++ ] = c;
+                    src_buf[ src_size++ ] = (char)c;
                 }
                 m_Input.SkipChar();
             }
@@ -2520,13 +2520,13 @@ size_t CObjectIStreamXml::ReadBytes(ByteBlock& block,
         }
         int c2 = GetHexChar();
         if ( c2 < 0 ) {
-            *dst++ = c1 << 4;
+            *dst++ = char(c1 << 4);
             count++;
             block.EndOfBlock();
             return count;
         }
         else {
-            *dst++ = (c1 << 4) | c2;
+            *dst++ = char((c1 << 4) | c2);
             count++;
         }
     }
diff --git a/c++/src/serial/objostr.cpp b/c++/src/serial/objostr.cpp
index 796664c..9bba4db 100644
--- a/c++/src/serial/objostr.cpp
+++ b/c++/src/serial/objostr.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objostr.cpp 484578 2015-11-12 19:13:20Z vasilche $
+/*  $Id: objostr.cpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -289,12 +289,13 @@ EFixNonPrint CObjectOStream::x_GetFixCharsMethodDefault(void) const
 CObjectOStream::CObjectOStream(ESerialDataFormat format,
                                CNcbiOstream& out, EOwnership edeleteOut)
     : m_Output(out, edeleteOut == eTakeOwnership), m_Fail(fNoError), m_Flags(fFlagNone),
-      m_Separator(""), m_AutoSeparator(false),
+      m_Separator(""),
       m_DataFormat(format),
-      m_WriteNamedIntegersByValue(false),
       m_ParseDelayBuffers(eDelayBufferPolicyNotSet),
-      m_FastWriteDouble(s_FastWriteDouble->Get()),
       m_SpecialCaseWrite(eWriteAsNormal),
+      m_AutoSeparator(false),
+      m_WriteNamedIntegersByValue(false),
+      m_FastWriteDouble(s_FastWriteDouble->Get()),
       m_EnforceWritingDefaults(false),
       m_FixMethod(x_GetFixCharsMethodDefault()),
       m_VerifyData(x_GetVerifyDataDefault())
@@ -497,14 +498,14 @@ string CObjectOStream::GetPosition(void) const
 }
 
 void CObjectOStream::ThrowError1(const CDiagCompileInfo& diag_info, 
-                                 TFailFlags fail, const char* message,
+                                 TFailFlags flags, const char* message,
                                  CException* exc)
 {
-    ThrowError1(diag_info,fail,string(message),exc);
+    ThrowError1(diag_info, flags, string(message),exc);
 }
 
 void CObjectOStream::ThrowError1(const CDiagCompileInfo& diag_info, 
-                                 TFailFlags fail, const string& message,
+                                 TFailFlags flags, const string& message,
                                  CException* exc)
 {
     CSerialException::EErrCode err;
@@ -513,12 +514,12 @@ void CObjectOStream::ThrowError1(const CDiagCompileInfo& diag_info,
     } catch(...) {
     }
     string msg(message);
-    if (fail == fUnassigned) {
+    if (flags == fUnassigned) {
         msg = "cannot write unassigned member "+message;
     }
-    SetFailFlags(fail, msg.c_str());
+    SetFailFlags(flags, msg.c_str());
     msg.insert(0,GetPosition()+": ");
-    switch(fail)
+    switch (flags)
     {
     case fNoError:
         CNcbiDiag(diag_info, eDiag_Trace) << ErrCode(NCBI_ERRCODE_X, 12)
@@ -710,7 +711,8 @@ void CObjectOStream::WriteFloat(float data)
 #if SIZEOF_LONG_DOUBLE != 0
 void CObjectOStream::WriteLDouble(long double data)
 {
-    WriteDouble(data);
+   // TODO: remove conversion to double when CXX-5612 will be implemented
+   WriteDouble((double)data);
 }
 #endif
 
diff --git a/c++/src/serial/objostrasn.cpp b/c++/src/serial/objostrasn.cpp
index 3a5f880..2433816 100644
--- a/c++/src/serial/objostrasn.cpp
+++ b/c++/src/serial/objostrasn.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objostrasn.cpp 481847 2015-10-16 15:34:27Z gouriano $
+/*  $Id: objostrasn.cpp 501450 2016-05-16 14:53:19Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -119,7 +119,7 @@ void CObjectOStreamAsn::WriteEnum(
     } else {
 // names coming from XML can begin with uppercase char;
 // in ASN, they must begin with lowercase one.
-        m_Output.PutChar(tolower((unsigned char)valueName[0]));
+        m_Output.PutChar((char)tolower((unsigned char)valueName[0]));
         m_Output.PutString(valueName.data()+1, valueName.size()-1);
     }    
 }
@@ -335,7 +335,7 @@ void CObjectOStreamAsn::WriteBitString(const CBitString& obj)
         if (hex) {
             Uint1 data, mask;
             while (i < ilast) {
-                for (data=0, mask=0x8; mask!=0; mask >>= 1, ++i) {
+                for (data=0, mask=0x8; mask!=0; mask = Uint1(mask >> 1), ++i) {
                     if (i == *e) {
                         data |= mask;
                         ++e;
@@ -582,7 +582,7 @@ void CObjectOStreamAsn::WriteMemberId(const CMemberId& id)
     const string& name = id.GetName();
     if ( !name.empty() ) {
         if (id.HaveNoPrefix() && isupper((unsigned char)name[0])) {
-            m_Output.PutChar(tolower((unsigned char)name[0]));
+            m_Output.PutChar((char)tolower((unsigned char)name[0]));
             m_Output.PutString(name.data()+1, name.size()-1);
         } else {
             m_Output.PutString(name);
@@ -663,7 +663,7 @@ bool CObjectOStreamAsn::WriteClassMember(const CMemberId& memberId,
 void CObjectOStreamAsn::CopyClassRandom(const CClassTypeInfo* classType,
                                         CObjectStreamCopier& copier)
 {
-    BEGIN_OBJECT_FRAME_OF2(copier.In(), eFrameClass, classType);
+    BEGIN_OBJECT_2FRAMES_OF2(copier, eFrameClass, classType);
     copier.In().BeginClass(classType);
 
     StartBlock();
@@ -678,6 +678,7 @@ void CObjectOStreamAsn::CopyClassRandom(const CClassTypeInfo* classType,
         const CMemberInfo* memberInfo = classType->GetMemberInfo(index);
         copier.In().SetTopMemberId(memberInfo->GetId());
         SetTopMemberId(memberInfo->GetId());
+        copier.SetPathHooks(*this, true);
 
         if ( read[index] ) {
             copier.DuplicatedMember(memberInfo);
@@ -690,7 +691,7 @@ void CObjectOStreamAsn::CopyClassRandom(const CClassTypeInfo* classType,
 
             memberInfo->CopyMember(copier);
         }
-        
+        copier.SetPathHooks(*this, false);
         copier.In().EndClassMember();
     }
 
@@ -706,13 +707,13 @@ void CObjectOStreamAsn::CopyClassRandom(const CClassTypeInfo* classType,
     EndBlock();
 
     copier.In().EndClass();
-    END_OBJECT_FRAME_OF(copier.In());
+    END_OBJECT_2FRAMES_OF(copier);
 }
 
 void CObjectOStreamAsn::CopyClassSequential(const CClassTypeInfo* classType,
                                             CObjectStreamCopier& copier)
 {
-    BEGIN_OBJECT_FRAME_OF2(copier.In(), eFrameClass, classType);
+    BEGIN_OBJECT_2FRAMES_OF2(copier, eFrameClass, classType);
     copier.In().BeginClass(classType);
 
     StartBlock();
@@ -726,6 +727,7 @@ void CObjectOStreamAsn::CopyClassSequential(const CClassTypeInfo* classType,
         const CMemberInfo* memberInfo = classType->GetMemberInfo(index);
         copier.In().SetTopMemberId(memberInfo->GetId());
         SetTopMemberId(memberInfo->GetId());
+        copier.SetPathHooks(*this, true);
 
         for ( TMemberIndex i = *pos; i < index; ++i ) {
             // init missing member
@@ -739,6 +741,7 @@ void CObjectOStreamAsn::CopyClassSequential(const CClassTypeInfo* classType,
         
         pos.SetIndex(index + 1);
 
+        copier.SetPathHooks(*this, false);
         copier.In().EndClassMember();
     }
 
@@ -752,7 +755,7 @@ void CObjectOStreamAsn::CopyClassSequential(const CClassTypeInfo* classType,
     EndBlock();
 
     copier.In().EndClass();
-    END_OBJECT_FRAME_OF(copier.In());
+    END_OBJECT_2FRAMES_OF(copier);
 }
 #endif
 
diff --git a/c++/src/serial/objostrasnb.cpp b/c++/src/serial/objostrasnb.cpp
index 9f2b720..3b02f23 100644
--- a/c++/src/serial/objostrasnb.cpp
+++ b/c++/src/serial/objostrasnb.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objostrasnb.cpp 472634 2015-07-13 14:50:50Z gouriano $
+/*  $Id: objostrasnb.cpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -331,7 +331,7 @@ void CObjectOStreamAsnBinary::WriteLongTag(ETagClass tag_class,
     // beginning of tag
     while ( shift != 0 ) {
         shift -= 7;
-        WriteByte((tag_value >> shift) | 0x80);
+        WriteByte(Uint1(tag_value >> shift) | 0x80);
     }
     // write remaining bits
     WriteByte(tag_value & 0x7f);
@@ -371,7 +371,7 @@ void CObjectOStreamAsnBinary::WriteClassTag(TTypeInfo typeInfo)
         char c = tag[i];
         _ASSERT( (c & 0x80) == 0 );
         if ( i != last )
-            c |= 0x80;
+            c |= (char)0x80;
         WriteByte(c);
     }
 }
@@ -483,7 +483,7 @@ void CObjectOStreamAsnBinary::WriteBitString(const CBitString& obj)
 
 #if BITSTRING_AS_VECTOR
     for ( CBitString::const_iterator i = obj.begin(); !done; ) {
-        for (data=0, mask=0x80; mask != 0 && !done; mask >>= 1) {
+        for (data=0, mask=0x80; mask != 0 && !done; mask = Uint1(mask >> 1)) {
             if (*i) {
                 data |= mask;
             }
@@ -505,7 +505,7 @@ void CObjectOStreamAsnBinary::WriteBitString(const CBitString& obj)
     CBitString::size_type ilast = obj.size();
     CBitString::enumerator e = obj.first();
     while (!done) {
-        for (data=0, mask=0x80; !done && mask!=0; mask >>= 1) {
+        for (data=0, mask=0x80; !done && mask!=0; mask = Uint1(mask >> 1)) {
             if (i == *e) {
                 data |= mask;
                 ++e;
@@ -676,9 +676,16 @@ void CObjectOStreamAsnBinary::WriteUint4(Uint4 data)
     WriteNumberValue(data);
 }
 
+static inline
+bool s_IsOldStyleInt8(const CObjectOStreamAsnBinary* os)
+{
+    TTypeInfo type = os->GetRecentTypeInfo();
+    return type != nullptr && type->GetCodeVersion() < 21600;
+}
+
 void CObjectOStreamAsnBinary::WriteInt8(Int8 data)
 {
-    if ( m_CStyleBigInt ) {
+    if ( m_CStyleBigInt && (m_SpecialCaseWrite == eWriteAsBigInt || s_IsOldStyleInt8(this))) {
         WriteShortTag(eApplication, ePrimitive, eInteger);
     } else {
         WriteSysTag(eInteger);
@@ -688,7 +695,7 @@ void CObjectOStreamAsnBinary::WriteInt8(Int8 data)
 
 void CObjectOStreamAsnBinary::WriteUint8(Uint8 data)
 {
-    if ( m_CStyleBigInt ) {
+    if ( m_CStyleBigInt && (m_SpecialCaseWrite == eWriteAsBigInt || s_IsOldStyleInt8(this))) {
         WriteShortTag(eApplication, ePrimitive, eInteger);
     } else {
         WriteSysTag(eInteger);
@@ -1443,6 +1450,7 @@ void CObjectOStreamAsnBinary::CopyClassRandom(const CClassTypeInfo* classType,
         const CMemberInfo* memberInfo = classType->GetMemberInfo(index);
         copier.In().SetTopMemberId(memberInfo->GetId());
         SetTopMemberId(memberInfo->GetId());
+        copier.SetPathHooks(*this, true);
 
         if ( read[index] ) {
             copier.DuplicatedMember(memberInfo);
@@ -1468,6 +1476,7 @@ void CObjectOStreamAsnBinary::CopyClassRandom(const CClassTypeInfo* classType,
 #endif
         }
         
+        copier.SetPathHooks(*this, false);
         copier.In().EndClassMember();
     }
 
@@ -1519,6 +1528,7 @@ void CObjectOStreamAsnBinary::CopyClassSequential(const CClassTypeInfo* classTyp
             // init missing member
             classType->GetMemberInfo(i)->CopyMissingMember(copier);
         }
+        copier.SetPathHooks(*this, true);
 
 #if USE_OLD_TAGS
         WriteTag(eContextSpecific, eConstructed, memberInfo->GetId().GetTag());
@@ -1537,6 +1547,7 @@ void CObjectOStreamAsnBinary::CopyClassSequential(const CClassTypeInfo* classTyp
         
         pos.SetIndex(index + 1);
 
+        copier.SetPathHooks(*this, false);
         copier.In().EndClassMember();
     }
 
diff --git a/c++/src/serial/objostrjson.cpp b/c++/src/serial/objostrjson.cpp
index 2496dd3..0e9b2fe 100644
--- a/c++/src/serial/objostrjson.cpp
+++ b/c++/src/serial/objostrjson.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objostrjson.cpp 483499 2015-11-02 13:37:41Z gouriano $
+/*  $Id: objostrjson.cpp 501456 2016-05-16 15:12:46Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -326,7 +326,7 @@ void CObjectOStreamJson::WriteBitString(const CBitString& obj)
     Uint1 data, mask;
     bool done = false;
     for ( CBitString::const_iterator i = obj.begin(); !done; ) {
-        for (data=0, mask=0x8; !done && mask!=0; mask >>= 1) {
+        for (data=0, mask=0x8; !done && mask!=0; mask = Uint1(mask >> 1)) {
             if (*i) {
                 data |= mask;
             }
@@ -490,7 +490,7 @@ void CObjectOStreamJson::EndChoice(void)
 }
 
 void CObjectOStreamJson::BeginChoiceVariant(const CChoiceTypeInfo* /*choiceType*/,
-                                const CMemberId& id)
+                                            const CMemberId& id)
 {
     if (id.HasNotag() || id.IsAttlist()) {
         m_SkippedMemberId = id.GetName();
@@ -524,8 +524,8 @@ void CObjectOStreamJson::BeginBytes(const ByteBlock& )
     }
 }
 
-void CObjectOStreamJson::WriteBytes(const ByteBlock& block,
-                        const char* bytes, size_t length)
+void CObjectOStreamJson::WriteBytes(const ByteBlock& /*block*/,
+                                    const char* bytes, size_t length)
 {
     if (m_BinaryFormat != CObjectOStreamJson::eDefault) {
         WriteCustomBytes(bytes,length);
@@ -608,7 +608,7 @@ void CObjectOStreamJson::WriteCustomBytes(const char* bytes, size_t length)
         Uint1 mask=0x80;
         switch (m_BinaryFormat) {
         case eArray_Bool:
-            for (; mask!=0; mask >>= 1) {
+            for (; mask!=0; mask = Uint1(mask >> 1)) {
                 if (m_WrapAt != 0) {
                     m_Output.WrapAt(m_WrapAt, false);
                 }
@@ -617,7 +617,7 @@ void CObjectOStreamJson::WriteCustomBytes(const char* bytes, size_t length)
             }
             break;
         case eArray_01:
-            for (; mask!=0; mask >>= 1) {
+            for (; mask!=0; mask = Uint1(mask >> 1)) {
                 if (m_WrapAt != 0) {
                     m_Output.WrapAt(m_WrapAt, false);
                 }
@@ -635,7 +635,7 @@ void CObjectOStreamJson::WriteCustomBytes(const char* bytes, size_t length)
             break;
         case eString_01:
         case eString_01B:
-            for (; mask!=0; mask >>= 1) {
+            for (; mask!=0; mask = Uint1(mask >> 1)) {
                 m_Output.PutChar( (mask & c) ? '1' : '0');
             }
             break;
diff --git a/c++/src/serial/objostrxml.cpp b/c++/src/serial/objostrxml.cpp
index 3a3de22..3d82102 100644
--- a/c++/src/serial/objostrxml.cpp
+++ b/c++/src/serial/objostrxml.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objostrxml.cpp 471224 2015-06-24 17:35:04Z gouriano $
+/*  $Id: objostrxml.cpp 507946 2016-07-22 16:50:31Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -550,22 +550,29 @@ void CObjectOStreamXml::WriteEncodedChar(const char*& src, EStringType type)
     }
 }
 
-void CObjectOStreamXml::x_SpecialCaseWrite(void) {
-    OpenTagEndBack();
-    if (m_SpecialCaseWrite == eWriteAsNil) {
+bool CObjectOStreamXml::x_SpecialCaseWrite(void)
+{
+    if (m_SpecialCaseWrite == eWriteAsDefault) {
+        OpenTagEndBack();
+        SelfCloseTagEnd();
+        return true;
+    }
+    else if (m_SpecialCaseWrite == eWriteAsNil) {
+        OpenTagEndBack();
          m_Output.PutChar(' ');
         if (m_UseSchemaRef) {
             m_Output.PutString("xs:");
         }
         m_Output.PutString("nil=\"true\"");
+        SelfCloseTagEnd();
+        return true;
     }
-    SelfCloseTagEnd();
+    return false;
 }
 
 void CObjectOStreamXml::WriteBool(bool data)
 {
-    if (m_SpecialCaseWrite) {
-        x_SpecialCaseWrite();
+    if (m_SpecialCaseWrite && x_SpecialCaseWrite()) {
         return;
     }
     if ( !x_IsStdXml() ) {
@@ -590,8 +597,7 @@ void CObjectOStreamXml::WriteChar(char data)
 
 void CObjectOStreamXml::WriteInt4(Int4 data)
 {
-    if (m_SpecialCaseWrite) {
-        x_SpecialCaseWrite();
+    if (m_SpecialCaseWrite && x_SpecialCaseWrite()) {
         return;
     }
     m_Output.PutInt4(data);
@@ -599,8 +605,7 @@ void CObjectOStreamXml::WriteInt4(Int4 data)
 
 void CObjectOStreamXml::WriteUint4(Uint4 data)
 {
-    if (m_SpecialCaseWrite) {
-        x_SpecialCaseWrite();
+    if (m_SpecialCaseWrite && x_SpecialCaseWrite()) {
         return;
     }
     m_Output.PutUint4(data);
@@ -608,8 +613,7 @@ void CObjectOStreamXml::WriteUint4(Uint4 data)
 
 void CObjectOStreamXml::WriteInt8(Int8 data)
 {
-    if (m_SpecialCaseWrite) {
-        x_SpecialCaseWrite();
+    if (m_SpecialCaseWrite && x_SpecialCaseWrite()) {
         return;
     }
     m_Output.PutInt8(data);
@@ -617,8 +621,7 @@ void CObjectOStreamXml::WriteInt8(Int8 data)
 
 void CObjectOStreamXml::WriteUint8(Uint8 data)
 {
-    if (m_SpecialCaseWrite) {
-        x_SpecialCaseWrite();
+    if (m_SpecialCaseWrite && x_SpecialCaseWrite()) {
         return;
     }
     m_Output.PutUint8(data);
@@ -626,8 +629,7 @@ void CObjectOStreamXml::WriteUint8(Uint8 data)
 
 void CObjectOStreamXml::WriteDouble2(double data, unsigned digits)
 {
-    if (m_SpecialCaseWrite) {
-        x_SpecialCaseWrite();
+    if (m_SpecialCaseWrite && x_SpecialCaseWrite()) {
         return;
     }
     if (isnan(data)) {
@@ -893,8 +895,7 @@ void CObjectOStreamXml::WriteCString(const char* str)
 
 void CObjectOStreamXml::WriteString(const string& str, EStringType type)
 {
-    if (m_SpecialCaseWrite) {
-        x_SpecialCaseWrite();
+    if (m_SpecialCaseWrite && x_SpecialCaseWrite()) {
         return;
     }
     for ( const char* src = str.c_str(); *src; ++src ) {
@@ -943,7 +944,7 @@ void CObjectOStreamXml::WriteNullPointer(void)
         }
         return;
     }
-    m_SpecialCaseWrite = nillable ? eWriteAsNil : eWriteAsNormal;
+    m_SpecialCaseWrite = nillable ? eWriteAsNil : eWriteAsDefault;
     x_SpecialCaseWrite();
     m_SpecialCaseWrite = eWriteAsNormal;
 }
@@ -1536,7 +1537,7 @@ bool CObjectOStreamXml::WriteClassMember(const CMemberId& memberId,
 }
 
 void CObjectOStreamXml::WriteClassMemberSpecialCase(const CMemberId& memberId,
-    TTypeInfo memberType, TConstObjectPtr memberPtr, ESpecialCaseWrite how)
+    TTypeInfo /*memberType*/, TConstObjectPtr /*memberPtr*/, ESpecialCaseWrite how)
 {
     if (m_Attlist) {
         return;
diff --git a/c++/src/serial/objstack.cpp b/c++/src/serial/objstack.cpp
index bbaa149..d888ee5 100644
--- a/c++/src/serial/objstack.cpp
+++ b/c++/src/serial/objstack.cpp
@@ -1,4 +1,4 @@
-/*  $Id: objstack.cpp 481847 2015-10-16 15:34:27Z gouriano $
+/*  $Id: objstack.cpp 501450 2016-05-16 14:53:19Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -251,7 +251,7 @@ void CObjectStack::x_PopStackPath(void)
 
 const string& CObjectStack::GetStackPath(void)
 {
-    if (!m_PathValid && GetStackDepth()) {
+    if (GetStackDepth()) {
 //        _ASSERT(FetchFrameFromBottom(0).m_FrameType == TFrame::eFrameNamed);
 //        _ASSERT(FetchFrameFromBottom(0).m_TypeInfo);
 //        m_MemberPath = FetchFrameFromBottom(0).GetTypeInfo()->GetName();
diff --git a/c++/src/serial/rpcbase.cpp b/c++/src/serial/rpcbase.cpp
index 194af4a..9c157d5 100644
--- a/c++/src/serial/rpcbase.cpp
+++ b/c++/src/serial/rpcbase.cpp
@@ -1,4 +1,4 @@
-/*  $Id: rpcbase.cpp 499300 2016-04-25 15:23:35Z ivanov $
+/*  $Id: rpcbase.cpp 501456 2016-05-16 15:12:46Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -153,7 +153,6 @@ public:
     CCounterGuard(int* counter)
         : m_Counter(*counter)
     {
-
         m_Counter++;
     }
 
@@ -275,7 +274,7 @@ void CRPCClient_Base::x_Ask(const CSerialObject& request, CSerialObject& reply)
 }
 
 
-bool CRPCClient_Base::x_ShouldRetry(unsigned int tries)
+bool CRPCClient_Base::x_ShouldRetry(unsigned int tries) /* NCBI_FAKE_WARNING */
 {
     _TRACE("CRPCClient_Base::x_ShouldRetry: retrying after " << tries
            << " failures");
diff --git a/c++/src/serial/serialobject.cpp b/c++/src/serial/serialobject.cpp
index 2185d9d..a8e8cb1 100644
--- a/c++/src/serial/serialobject.cpp
+++ b/c++/src/serial/serialobject.cpp
@@ -1,4 +1,4 @@
-/*  $Id: serialobject.cpp 435003 2014-05-13 15:08:30Z ucko $
+/*  $Id: serialobject.cpp 501456 2016-05-16 15:12:46Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -248,7 +248,7 @@ CNcbiOstream& operator<<(CNcbiOstream& out, SPrintIdentifier s)
                 c = '_';
             }
             if ( capitalize ) {
-                c = toupper((unsigned char)c);
+                c = (char)toupper((unsigned char)c);
                 capitalize = false;
             }
             out << c;
diff --git a/c++/src/serial/stdtypes.cpp b/c++/src/serial/stdtypes.cpp
index 837d0b7..ab3c0ef 100644
--- a/c++/src/serial/stdtypes.cpp
+++ b/c++/src/serial/stdtypes.cpp
@@ -1,4 +1,4 @@
-/*  $Id: stdtypes.cpp 440966 2014-07-18 15:38:14Z gouriano $
+/*  $Id: stdtypes.cpp 507801 2016-07-21 17:37:25Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -446,7 +446,14 @@ long double CPrimitiveTypeInfo::GetValueLDouble(TConstObjectPtr objectPtr) const
 void CPrimitiveTypeInfo::SetValueLDouble(TObjectPtr objectPtr,
                                          long double value) const
 {
-    SetValueDouble(objectPtr, value);
+    // TODO: 
+    // - remove conversion to double when CXX-5612 will be implemented
+    // - change ThrowIncompatibleValue() to _Overflow_
+#if defined(DBL_MIN) && defined(DBL_MAX)
+    if ( value < DBL_MIN || value > DBL_MAX )
+        ThrowIncompatibleValue();
+#endif
+    SetValueDouble(objectPtr, (double)value);
 }
 #endif
 
@@ -1018,6 +1025,7 @@ void CPrimitiveTypeInfoFloat::SetValueDouble(TObjectPtr objectPtr,
 {
 #if defined(FLT_MIN) && defined(FLT_MAX)
     if ( value < FLT_MIN || value > FLT_MAX )
+        // TODO: change ThrowIncompatibleValue() to _Overflow_
         ThrowIncompatibleValue();
 #endif
     CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr) = TObjectType(value);
@@ -1045,7 +1053,8 @@ CPrimitiveTypeInfoLongDouble::CPrimitiveTypeInfoLongDouble(void)
 
 double CPrimitiveTypeInfoLongDouble::GetValueDouble(TConstObjectPtr objectPtr) const
 {
-    return CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr);
+    // TODO: remove conversion to double when CXX-5612 will be implemented
+    return (double)CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr);
 }
 
 void CPrimitiveTypeInfoLongDouble::SetValueDouble(TObjectPtr objectPtr,
@@ -1223,6 +1232,48 @@ CTypeInfo* CStdTypeInfo<ncbi::utf8_string_type>::CreateTypeInfo(void)
     return new CPrimitiveTypeInfoString(CPrimitiveTypeInfoString::eStringTypeUTF8);
 }
 
+template<typename T>
+class CPrimitiveTypeInfoBigIntFunctions : public CPrimitiveTypeInfoIntFunctions<T>
+{
+    typedef CPrimitiveTypeInfoIntFunctions<T> CParent;
+public:
+    static CPrimitiveTypeInfoInt* CreateTypeInfo(void)
+        {
+            CPrimitiveTypeInfoInt* info = CParent::CreateTypeInfo();
+            info->SetIOFunctions(&CParent::Read,
+                &CPrimitiveTypeInfoBigIntFunctions::Write,
+                &CPrimitiveTypeInfoBigIntFunctions::Copy,
+                &CParent::Skip);
+            return info;
+        }
+    static void Write(CObjectOStream& out,
+                      TTypeInfo , TConstObjectPtr objectPtr)
+        {
+            out.SetSpecialCaseWrite( CObjectOStream::eWriteAsBigInt);
+            out.WriteStd(CParent::Get(objectPtr));
+            out.SetSpecialCaseWrite( CObjectOStream::eWriteAsNormal);
+        }
+    static void Copy(CObjectStreamCopier& copier, TTypeInfo )
+        {
+            typename CParent::TObjectType data;
+            copier.In().ReadStd(data);
+            copier.In().SetSpecialCaseUsed(CObjectIStream::eReadAsNormal);
+            copier.Out().SetSpecialCaseWrite(CObjectOStream::eWriteAsBigInt);
+            copier.Out().WriteStd(data);
+            copier.Out().SetSpecialCaseWrite(CObjectOStream::eWriteAsNormal);
+        }
+};
+
+TTypeInfo CStdTypeInfo<ncbi::bigint_type>::GetTypeInfo(void)
+{
+    static TTypeInfo info = CreateTypeInfo();
+    return info;
+}
+
+CTypeInfo* CStdTypeInfo<ncbi::bigint_type>::CreateTypeInfo(void)
+{
+    return CPrimitiveTypeInfoBigIntFunctions<Int8>::CreateTypeInfo();
+}
 
 class CStringStoreFunctions : public CStringFunctions<string>
 {
diff --git a/c++/src/serial/typeinfo.cpp b/c++/src/serial/typeinfo.cpp
index 56a2571..146adc9 100644
--- a/c++/src/serial/typeinfo.cpp
+++ b/c++/src/serial/typeinfo.cpp
@@ -1,4 +1,4 @@
-/*  $Id: typeinfo.cpp 412224 2013-09-05 15:30:00Z gouriano $
+/*  $Id: typeinfo.cpp 507795 2016-07-21 17:24:14Z gouriano $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -95,6 +95,7 @@ typedef CTypeInfoFunctions TFunc;
 CTypeInfo::CTypeInfo(ETypeFamily typeFamily, size_t size)
     : m_TypeFamily(typeFamily), m_Size(size), m_Name(),
       m_InfoItem(0),
+      m_CodeVer(0),
       m_IsCObject(false),
       m_IsInternal(false),
       m_Tag(eNoExplicitTag), m_TagClass(CAsnBinaryDefs::eUniversal),
@@ -114,6 +115,7 @@ CTypeInfo::CTypeInfo(ETypeFamily typeFamily, size_t size)
 CTypeInfo::CTypeInfo(ETypeFamily typeFamily, size_t size, const char* name)
     : m_TypeFamily(typeFamily), m_Size(size), m_Name(name),
       m_InfoItem(0),
+      m_CodeVer(0),
       m_IsCObject(false),
       m_IsInternal(false),
       m_Tag(eNoExplicitTag), m_TagClass(CAsnBinaryDefs::eUniversal),
@@ -132,6 +134,7 @@ CTypeInfo::CTypeInfo(ETypeFamily typeFamily, size_t size, const char* name)
 CTypeInfo::CTypeInfo(ETypeFamily typeFamily, size_t size, const string& name)
     : m_TypeFamily(typeFamily), m_Size(size), m_Name(name),
       m_InfoItem(0),
+      m_CodeVer(0),
       m_IsCObject(false),
       m_IsInternal(false),
       m_Tag(eNoExplicitTag), m_TagClass(CAsnBinaryDefs::eUniversal),
diff --git a/c++/src/util/Makefile.util.lib b/c++/src/util/Makefile.util.lib
index 2cc98da..63a0c76 100644
--- a/c++/src/util/Makefile.util.lib
+++ b/c++/src/util/Makefile.util.lib
@@ -1,4 +1,4 @@
-# $Id: Makefile.util.lib 486585 2015-12-07 18:41:13Z gouriano $
+# $Id: Makefile.util.lib 501626 2016-05-17 17:32:10Z kornbluh $
 
 SRC = random_gen utf8 checksum bytesrc strbuffer itree smalldns \
       thread_pool_old ddump_viewer strsearch logrotate \
@@ -14,7 +14,7 @@ PROJ_TAG = core
 
 LIBS = $(ORIG_LIBS)
 
-WATCHERS = vakatov kornbluh
+WATCHERS = vakatov
 
 
 
diff --git a/c++/src/util/bytesrc.cpp b/c++/src/util/bytesrc.cpp
index e2df545..0b3a01d 100644
--- a/c++/src/util/bytesrc.cpp
+++ b/c++/src/util/bytesrc.cpp
@@ -1,4 +1,4 @@
-/*  $Id: bytesrc.cpp 415499 2013-10-17 16:29:24Z gouriano $
+/*  $Id: bytesrc.cpp 506679 2016-07-11 12:10:32Z gouriano $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -513,7 +513,13 @@ size_t CMemoryByteSourceReader::Read(char* buffer, size_t bufferLength)
 
 bool CMemoryByteSourceReader::EndOfData(void) const
 {
-    return !m_CurrentChunk;
+    if (!m_CurrentChunk) {
+        return true;
+    }
+    if (GetCurrentChunkAvailable() != 0) {
+        return false;
+    }
+    return !(m_CurrentChunk->GetNextChunk());
 }
 
 
diff --git a/c++/src/util/compress/api/archive_zip.cpp b/c++/src/util/compress/api/archive_zip.cpp
index 0ede917..532a1c5 100644
--- a/c++/src/util/compress/api/archive_zip.cpp
+++ b/c++/src/util/compress/api/archive_zip.cpp
@@ -1,4 +1,4 @@
-/* $Id: archive_zip.cpp 447940 2014-10-01 17:43:28Z ivanov $
+/* $Id: archive_zip.cpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -263,7 +263,7 @@ void CArchiveZip::GetEntryInfo(size_t index, CArchiveEntryInfo* info)
     // is very OS- and creation software dependent. 
     // Try to analyze some common cases for Unix-type attributes:
 
-    char ver = fs.m_version_made_by >> 8;
+    char ver = (char)(fs.m_version_made_by >> 8);
     mode_t mode = (fs.m_external_attr >> 16) & 0xFFFF;
 
     switch (ver) {
diff --git a/c++/src/util/compress/api/stream.cpp b/c++/src/util/compress/api/stream.cpp
index c9bd9ef..990555d 100644
--- a/c++/src/util/compress/api/stream.cpp
+++ b/c++/src/util/compress/api/stream.cpp
@@ -1,4 +1,4 @@
-/*  $Id: stream.cpp 430126 2014-03-24 12:25:47Z ivanov $
+/*  $Id: stream.cpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -282,7 +282,7 @@ CCompressionProcessor::EStatus CTransparentProcessor::Process(
 }
 
 CCompressionProcessor::EStatus CTransparentProcessor::Flush(
-                      char* out_buf, size_t  out_size,
+                      char* /*out_buf*/, size_t /*out_size*/,
                       /* out */      size_t* out_avail)
 {
     *out_avail = 0;
@@ -290,14 +290,14 @@ CCompressionProcessor::EStatus CTransparentProcessor::Flush(
 }
 
 CCompressionProcessor::EStatus CTransparentProcessor::Finish(
-                      char* out_buf, size_t  out_size,
-                      /* out */      size_t* out_avail)
+                      char* /*out_buf*/, size_t  /*out_size*/,
+                      /* out */          size_t* out_avail)
 {
     *out_avail = 0;
     return eStatus_EndOfData;
 }
 
-CCompressionProcessor::EStatus CTransparentProcessor::End(int abandon)
+CCompressionProcessor::EStatus CTransparentProcessor::End(int /*abandon*/)
 {
     SetBusy(false);
     return eStatus_Success;
diff --git a/c++/src/util/compress/api/stream_util.cpp b/c++/src/util/compress/api/stream_util.cpp
index 862d5b6..e100bfd 100644
--- a/c++/src/util/compress/api/stream_util.cpp
+++ b/c++/src/util/compress/api/stream_util.cpp
@@ -1,4 +1,4 @@
-/*  $Id: stream_util.cpp 438799 2014-06-20 13:06:09Z gotvyans $
+/*  $Id: stream_util.cpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -127,10 +127,10 @@ CCompressionStreamProcessor* s_Init(EInitType                type,
 
 
 CCompressIStream::CCompressIStream(CNcbiIstream& stream, EMethod method, 
-                                   ICompression::TFlags flags,
+                                   ICompression::TFlags stm_flags,
                                    ICompression::ELevel level)
 {
-    CCompressionStreamProcessor* processor = s_Init(eCompress, method, flags, level);
+    CCompressionStreamProcessor* processor = s_Init(eCompress, method, stm_flags, level);
     if (processor) {
         Create(stream, processor, CCompressionStream::fOwnProcessor);
     }
@@ -138,11 +138,11 @@ CCompressIStream::CCompressIStream(CNcbiIstream& stream, EMethod method,
 
 
 CCompressOStream::CCompressOStream(CNcbiOstream& stream, EMethod method, 
-                                   ICompression::TFlags flags, 
+                                   ICompression::TFlags stm_flags, 
                                    ICompression::ELevel level,
                                    ENcbiOwnership own_ostream)
 {
-    CCompressionStreamProcessor* processor = s_Init(eCompress, method, flags, level);
+    CCompressionStreamProcessor* processor = s_Init(eCompress, method, stm_flags, level);
     if (processor) {
         Create(stream, processor, own_ostream==eTakeOwnership?CCompressionStream::fOwnAll:CCompressionStream::fOwnProcessor);
     }
@@ -150,11 +150,11 @@ CCompressOStream::CCompressOStream(CNcbiOstream& stream, EMethod method,
 
 
 CDecompressIStream::CDecompressIStream(CNcbiIstream& stream, EMethod method, 
-                                       ICompression::TFlags flags,
+                                       ICompression::TFlags stm_flags,
                                        ENcbiOwnership own_instream)
 {
     CCompressionStreamProcessor* processor = 
-        s_Init(eDecompress, method, flags, ICompression::eLevel_Default);
+        s_Init(eDecompress, method, stm_flags, ICompression::eLevel_Default);
     if (processor) {
         Create(stream, processor, own_instream==eTakeOwnership?CCompressionStream::fOwnAll:CCompressionStream::fOwnProcessor);
     }
@@ -162,10 +162,10 @@ CDecompressIStream::CDecompressIStream(CNcbiIstream& stream, EMethod method,
 
 
 CDecompressOStream::CDecompressOStream(CNcbiOstream& stream, EMethod method, 
-                                       ICompression::TFlags flags)
+                                       ICompression::TFlags stm_flags)
 {
     CCompressionStreamProcessor* processor = 
-        s_Init(eDecompress, method, flags, ICompression::eLevel_Default);
+        s_Init(eDecompress, method, stm_flags, ICompression::eLevel_Default);
     if (processor) {
         Create(stream, processor, CCompressionStream::fOwnProcessor);
     }
diff --git a/c++/src/util/compress/api/streambuf.cpp b/c++/src/util/compress/api/streambuf.cpp
index d94a416..a88ee6c 100644
--- a/c++/src/util/compress/api/streambuf.cpp
+++ b/c++/src/util/compress/api/streambuf.cpp
@@ -1,4 +1,4 @@
-/* $Id: streambuf.cpp 489095 2016-01-08 13:02:41Z ivanov $
+/* $Id: streambuf.cpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -254,7 +254,7 @@ int CCompressionStreambuf::Flush(CCompressionStream::EDirection dir)
 
     // Flush stream compressor
     CT_CHAR_TYPE* buf = 0;
-    size_t out_size = 0, out_avail = 0;
+    size_t out_size = 0, out_available = 0;
     do {
         // Get pointer to the free space in the buffer
         if ( dir == CCompressionStream::eRead ) {
@@ -265,16 +265,16 @@ int CCompressionStreambuf::Flush(CCompressionStream::EDirection dir)
         out_size = sp->m_OutBuf + sp->m_OutBufSize - buf;
 
         // Get data from processor
-        out_avail = 0;
+        out_available = 0;
         if ( sp->m_State == CSP::eFinalize ) {
             // State is eFinalize
             sp->m_LastStatus = 
-                sp->m_Processor->Finish(buf, out_size, &out_avail);
+                sp->m_Processor->Finish(buf, out_size, &out_available);
         } else {
             // State is eActive
             _VERIFY(sp->m_State == CSP::eActive);
             sp->m_LastStatus = 
-                sp->m_Processor->Flush(buf, out_size, &out_avail);
+                sp->m_Processor->Flush(buf, out_size, &out_available);
             // No more data -- automatically finalize stream
             if ( sp->m_LastStatus == CP::eStatus_EndOfData ) {
                 sp->m_State = CSP::eFinalize;
@@ -286,10 +286,10 @@ int CCompressionStreambuf::Flush(CCompressionStream::EDirection dir)
         }
         if ( dir == CCompressionStream::eRead ) {
             // Update the get's pointers
-            setg(sp->m_OutBuf, gptr(), egptr() + out_avail);
+            setg(sp->m_OutBuf, gptr(), egptr() + out_available);
         } else { // CCompressionStream::eWrite
             // Update the output buffer pointer
-            sp->m_End += out_avail;
+            sp->m_End += out_available;
             // Write data to the underlying stream only if the output buffer
             // is full or an overflow/endofdata occurs.
             if ( !WriteOutBufToStream() ) {
@@ -297,8 +297,8 @@ int CCompressionStreambuf::Flush(CCompressionStream::EDirection dir)
             }
         }
     } while (sp->m_LastStatus == CP::eStatus_Repeat  ||
-            (out_avail  &&  (sp->m_LastStatus == CP::eStatus_Success || 
-                             sp->m_LastStatus == CP::eStatus_Overflow))
+            (out_available  &&  (sp->m_LastStatus == CP::eStatus_Success || 
+                                 sp->m_LastStatus == CP::eStatus_Overflow))
             );
 
     // Flush underlying stream (on write)
@@ -358,7 +358,7 @@ CT_INT_TYPE CCompressionStreambuf::underflow(void)
 
 bool CCompressionStreambuf::ProcessStreamRead()
 {
-    size_t     in_len, in_avail, out_size, out_avail;
+    size_t     in_len, in_available, out_size, out_available;
     streamsize n_read;
 
     // End of stream has been detected
@@ -374,9 +374,9 @@ bool CCompressionStreambuf::ProcessStreamRead()
     // Put data into the (de)compressor until there is something
     // in the output buffer
     do {
-        in_avail  = 0;
-        out_avail = 0;
-        out_size  = m_Reader->m_OutBuf + m_Reader->m_OutBufSize - egptr();
+        in_available  = 0;
+        out_available = 0;
+        out_size      = m_Reader->m_OutBuf + m_Reader->m_OutBufSize - egptr();
 
         // Refill the output buffer if necessary
         if ( m_Reader->m_LastStatus != CP::eStatus_Overflow ) {
@@ -407,7 +407,7 @@ bool CCompressionStreambuf::ProcessStreamRead()
             in_len = m_Reader->m_End - m_Reader->m_Begin;
             m_Reader->m_LastStatus = m_Reader->m_Processor->Process(
                                 m_Reader->m_Begin, in_len, egptr(), out_size,
-                                &in_avail, &out_avail);
+                                &in_available, &out_available);
         } else {
             // Check available space in the output buffer
             if ( !out_size ) {
@@ -415,9 +415,9 @@ bool CCompressionStreambuf::ProcessStreamRead()
             }
             // Get unprocessed data size
             in_len = m_Reader->m_End - m_Reader->m_Begin;
-            in_avail = in_len;
+            in_available = in_len;
             m_Reader->m_LastStatus = 
-                m_Reader->m_Processor->Flush(egptr(), out_size, &out_avail);
+                m_Reader->m_Processor->Flush(egptr(), out_size, &out_available);
         }
         if ( m_Reader->m_LastStatus == CP::eStatus_Error ) {
             return false;
@@ -428,15 +428,15 @@ bool CCompressionStreambuf::ProcessStreamRead()
         }
 
         // Update pointer to an unprocessed data
-        m_Reader->m_Begin += (in_len - in_avail);
+        m_Reader->m_Begin += (in_len - in_available);
         // Update the get's pointers
-        setg(m_Reader->m_OutBuf, gptr(), egptr() + out_avail);
+        setg(m_Reader->m_OutBuf, gptr(), egptr() + out_available);
 
-        if ( m_Reader->m_LastStatus == CP::eStatus_EndOfData   &&  !out_avail ) { 
+        if ( m_Reader->m_LastStatus == CP::eStatus_EndOfData   &&  !out_available ) { 
             return false;
         }
 
-    } while ( !out_avail );
+    } while ( !out_available );
 
     return true;
 }
@@ -444,9 +444,9 @@ bool CCompressionStreambuf::ProcessStreamRead()
 
 bool CCompressionStreambuf::ProcessStreamWrite()
 {
-    const char*  in_buf    = pbase();
-    const size_t count     = pptr() - pbase();
-    size_t       in_avail  = count;
+    const char*  in_buf       = pbase();
+    const size_t count        = pptr() - pbase();
+    size_t       in_available = count;
 
     // Nothing was written into processor yet
     if ( m_Writer->m_State == CSP::eInit ) {
@@ -465,14 +465,14 @@ bool CCompressionStreambuf::ProcessStreamWrite()
     }
 
     // Loop until no data is left
-    while ( in_avail ) {
+    while ( in_available ) {
         // Process next data portion
-        size_t out_avail = 0;
+        size_t out_available = 0;
         size_t out_size = m_Writer->m_OutBuf + 
                           m_Writer->m_OutBufSize - m_Writer->m_End;
         m_Writer->m_LastStatus = m_Writer->m_Processor->Process(
-            in_buf + count - in_avail, in_avail, m_Writer->m_End, out_size,
-            &in_avail, &out_avail);
+            in_buf + count - in_available, in_available, m_Writer->m_End, out_size,
+            &in_available, &out_available);
 
         // Check on error / small output buffer
         if ( m_Writer->m_LastStatus == CP::eStatus_Error ) {
@@ -483,7 +483,7 @@ bool CCompressionStreambuf::ProcessStreamWrite()
             m_Writer->m_State = CSP::eFinalize;
         }
         // Update the output buffer pointer
-        m_Writer->m_End += out_avail;
+        m_Writer->m_End += out_available;
 
         // Write data to the underlying stream only if the output buffer
         // is full or an overflow occurs.
diff --git a/c++/src/util/compress/api/zlib.cpp b/c++/src/util/compress/api/zlib.cpp
index 17588b2..b3434c2 100644
--- a/c++/src/util/compress/api/zlib.cpp
+++ b/c++/src/util/compress/api/zlib.cpp
@@ -1,4 +1,4 @@
-/*  $Id: zlib.cpp 489095 2016-01-08 13:02:41Z ivanov $
+/*  $Id: zlib.cpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1475,7 +1475,7 @@ void g_GZip_ScanForChunks(CNcbiIstream& is, IChunkHandler& handler)
                     strm.zalloc   = Z_NULL;
                     strm.zfree    = Z_NULL;
                     strm.opaque   = Z_NULL;
-                    ret = inflateInit2(&strm, 15+16 /* max windowbits + automatic gzip header decoding */);
+                    ret = inflateInit2(&strm, 15+16 /* max windowbits + automatic gzip header decoding */); /* NCBI_FAKE_WARNING */
                     if (ret != Z_OK) {
                         throw "inflateInit2() failed: " + string(zError(ret));
                     }
diff --git a/c++/src/util/compress/bzip2/CHANGES b/c++/src/util/compress/bzip2/CHANGES
index d984395..81e97ca 100644
--- a/c++/src/util/compress/bzip2/CHANGES
+++ b/c++/src/util/compress/bzip2/CHANGES
@@ -1,3 +1,16 @@
+ ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.6 of 6 September 2010
+ Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------
 
 
 0.9.0
@@ -251,3 +264,64 @@ of bzip2:
 
 * added --fast and --best aliases for -1 -9 for gzip compatibility.
 
+
+1.0.3 (15 Feb 05)
+~~~~~~~~~~~~~~~~~
+Fixes some minor bugs since the last version, 1.0.2.
+
+* Further robustification against corrupted compressed data.
+  There are currently no known bitstreams which can cause the
+  decompressor to crash, loop or access memory which does not
+  belong to it.  If you are using bzip2 or the library to 
+  decompress bitstreams from untrusted sources, an upgrade
+  to 1.0.3 is recommended.  This fixes CAN-2005-1260.
+
+* The documentation has been converted to XML, from which html
+  and pdf can be derived.
+
+* Various minor bugs in the documentation have been fixed.
+
+* Fixes for various compilation warnings with newer versions of
+  gcc, and on 64-bit platforms.
+
+* The BZ_NO_STDIO cpp symbol was not properly observed in 1.0.2.
+  This has been fixed.
+
+
+1.0.4 (20 Dec 06)
+~~~~~~~~~~~~~~~~~
+Fixes some minor bugs since the last version, 1.0.3.
+
+* Fix file permissions race problem (CAN-2005-0953).
+
+* Avoid possible segfault in BZ2_bzclose.  From Coverity's NetBSD
+  scan.
+
+* 'const'/prototype cleanups in the C code.
+
+* Change default install location to /usr/local, and handle multiple
+  'make install's without error.
+
+* Sanitise file names more carefully in bzgrep.  Fixes CAN-2005-0758
+  to the extent that applies to bzgrep.
+
+* Use 'mktemp' rather than 'tempfile' in bzdiff.
+
+* Tighten up a couple of assertions in blocksort.c following automated
+  analysis.
+
+* Fix minor doc/comment bugs.
+
+
+1.0.5 (10 Dec 07)
+~~~~~~~~~~~~~~~~~
+Security fix only.  Fixes CERT-FI 20469 as it applies to bzip2.
+
+
+1.0.6 (6 Sept 10)
+~~~~~~~~~~~~~~~~~
+
+* Security fix for CVE-2010-0405.  This was reported by Mikolaj
+  Izdebski.
+
+* Make the documentation build on Ubuntu 10.04
diff --git a/c++/src/util/compress/bzip2/LICENSE b/c++/src/util/compress/bzip2/LICENSE
index 9d4fa43..cc61417 100644
--- a/c++/src/util/compress/bzip2/LICENSE
+++ b/c++/src/util/compress/bzip2/LICENSE
@@ -1,6 +1,9 @@
 
-This program, "bzip2" and associated library "libbzip2", are
-copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
+--------------------------------------------------------------------------
+
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2010 Julian R Seward.  All
+rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
@@ -33,7 +36,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-Julian Seward, Cambridge, UK.
-jseward at acm.org
-bzip2/libbzip2 version 1.0.2 of 30 December 2001
+Julian Seward, jseward at bzip.org
+bzip2/libbzip2 version 1.0.6 of 6 September 2010
 
+--------------------------------------------------------------------------
diff --git a/c++/src/util/compress/bzip2/README b/c++/src/util/compress/bzip2/README
index 07505d8..9fb0f63 100644
--- a/c++/src/util/compress/bzip2/README
+++ b/c++/src/util/compress/bzip2/README
@@ -1,33 +1,48 @@
 
-This is the README for bzip2, a block-sorting file compressor, version
-1.0.2.  This version is fully compatible with the previous public
-releases, versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0 and 1.0.1.
+This is the README for bzip2/libzip2.
+This version is fully compatible with the previous public releases.
 
-bzip2-1.0.2 is distributed under a BSD-style license.  For details,
-see the file LICENSE.
+------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.6 of 6 September 2010
+Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in this file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------
 
 Complete documentation is available in Postscript form (manual.ps),
-PDF (manual.pdf, amazingly enough) or html (manual_toc.html).  A
-plain-text version of the manual page is available as bzip2.txt.  
-A statement about Y2K issues is now included in the file Y2K_INFO.
+PDF (manual.pdf) or html (manual.html).  A plain-text version of the
+manual page is available as bzip2.txt.
 
 
 HOW TO BUILD -- UNIX
 
-Type `make'.  This builds the library libbz2.a and then the
-programs bzip2 and bzip2recover.  Six self-tests are run.
-If the self-tests complete ok, carry on to installation:
+Type 'make'.  This builds the library libbz2.a and then the programs
+bzip2 and bzip2recover.  Six self-tests are run.  If the self-tests
+complete ok, carry on to installation:
+
+To install in /usr/local/bin, /usr/local/lib, /usr/local/man and
+/usr/local/include, type
 
-To install in /usr/bin, /usr/lib, /usr/man and /usr/include, type
    make install
-To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type 
+
+To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type
+
    make install PREFIX=/xxx/yyy
+
 If you are (justifiably) paranoid and want to see what 'make install'
 is going to do, you can first do
+
    make -n install                      or
    make -n install PREFIX=/xxx/yyy      respectively.
-The -n instructs make to show the commands it would execute, but
-not actually execute them.
+
+The -n instructs make to show the commands it would execute, but not
+actually execute them.
 
 
 HOW TO BUILD -- UNIX, shared library libbz2.so.
@@ -49,23 +64,25 @@ Important note for people upgrading .so's from 0.9.0/0.9.5 to version
 bzCompress to BZ2_bzCompress, to avoid namespace pollution.
 Unfortunately this means that the libbz2.so created by
 Makefile-libbz2_so will not work with any program which used an older
-version of the library.  Sorry.  I do encourage library clients to
-make the effort to upgrade to use version 1.0, since it is both faster
-and more robust than previous versions.
+version of the library.  I do encourage library clients to make the
+effort to upgrade to use version 1.0, since it is both faster and more
+robust than previous versions.
 
 
 HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc.
 
 It's difficult for me to support compilation on all these platforms.
 My approach is to collect binaries for these platforms, and put them
-on the master web page (http://sources.redhat.com/bzip2).  Look there.
-However (FWIW), bzip2-1.0.X is very standard ANSI C and should compile
+on the master web site (http://www.bzip.org).  Look there.  However
+(FWIW), bzip2-1.0.X is very standard ANSI C and should compile
 unmodified with MS Visual C.  If you have difficulties building, you
 might want to read README.COMPILATION.PROBLEMS.
 
 At least using MS Visual C++ 6, you can build from the unmodified
 sources by issuing, in a command shell: 
+
    nmake -f makefile.msc
+
 (you may need to first run the MSVC-provided script VCVARS32.BAT
  so as to set up paths to the MSVC tools correctly).
 
@@ -78,8 +95,7 @@ importance.  To validate bzip2, I used a modified version of Mark
 Nelson's churn program.  Churn is an automated test driver which
 recursively traverses a directory structure, using bzip2 to compress
 and then decompress each file it encounters, and checking that the
-decompressed data is the same as the original.  There are more details
-in Section 4 of the user guide.
+decompressed data is the same as the original.
 
 
 
@@ -87,18 +103,19 @@ Please read and be aware of the following:
 
 WARNING:
 
-   This program (attempts to) compress data by performing several
-   non-trivial transformations on it.  Unless you are 100% familiar
-   with *all* the algorithms contained herein, and with the
-   consequences of modifying them, you should NOT meddle with the
-   compression or decompression machinery.  Incorrect changes can and
-   very likely *will* lead to disastrous loss of data.
+   This program and library (attempts to) compress data by 
+   performing several non-trivial transformations on it.  
+   Unless you are 100% familiar with *all* the algorithms 
+   contained herein, and with the consequences of modifying them, 
+   you should NOT meddle with the compression or decompression 
+   machinery.  Incorrect changes can and very likely *will* 
+   lead to disastrous loss of data.
 
 
 DISCLAIMER:
 
    I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
-   USE OF THIS PROGRAM, HOWSOEVER CAUSED.
+   USE OF THIS PROGRAM/LIBRARY, HOWSOEVER CAUSED.
 
    Every compression of a file implies an assumption that the
    compressed file can be decompressed to reproduce the original.
@@ -111,19 +128,18 @@ DISCLAIMER:
    PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER
    SMALL, THAT THE DATA WILL NOT BE RECOVERABLE.
 
-   That is not to say this program is inherently unreliable.  Indeed,
-   I very much hope the opposite is true.  bzip2 has been carefully
-   constructed and extensively tested.
+   That is not to say this program is inherently unreliable.  
+   Indeed, I very much hope the opposite is true.  bzip2/libbzip2 
+   has been carefully constructed and extensively tested.
 
 
 PATENTS:
 
-   To the best of my knowledge, bzip2 does not use any patented
-   algorithms.  However, I do not have the resources available to
-   carry out a full patent search.  Therefore I cannot give any
+   To the best of my knowledge, bzip2/libbzip2 does not use any 
+   patented algorithms.  However, I do not have the resources 
+   to carry out a patent search.  Therefore I cannot give any 
    guarantee of the above statement.
 
-End of legalities.
 
 
 WHAT'S NEW IN 0.9.0 (as compared to 0.1pl2) ?
@@ -153,22 +169,36 @@ WHAT'S NEW IN 1.0.2 ?
 
    See the CHANGES file.
 
+WHAT'S NEW IN 1.0.3 ?
+
+   See the CHANGES file.
+
+WHAT'S NEW IN 1.0.4 ?
+
+   See the CHANGES file.
+
+WHAT'S NEW IN 1.0.5 ?
+
+   See the CHANGES file.
+
+WHAT'S NEW IN 1.0.6 ?
+
+   See the CHANGES file.
+
 
 I hope you find bzip2 useful.  Feel free to contact me at
-   jseward at acm.org
+   jseward at bzip.org
 if you have any suggestions or queries.  Many people mailed me with
 comments, suggestions and patches after the releases of bzip-0.15,
-bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0 and 1.0.1,
-and the changes in bzip2 are largely a result of this feedback.
-I thank you for your comments.
+bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1,
+1.0.2 and 1.0.3, and the changes in bzip2 are largely a result of this
+feedback.  I thank you for your comments.
 
-At least for the time being, bzip2's "home" is (or can be reached via)
-http://sources.redhat.com/bzip2.
+bzip2's "home" is http://www.bzip.org/
 
 Julian Seward
-jseward at acm.org
-
-Cambridge, UK (and what a great town this is!)
+jseward at bzip.org
+Cambridge, UK.
 
 18     July 1996 (version 0.15)
 25   August 1996 (version 0.21)
@@ -178,4 +208,8 @@ Cambridge, UK (and what a great town this is!)
  8     June 1999 (bzip2, version 0.9.5)
  4     Sept 1999 (bzip2, version 0.9.5d)
  5      May 2000 (bzip2, version 1.0pre8)
-30 December 2001 (bzip2, version 1.0.2pre1)
\ No newline at end of file
+30 December 2001 (bzip2, version 1.0.2pre1)
+15 February 2005 (bzip2, version 1.0.3)
+20 December 2006 (bzip2, version 1.0.4)
+10 December 2007 (bzip2, version 1.0.5)
+ 6     Sept 2010 (bzip2, version 1.0.6)
diff --git a/c++/src/util/compress/bzip2/README.COMPILATION.PROBLEMS b/c++/src/util/compress/bzip2/README.COMPILATION.PROBLEMS
index bd1822d..667d0d6 100644
--- a/c++/src/util/compress/bzip2/README.COMPILATION.PROBLEMS
+++ b/c++/src/util/compress/bzip2/README.COMPILATION.PROBLEMS
@@ -1,33 +1,47 @@
+------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
 
-bzip2-1.0 should compile without problems on the vast majority of
+bzip2/libbzip2 version 1.0.6 of 6 September 2010
+Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+README file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------
+
+bzip2-1.0.6 should compile without problems on the vast majority of
 platforms.  Using the supplied Makefile, I've built and tested it
-myself for x86-linux, sparc-solaris, alpha-linux, x86-cygwin32 and
-alpha-tru64unix.  With makefile.msc, Visual C++ 6.0 and nmake, you can
-build a native Win32 version too.  Large file support seems to work
-correctly on at least alpha-tru64unix and x86-cygwin32 (on Windows
-2000).
+myself for x86-linux and amd64-linux.  With makefile.msc, Visual C++
+6.0 and nmake, you can build a native Win32 version too.  Large file
+support seems to work correctly on at least on amd64-linux.
 
 When I say "large file" I mean a file of size 2,147,483,648 (2^31)
 bytes or above.  Many older OSs can't handle files above this size,
 but many newer ones can.  Large files are pretty huge -- most files
 you'll encounter are not Large Files.
 
-Earlier versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide
-variety of platforms without difficulty, and I hope this version will
-continue in that tradition.  However, in order to support large files,
-I've had to include the define -D_FILE_OFFSET_BITS=64 in the Makefile.
-This can cause problems.
+Early versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide variety
+of platforms without difficulty, and I hope this version will continue
+in that tradition.  However, in order to support large files, I've had
+to include the define -D_FILE_OFFSET_BITS=64 in the Makefile.  This
+can cause problems.
 
 The technique of adding -D_FILE_OFFSET_BITS=64 to get large file
 support is, as far as I know, the Recommended Way to get correct large
 file support.  For more details, see the Large File Support
 Specification, published by the Large File Summit, at
-   http://www.sas.com/standard/large.file/
+
+   http://ftp.sas.com/standards/large.file
 
 As a general comment, if you get compilation errors which you think
 are related to large file support, try removing the above define from
 the Makefile, ie, delete the line
+
    BIGFILES=-D_FILE_OFFSET_BITS=64 
+
 from the Makefile, and do 'make clean ; make'.  This will give you a
 version of bzip2 without large file support, which, for most
 applications, is probably not a problem.  
@@ -39,92 +53,6 @@ large file support, if you are feeling paranoid.  Be aware though that
 any compilation problems which affect bzip2 will also affect spewG.c,
 alas.
 
-
-Known problems as of 1.0pre8:
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-* HP/UX 10.20 and 11.00, using gcc (2.7.2.3 and 2.95.2):  A large
-  number of warnings appear, including the following:
-
-     /usr/include/sys/resource.h: In function `getrlimit':
-     /usr/include/sys/resource.h:168: 
-        warning: implicit declaration of function `__getrlimit64'
-     /usr/include/sys/resource.h: In function `setrlimit':
-     /usr/include/sys/resource.h:170: 
-        warning: implicit declaration of function `__setrlimit64'
-
-  This would appear to be a problem with large file support, header
-  files and gcc.  gcc may or may not give up at this point.  If it
-  fails, you might be able to improve matters by adding 
-     -D__STDC_EXT__=1
-  to the BIGFILES variable in the Makefile (ie, change its definition
-  to
-     BIGFILES=-D_FILE_OFFSET_BITS=64 -D__STDC_EXT__=1
-
-  Even if gcc does produce a binary which appears to work (ie passes
-  its self-tests), you might want to test it to see if it works properly
-  on large files.
-
-
-* HP/UX 10.20 and 11.00, using HP's cc compiler.
-
-  No specific problems for this combination, except that you'll need to
-  specify the -Ae flag, and zap the gcc-specific stuff
-  -Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce.
-  You should retain -D_FILE_OFFSET_BITS=64 in order to get large
-  file support -- which is reported to work ok for this HP/UX + cc
-  combination.
-
-
-* SunOS 4.1.X.
-
-  Amazingly, there are still people out there using this venerable old
-  banger.  I shouldn't be too rude -- I started life on SunOS, and
-  it was a pretty darn good OS, way back then.  Anyway:
-
-     SunOS doesn't seem to have strerror(), so you'll have to use
-     perror(), perhaps by doing adding this (warning: UNTESTED CODE):
-
-     char* strerror ( int errnum )
-     {
-        if (errnum < 0 || errnum >= sys_nerr)
-           return "Unknown error"; 
-        else
-           return sys_errlist[errnum];
-     }
-
-   Or you could comment out the relevant calls to strerror; they're
-   not mission-critical.  Or you could upgrade to Solaris.  Ha ha ha!
-   (what??  you think I've got Bad Attitude?) 
-
-
-* Making a shared library on Solaris.  (Not really a compilation
-  problem, but many people ask ...)  
-
-  Firstly, if you have Solaris 8, either you have libbz2.so already
-  on your system, or you can install it from the Solaris CD.  
-
-  Secondly, be aware that there are potential naming conflicts
-  between the .so file supplied with Solaris 8, and the .so file
-  which Makefile-libbz2_so will make.  Makefile-libbz2_so creates
-  a .so which has the names which I intend to be "official" as
-  of version 1.0.0 and onwards.  Unfortunately, the .so in
-  Solaris 8 appeared before I decided on the final names, so
-  the two libraries are incompatible.  We have since communicated
-  and I hope that the problems will have been solved in the next
-  version of Solaris, whenever that might appear.
-
-  All that said: you might be able to get somewhere
-  by finding the line in Makefile-libbz2_so which says
-
-  $(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.2 $(OBJS)
-
-  and replacing with 
-
-  $(CC) -G -shared -o libbz2.so.1.0.2 -h libbz2.so.1.0 $(OBJS)
-  
-  If gcc objects to the combination -fpic -fPIC, get rid of
-  the second one, leaving just "-fpic".
-
-
-That's the end of the currently known compilation problems.
+AIX: I have reports that for large file support, you need to specify
+-D_LARGE_FILES rather than -D_FILE_OFFSET_BITS=64.  I have not tested
+this myself.
diff --git a/c++/src/util/compress/bzip2/README.XML.STUFF b/c++/src/util/compress/bzip2/README.XML.STUFF
new file mode 100644
index 0000000..3a57f3f
--- /dev/null
+++ b/c++/src/util/compress/bzip2/README.XML.STUFF
@@ -0,0 +1,45 @@
+  ----------------------------------------------------------------
+  This file is part of bzip2/libbzip2, a program and library for
+  lossless, block-sorting data compression.
+
+  bzip2/libbzip2 version 1.0.6 of 6 September 2010
+  Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+  Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+  README file.
+
+  This program is released under the terms of the license contained
+  in the file LICENSE.
+  ----------------------------------------------------------------
+
+The script xmlproc.sh takes an xml file as input,
+and processes it to create .pdf, .html or .ps output.
+It uses format.pl, a perl script to format <pre> blocks nicely,
+ and add CDATA tags so writers do not have to use eg. < 
+
+The file "entities.xml" must be edited to reflect current
+version, year, etc.
+
+
+Usage:
+
+  ./xmlproc.sh -v manual.xml
+  Validates an xml file to ensure no dtd-compliance errors
+
+  ./xmlproc.sh -html manual.xml
+  Output: manual.html
+
+  ./xmlproc.sh -pdf manual.xml
+  Output: manual.pdf
+
+  ./xmlproc.sh -ps manual.xml
+  Output: manual.ps
+
+
+Notum bene: 
+- pdfxmltex barfs if given a filename with an underscore in it
+
+- xmltex won't work yet - there's a bug in passivetex
+    which we are all waiting for Sebastian to fix.
+  So we are going the xml -> pdf -> ps route for the time being,
+    using pdfxmltex.
diff --git a/c++/src/util/compress/bzip2/Y2K_INFO b/c++/src/util/compress/bzip2/Y2K_INFO
deleted file mode 100644
index 55fd56a..0000000
--- a/c++/src/util/compress/bzip2/Y2K_INFO
+++ /dev/null
@@ -1,34 +0,0 @@
-
-Y2K status of bzip2 and libbzip2, versions 0.1, 0.9.0 and 0.9.5
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Informally speaking:
-   bzip2 is a compression program built on top of libbzip2, 
-   a library which does the real work of compression and 
-   decompression.  As far as I am aware, libbzip2 does not have 
-   any date-related code at all.
-
-   bzip2 itself copies dates from source to destination files 
-   when compressing or decompressing, using the 'stat' and 'utime' 
-   UNIX system calls.  It doesn't examine, manipulate or store the 
-   dates in any way.  So as far as I can see, there shouldn't be any 
-   problem with bzip2 providing 'stat' and 'utime' work correctly 
-   on your system.
-
-   On non-unix platforms (those for which BZ_UNIX in bzip2.c is
-   not set to 1), bzip2 doesn't even do the date copying.
-
-   Overall, informally speaking, I don't think bzip2 or libbzip2 
-   have a Y2K problem.
-
-Formally speaking:
-   I am not prepared to offer you any assurance whatsoever 
-   regarding Y2K issues in my software.  You alone assume the 
-   entire risk of using the software.  The disclaimer of liability 
-   in the LICENSE file in the bzip2 source distribution continues 
-   to apply on this issue as with every other issue pertaining 
-   to the software.
-
-Julian Seward
-Cambridge, UK
-25 August 1999
diff --git a/c++/src/util/compress/bzip2/blocksort.c b/c++/src/util/compress/bzip2/blocksort.c
index aba3efc..d0d662c 100644
--- a/c++/src/util/compress/bzip2/blocksort.c
+++ b/c++/src/util/compress/bzip2/blocksort.c
@@ -4,66 +4,19 @@
 /*---                                           blocksort.c ---*/
 /*-------------------------------------------------------------*/
 
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward at acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
-
-  To get some idea how the block sorting algorithms in this file 
-  work, read my paper 
-     On the Performance of BWT Sorting Algorithms
-  in Proceedings of the IEEE Data Compression Conference 2000,
-  Snowbird, Utah, USA, 27-30 March 2000.  The main sort in this
-  file implements the algorithm called  cache  in the paper.
---*/
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
 
 
 #include "bzlib_private.h"
@@ -155,7 +108,7 @@ void fallbackQSort3 ( UInt32* fmap,
 
    while (sp > 0) {
 
-      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
+      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
 
       fpop ( lo, hi );
       if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
@@ -690,7 +643,7 @@ void mainQSort3 ( UInt32* ptr,
 
    while (sp > 0) {
 
-      AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
+      AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
 
       mpop ( lo, hi, d );
       if (hi - lo < MAIN_QSORT_SMALL_THRESH || 
diff --git a/c++/src/util/compress/bzip2/bzdiff b/c++/src/util/compress/bzip2/bzdiff
index 3c2eb85..6fc38f9 100644
--- a/c++/src/util/compress/bzip2/bzdiff
+++ b/c++/src/util/compress/bzip2/bzdiff
@@ -12,7 +12,7 @@
 # necessary) and fed to cmp or diff.  The exit status from cmp
 # or diff is preserved.
 
-PATH="/usr/bin:$PATH"; export PATH
+PATH="/usr/bin:/bin:$PATH"; export PATH
 prog=`echo $0 | sed 's|.*/||'`
 case "$prog" in
   *cmp) comp=${CMP-cmp}   ;;
@@ -37,7 +37,7 @@ if test -z "$FILES"; then
 	echo "Usage: $prog [${comp}_options] file [file]"
 	exit 1
 fi
-tmp=`tempfile -d /tmp -p bz` || {
+tmp=`mktemp ${TMPDIR:-/tmp}/bzdiff.XXXXXXXXXX` || {
       echo 'cannot create a temporary file' >&2
       exit 1
 }
diff --git a/c++/src/util/compress/bzip2/bzgrep b/c++/src/util/compress/bzip2/bzgrep
index dbfc00e..9a04b83 100644
--- a/c++/src/util/compress/bzip2/bzgrep
+++ b/c++/src/util/compress/bzip2/bzgrep
@@ -63,7 +63,11 @@ for i do
     bzip2 -cdfq "$i" | $grep $opt "$pat"
     r=$?
   else
-    bzip2 -cdfq "$i" | $grep $opt "$pat" | sed "s|^|${i}:|"
+    j=${i//\\/\\\\}
+    j=${j//|/\\|}
+    j=${j//&/\\&}
+    j=`printf "%s" "$j" | tr '\n' ' '`
+    bzip2 -cdfq "$i" | $grep $opt "$pat" | sed "s|^|${j}:|"
     r=$?
   fi
   test "$r" -ne 0 && res="$r"
diff --git a/c++/src/util/compress/bzip2/bzip.css b/c++/src/util/compress/bzip2/bzip.css
new file mode 100644
index 0000000..43193d8
--- /dev/null
+++ b/c++/src/util/compress/bzip2/bzip.css
@@ -0,0 +1,74 @@
+/* Colours:
+#74240f  dark brown      h1, h2, h3, h4
+#336699  medium blue     links
+#339999  turquoise       link hover colour
+#202020  almost black    general text
+#761596  purple          md5sum text
+#626262  dark gray       pre border
+#eeeeee  very light gray pre background
+#f2f2f9  very light blue nav table background
+#3366cc  medium blue     nav table border
+*/
+
+a, a:link, a:visited, a:active { color: #336699; }
+a:hover { color: #339999; }
+
+body { font: 80%/126% sans-serif; }
+h1, h2, h3, h4 { color: #74240f; }
+
+dt { color: #336699; font-weight: bold }
+dd { 
+ margin-left: 1.5em; 
+ padding-bottom: 0.8em;
+}
+
+/* -- ruler -- */
+div.hr_blue { 
+  height:  3px; 
+  background:#ffffff url("/images/hr_blue.png") repeat-x; }
+div.hr_blue hr { display:none; }
+
+/* release styles */
+#release p { margin-top: 0.4em; }
+#release .md5sum { color: #761596; }
+
+
+/* ------ styles for docs|manuals|howto ------ */
+/* -- lists -- */
+ul  { 
+ margin:     0px 4px 16px 16px;
+ padding:    0px;
+ list-style: url("/images/li-blue.png"); 
+}
+ul li { 
+ margin-bottom: 10px;
+}
+ul ul	{ 
+ list-style-type:  none; 
+ list-style-image: none; 
+ margin-left:      0px; 
+}
+
+/* header / footer nav tables */
+table.nav {
+ border:     solid 1px #3366cc;
+ background: #f2f2f9;
+ background-color: #f2f2f9;
+ margin-bottom: 0.5em;
+}
+/* don't have underlined links in chunked nav menus */
+table.nav a { text-decoration: none; }
+table.nav a:hover { text-decoration: underline; }
+table.nav td { font-size: 85%; }
+
+code, tt, pre { font-size: 120%; }
+code, tt { color: #761596; }
+
+div.literallayout, pre.programlisting, pre.screen {
+ color:      #000000;
+ padding:    0.5em;
+ background: #eeeeee;
+ border:     1px solid #626262;
+ background-color: #eeeeee;
+ margin: 4px 0px 4px 0px; 
+}
diff --git a/c++/src/util/compress/bzip2/bzip2.1 b/c++/src/util/compress/bzip2/bzip2.1
index 623435c..ce3a78e 100644
--- a/c++/src/util/compress/bzip2/bzip2.1
+++ b/c++/src/util/compress/bzip2/bzip2.1
@@ -1,7 +1,7 @@
 .PU
 .TH bzip2 1
 .SH NAME
-bzip2, bunzip2 \- a block-sorting file compressor, v1.0.2
+bzip2, bunzip2 \- a block-sorting file compressor, v1.0.6
 .br
 bzcat \- decompresses files to stdout
 .br
@@ -405,19 +405,19 @@ I/O error messages are not as helpful as they could be.
 tries hard to detect I/O errors and exit cleanly, but the details of
 what the problem is sometimes seem rather misleading.
 
-This manual page pertains to version 1.0.2 of
+This manual page pertains to version 1.0.6 of
 .I bzip2.  
 Compressed data created by this version is entirely forwards and
 backwards compatible with the previous public releases, versions
-0.1pl2, 0.9.0, 0.9.5, 1.0.0 and 1.0.1, but with the following
+0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1, 1.0.2 and above, but with the following
 exception: 0.9.0 and above can correctly decompress multiple
 concatenated compressed files.  0.1pl2 cannot do this; it will stop
 after decompressing just the first file in the stream.
 
 .I bzip2recover
-versions prior to this one, 1.0.2, used 32-bit integers to represent
-bit positions in compressed files, so it could not handle compressed
-files more than 512 megabytes long.  Version 1.0.2 and above uses
+versions prior to 1.0.2 used 32-bit integers to represent
+bit positions in compressed files, so they could not handle compressed
+files more than 512 megabytes long.  Versions 1.0.2 and above use
 64-bit ints on some platforms which support them (GNU supported
 targets, and Windows).  To establish whether or not bzip2recover was
 built with such a limitation, run it without arguments.  In any event
@@ -427,9 +427,9 @@ with MaybeUInt64 set to be an unsigned 64-bit integer.
 
 
 .SH AUTHOR
-Julian Seward, jseward at acm.org.
+Julian Seward, jsewardbzip.org.
 
-http://sources.redhat.com/bzip2
+http://www.bzip.org
 
 The ideas embodied in
 .I bzip2
@@ -447,6 +447,7 @@ source distribution for pointers to sources of documentation.  Christian
 von Roques encouraged me to look for faster sorting algorithms, so as to
 speed up compression.  Bela Lubkin encouraged me to improve the
 worst-case compression performance.  
+Donna Robinson XMLised the documentation.
 The bz* scripts are derived from those of GNU gzip.
 Many people sent patches, helped
 with portability problems, lent machines, gave advice and were generally
diff --git a/c++/src/util/compress/bzip2/bzip2.1.preformatted b/c++/src/util/compress/bzip2/bzip2.1.preformatted
deleted file mode 100644
index 0f20cb5..0000000
--- a/c++/src/util/compress/bzip2/bzip2.1.preformatted
+++ /dev/null
@@ -1,398 +0,0 @@
-bzip2(1)                                                 bzip2(1)
-
-
-
-NNAAMMEE
-       bzip2, bunzip2 - a block-sorting file compressor, v1.0.2
-       bzcat - decompresses files to stdout
-       bzip2recover - recovers data from damaged bzip2 files
-
-
-SSYYNNOOPPSSIISS
-       bbzziipp22 [ --ccddffkkqqssttvvzzVVLL112233445566778899 ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
-       bbuunnzziipp22 [ --ffkkvvssVVLL ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
-       bbzzccaatt [ --ss ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
-       bbzziipp22rreeccoovveerr _f_i_l_e_n_a_m_e
-
-
-DDEESSCCRRIIPPTTIIOONN
-       _b_z_i_p_2  compresses  files  using  the Burrows-Wheeler block
-       sorting text compression algorithm,  and  Huffman  coding.
-       Compression  is  generally  considerably  better than that
-       achieved by more conventional LZ77/LZ78-based compressors,
-       and  approaches  the performance of the PPM family of sta�
-       tistical compressors.
-
-       The command-line options are deliberately very similar  to
-       those of _G_N_U _g_z_i_p_, but they are not identical.
-
-       _b_z_i_p_2  expects  a list of file names to accompany the com�
-       mand-line flags.  Each file is replaced  by  a  compressed
-       version  of  itself,  with  the  name "original_name.bz2".
-       Each compressed file has the same modification date,  per�
-       missions, and, when possible, ownership as the correspond�
-       ing original, so that these properties  can  be  correctly
-       restored  at  decompression  time.   File name handling is
-       naive in the sense that there is no mechanism for preserv�
-       ing  original file names, permissions, ownerships or dates
-       in filesystems which lack these concepts, or have  serious
-       file name length restrictions, such as MS-DOS.
-
-       _b_z_i_p_2  and  _b_u_n_z_i_p_2 will by default not overwrite existing
-       files.  If you want this to happen, specify the -f flag.
-
-       If no file names  are  specified,  _b_z_i_p_2  compresses  from
-       standard  input  to  standard output.  In this case, _b_z_i_p_2
-       will decline to write compressed output to a terminal,  as
-       this  would  be  entirely  incomprehensible  and therefore
-       pointless.
-
-       _b_u_n_z_i_p_2 (or _b_z_i_p_2 _-_d_) decompresses  all  specified  files.
-       Files which were not created by _b_z_i_p_2 will be detected and
-       ignored, and a warning issued.  _b_z_i_p_2  attempts  to  guess
-       the  filename  for  the decompressed file from that of the
-       compressed file as follows:
-
-              filename.bz2    becomes   filename
-              filename.bz     becomes   filename
-              filename.tbz2   becomes   filename.tar
-              filename.tbz    becomes   filename.tar
-              anyothername    becomes   anyothername.out
-
-       If the file does not end in one of the recognised endings,
-       _._b_z_2_,  _._b_z_,  _._t_b_z_2 or _._t_b_z_, _b_z_i_p_2 complains that it cannot
-       guess the name of the original file, and uses the original
-       name with _._o_u_t appended.
-
-       As  with compression, supplying no filenames causes decom�
-       pression from standard input to standard output.
-
-       _b_u_n_z_i_p_2 will correctly decompress a file which is the con�
-       catenation of two or more compressed files.  The result is
-       the concatenation of the corresponding uncompressed files.
-       Integrity testing (-t) of concatenated compressed files is
-       also supported.
-
-       You can also compress or decompress files to the  standard
-       output  by giving the -c flag.  Multiple files may be com�
-       pressed and decompressed like this.  The resulting outputs
-       are  fed  sequentially to stdout.  Compression of multiple
-       files in this manner generates a stream containing  multi�
-       ple compressed file representations.  Such a stream can be
-       decompressed correctly only  by  _b_z_i_p_2  version  0.9.0  or
-       later.   Earlier  versions of _b_z_i_p_2 will stop after decom�
-       pressing the first file in the stream.
-
-       _b_z_c_a_t (or _b_z_i_p_2 _-_d_c_) decompresses all specified  files  to
-       the standard output.
-
-       _b_z_i_p_2  will  read arguments from the environment variables
-       _B_Z_I_P_2 and _B_Z_I_P_, in  that  order,  and  will  process  them
-       before  any  arguments  read  from the command line.  This
-       gives a convenient way to supply default arguments.
-
-       Compression is always performed, even  if  the  compressed
-       file  is slightly larger than the original.  Files of less
-       than about one hundred bytes tend to get larger, since the
-       compression  mechanism  has  a  constant  overhead  in the
-       region of 50 bytes.  Random data (including the output  of
-       most  file  compressors)  is  coded at about 8.05 bits per
-       byte, giving an expansion of around 0.5%.
-
-       As a self-check for your  protection,  _b_z_i_p_2  uses  32-bit
-       CRCs  to make sure that the decompressed version of a file
-       is identical to the original.  This guards against corrup�
-       tion  of  the compressed data, and against undetected bugs
-       in _b_z_i_p_2 (hopefully very unlikely).  The chances  of  data
-       corruption  going  undetected  is  microscopic,  about one
-       chance in four billion for each file processed.  Be aware,
-       though,  that  the  check occurs upon decompression, so it
-       can only tell you that something is wrong.  It can't  help
-       you  recover  the original uncompressed data.  You can use
-       _b_z_i_p_2_r_e_c_o_v_e_r to try to recover data from damaged files.
-
-       Return values: 0 for a normal exit,  1  for  environmental
-       problems  (file not found, invalid flags, I/O errors, &c),
-       2 to indicate a corrupt compressed file, 3 for an internal
-       consistency error (eg, bug) which caused _b_z_i_p_2 to panic.
-
-
-OOPPTTIIOONNSS
-       --cc ----ssttddoouutt
-              Compress or decompress to standard output.
-
-       --dd ----ddeeccoommpprreessss
-              Force  decompression.  _b_z_i_p_2_, _b_u_n_z_i_p_2 and _b_z_c_a_t are
-              really the same program,  and  the  decision  about
-              what  actions to take is done on the basis of which
-              name is used.  This flag overrides that  mechanism,
-              and forces _b_z_i_p_2 to decompress.
-
-       --zz ----ccoommpprreessss
-              The   complement   to   -d:   forces   compression,
-              regardless of the invocation name.
-
-       --tt ----tteesstt
-              Check integrity of the specified file(s), but don't
-              decompress  them.   This  really  performs  a trial
-              decompression and throws away the result.
-
-       --ff ----ffoorrccee
-              Force overwrite of output files.   Normally,  _b_z_i_p_2
-              will  not  overwrite  existing  output files.  Also
-              forces _b_z_i_p_2 to break hard links to files, which it
-              otherwise wouldn't do.
-
-              bzip2  normally  declines to decompress files which
-              don't have the  correct  magic  header  bytes.   If
-              forced  (-f),  however,  it  will  pass  such files
-              through unmodified.  This is how GNU gzip  behaves.
-
-       --kk ----kkeeeepp
-              Keep  (don't delete) input files during compression
-              or decompression.
-
-       --ss ----ssmmaallll
-              Reduce memory usage, for compression, decompression
-              and  testing.   Files  are  decompressed and tested
-              using a modified algorithm which only requires  2.5
-              bytes  per  block byte.  This means any file can be
-              decompressed in 2300k of memory,  albeit  at  about
-              half the normal speed.
-
-              During  compression,  -s  selects  a  block size of
-              200k, which limits memory use to  around  the  same
-              figure,  at  the expense of your compression ratio.
-              In short, if your  machine  is  low  on  memory  (8
-              megabytes  or  less),  use  -s for everything.  See
-              MEMORY MANAGEMENT below.
-
-       --qq ----qquuiieett
-              Suppress non-essential warning messages.   Messages
-              pertaining  to I/O errors and other critical events
-              will not be suppressed.
-
-       --vv ----vveerrbboossee
-              Verbose mode -- show the compression ratio for each
-              file  processed.   Further  -v's  increase the ver�
-              bosity level, spewing out lots of information which
-              is primarily of interest for diagnostic purposes.
-
-       --LL ----lliicceennssee --VV ----vveerrssiioonn
-              Display  the  software  version,  license terms and
-              conditions.
-
-       --11 ((oorr ----ffaasstt)) ttoo --99 ((oorr ----bbeesstt))
-              Set the block size to 100 k, 200 k ..  900  k  when
-              compressing.   Has  no  effect  when decompressing.
-              See MEMORY MANAGEMENT below.  The --fast and --best
-              aliases  are  primarily for GNU gzip compatibility.
-              In particular, --fast doesn't make things  signifi�
-              cantly  faster.   And  --best  merely  selects  the
-              default behaviour.
-
-       ----     Treats all subsequent arguments as file names, even
-              if they start with a dash.  This is so you can han�
-              dle files with names beginning  with  a  dash,  for
-              example: bzip2 -- -myfilename.
-
-       ----rreeppeettiittiivvee--ffaasstt ----rreeppeettiittiivvee--bbeesstt
-              These  flags  are  redundant  in versions 0.9.5 and
-              above.  They provided some coarse control over  the
-              behaviour  of the sorting algorithm in earlier ver�
-              sions, which was sometimes useful.  0.9.5 and above
-              have  an  improved  algorithm  which  renders these
-              flags irrelevant.
-
-
-MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
-       _b_z_i_p_2 compresses large files in blocks.   The  block  size
-       affects  both  the  compression  ratio  achieved,  and the
-       amount of memory needed for compression and decompression.
-       The  flags  -1  through  -9  specify  the block size to be
-       100,000 bytes through 900,000 bytes (the default)  respec�
-       tively.   At  decompression  time, the block size used for
-       compression is read from  the  header  of  the  compressed
-       file, and _b_u_n_z_i_p_2 then allocates itself just enough memory
-       to decompress the file.  Since block sizes are  stored  in
-       compressed  files,  it follows that the flags -1 to -9 are
-       irrelevant to and so ignored during decompression.
-
-       Compression and decompression requirements, in bytes,  can
-       be estimated as:
-
-              Compression:   400k + ( 8 x block size )
-
-              Decompression: 100k + ( 4 x block size ), or
-                             100k + ( 2.5 x block size )
-
-       Larger  block  sizes  give  rapidly  diminishing  marginal
-       returns.  Most of the compression comes from the first two
-       or  three hundred k of block size, a fact worth bearing in
-       mind when using _b_z_i_p_2  on  small  machines.   It  is  also
-       important  to  appreciate  that  the  decompression memory
-       requirement is set at compression time by  the  choice  of
-       block size.
-
-       For  files  compressed  with  the default 900k block size,
-       _b_u_n_z_i_p_2 will require about 3700 kbytes to decompress.   To
-       support decompression of any file on a 4 megabyte machine,
-       _b_u_n_z_i_p_2 has an option to  decompress  using  approximately
-       half this amount of memory, about 2300 kbytes.  Decompres�
-       sion speed is also halved, so you should use  this  option
-       only where necessary.  The relevant flag is -s.
-
-       In general, try and use the largest block size memory con�
-       straints  allow,  since  that  maximises  the  compression
-       achieved.   Compression and decompression speed are virtu�
-       ally unaffected by block size.
-
-       Another significant point applies to files which fit in  a
-       single  block  --  that  means  most files you'd encounter
-       using a large block  size.   The  amount  of  real  memory
-       touched is proportional to the size of the file, since the
-       file is smaller than a block.  For example, compressing  a
-       file  20,000  bytes  long  with the flag -9 will cause the
-       compressor to allocate around 7600k of  memory,  but  only
-       touch 400k + 20000 * 8 = 560 kbytes of it.  Similarly, the
-       decompressor will allocate 3700k but  only  touch  100k  +
-       20000 * 4 = 180 kbytes.
-
-       Here  is a table which summarises the maximum memory usage
-       for different block sizes.  Also  recorded  is  the  total
-       compressed  size for 14 files of the Calgary Text Compres�
-       sion Corpus totalling 3,141,622 bytes.  This column  gives
-       some  feel  for  how  compression  varies with block size.
-       These figures tend to understate the advantage  of  larger
-       block  sizes  for  larger files, since the Corpus is domi�
-       nated by smaller files.
-
-                  Compress   Decompress   Decompress   Corpus
-           Flag     usage      usage       -s usage     Size
-
-            -1      1200k       500k         350k      914704
-            -2      2000k       900k         600k      877703
-            -3      2800k      1300k         850k      860338
-            -4      3600k      1700k        1100k      846899
-            -5      4400k      2100k        1350k      845160
-            -6      5200k      2500k        1600k      838626
-            -7      6100k      2900k        1850k      834096
-            -8      6800k      3300k        2100k      828642
-            -9      7600k      3700k        2350k      828642
-
-
-RREECCOOVVEERRIINNGG DDAATTAA FFRROOMM DDAAMMAAGGEEDD FFIILLEESS
-       _b_z_i_p_2 compresses files in blocks, usually 900kbytes  long.
-       Each block is handled independently.  If a media or trans�
-       mission error causes a multi-block  .bz2  file  to  become
-       damaged,  it  may  be  possible  to  recover data from the
-       undamaged blocks in the file.
-
-       The compressed representation of each block  is  delimited
-       by  a  48-bit pattern, which makes it possible to find the
-       block boundaries with reasonable  certainty.   Each  block
-       also  carries its own 32-bit CRC, so damaged blocks can be
-       distinguished from undamaged ones.
-
-       _b_z_i_p_2_r_e_c_o_v_e_r is a  simple  program  whose  purpose  is  to
-       search  for blocks in .bz2 files, and write each block out
-       into its own .bz2 file.  You can then use _b_z_i_p_2 -t to test
-       the integrity of the resulting files, and decompress those
-       which are undamaged.
-
-       _b_z_i_p_2_r_e_c_o_v_e_r takes a single argument, the name of the dam�
-       aged    file,    and    writes    a    number   of   files
-       "rec00001file.bz2",  "rec00002file.bz2",  etc,  containing
-       the   extracted   blocks.   The   output   filenames   are
-       designed  so  that the use of wildcards in subsequent pro�
-       cessing  -- for example, "bzip2 -dc  rec*file.bz2 > recov�
-       ered_data" -- processes the files in the correct order.
-
-       _b_z_i_p_2_r_e_c_o_v_e_r should be of most use dealing with large .bz2
-       files,  as  these will contain many blocks.  It is clearly
-       futile to use it on damaged single-block  files,  since  a
-       damaged  block  cannot  be recovered.  If you wish to min�
-       imise any potential data loss through media  or  transmis�
-       sion errors, you might consider compressing with a smaller
-       block size.
-
-
-PPEERRFFOORRMMAANNCCEE NNOOTTEESS
-       The sorting phase of compression gathers together  similar
-       strings  in  the  file.  Because of this, files containing
-       very long runs of  repeated  symbols,  like  "aabaabaabaab
-       ..."   (repeated  several hundred times) may compress more
-       slowly than normal.  Versions 0.9.5 and  above  fare  much
-       better  than previous versions in this respect.  The ratio
-       between worst-case and average-case compression time is in
-       the  region  of  10:1.  For previous versions, this figure
-       was more like 100:1.  You can use the -vvvv option to mon�
-       itor progress in great detail, if you want.
-
-       Decompression speed is unaffected by these phenomena.
-
-       _b_z_i_p_2  usually  allocates  several  megabytes of memory to
-       operate in, and then charges all over it in a fairly  ran�
-       dom  fashion.   This means that performance, both for com�
-       pressing and decompressing, is largely determined  by  the
-       speed  at  which  your  machine  can service cache misses.
-       Because of this, small changes to the code to  reduce  the
-       miss  rate  have  been observed to give disproportionately
-       large performance improvements.  I imagine _b_z_i_p_2 will per�
-       form best on machines with very large caches.
-
-
-CCAAVVEEAATTSS
-       I/O  error  messages  are not as helpful as they could be.
-       _b_z_i_p_2 tries hard to detect I/O errors  and  exit  cleanly,
-       but  the  details  of  what  the problem is sometimes seem
-       rather misleading.
-
-       This manual page pertains to version 1.0.2 of _b_z_i_p_2_.  Com�
-       pressed  data created by this version is entirely forwards
-       and  backwards  compatible  with   the   previous   public
-       releases,  versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0 and 1.0.1,
-       but with the following exception: 0.9.0 and above can cor�
-       rectly  decompress multiple concatenated compressed files.
-       0.1pl2 cannot do this; it will  stop  after  decompressing
-       just the first file in the stream.
-
-       _b_z_i_p_2_r_e_c_o_v_e_r  versions  prior  to  this  one,  1.0.2, used
-       32-bit integers to represent bit positions  in  compressed
-       files,  so  it could not handle compressed files more than
-       512 megabytes long.  Version 1.0.2 and above  uses  64-bit
-       ints  on  some platforms which support them (GNU supported
-       targets,  and  Windows).   To  establish  whether  or  not
-       bzip2recover  was  built  with  such  a limitation, run it
-       without arguments.  In any event you can build yourself an
-       unlimited version if you can recompile it with MaybeUInt64
-       set to be an unsigned 64-bit integer.
-
-
-
-
-AAUUTTHHOORR
-       Julian Seward, jseward at acm.org.
-
-       http://sources.redhat.com/bzip2
-
-       The ideas embodied in _b_z_i_p_2 are due to (at least) the fol�
-       lowing  people: Michael Burrows and David Wheeler (for the
-       block sorting transformation), David Wheeler  (again,  for
-       the Huffman coder), Peter Fenwick (for the structured cod�
-       ing model in the original _b_z_i_p_, and many refinements), and
-       Alistair  Moffat,  Radford  Neal  and  Ian Witten (for the
-       arithmetic  coder  in  the  original  _b_z_i_p_)_.   I  am  much
-       indebted for their help, support and advice.  See the man�
-       ual in the source distribution for pointers to sources  of
-       documentation.  Christian von Roques encouraged me to look
-       for faster sorting algorithms, so as to speed up  compres�
-       sion.  Bela Lubkin encouraged me to improve the worst-case
-       compression performance.  The bz* scripts are derived from
-       those  of GNU gzip.  Many people sent patches, helped with
-       portability problems, lent machines, gave advice and  were
-       generally helpful.
-
-
-
-                                                         bzip2(1)
diff --git a/c++/src/util/compress/bzip2/bzip2.c b/c++/src/util/compress/bzip2/bzip2.c
index 807f420..6de9d1d 100644
--- a/c++/src/util/compress/bzip2/bzip2.c
+++ b/c++/src/util/compress/bzip2/bzip2.c
@@ -3,118 +3,26 @@
 /*--- A block-sorting, lossless compressor        bzip2.c ---*/
 /*-----------------------------------------------------------*/
 
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward at acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
---*/
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
 
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
 
-/*----------------------------------------------------*/
-/*--- IMPORTANT                                    ---*/
-/*----------------------------------------------------*/
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
 
-/*--
-   WARNING:
-      This program and library (attempts to) compress data by 
-      performing several non-trivial transformations on it.  
-      Unless you are 100% familiar with *all* the algorithms 
-      contained herein, and with the consequences of modifying them, 
-      you should NOT meddle with the compression or decompression 
-      machinery.  Incorrect changes can and very likely *will* 
-      lead to disasterous loss of data.
-
-   DISCLAIMER:
-      I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
-      USE OF THIS PROGRAM, HOWSOEVER CAUSED.
-
-      Every compression of a file implies an assumption that the
-      compressed file can be decompressed to reproduce the original.
-      Great efforts in design, coding and testing have been made to
-      ensure that this program works correctly.  However, the
-      complexity of the algorithms, and, in particular, the presence
-      of various special cases in the code which occur with very low
-      but non-zero probability make it impossible to rule out the
-      possibility of bugs remaining in the program.  DO NOT COMPRESS
-      ANY DATA WITH THIS PROGRAM AND/OR LIBRARY UNLESS YOU ARE PREPARED 
-      TO ACCEPT THE POSSIBILITY, HOWEVER SMALL, THAT THE DATA WILL 
-      NOT BE RECOVERABLE.
-
-      That is not to say this program is inherently unreliable.
-      Indeed, I very much hope the opposite is true.  bzip2/libbzip2
-      has been carefully constructed and extensively tested.
-
-   PATENTS:
-      To the best of my knowledge, bzip2/libbzip2 does not use any 
-      patented algorithms.  However, I do not have the resources 
-      available to carry out a full patent search.  Therefore I cannot 
-      give any guarantee of the above statement.
---*/
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
 
 
-
-/*----------------------------------------------------*/
-/*--- and now for something much more pleasant :-) ---*/
-/*----------------------------------------------------*/
-
-/*---------------------------------------------*/
-/*--
-  Place a 1 beside your platform, and 0 elsewhere.
---*/
-
-/*--
-  Generic 32-bit Unix.
-  Also works on 64-bit Unix boxes.
-  This is the default.
---*/
+/* Place a 1 beside your platform, and 0 elsewhere.
+   Generic 32-bit Unix.
+   Also works on 64-bit Unix boxes.
+   This is the default.
+*/
 #define BZ_UNIX      1
 
 /*--
@@ -302,16 +210,17 @@ Char    progNameReally[FILE_NAME_LEN];
 FILE    *outputHandleJustInCase;
 Int32   workFactor;
 
-static void    panic                 ( Char* )   NORETURN;
-static void    ioError               ( void )    NORETURN;
-static void    outOfMemory           ( void )    NORETURN;
-static void    configError           ( void )    NORETURN;
-static void    crcError              ( void )    NORETURN;
-static void    cleanUpAndFail        ( Int32 )   NORETURN;
-static void    compressedStreamEOF   ( void )    NORETURN;
+static void    panic                 ( const Char* ) NORETURN;
+static void    ioError               ( void )        NORETURN;
+static void    outOfMemory           ( void )        NORETURN;
+static void    configError           ( void )        NORETURN;
+static void    crcError              ( void )        NORETURN;
+static void    cleanUpAndFail        ( Int32 )       NORETURN;
+static void    compressedStreamEOF   ( void )        NORETURN;
 
 static void    copyFileName ( Char*, Char* );
 static void*   myMalloc     ( Int32 );
+static void    applySavedFileAttrToOutputFile ( IntNative fd );
 
 
 
@@ -457,6 +366,9 @@ void compressStream ( FILE *stream, FILE *zStream )
    ret = fflush ( zStream );
    if (ret == EOF) goto errhandler_io;
    if (zStream != stdout) {
+      Int32 fd = fileno ( zStream );
+      if (fd < 0) goto errhandler_io;
+      applySavedFileAttrToOutputFile ( fd );
       ret = fclose ( zStream );
       outputHandleJustInCase = NULL;
       if (ret == EOF) goto errhandler_io;
@@ -525,6 +437,7 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
    UChar   obuf[5000];
    UChar   unused[BZ_MAX_UNUSED];
    Int32   nUnused;
+   void*   unusedTmpV;
    UChar*  unusedTmp;
 
    nUnused = 0;
@@ -554,9 +467,10 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
       }
       if (bzerr != BZ_STREAM_END) goto errhandler;
 
-      BZ2_bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused );
+      BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
       if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
 
+      unusedTmp = (UChar*)unusedTmpV;
       for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
 
       BZ2_bzReadClose ( &bzerr, bzf );
@@ -567,6 +481,11 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
 
    closeok:
    if (ferror(zStream)) goto errhandler_io;
+   if (stream != stdout) {
+      Int32 fd = fileno ( stream );
+      if (fd < 0) goto errhandler_io;
+      applySavedFileAttrToOutputFile ( fd );
+   }
    ret = fclose ( zStream );
    if (ret == EOF) goto errhandler_io;
 
@@ -639,6 +558,7 @@ Bool testStream ( FILE *zStream )
    UChar   obuf[5000];
    UChar   unused[BZ_MAX_UNUSED];
    Int32   nUnused;
+   void*   unusedTmpV;
    UChar*  unusedTmp;
 
    nUnused = 0;
@@ -662,9 +582,10 @@ Bool testStream ( FILE *zStream )
       }
       if (bzerr != BZ_STREAM_END) goto errhandler;
 
-      BZ2_bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused );
+      BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
       if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
 
+      unusedTmp = (UChar*)unusedTmpV;
       for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
 
       BZ2_bzReadClose ( &bzerr, bzf );
@@ -822,13 +743,13 @@ void cleanUpAndFail ( Int32 ec )
 
 /*---------------------------------------------*/
 static 
-void panic ( Char* s )
+void panic ( const Char* s )
 {
    fprintf ( stderr,
              "\n%s: PANIC -- internal consistency error:\n"
              "\t%s\n"
              "\tThis is a BUG.  Please report it to me at:\n"
-             "\tjseward at acm.org\n",
+             "\tjseward at bzip.org\n",
              progName, s );
    showFileNames();
    cleanUpAndFail( 3 );
@@ -908,7 +829,7 @@ void mySIGSEGVorSIGBUScatcher ( IntNative n )
       "   The user's manual, Section 4.3, has more info on (1) and (2).\n"
       "   \n"
       "   If you suspect this is a bug in bzip2, or are unsure about (1)\n"
-      "   or (2), feel free to report it to me at: jseward at acm.org.\n"
+      "   or (2), feel free to report it to me at: jseward at bzip.org.\n"
       "   Section 4.3 of the user's manual describes the info a useful\n"
       "   bug report should have.  If the manual is available on your\n"
       "   system, please try and read it before mailing me.  If you don't\n"
@@ -931,7 +852,7 @@ void mySIGSEGVorSIGBUScatcher ( IntNative n )
       "   The user's manual, Section 4.3, has more info on (2) and (3).\n"
       "   \n"
       "   If you suspect this is a bug in bzip2, or are unsure about (2)\n"
-      "   or (3), feel free to report it to me at: jseward at acm.org.\n"
+      "   or (3), feel free to report it to me at: jseward at bzip.org.\n"
       "   Section 4.3 of the user's manual describes the info a useful\n"
       "   bug report should have.  If the manual is available on your\n"
       "   system, please try and read it before mailing me.  If you don't\n"
@@ -1035,6 +956,7 @@ Bool fileExists ( Char* name )
    For non-Unix platforms, if we are not worrying about
    security issues, simple this simply behaves like fopen.
 */
+static
 FILE* fopen_output_safely ( Char* name, const char* mode )
 {
 #  if BZ_UNIX
@@ -1125,7 +1047,7 @@ void saveInputFileMetaInfo ( Char *srcName )
 
 
 static 
-void applySavedMetaInfoToOutputFile ( Char *dstName )
+void applySavedTimeInfoToOutputFile ( Char *dstName )
 {
 #  if BZ_UNIX
    IntNative      retVal;
@@ -1134,13 +1056,21 @@ void applySavedMetaInfoToOutputFile ( Char *dstName )
    uTimBuf.actime = fileMetaInfo.st_atime;
    uTimBuf.modtime = fileMetaInfo.st_mtime;
 
-   retVal = chmod ( dstName, fileMetaInfo.st_mode );
+   retVal = utime ( dstName, &uTimBuf );
    ERROR_IF_NOT_ZERO ( retVal );
+#  endif
+}
 
-   retVal = utime ( dstName, &uTimBuf );
+static 
+void applySavedFileAttrToOutputFile ( IntNative fd )
+{
+#  if BZ_UNIX
+   IntNative retVal;
+
+   retVal = fchmod ( fd, fileMetaInfo.st_mode );
    ERROR_IF_NOT_ZERO ( retVal );
 
-   retVal = chown ( dstName, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
+   (void) fchown ( fd, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
    /* chown() will in many cases return with EPERM, which can
       be safely ignored.
    */
@@ -1171,13 +1101,13 @@ Bool containsDubiousChars ( Char* name )
 /*---------------------------------------------*/
 #define BZ_N_SUFFIX_PAIRS 4
 
-Char* zSuffix[BZ_N_SUFFIX_PAIRS] 
+const Char* zSuffix[BZ_N_SUFFIX_PAIRS] 
    = { ".bz2", ".bz", ".tbz2", ".tbz" };
-Char* unzSuffix[BZ_N_SUFFIX_PAIRS] 
+const Char* unzSuffix[BZ_N_SUFFIX_PAIRS] 
    = { "", "", ".tar", ".tar" };
 
 static 
-Bool hasSuffix ( Char* s, Char* suffix )
+Bool hasSuffix ( Char* s, const Char* suffix )
 {
    Int32 ns = strlen(s);
    Int32 nx = strlen(suffix);
@@ -1188,7 +1118,8 @@ Bool hasSuffix ( Char* s, Char* suffix )
 
 static 
 Bool mapSuffix ( Char* name, 
-                 Char* oldSuffix, Char* newSuffix )
+                 const Char* oldSuffix, 
+                 const Char* newSuffix )
 {
    if (!hasSuffix(name,oldSuffix)) return False;
    name[strlen(name)-strlen(oldSuffix)] = 0;
@@ -1213,8 +1144,8 @@ void compress ( Char *name )
 
    switch (srcMode) {
       case SM_I2O: 
-         copyFileName ( inName, "(stdin)" );
-         copyFileName ( outName, "(stdout)" ); 
+         copyFileName ( inName, (Char*)"(stdin)" );
+         copyFileName ( outName, (Char*)"(stdout)" ); 
          break;
       case SM_F2F: 
          copyFileName ( inName, name );
@@ -1223,7 +1154,7 @@ void compress ( Char *name )
          break;
       case SM_F2O: 
          copyFileName ( inName, name );
-         copyFileName ( outName, "(stdout)" ); 
+         copyFileName ( outName, (Char*)"(stdout)" ); 
          break;
    }
 
@@ -1366,7 +1297,7 @@ void compress ( Char *name )
 
    /*--- If there was an I/O error, we won't get here. ---*/
    if ( srcMode == SM_F2F ) {
-      applySavedMetaInfoToOutputFile ( outName );
+      applySavedTimeInfoToOutputFile ( outName );
       deleteOutputOnInterrupt = False;
       if ( !keepInputFiles ) {
          IntNative retVal = remove ( inName );
@@ -1397,8 +1328,8 @@ void uncompress ( Char *name )
    cantGuess = False;
    switch (srcMode) {
       case SM_I2O: 
-         copyFileName ( inName, "(stdin)" );
-         copyFileName ( outName, "(stdout)" ); 
+         copyFileName ( inName, (Char*)"(stdin)" );
+         copyFileName ( outName, (Char*)"(stdout)" ); 
          break;
       case SM_F2F: 
          copyFileName ( inName, name );
@@ -1411,7 +1342,7 @@ void uncompress ( Char *name )
          break;
       case SM_F2O: 
          copyFileName ( inName, name );
-         copyFileName ( outName, "(stdout)" ); 
+         copyFileName ( outName, (Char*)"(stdout)" ); 
          break;
    }
 
@@ -1544,7 +1475,7 @@ void uncompress ( Char *name )
    /*--- If there was an I/O error, we won't get here. ---*/
    if ( magicNumberOK ) {
       if ( srcMode == SM_F2F ) {
-         applySavedMetaInfoToOutputFile ( outName );
+         applySavedTimeInfoToOutputFile ( outName );
          deleteOutputOnInterrupt = False;
          if ( !keepInputFiles ) {
             IntNative retVal = remove ( inName );
@@ -1589,9 +1520,9 @@ void testf ( Char *name )
    if (name == NULL && srcMode != SM_I2O)
       panic ( "testf: bad modes\n" );
 
-   copyFileName ( outName, "(none)" );
+   copyFileName ( outName, (Char*)"(none)" );
    switch (srcMode) {
-      case SM_I2O: copyFileName ( inName, "(stdin)" ); break;
+      case SM_I2O: copyFileName ( inName, (Char*)"(stdin)" ); break;
       case SM_F2F: copyFileName ( inName, name ); break;
       case SM_F2O: copyFileName ( inName, name ); break;
    }
@@ -1674,11 +1605,11 @@ void license ( void )
     "bzip2, a block-sorting file compressor.  "
     "Version %s.\n"
     "   \n"
-    "   Copyright (C) 1996-2002 by Julian Seward.\n"
+    "   Copyright (C) 1996-2010 by Julian Seward.\n"
     "   \n"
     "   This program is free software; you can redistribute it and/or modify\n"
     "   it under the terms set out in the LICENSE file, which is included\n"
-    "   in the bzip2-1.0 source distribution.\n"
+    "   in the bzip2-1.0.6 source distribution.\n"
     "   \n"
     "   This program is distributed in the hope that it will be useful,\n"
     "   but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
@@ -1881,8 +1812,8 @@ IntNative main ( IntNative argc, Char *argv[] )
 #  endif
 #  endif
 
-   copyFileName ( inName,  "(none)" );
-   copyFileName ( outName, "(none)" );
+   copyFileName ( inName,  (Char*)"(none)" );
+   copyFileName ( outName, (Char*)"(none)" );
 
    copyFileName ( progNameReally, argv[0] );
    progName = &progNameReally[0];
@@ -1894,8 +1825,8 @@ IntNative main ( IntNative argc, Char *argv[] )
         expand filename wildcards in arg list.
    --*/
    argList = NULL;
-   addFlagsFromEnvVar ( &argList,  "BZIP2" );
-   addFlagsFromEnvVar ( &argList,  "BZIP" );
+   addFlagsFromEnvVar ( &argList,  (Char*)"BZIP2" );
+   addFlagsFromEnvVar ( &argList,  (Char*)"BZIP" );
    for (i = 1; i <= argc-1; i++)
       APPEND_FILESPEC(argList, argv[i]);
 
diff --git a/c++/src/util/compress/bzip2/bzip2.txt b/c++/src/util/compress/bzip2/bzip2.txt
index 6afe358..d2deb39 100644
--- a/c++/src/util/compress/bzip2/bzip2.txt
+++ b/c++/src/util/compress/bzip2/bzip2.txt
@@ -1,6 +1,6 @@
 
 NAME
-       bzip2, bunzip2 - a block-sorting file compressor, v1.0.2
+       bzip2, bunzip2 - a block-sorting file compressor, v1.0.6
        bzcat - decompresses files to stdout
        bzip2recover - recovers data from damaged bzip2 files
 
@@ -17,20 +17,20 @@ DESCRIPTION
        sorting text compression algorithm,  and  Huffman  coding.
        Compression  is  generally  considerably  better than that
        achieved by more conventional LZ77/LZ78-based compressors,
-       and  approaches  the performance of the PPM family of sta�
+       and  approaches  the performance of the PPM family of sta-
        tistical compressors.
 
        The command-line options are deliberately very similar  to
        those of GNU gzip, but they are not identical.
 
-       bzip2  expects  a list of file names to accompany the com�
+       bzip2  expects  a list of file names to accompany the com-
        mand-line flags.  Each file is replaced  by  a  compressed
        version  of  itself,  with  the  name "original_name.bz2".
-       Each compressed file has the same modification date,  per�
-       missions, and, when possible, ownership as the correspond�
+       Each compressed file has the same modification date,  per-
+       missions, and, when possible, ownership as the correspond-
        ing original, so that these properties  can  be  correctly
        restored  at  decompression  time.   File name handling is
-       naive in the sense that there is no mechanism for preserv�
+       naive in the sense that there is no mechanism for preserv-
        ing  original file names, permissions, ownerships or dates
        in filesystems which lack these concepts, or have  serious
        file name length restrictions, such as MS-DOS.
@@ -61,23 +61,23 @@ DESCRIPTION
        guess the name of the original file, and uses the original
        name with .out appended.
 
-       As  with compression, supplying no filenames causes decom�
+       As  with compression, supplying no filenames causes decom-
        pression from standard input to standard output.
 
-       bunzip2 will correctly decompress a file which is the con�
+       bunzip2 will correctly decompress a file which is the con-
        catenation of two or more compressed files.  The result is
        the concatenation of the corresponding uncompressed files.
        Integrity testing (-t) of concatenated compressed files is
        also supported.
 
        You can also compress or decompress files to the  standard
-       output  by giving the -c flag.  Multiple files may be com�
+       output  by giving the -c flag.  Multiple files may be com-
        pressed and decompressed like this.  The resulting outputs
        are  fed  sequentially to stdout.  Compression of multiple
-       files in this manner generates a stream containing  multi�
+       files in this manner generates a stream containing  multi-
        ple compressed file representations.  Such a stream can be
        decompressed correctly only  by  bzip2  version  0.9.0  or
-       later.   Earlier  versions of bzip2 will stop after decom�
+       later.   Earlier  versions of bzip2 will stop after decom-
        pressing the first file in the stream.
 
        bzcat (or bzip2 -dc) decompresses all specified  files  to
@@ -98,7 +98,7 @@ DESCRIPTION
 
        As a self-check for your  protection,  bzip2  uses  32-bit
        CRCs  to make sure that the decompressed version of a file
-       is identical to the original.  This guards against corrup�
+       is identical to the original.  This guards against corrup-
        tion  of  the compressed data, and against undetected bugs
        in bzip2 (hopefully very unlikely).  The chances  of  data
        corruption  going  undetected  is  microscopic,  about one
@@ -171,7 +171,7 @@ OPTIONS
 
        -v --verbose
               Verbose mode -- show the compression ratio for each
-              file  processed.   Further  -v's  increase the ver�
+              file  processed.   Further  -v's  increase the ver-
               bosity level, spewing out lots of information which
               is primarily of interest for diagnostic purposes.
 
@@ -184,19 +184,19 @@ OPTIONS
               compressing.   Has  no  effect  when decompressing.
               See MEMORY MANAGEMENT below.  The --fast and --best
               aliases  are  primarily for GNU gzip compatibility.
-              In particular, --fast doesn't make things  signifi�
+              In particular, --fast doesn't make things  signifi-
               cantly  faster.   And  --best  merely  selects  the
               default behaviour.
 
        --     Treats all subsequent arguments as file names, even
-              if they start with a dash.  This is so you can han�
+              if they start with a dash.  This is so you can han-
               dle files with names beginning  with  a  dash,  for
               example: bzip2 -- -myfilename.
 
        --repetitive-fast --repetitive-best
               These  flags  are  redundant  in versions 0.9.5 and
               above.  They provided some coarse control over  the
-              behaviour  of the sorting algorithm in earlier ver�
+              behaviour  of the sorting algorithm in earlier ver-
               sions, which was sometimes useful.  0.9.5 and above
               have  an  improved  algorithm  which  renders these
               flags irrelevant.
@@ -207,7 +207,7 @@ MEMORY MANAGEMENT
        affects  both  the  compression  ratio  achieved,  and the
        amount of memory needed for compression and decompression.
        The  flags  -1  through  -9  specify  the block size to be
-       100,000 bytes through 900,000 bytes (the default)  respec�
+       100,000 bytes through 900,000 bytes (the default)  respec-
        tively.   At  decompression  time, the block size used for
        compression is read from  the  header  of  the  compressed
        file, and bunzip2 then allocates itself just enough memory
@@ -235,13 +235,13 @@ MEMORY MANAGEMENT
        bunzip2 will require about 3700 kbytes to decompress.   To
        support decompression of any file on a 4 megabyte machine,
        bunzip2 has an option to  decompress  using  approximately
-       half this amount of memory, about 2300 kbytes.  Decompres�
+       half this amount of memory, about 2300 kbytes.  Decompres-
        sion speed is also halved, so you should use  this  option
        only where necessary.  The relevant flag is -s.
 
-       In general, try and use the largest block size memory con�
+       In general, try and use the largest block size memory con-
        straints  allow,  since  that  maximises  the  compression
-       achieved.   Compression and decompression speed are virtu�
+       achieved.   Compression and decompression speed are virtu-
        ally unaffected by block size.
 
        Another significant point applies to files which fit in  a
@@ -257,11 +257,11 @@ MEMORY MANAGEMENT
 
        Here  is a table which summarises the maximum memory usage
        for different block sizes.  Also  recorded  is  the  total
-       compressed  size for 14 files of the Calgary Text Compres�
+       compressed  size for 14 files of the Calgary Text Compres-
        sion Corpus totalling 3,141,622 bytes.  This column  gives
        some  feel  for  how  compression  varies with block size.
        These figures tend to understate the advantage  of  larger
-       block  sizes  for  larger files, since the Corpus is domi�
+       block  sizes  for  larger files, since the Corpus is domi-
        nated by smaller files.
 
                   Compress   Decompress   Decompress   Corpus
@@ -280,7 +280,7 @@ MEMORY MANAGEMENT
 
 RECOVERING DATA FROM DAMAGED FILES
        bzip2 compresses files in blocks, usually 900kbytes  long.
-       Each block is handled independently.  If a media or trans�
+       Each block is handled independently.  If a media or trans-
        mission error causes a multi-block  .bz2  file  to  become
        damaged,  it  may  be  possible  to  recover data from the
        undamaged blocks in the file.
@@ -297,19 +297,19 @@ RECOVERING DATA FROM DAMAGED FILES
        the integrity of the resulting files, and decompress those
        which are undamaged.
 
-       bzip2recover takes a single argument, the name of the dam�
+       bzip2recover takes a single argument, the name of the dam-
        aged    file,    and    writes    a    number   of   files
        "rec00001file.bz2",  "rec00002file.bz2",  etc,  containing
        the   extracted   blocks.   The   output   filenames   are
-       designed  so  that the use of wildcards in subsequent pro�
-       cessing  -- for example, "bzip2 -dc  rec*file.bz2 > recov�
+       designed  so  that the use of wildcards in subsequent pro-
+       cessing  -- for example, "bzip2 -dc  rec*file.bz2 > recov-
        ered_data" -- processes the files in the correct order.
 
        bzip2recover should be of most use dealing with large .bz2
        files,  as  these will contain many blocks.  It is clearly
        futile to use it on damaged single-block  files,  since  a
-       damaged  block  cannot  be recovered.  If you wish to min�
-       imise any potential data loss through media  or  transmis�
+       damaged  block  cannot  be recovered.  If you wish to min-
+       imise any potential data loss through media  or  transmis-
        sion errors, you might consider compressing with a smaller
        block size.
 
@@ -323,19 +323,19 @@ PERFORMANCE NOTES
        better  than previous versions in this respect.  The ratio
        between worst-case and average-case compression time is in
        the  region  of  10:1.  For previous versions, this figure
-       was more like 100:1.  You can use the -vvvv option to mon�
+       was more like 100:1.  You can use the -vvvv option to mon-
        itor progress in great detail, if you want.
 
        Decompression speed is unaffected by these phenomena.
 
        bzip2  usually  allocates  several  megabytes of memory to
-       operate in, and then charges all over it in a fairly  ran�
-       dom  fashion.   This means that performance, both for com�
+       operate in, and then charges all over it in a fairly  ran-
+       dom  fashion.   This means that performance, both for com-
        pressing and decompressing, is largely determined  by  the
        speed  at  which  your  machine  can service cache misses.
        Because of this, small changes to the code to  reduce  the
        miss  rate  have  been observed to give disproportionately
-       large performance improvements.  I imagine bzip2 will per�
+       large performance improvements.  I imagine bzip2 will per-
        form best on machines with very large caches.
 
 
@@ -345,46 +345,47 @@ CAVEATS
        but  the  details  of  what  the problem is sometimes seem
        rather misleading.
 
-       This manual page pertains to version 1.0.2 of bzip2.  Com�
+       This manual page pertains to version 1.0.6 of bzip2.  Com-
        pressed  data created by this version is entirely forwards
        and  backwards  compatible  with   the   previous   public
-       releases,  versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0 and 1.0.1,
-       but with the following exception: 0.9.0 and above can cor�
-       rectly  decompress multiple concatenated compressed files.
-       0.1pl2 cannot do this; it will  stop  after  decompressing
-       just the first file in the stream.
-
-       bzip2recover  versions  prior  to  this  one,  1.0.2, used
-       32-bit integers to represent bit positions  in  compressed
-       files,  so  it could not handle compressed files more than
-       512 megabytes long.  Version 1.0.2 and above  uses  64-bit
-       ints  on  some platforms which support them (GNU supported
-       targets,  and  Windows).   To  establish  whether  or  not
-       bzip2recover  was  built  with  such  a limitation, run it
-       without arguments.  In any event you can build yourself an
-       unlimited version if you can recompile it with MaybeUInt64
-       set to be an unsigned 64-bit integer.
+       releases,  versions  0.1pl2,  0.9.0,  0.9.5, 1.0.0, 1.0.1,
+       1.0.2 and above, but with the  following  exception: 0.9.0
+       and above can  correctly decompress  multiple concatenated
+       compressed files.  0.1pl2  cannot do this;  it  will  stop
+       after  decompressing just the first file in the stream.
+
+       bzip2recover  versions prior to 1.0.2 used 32-bit integers
+       to represent bit positions in compressed  files,  so  they
+       could  not handle compressed files more than 512 megabytes
+       long.  Versions 1.0.2 and above use 64-bit  ints  on  some
+       platforms  which  support them (GNU supported targets, and
+       Windows).  To establish whether or  not  bzip2recover  was
+       built  with  such  a limitation, run it without arguments.
+       In any event you can build yourself an  unlimited  version
+       if  you  can  recompile  it  with MaybeUInt64 set to be an
+       unsigned 64-bit integer.
 
 
 AUTHOR
-       Julian Seward, jseward at acm.org.
+       Julian Seward, jsewardbzip.org.
 
-       http://sources.redhat.com/bzip2
+       http://www.bzip.org
 
-       The ideas embodied in bzip2 are due to (at least) the fol�
+       The ideas embodied in bzip2 are due to (at least) the fol-
        lowing  people: Michael Burrows and David Wheeler (for the
        block sorting transformation), David Wheeler  (again,  for
-       the Huffman coder), Peter Fenwick (for the structured cod�
+       the Huffman coder), Peter Fenwick (for the structured cod-
        ing model in the original bzip, and many refinements), and
        Alistair  Moffat,  Radford  Neal  and  Ian Witten (for the
        arithmetic  coder  in  the  original  bzip).   I  am  much
-       indebted for their help, support and advice.  See the man�
+       indebted for their help, support and advice.  See the man-
        ual in the source distribution for pointers to sources  of
        documentation.  Christian von Roques encouraged me to look
-       for faster sorting algorithms, so as to speed up  compres�
+       for faster sorting algorithms, so as to speed up  compres-
        sion.  Bela Lubkin encouraged me to improve the worst-case
-       compression performance.  The bz* scripts are derived from
-       those  of GNU gzip.  Many people sent patches, helped with
-       portability problems, lent machines, gave advice and  were
-       generally helpful.
+       compression performance.  Donna Robinson XMLised the docu-
+       mentation.   The bz* scripts are derived from those of GNU
+       gzip.  Many people sent patches, helped  with  portability
+       problems,  lent  machines,  gave advice and were generally
+       helpful.
 
diff --git a/c++/src/util/compress/bzip2/bzip2recover.c b/c++/src/util/compress/bzip2/bzip2recover.c
index 286873b..f9de049 100644
--- a/c++/src/util/compress/bzip2/bzip2recover.c
+++ b/c++/src/util/compress/bzip2/bzip2recover.c
@@ -1,56 +1,24 @@
-
 /*-----------------------------------------------------------*/
 /*--- Block recoverer program for bzip2                   ---*/
 /*---                                      bzip2recover.c ---*/
 /*-----------------------------------------------------------*/
 
-/*--
-  This program is bzip2recover, a program to attempt data 
-  salvage from damaged files created by the accompanying
-  bzip2-1.0 program.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward at acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
---*/
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
 
-/*--
-  This program is a complete hack and should be rewritten
-  properly.  It isn't very complicated.
---*/
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+/* This program is a complete hack and should be rewritten properly.
+	 It isn't very complicated. */
 
 #include <stdio.h>
 #include <errno.h>
@@ -114,7 +82,7 @@ MaybeUInt64 bytesIn  = 0;
 /*---------------------------------------------------*/
 
 /*---------------------------------------------*/
-void readError ( void )
+static void readError ( void )
 {
    fprintf ( stderr,
              "%s: I/O error reading `%s', possible reason follows.\n",
@@ -127,7 +95,7 @@ void readError ( void )
 
 
 /*---------------------------------------------*/
-void writeError ( void )
+static void writeError ( void )
 {
    fprintf ( stderr,
              "%s: I/O error reading `%s', possible reason follows.\n",
@@ -140,7 +108,7 @@ void writeError ( void )
 
 
 /*---------------------------------------------*/
-void mallocFail ( Int32 n )
+static void mallocFail ( Int32 n )
 {
    fprintf ( stderr,
              "%s: malloc failed on request for %d bytes.\n",
@@ -152,7 +120,7 @@ void mallocFail ( Int32 n )
 
 
 /*---------------------------------------------*/
-void tooManyBlocks ( Int32 max_handled_blocks )
+static void tooManyBlocks ( Int32 max_handled_blocks )
 {
    fprintf ( stderr,
              "%s: `%s' appears to contain more than %d blocks\n",
@@ -183,7 +151,7 @@ typedef
 
 
 /*---------------------------------------------*/
-BitStream* bsOpenReadStream ( FILE* stream )
+static BitStream* bsOpenReadStream ( FILE* stream )
 {
    BitStream *bs = malloc ( sizeof(BitStream) );
    if (bs == NULL) mallocFail ( sizeof(BitStream) );
@@ -196,7 +164,7 @@ BitStream* bsOpenReadStream ( FILE* stream )
 
 
 /*---------------------------------------------*/
-BitStream* bsOpenWriteStream ( FILE* stream )
+static BitStream* bsOpenWriteStream ( FILE* stream )
 {
    BitStream *bs = malloc ( sizeof(BitStream) );
    if (bs == NULL) mallocFail ( sizeof(BitStream) );
@@ -209,7 +177,7 @@ BitStream* bsOpenWriteStream ( FILE* stream )
 
 
 /*---------------------------------------------*/
-void bsPutBit ( BitStream* bs, Int32 bit )
+static void bsPutBit ( BitStream* bs, Int32 bit )
 {
    if (bs->buffLive == 8) {
       Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
@@ -228,7 +196,7 @@ void bsPutBit ( BitStream* bs, Int32 bit )
 /*--
    Returns 0 or 1, or 2 to indicate EOF.
 --*/
-Int32 bsGetBit ( BitStream* bs )
+static Int32 bsGetBit ( BitStream* bs )
 {
    if (bs->buffLive > 0) {
       bs->buffLive --;
@@ -247,7 +215,7 @@ Int32 bsGetBit ( BitStream* bs )
 
 
 /*---------------------------------------------*/
-void bsClose ( BitStream* bs )
+static void bsClose ( BitStream* bs )
 {
    Int32 retVal;
 
@@ -271,7 +239,7 @@ void bsClose ( BitStream* bs )
 
 
 /*---------------------------------------------*/
-void bsPutUChar ( BitStream* bs, UChar c )
+static void bsPutUChar ( BitStream* bs, UChar c )
 {
    Int32 i;
    for (i = 7; i >= 0; i--)
@@ -280,7 +248,7 @@ void bsPutUChar ( BitStream* bs, UChar c )
 
 
 /*---------------------------------------------*/
-void bsPutUInt32 ( BitStream* bs, UInt32 c )
+static void bsPutUInt32 ( BitStream* bs, UInt32 c )
 {
    Int32 i;
 
@@ -290,7 +258,7 @@ void bsPutUInt32 ( BitStream* bs, UInt32 c )
 
 
 /*---------------------------------------------*/
-Bool endsInBz2 ( Char* name )
+static Bool endsInBz2 ( Char* name )
 {
    Int32 n = strlen ( name );
    if (n <= 4) return False;
@@ -345,7 +313,7 @@ Int32 main ( Int32 argc, Char** argv )
    inFileName[0] = outFileName[0] = 0;
 
    fprintf ( stderr, 
-             "bzip2recover 1.0.2: extracts blocks from damaged .bz2 files.\n" );
+             "bzip2recover 1.0.6: extracts blocks from damaged .bz2 files.\n" );
 
    if (argc != 2) {
       fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
@@ -374,7 +342,7 @@ Int32 main ( Int32 argc, Char** argv )
    if (strlen(argv[1]) >= BZ_MAX_FILENAME-20) {
       fprintf ( stderr, 
                 "%s: supplied filename is suspiciously (>= %d chars) long.  Bye!\n",
-                progName, strlen(argv[1]) );
+                progName, (int)strlen(argv[1]) );
       exit(1);
    }
 
diff --git a/c++/src/util/compress/bzip2/bzlib.c b/c++/src/util/compress/bzip2/bzlib.c
index 7d1cb27..bd358a7 100644
--- a/c++/src/util/compress/bzip2/bzlib.c
+++ b/c++/src/util/compress/bzip2/bzlib.c
@@ -4,74 +4,29 @@
 /*---                                               bzlib.c ---*/
 /*-------------------------------------------------------------*/
 
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward at acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
---*/
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
 
-/*--
-   CHANGES
-   ~~~~~~~
-   0.9.0 -- original version.
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
 
-   0.9.0a/b -- no changes in this file.
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
 
-   0.9.0c
-      * made zero-length BZ_FLUSH work correctly in bzCompress().
-      * fixed bzWrite/bzRead to ignore zero-length requests.
-      * fixed bzread to correctly handle read requests after EOF.
-      * wrong parameter order in call to bzDecompressInit in
-        bzBuffToBuffDecompress.  Fixed.
---*/
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+/* CHANGES
+   0.9.0    -- original version.
+   0.9.0a/b -- no changes in this file.
+   0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
+     fixed bzWrite/bzRead to ignore zero-length requests.
+     fixed bzread to correctly handle read requests after EOF.
+     wrong parameter order in call to bzDecompressInit in
+     bzBuffToBuffDecompress.  Fixed.
+*/
 
 #include "bzlib_private.h"
 
@@ -88,12 +43,12 @@ void BZ2_bz__AssertH__fail ( int errcode )
    fprintf(stderr, 
       "\n\nbzip2/libbzip2: internal error number %d.\n"
       "This is a bug in bzip2/libbzip2, %s.\n"
-      "Please report it to me at: jseward at acm.org.  If this happened\n"
+      "Please report it to me at: jseward at bzip.org.  If this happened\n"
       "when you were using some program which uses libbzip2 as a\n"
       "component, you should also report this bug to the author(s)\n"
       "of that program.  Please make an effort to report this bug;\n"
       "timely and accurate bug reports eventually lead to higher\n"
-      "quality software.  Thanks.  Julian Seward, 30 December 2001.\n\n",
+      "quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n",
       errcode,
       BZ2_bzlibVersion()
    );
@@ -574,8 +529,11 @@ int BZ_API(BZ2_bzDecompressInit)
 
 
 /*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
 static
-void unRLE_obuf_to_output_FAST ( DState* s )
+Bool unRLE_obuf_to_output_FAST ( DState* s )
 {
    UChar k1;
 
@@ -584,7 +542,7 @@ void unRLE_obuf_to_output_FAST ( DState* s )
       while (True) {
          /* try to finish existing run */
          while (True) {
-            if (s->strm->avail_out == 0) return;
+            if (s->strm->avail_out == 0) return False;
             if (s->state_out_len == 0) break;
             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
@@ -594,10 +552,13 @@ void unRLE_obuf_to_output_FAST ( DState* s )
             s->strm->total_out_lo32++;
             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
          }
-   
+
          /* can a new run be started? */
-         if (s->nblock_used == s->save_nblock+1) return;
+         if (s->nblock_used == s->save_nblock+1) return False;
                
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
    
          s->state_out_len = 1;
          s->state_out_ch = s->k0;
@@ -637,6 +598,7 @@ void unRLE_obuf_to_output_FAST ( DState* s )
       UInt32        c_tPos               = s->tPos;
       char*         cs_next_out          = s->strm->next_out;
       unsigned int  cs_avail_out         = s->strm->avail_out;
+      Int32         ro_blockSize100k     = s->blockSize100k;
       /* end restore */
 
       UInt32       avail_out_INIT = cs_avail_out;
@@ -667,6 +629,10 @@ void unRLE_obuf_to_output_FAST ( DState* s )
                cs_avail_out--;
             }
          }   
+         /* Only caused by corrupt data stream? */
+         if (c_nblock_used > s_save_nblockPP)
+            return True;
+
          /* can a new run be started? */
          if (c_nblock_used == s_save_nblockPP) {
             c_state_out_len = 0; goto return_notr;
@@ -712,6 +678,7 @@ void unRLE_obuf_to_output_FAST ( DState* s )
       s->strm->avail_out    = cs_avail_out;
       /* end save */
    }
+   return False;
 }
 
 
@@ -732,8 +699,11 @@ __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
 
 
 /*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
 static
-void unRLE_obuf_to_output_SMALL ( DState* s )
+Bool unRLE_obuf_to_output_SMALL ( DState* s )
 {
    UChar k1;
 
@@ -742,7 +712,7 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
       while (True) {
          /* try to finish existing run */
          while (True) {
-            if (s->strm->avail_out == 0) return;
+            if (s->strm->avail_out == 0) return False;
             if (s->state_out_len == 0) break;
             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
@@ -754,8 +724,11 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
          }
    
          /* can a new run be started? */
-         if (s->nblock_used == s->save_nblock+1) return;
-               
+         if (s->nblock_used == s->save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
    
          s->state_out_len = 1;
          s->state_out_ch = s->k0;
@@ -788,7 +761,7 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
       while (True) {
          /* try to finish existing run */
          while (True) {
-            if (s->strm->avail_out == 0) return;
+            if (s->strm->avail_out == 0) return False;
             if (s->state_out_len == 0) break;
             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
@@ -800,7 +773,11 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
          }
    
          /* can a new run be started? */
-         if (s->nblock_used == s->save_nblock+1) return;
+         if (s->nblock_used == s->save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
    
          s->state_out_len = 1;
          s->state_out_ch = s->k0;
@@ -830,6 +807,7 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
 /*---------------------------------------------------*/
 int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
 {
+   Bool    corrupt;
    DState* s;
    if (strm == NULL) return BZ_PARAM_ERROR;
    s = strm->state;
@@ -840,12 +818,13 @@ int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
       if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
       if (s->state == BZ_X_OUTPUT) {
          if (s->smallDecompress)
-            unRLE_obuf_to_output_SMALL ( s ); else
-            unRLE_obuf_to_output_FAST  ( s );
+            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
+            corrupt = unRLE_obuf_to_output_FAST  ( s );
+         if (corrupt) return BZ_DATA_ERROR;
          if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
             BZ_FINALISE_CRC ( s->calculatedBlockCRC );
             if (s->verbosity >= 3) 
-               VPrintf2 ( " {0x%x, 0x%x}", s->storedBlockCRC, 
+               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, 
                           s->calculatedBlockCRC );
             if (s->verbosity >= 2) VPrintf0 ( "]" );
             if (s->calculatedBlockCRC != s->storedBlockCRC)
@@ -863,7 +842,7 @@ int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
          Int32 r = BZ2_decompress ( s );
          if (r == BZ_STREAM_END) {
             if (s->verbosity >= 3)
-               VPrintf2 ( "\n    combined CRCs: stored = 0x%x, computed = 0x%x", 
+               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x", 
                           s->storedCombinedCRC, s->calculatedCombinedCRC );
             if (s->calculatedCombinedCRC != s->storedCombinedCRC)
                return BZ_DATA_ERROR;
@@ -1371,8 +1350,7 @@ int BZ_API(BZ2_bzBuffToBuffDecompress)
 
 /*---------------------------------------------------*/
 /*--
-   Code contributed by Yoshioka Tsuneo
-   (QWF00133 at niftyserve.or.jp/tsuneo-y at is.aist-nara.ac.jp),
+   Code contributed by Yoshioka Tsuneo (tsuneo at rr.iij4u.or.jp)
    to support better zlib compatibility.
    This code is not _officially_ part of libbzip2 (yet);
    I haven't tested it, documented it, or considered the
@@ -1383,7 +1361,7 @@ int BZ_API(BZ2_bzBuffToBuffDecompress)
 
 /*---------------------------------------------------*/
 /*--
-   return version like "0.9.0c".
+   return version like "0.9.5d, 4-Sept-1999".
 --*/
 const char * BZ_API(BZ2_bzlibVersion)(void)
 {
@@ -1536,9 +1514,10 @@ int BZ_API(BZ2_bzflush) (BZFILE *b)
 void BZ_API(BZ2_bzclose) (BZFILE* b)
 {
    int bzerr;
-   FILE *fp = ((bzFile *)b)->handle;
+   FILE *fp;
    
    if (b==NULL) {return;}
+   fp = ((bzFile *)b)->handle;
    if(((bzFile*)b)->writing){
       BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
       if(bzerr != BZ_OK){
@@ -1557,7 +1536,7 @@ void BZ_API(BZ2_bzclose) (BZFILE* b)
 /*--
    return last error code 
 --*/
-static char *bzerrorstrings[] = {
+static const char *bzerrorstrings[] = {
        "OK"
       ,"SEQUENCE_ERROR"
       ,"PARAM_ERROR"
diff --git a/c++/src/util/compress/bzip2/bzlib_private.h b/c++/src/util/compress/bzip2/bzlib_private.h
index ff973c3..5d0217f 100644
--- a/c++/src/util/compress/bzip2/bzlib_private.h
+++ b/c++/src/util/compress/bzip2/bzlib_private.h
@@ -4,59 +4,19 @@
 /*---                                       bzlib_private.h ---*/
 /*-------------------------------------------------------------*/
 
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward at acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
---*/
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
 
 
 #ifndef _BZLIB_PRIVATE_H
@@ -76,7 +36,7 @@
 
 /*-- General stuff. --*/
 
-#define BZ_VERSION  "1.0.2, 30-Dec-2001"
+#define BZ_VERSION  "1.0.6, 6-Sept-2010"
 
 typedef char            Char;
 typedef unsigned char   Bool;
@@ -94,9 +54,11 @@ typedef unsigned short  UInt16;
 #endif 
 
 #ifndef BZ_NO_STDIO
+
 extern void BZ2_bz__AssertH__fail ( int errcode );
 #define AssertH(cond,errcode) \
    { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
+
 #if BZ_DEBUG
 #define AssertD(cond,msg) \
    { if (!(cond)) {       \
@@ -107,6 +69,7 @@ extern void BZ2_bz__AssertH__fail ( int errcode );
 #else
 #define AssertD(cond,msg) /* */
 #endif
+
 #define VPrintf0(zf) \
    fprintf(stderr,zf)
 #define VPrintf1(zf,za1) \
@@ -119,17 +82,20 @@ extern void BZ2_bz__AssertH__fail ( int errcode );
    fprintf(stderr,zf,za1,za2,za3,za4)
 #define VPrintf5(zf,za1,za2,za3,za4,za5) \
    fprintf(stderr,zf,za1,za2,za3,za4,za5)
+
 #else
+
 extern void bz_internal_error ( int errcode );
 #define AssertH(cond,errcode) \
    { if (!(cond)) bz_internal_error ( errcode ); }
-#define AssertD(cond,msg) /* */
-#define VPrintf0(zf) /* */
-#define VPrintf1(zf,za1) /* */
-#define VPrintf2(zf,za1,za2) /* */
-#define VPrintf3(zf,za1,za2,za3) /* */
-#define VPrintf4(zf,za1,za2,za3,za4) /* */
-#define VPrintf5(zf,za1,za2,za3,za4,za5) /* */
+#define AssertD(cond,msg)                do { } while (0)
+#define VPrintf0(zf)                     do { } while (0)
+#define VPrintf1(zf,za1)                 do { } while (0)
+#define VPrintf2(zf,za1,za2)             do { } while (0)
+#define VPrintf3(zf,za1,za2,za3)         do { } while (0)
+#define VPrintf4(zf,za1,za2,za3,za4)     do { } while (0)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
+
 #endif
 
 
@@ -476,11 +442,15 @@ typedef
 /*-- Macros for decompression. --*/
 
 #define BZ_GET_FAST(cccc)                     \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
     s->tPos = s->tt[s->tPos];                 \
     cccc = (UChar)(s->tPos & 0xff);           \
     s->tPos >>= 8;
 
 #define BZ_GET_FAST_C(cccc)                   \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
     c_tPos = c_tt[c_tPos];                    \
     cccc = (UChar)(c_tPos & 0xff);            \
     c_tPos >>= 8;
@@ -503,8 +473,10 @@ typedef
    (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
 
 #define BZ_GET_SMALL(cccc)                            \
-      cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
-      s->tPos = GET_LL(s->tPos);
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+    cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
+    s->tPos = GET_LL(s->tPos);
 
 
 /*-- externs for decompression. --*/
diff --git a/c++/src/util/compress/bzip2/compress.c b/c++/src/util/compress/bzip2/compress.c
index 56501c1..caf7696 100644
--- a/c++/src/util/compress/bzip2/compress.c
+++ b/c++/src/util/compress/bzip2/compress.c
@@ -4,71 +4,27 @@
 /*---                                            compress.c ---*/
 /*-------------------------------------------------------------*/
 
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward at acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
---*/
-
-/*--
-   CHANGES
-   ~~~~~~~
-   0.9.0 -- original version.
-
-   0.9.0a/b -- no changes in this file.
-
-   0.9.0c
-      * changed setting of nGroups in sendMTFValues() so as to 
-        do a bit better on small files
---*/
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+/* CHANGES
+    0.9.0    -- original version.
+    0.9.0a/b -- no changes in this file.
+    0.9.0c   -- changed setting of nGroups in sendMTFValues() 
+                so as to do a bit better on small files
+*/
 
 #include "bzlib_private.h"
 
@@ -488,9 +444,11 @@ void sendMTFValues ( EState* s )
       /*--
         Recompute the tables based on the accumulated frequencies.
       --*/
+      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See 
+         comment in huffman.c for details. */
       for (t = 0; t < nGroups; t++)
          BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 
-                                 alphaSize, 20 );
+                                 alphaSize, 17 /*20*/ );
    }
 
 
@@ -527,7 +485,7 @@ void sendMTFValues ( EState* s )
          if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
          if (s->len[t][i] < minLen) minLen = s->len[t][i];
       }
-      AssertH ( !(maxLen > 20), 3004 );
+      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
       AssertH ( !(minLen < 1),  3005 );
       BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 
                           minLen, maxLen, alphaSize );
@@ -651,8 +609,8 @@ void BZ2_compressBlock ( EState* s, Bool is_last_block )
       if (s->blockNo > 1) s->numZ = 0;
 
       if (s->verbosity >= 2)
-         VPrintf4( "    block %d: crc = 0x%8x, "
-                   "combined CRC = 0x%8x, size = %d\n",
+         VPrintf4( "    block %d: crc = 0x%08x, "
+                   "combined CRC = 0x%08x, size = %d\n",
                    s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
 
       BZ2_blockSort ( s );
@@ -703,7 +661,7 @@ void BZ2_compressBlock ( EState* s, Bool is_last_block )
       bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
       bsPutUInt32 ( s, s->combinedCRC );
       if (s->verbosity >= 2)
-         VPrintf1( "    final combined CRC = 0x%x\n   ", s->combinedCRC );
+         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
       bsFinishWrite ( s );
    }
 }
diff --git a/c++/src/util/compress/bzip2/crctable.c b/c++/src/util/compress/bzip2/crctable.c
index b16746a..1fea7e9 100644
--- a/c++/src/util/compress/bzip2/crctable.c
+++ b/c++/src/util/compress/bzip2/crctable.c
@@ -4,59 +4,19 @@
 /*---                                            crctable.c ---*/
 /*-------------------------------------------------------------*/
 
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
 
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
 
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
 
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward at acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
---*/
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
 
 
 #include "bzlib_private.h"
diff --git a/c++/src/util/compress/bzip2/decompress.c b/c++/src/util/compress/bzip2/decompress.c
index e921347..311f566 100644
--- a/c++/src/util/compress/bzip2/decompress.c
+++ b/c++/src/util/compress/bzip2/decompress.c
@@ -4,59 +4,19 @@
 /*---                                          decompress.c ---*/
 /*-------------------------------------------------------------*/
 
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward at acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
---*/
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
 
 
 #include "bzlib_private.h"
@@ -421,6 +381,13 @@ Int32 BZ2_decompress ( DState* s )
             es = -1;
             N = 1;
             do {
+               /* Check that N doesn't get too big, so that es doesn't
+                  go negative.  The maximum value that can be
+                  RUNA/RUNB encoded is equal to the block size (post
+                  the initial RLE), viz, 900k, so bounding N at 2
+                  million should guard against overflow without
+                  rejecting any legitimate inputs. */
+               if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
                if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
                if (nextSym == BZ_RUNB) es = es + (1+1) * N;
                N = N * 2;
@@ -524,17 +491,36 @@ Int32 BZ2_decompress ( DState* s )
       if (s->origPtr < 0 || s->origPtr >= nblock)
          RETURN(BZ_DATA_ERROR);
 
+      /*-- Set up cftab to facilitate generation of T^(-1) --*/
+      /* Check: unzftab entries in range. */
+      for (i = 0; i <= 255; i++) {
+         if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
+            RETURN(BZ_DATA_ERROR);
+      }
+      /* Actually generate cftab. */
+      s->cftab[0] = 0;
+      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
+      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
+      /* Check: cftab entries in range. */
+      for (i = 0; i <= 256; i++) {
+         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
+            /* s->cftab[i] can legitimately be == nblock */
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
+      /* Check: cftab entries non-descending. */
+      for (i = 1; i <= 256; i++) {
+         if (s->cftab[i-1] > s->cftab[i]) {
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
+
       s->state_out_len = 0;
       s->state_out_ch  = 0;
       BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
       s->state = BZ_X_OUTPUT;
       if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
 
-      /*-- Set up cftab to facilitate generation of T^(-1) --*/
-      s->cftab[0] = 0;
-      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
-      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
-
       if (s->smallDecompress) {
 
          /*-- Make a copy of cftab, used in generation of T --*/
diff --git a/c++/src/util/compress/bzip2/dlltest.c b/c++/src/util/compress/bzip2/dlltest.c
index eb86bb6..4e27da2 100644
--- a/c++/src/util/compress/bzip2/dlltest.c
+++ b/c++/src/util/compress/bzip2/dlltest.c
@@ -1,9 +1,8 @@
 /*
    minibz2
       libbz2.dll test program.
-      by Yoshioka Tsuneo(QWF00133 at nifty.ne.jp/tsuneo-y at is.aist-nara.ac.jp)
-      This file is Public Domain.
-      welcome any email to me.
+      by Yoshioka Tsuneo (tsuneo at rr.iij4u.or.jp)
+      This file is Public Domain.  Welcome any email to me.
 
    usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
 */
diff --git a/c++/src/util/compress/bzip2/huffman.c b/c++/src/util/compress/bzip2/huffman.c
index 293095c..2283fdb 100644
--- a/c++/src/util/compress/bzip2/huffman.c
+++ b/c++/src/util/compress/bzip2/huffman.c
@@ -4,59 +4,19 @@
 /*---                                             huffman.c ---*/
 /*-------------------------------------------------------------*/
 
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward at acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
---*/
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
 
 
 #include "bzlib_private.h"
@@ -162,7 +122,24 @@ void BZ2_hbMakeCodeLengths ( UChar *len,
       
       if (! tooLong) break;
 
-      for (i = 1; i < alphaSize; i++) {
+      /* 17 Oct 04: keep-going condition for the following loop used
+         to be 'i < alphaSize', which missed the last element,
+         theoretically leading to the possibility of the compressor
+         looping.  However, this count-scaling step is only needed if
+         one of the generated Huffman code words is longer than
+         maxLen, which up to and including version 1.0.2 was 20 bits,
+         which is extremely unlikely.  In version 1.0.3 maxLen was
+         changed to 17 bits, which has minimal effect on compression
+         ratio, but does mean this scaling step is used from time to
+         time, enough to verify that it works.
+
+         This means that bzip2-1.0.3 and later will only produce
+         Huffman codes with a maximum length of 17 bits.  However, in
+         order to preserve backwards compatibility with bitstreams
+         produced by versions pre-1.0.3, the decompressor must still
+         handle lengths of up to 20. */
+
+      for (i = 1; i <= alphaSize; i++) {
          j = weight[i] >> 8;
          j = 1 + (j / 2);
          weight[i] = j << 8;
diff --git a/c++/src/util/compress/bzip2/manual.html b/c++/src/util/compress/bzip2/manual.html
index 3218979..f59427f 100644
--- a/c++/src/util/compress/bzip2/manual.html
+++ b/c++/src/util/compress/bzip2/manual.html
@@ -1,117 +1,2540 @@
-<HTML>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<!-- Created on January, 5  2002 by texi2html 1.64 -->
-<!-- 
-Written by: Lionel Cons <Lionel.Cons at cern.ch> (original author)
-            Karl Berry  <karl at freefriends.org>
-            Olaf Bachmann <obachman at mathematik.uni-kl.de>
-            and many others.
-Maintained by: Olaf Bachmann <obachman at mathematik.uni-kl.de>
-Send bugs and suggestions to <texi2html at mathematik.uni-kl.de>
- 
--->
-<HEAD>
-<TITLE>Untitled Document: Untitled Document</TITLE>
-
-<META NAME="description" CONTENT="Untitled Document: Untitled Document">
-<META NAME="keywords" CONTENT="Untitled Document: Untitled Document">
-<META NAME="resource-type" CONTENT="document">
-<META NAME="distribution" CONTENT="global">
-<META NAME="Generator" CONTENT="texi2html 1.64">
-
-</HEAD>
-
-<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
-
-<A NAME="SEC_Top"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H1>Untitled Document</H1></P><P>
-
-The following text is the License for this software.  You should
-find it identical to that contained in the file LICENSE in the 
-source distribution.
-</P><P>
-
- at bf{------------------ START OF THE LICENSE ------------------}
-</P><P>
-
-This program, <CODE>bzip2</CODE>, 
-and associated library <CODE>libbzip2</CODE>, are
-Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-</P><P>
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-<UL>
-<LI>
-   Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-<LI>
-   The origin of this software must not be misrepresented; you must 
-   not claim that you wrote the original software.  If you use this 
-   software in a product, an acknowledgment in the product 
-   documentation would be appreciated but is not required.
-<LI>
-   Altered source versions must be plainly marked as such, and must
-   not be misrepresented as being the original software.
-<LI>
-   The name of the author may not be used to endorse or promote 
-   products derived from this software without specific prior written 
-   permission.
-</UL>
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS
-OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-<P>
-
-Julian Seward, Cambridge, UK.
-</P><P>
-
-<CODE>jseward at acm.org</CODE>
-</P><P>
-
-<CODE>bzip2</CODE>/<CODE>libbzip2</CODE> version 1.0.2 of 30 December 2001.
-</P><P>
-
- at bf{------------------ END OF THE LICENSE ------------------}
-</P><P>
-
-Web sites:
-</P><P>
-
-<CODE>http://sources.redhat.com/bzip2</CODE>
-</P><P>
-
-<CODE>http://www.cacheprof.org</CODE>
-</P><P>
-
-PATENTS: To the best of my knowledge, <CODE>bzip2</CODE> does not use any patented
-algorithms.  However, I do not have the resources available to carry out
-a full patent search.  Therefore I cannot give any guarantee of the
-above statement.
-</P><P>
-
-<HR SIZE=1>
-<BR>  
-<FONT SIZE="-1">
-This document was generated
-by <I>Julian Seward</I> on <I>January, 5  2002</I>
-using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
-"><I>texi2html</I></A>
-
-</BODY>
-</HTML>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>bzip2 and libbzip2, version 1.0.6</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
+<style type="text/css" media="screen">/* Colours:
+#74240f  dark brown      h1, h2, h3, h4
+#336699  medium blue     links
+#339999  turquoise       link hover colour
+#202020  almost black    general text
+#761596  purple          md5sum text
+#626262  dark gray       pre border
+#eeeeee  very light gray pre background
+#f2f2f9  very light blue nav table background
+#3366cc  medium blue     nav table border
+*/
+
+a, a:link, a:visited, a:active { color: #336699; }
+a:hover { color: #339999; }
+
+body { font: 80%/126% sans-serif; }
+h1, h2, h3, h4 { color: #74240f; }
+
+dt { color: #336699; font-weight: bold }
+dd { 
+ margin-left: 1.5em; 
+ padding-bottom: 0.8em;
+}
+
+/* -- ruler -- */
+div.hr_blue { 
+  height:  3px; 
+  background:#ffffff url("/images/hr_blue.png") repeat-x; }
+div.hr_blue hr { display:none; }
+
+/* release styles */
+#release p { margin-top: 0.4em; }
+#release .md5sum { color: #761596; }
+
+
+/* ------ styles for docs|manuals|howto ------ */
+/* -- lists -- */
+ul  { 
+ margin:     0px 4px 16px 16px;
+ padding:    0px;
+ list-style: url("/images/li-blue.png"); 
+}
+ul li { 
+ margin-bottom: 10px;
+}
+ul ul	{ 
+ list-style-type:  none; 
+ list-style-image: none; 
+ margin-left:      0px; 
+}
+
+/* header / footer nav tables */
+table.nav {
+ border:     solid 1px #3366cc;
+ background: #f2f2f9;
+ background-color: #f2f2f9;
+ margin-bottom: 0.5em;
+}
+/* don't have underlined links in chunked nav menus */
+table.nav a { text-decoration: none; }
+table.nav a:hover { text-decoration: underline; }
+table.nav td { font-size: 85%; }
+
+code, tt, pre { font-size: 120%; }
+code, tt { color: #761596; }
+
+div.literallayout, pre.programlisting, pre.screen {
+ color:      #000000;
+ padding:    0.5em;
+ background: #eeeeee;
+ border:     1px solid #626262;
+ background-color: #eeeeee;
+ margin: 4px 0px 4px 0px; 
+}
+</style>
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div lang="en" class="book" title="bzip2 and libbzip2, version 1.0.6">
+<div class="titlepage">
+<div>
+<div><h1 class="title">
+<a name="userman"></a>bzip2 and libbzip2, version 1.0.6</h1></div>
+<div><h2 class="subtitle">A program and library for data compression</h2></div>
+<div><div class="authorgroup"><div class="author">
+<h3 class="author">
+<span class="firstname">Julian</span> <span class="surname">Seward</span>
+</h3>
+<div class="affiliation"><span class="orgname">http://www.bzip.org<br></span></div>
+</div></div></div>
+<div><p class="releaseinfo">Version 1.0.6 of 6 September 2010</p></div>
+<div><p class="copyright">Copyright � 1996-2010 Julian Seward</p></div>
+<div><div class="legalnotice" title="Legal Notice">
+<a name="id537185"></a><p>This program, <code class="computeroutput">bzip2</code>, the
+  associated library <code class="computeroutput">libbzip2</code>, and
+  all documentation, are copyright � 1996-2010 Julian Seward.
+  All rights reserved.</p>
+<p>Redistribution and use in source and binary forms, with
+  or without modification, are permitted provided that the
+  following conditions are met:</p>
+<div class="itemizedlist"><ul class="itemizedlist" type="bullet">
+<li class="listitem" style="list-style-type: disc"><p>Redistributions of source code must retain the
+   above copyright notice, this list of conditions and the
+   following disclaimer.</p></li>
+<li class="listitem" style="list-style-type: disc"><p>The origin of this software must not be
+   misrepresented; you must not claim that you wrote the original
+   software.  If you use this software in a product, an
+   acknowledgment in the product documentation would be
+   appreciated but is not required.</p></li>
+<li class="listitem" style="list-style-type: disc"><p>Altered source versions must be plainly marked
+   as such, and must not be misrepresented as being the original
+   software.</p></li>
+<li class="listitem" style="list-style-type: disc"><p>The name of the author may not be used to
+   endorse or promote products derived from this software without
+   specific prior written permission.</p></li>
+</ul></div>
+<p>THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY
+  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+  AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+  THE POSSIBILITY OF SUCH DAMAGE.</p>
+<p>PATENTS: To the best of my knowledge,
+ <code class="computeroutput">bzip2</code> and
+ <code class="computeroutput">libbzip2</code> do not use any patented
+ algorithms.  However, I do not have the resources to carry
+ out a patent search.  Therefore I cannot give any guarantee of
+ the above statement.
+ </p>
+</div></div>
+</div>
+<hr>
+</div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt>
+<dt><span class="chapter"><a href="#using">2. How to use bzip2</a></span></dt>
+<dd><dl>
+<dt><span class="sect1"><a href="#name">2.1. NAME</a></span></dt>
+<dt><span class="sect1"><a href="#synopsis">2.2. SYNOPSIS</a></span></dt>
+<dt><span class="sect1"><a href="#description">2.3. DESCRIPTION</a></span></dt>
+<dt><span class="sect1"><a href="#options">2.4. OPTIONS</a></span></dt>
+<dt><span class="sect1"><a href="#memory-management">2.5. MEMORY MANAGEMENT</a></span></dt>
+<dt><span class="sect1"><a href="#recovering">2.6. RECOVERING DATA FROM DAMAGED FILES</a></span></dt>
+<dt><span class="sect1"><a href="#performance">2.7. PERFORMANCE NOTES</a></span></dt>
+<dt><span class="sect1"><a href="#caveats">2.8. CAVEATS</a></span></dt>
+<dt><span class="sect1"><a href="#author">2.9. AUTHOR</a></span></dt>
+</dl></dd>
+<dt><span class="chapter"><a href="#libprog">3. 
+Programming with <code class="computeroutput">libbzip2</code>
+</a></span></dt>
+<dd><dl>
+<dt><span class="sect1"><a href="#top-level">3.1. Top-level structure</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#ll-summary">3.1.1. Low-level summary</a></span></dt>
+<dt><span class="sect2"><a href="#hl-summary">3.1.2. High-level summary</a></span></dt>
+<dt><span class="sect2"><a href="#util-fns-summary">3.1.3. Utility functions summary</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#err-handling">3.2. Error handling</a></span></dt>
+<dt><span class="sect1"><a href="#low-level">3.3. Low-level interface</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#bzcompress-init">3.3.1. BZ2_bzCompressInit</a></span></dt>
+<dt><span class="sect2"><a href="#bzCompress">3.3.2. BZ2_bzCompress</a></span></dt>
+<dt><span class="sect2"><a href="#bzCompress-end">3.3.3. BZ2_bzCompressEnd</a></span></dt>
+<dt><span class="sect2"><a href="#bzDecompress-init">3.3.4. BZ2_bzDecompressInit</a></span></dt>
+<dt><span class="sect2"><a href="#bzDecompress">3.3.5. BZ2_bzDecompress</a></span></dt>
+<dt><span class="sect2"><a href="#bzDecompress-end">3.3.6. BZ2_bzDecompressEnd</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#hl-interface">3.4. High-level interface</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#bzreadopen">3.4.1. BZ2_bzReadOpen</a></span></dt>
+<dt><span class="sect2"><a href="#bzread">3.4.2. BZ2_bzRead</a></span></dt>
+<dt><span class="sect2"><a href="#bzreadgetunused">3.4.3. BZ2_bzReadGetUnused</a></span></dt>
+<dt><span class="sect2"><a href="#bzreadclose">3.4.4. BZ2_bzReadClose</a></span></dt>
+<dt><span class="sect2"><a href="#bzwriteopen">3.4.5. BZ2_bzWriteOpen</a></span></dt>
+<dt><span class="sect2"><a href="#bzwrite">3.4.6. BZ2_bzWrite</a></span></dt>
+<dt><span class="sect2"><a href="#bzwriteclose">3.4.7. BZ2_bzWriteClose</a></span></dt>
+<dt><span class="sect2"><a href="#embed">3.4.8. Handling embedded compressed data streams</a></span></dt>
+<dt><span class="sect2"><a href="#std-rdwr">3.4.9. Standard file-reading/writing code</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#util-fns">3.5. Utility functions</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#bzbufftobuffcompress">3.5.1. BZ2_bzBuffToBuffCompress</a></span></dt>
+<dt><span class="sect2"><a href="#bzbufftobuffdecompress">3.5.2. BZ2_bzBuffToBuffDecompress</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#zlib-compat">3.6. zlib compatibility functions</a></span></dt>
+<dt><span class="sect1"><a href="#stdio-free">3.7. Using the library in a stdio-free environment</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#stdio-bye">3.7.1. Getting rid of stdio</a></span></dt>
+<dt><span class="sect2"><a href="#critical-error">3.7.2. Critical error handling</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#win-dll">3.8. Making a Windows DLL</a></span></dt>
+</dl></dd>
+<dt><span class="chapter"><a href="#misc">4. Miscellanea</a></span></dt>
+<dd><dl>
+<dt><span class="sect1"><a href="#limits">4.1. Limitations of the compressed file format</a></span></dt>
+<dt><span class="sect1"><a href="#port-issues">4.2. Portability issues</a></span></dt>
+<dt><span class="sect1"><a href="#bugs">4.3. Reporting bugs</a></span></dt>
+<dt><span class="sect1"><a href="#package">4.4. Did you get the right package?</a></span></dt>
+<dt><span class="sect1"><a href="#reading">4.5. Further Reading</a></span></dt>
+</dl></dd>
+</dl>
+</div>
+<div class="chapter" title="1.�Introduction">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="intro"></a>1.�Introduction</h2></div></div></div>
+<p><code class="computeroutput">bzip2</code> compresses files
+using the Burrows-Wheeler block-sorting text compression
+algorithm, and Huffman coding.  Compression is generally
+considerably better than that achieved by more conventional
+LZ77/LZ78-based compressors, and approaches the performance of
+the PPM family of statistical compressors.</p>
+<p><code class="computeroutput">bzip2</code> is built on top of
+<code class="computeroutput">libbzip2</code>, a flexible library for
+handling compressed data in the
+<code class="computeroutput">bzip2</code> format.  This manual
+describes both how to use the program and how to work with the
+library interface.  Most of the manual is devoted to this
+library, not the program, which is good news if your interest is
+only in the program.</p>
+<div class="itemizedlist"><ul class="itemizedlist" type="bullet">
+<li class="listitem" style="list-style-type: disc"><p><a class="xref" href="#using" title="2.�How to use bzip2">How to use bzip2</a> describes how to use
+ <code class="computeroutput">bzip2</code>; this is the only part
+ you need to read if you just want to know how to operate the
+ program.</p></li>
+<li class="listitem" style="list-style-type: disc"><p><a class="xref" href="#libprog" title="3.� Programming with libbzip2">Programming with libbzip2</a> describes the
+ programming interfaces in detail, and</p></li>
+<li class="listitem" style="list-style-type: disc"><p><a class="xref" href="#misc" title="4.�Miscellanea">Miscellanea</a> records some
+ miscellaneous notes which I thought ought to be recorded
+ somewhere.</p></li>
+</ul></div>
+</div>
+<div class="chapter" title="2.�How to use bzip2">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="using"></a>2.�How to use bzip2</h2></div></div></div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="sect1"><a href="#name">2.1. NAME</a></span></dt>
+<dt><span class="sect1"><a href="#synopsis">2.2. SYNOPSIS</a></span></dt>
+<dt><span class="sect1"><a href="#description">2.3. DESCRIPTION</a></span></dt>
+<dt><span class="sect1"><a href="#options">2.4. OPTIONS</a></span></dt>
+<dt><span class="sect1"><a href="#memory-management">2.5. MEMORY MANAGEMENT</a></span></dt>
+<dt><span class="sect1"><a href="#recovering">2.6. RECOVERING DATA FROM DAMAGED FILES</a></span></dt>
+<dt><span class="sect1"><a href="#performance">2.7. PERFORMANCE NOTES</a></span></dt>
+<dt><span class="sect1"><a href="#caveats">2.8. CAVEATS</a></span></dt>
+<dt><span class="sect1"><a href="#author">2.9. AUTHOR</a></span></dt>
+</dl>
+</div>
+<p>This chapter contains a copy of the
+<code class="computeroutput">bzip2</code> man page, and nothing
+else.</p>
+<div class="sect1" title="2.1.�NAME">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="name"></a>2.1.�NAME</h2></div></div></div>
+<div class="itemizedlist"><ul class="itemizedlist" type="bullet">
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">bzip2</code>,
+  <code class="computeroutput">bunzip2</code> - a block-sorting file
+  compressor, v1.0.6</p></li>
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">bzcat</code> -
+   decompresses files to stdout</p></li>
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">bzip2recover</code> -
+   recovers data from damaged bzip2 files</p></li>
+</ul></div>
+</div>
+<div class="sect1" title="2.2.�SYNOPSIS">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="synopsis"></a>2.2.�SYNOPSIS</h2></div></div></div>
+<div class="itemizedlist"><ul class="itemizedlist" type="bullet">
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">bzip2</code> [
+  -cdfkqstvzVL123456789 ] [ filenames ...  ]</p></li>
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">bunzip2</code> [
+  -fkvsVL ] [ filenames ...  ]</p></li>
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">bzcat</code> [ -s ] [
+  filenames ...  ]</p></li>
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">bzip2recover</code>
+  filename</p></li>
+</ul></div>
+</div>
+<div class="sect1" title="2.3.�DESCRIPTION">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="description"></a>2.3.�DESCRIPTION</h2></div></div></div>
+<p><code class="computeroutput">bzip2</code> compresses files
+using the Burrows-Wheeler block sorting text compression
+algorithm, and Huffman coding.  Compression is generally
+considerably better than that achieved by more conventional
+LZ77/LZ78-based compressors, and approaches the performance of
+the PPM family of statistical compressors.</p>
+<p>The command-line options are deliberately very similar to
+those of GNU <code class="computeroutput">gzip</code>, but they are
+not identical.</p>
+<p><code class="computeroutput">bzip2</code> expects a list of
+file names to accompany the command-line flags.  Each file is
+replaced by a compressed version of itself, with the name
+<code class="computeroutput">original_name.bz2</code>.  Each
+compressed file has the same modification date, permissions, and,
+when possible, ownership as the corresponding original, so that
+these properties can be correctly restored at decompression time.
+File name handling is naive in the sense that there is no
+mechanism for preserving original file names, permissions,
+ownerships or dates in filesystems which lack these concepts, or
+have serious file name length restrictions, such as
+MS-DOS.</p>
+<p><code class="computeroutput">bzip2</code> and
+<code class="computeroutput">bunzip2</code> will by default not
+overwrite existing files.  If you want this to happen, specify
+the <code class="computeroutput">-f</code> flag.</p>
+<p>If no file names are specified,
+<code class="computeroutput">bzip2</code> compresses from standard
+input to standard output.  In this case,
+<code class="computeroutput">bzip2</code> will decline to write
+compressed output to a terminal, as this would be entirely
+incomprehensible and therefore pointless.</p>
+<p><code class="computeroutput">bunzip2</code> (or
+<code class="computeroutput">bzip2 -d</code>) decompresses all
+specified files.  Files which were not created by
+<code class="computeroutput">bzip2</code> will be detected and
+ignored, and a warning issued.
+<code class="computeroutput">bzip2</code> attempts to guess the
+filename for the decompressed file from that of the compressed
+file as follows:</p>
+<div class="itemizedlist"><ul class="itemizedlist" type="bullet">
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">filename.bz2 </code>
+  becomes
+  <code class="computeroutput">filename</code></p></li>
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">filename.bz </code>
+  becomes
+  <code class="computeroutput">filename</code></p></li>
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">filename.tbz2</code>
+  becomes
+  <code class="computeroutput">filename.tar</code></p></li>
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">filename.tbz </code>
+  becomes
+  <code class="computeroutput">filename.tar</code></p></li>
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">anyothername </code>
+  becomes
+  <code class="computeroutput">anyothername.out</code></p></li>
+</ul></div>
+<p>If the file does not end in one of the recognised endings,
+<code class="computeroutput">.bz2</code>,
+<code class="computeroutput">.bz</code>,
+<code class="computeroutput">.tbz2</code> or
+<code class="computeroutput">.tbz</code>,
+<code class="computeroutput">bzip2</code> complains that it cannot
+guess the name of the original file, and uses the original name
+with <code class="computeroutput">.out</code> appended.</p>
+<p>As with compression, supplying no filenames causes
+decompression from standard input to standard output.</p>
+<p><code class="computeroutput">bunzip2</code> will correctly
+decompress a file which is the concatenation of two or more
+compressed files.  The result is the concatenation of the
+corresponding uncompressed files.  Integrity testing
+(<code class="computeroutput">-t</code>) of concatenated compressed
+files is also supported.</p>
+<p>You can also compress or decompress files to the standard
+output by giving the <code class="computeroutput">-c</code> flag.
+Multiple files may be compressed and decompressed like this.  The
+resulting outputs are fed sequentially to stdout.  Compression of
+multiple files in this manner generates a stream containing
+multiple compressed file representations.  Such a stream can be
+decompressed correctly only by
+<code class="computeroutput">bzip2</code> version 0.9.0 or later.
+Earlier versions of <code class="computeroutput">bzip2</code> will
+stop after decompressing the first file in the stream.</p>
+<p><code class="computeroutput">bzcat</code> (or
+<code class="computeroutput">bzip2 -dc</code>) decompresses all
+specified files to the standard output.</p>
+<p><code class="computeroutput">bzip2</code> will read arguments
+from the environment variables
+<code class="computeroutput">BZIP2</code> and
+<code class="computeroutput">BZIP</code>, in that order, and will
+process them before any arguments read from the command line.
+This gives a convenient way to supply default arguments.</p>
+<p>Compression is always performed, even if the compressed
+file is slightly larger than the original.  Files of less than
+about one hundred bytes tend to get larger, since the compression
+mechanism has a constant overhead in the region of 50 bytes.
+Random data (including the output of most file compressors) is
+coded at about 8.05 bits per byte, giving an expansion of around
+0.5%.</p>
+<p>As a self-check for your protection,
+<code class="computeroutput">bzip2</code> uses 32-bit CRCs to make
+sure that the decompressed version of a file is identical to the
+original.  This guards against corruption of the compressed data,
+and against undetected bugs in
+<code class="computeroutput">bzip2</code> (hopefully very unlikely).
+The chances of data corruption going undetected is microscopic,
+about one chance in four billion for each file processed.  Be
+aware, though, that the check occurs upon decompression, so it
+can only tell you that something is wrong.  It can't help you
+recover the original uncompressed data.  You can use
+<code class="computeroutput">bzip2recover</code> to try to recover
+data from damaged files.</p>
+<p>Return values: 0 for a normal exit, 1 for environmental
+problems (file not found, invalid flags, I/O errors, etc.), 2
+to indicate a corrupt compressed file, 3 for an internal
+consistency error (eg, bug) which caused
+<code class="computeroutput">bzip2</code> to panic.</p>
+</div>
+<div class="sect1" title="2.4.�OPTIONS">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="options"></a>2.4.�OPTIONS</h2></div></div></div>
+<div class="variablelist"><dl>
+<dt><span class="term"><code class="computeroutput">-c --stdout</code></span></dt>
+<dd><p>Compress or decompress to standard
+  output.</p></dd>
+<dt><span class="term"><code class="computeroutput">-d --decompress</code></span></dt>
+<dd><p>Force decompression.
+  <code class="computeroutput">bzip2</code>,
+  <code class="computeroutput">bunzip2</code> and
+  <code class="computeroutput">bzcat</code> are really the same
+  program, and the decision about what actions to take is done on
+  the basis of which name is used.  This flag overrides that
+  mechanism, and forces bzip2 to decompress.</p></dd>
+<dt><span class="term"><code class="computeroutput">-z --compress</code></span></dt>
+<dd><p>The complement to
+  <code class="computeroutput">-d</code>: forces compression,
+  regardless of the invokation name.</p></dd>
+<dt><span class="term"><code class="computeroutput">-t --test</code></span></dt>
+<dd><p>Check integrity of the specified file(s), but
+  don't decompress them.  This really performs a trial
+  decompression and throws away the result.</p></dd>
+<dt><span class="term"><code class="computeroutput">-f --force</code></span></dt>
+<dd>
+<p>Force overwrite of output files.  Normally,
+  <code class="computeroutput">bzip2</code> will not overwrite
+  existing output files.  Also forces
+  <code class="computeroutput">bzip2</code> to break hard links to
+  files, which it otherwise wouldn't do.</p>
+<p><code class="computeroutput">bzip2</code> normally declines
+  to decompress files which don't have the correct magic header
+  bytes. If forced (<code class="computeroutput">-f</code>),
+  however, it will pass such files through unmodified. This is
+  how GNU <code class="computeroutput">gzip</code> behaves.</p>
+</dd>
+<dt><span class="term"><code class="computeroutput">-k --keep</code></span></dt>
+<dd><p>Keep (don't delete) input files during
+  compression or decompression.</p></dd>
+<dt><span class="term"><code class="computeroutput">-s --small</code></span></dt>
+<dd>
+<p>Reduce memory usage, for compression,
+  decompression and testing.  Files are decompressed and tested
+  using a modified algorithm which only requires 2.5 bytes per
+  block byte.  This means any file can be decompressed in 2300k
+  of memory, albeit at about half the normal speed.</p>
+<p>During compression, <code class="computeroutput">-s</code>
+  selects a block size of 200k, which limits memory use to around
+  the same figure, at the expense of your compression ratio.  In
+  short, if your machine is low on memory (8 megabytes or less),
+  use <code class="computeroutput">-s</code> for everything.  See
+  <a class="xref" href="#memory-management" title="2.5.�MEMORY MANAGEMENT">MEMORY MANAGEMENT</a> below.</p>
+</dd>
+<dt><span class="term"><code class="computeroutput">-q --quiet</code></span></dt>
+<dd><p>Suppress non-essential warning messages.
+  Messages pertaining to I/O errors and other critical events
+  will not be suppressed.</p></dd>
+<dt><span class="term"><code class="computeroutput">-v --verbose</code></span></dt>
+<dd><p>Verbose mode -- show the compression ratio for
+  each file processed.  Further
+  <code class="computeroutput">-v</code>'s increase the verbosity
+  level, spewing out lots of information which is primarily of
+  interest for diagnostic purposes.</p></dd>
+<dt><span class="term"><code class="computeroutput">-L --license -V --version</code></span></dt>
+<dd><p>Display the software version, license terms and
+  conditions.</p></dd>
+<dt><span class="term"><code class="computeroutput">-1</code> (or
+ <code class="computeroutput">--fast</code>) to
+ <code class="computeroutput">-9</code> (or
+ <code class="computeroutput">-best</code>)</span></dt>
+<dd><p>Set the block size to 100 k, 200 k ...  900 k
+  when compressing.  Has no effect when decompressing.  See <a class="xref" href="#memory-management" title="2.5.�MEMORY MANAGEMENT">MEMORY MANAGEMENT</a> below.  The
+  <code class="computeroutput">--fast</code> and
+  <code class="computeroutput">--best</code> aliases are primarily
+  for GNU <code class="computeroutput">gzip</code> compatibility.
+  In particular, <code class="computeroutput">--fast</code> doesn't
+  make things significantly faster.  And
+  <code class="computeroutput">--best</code> merely selects the
+  default behaviour.</p></dd>
+<dt><span class="term"><code class="computeroutput">--</code></span></dt>
+<dd><p>Treats all subsequent arguments as file names,
+  even if they start with a dash.  This is so you can handle
+  files with names beginning with a dash, for example:
+  <code class="computeroutput">bzip2 --
+  -myfilename</code>.</p></dd>
+<dt>
+<span class="term"><code class="computeroutput">--repetitive-fast</code>, </span><span class="term"><code class="computeroutput">--repetitive-best</code></span>
+</dt>
+<dd><p>These flags are redundant in versions 0.9.5 and
+  above.  They provided some coarse control over the behaviour of
+  the sorting algorithm in earlier versions, which was sometimes
+  useful.  0.9.5 and above have an improved algorithm which
+  renders these flags irrelevant.</p></dd>
+</dl></div>
+</div>
+<div class="sect1" title="2.5.�MEMORY MANAGEMENT">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="memory-management"></a>2.5.�MEMORY MANAGEMENT</h2></div></div></div>
+<p><code class="computeroutput">bzip2</code> compresses large
+files in blocks.  The block size affects both the compression
+ratio achieved, and the amount of memory needed for compression
+and decompression.  The flags <code class="computeroutput">-1</code>
+through <code class="computeroutput">-9</code> specify the block
+size to be 100,000 bytes through 900,000 bytes (the default)
+respectively.  At decompression time, the block size used for
+compression is read from the header of the compressed file, and
+<code class="computeroutput">bunzip2</code> then allocates itself
+just enough memory to decompress the file.  Since block sizes are
+stored in compressed files, it follows that the flags
+<code class="computeroutput">-1</code> to
+<code class="computeroutput">-9</code> are irrelevant to and so
+ignored during decompression.</p>
+<p>Compression and decompression requirements, in bytes, can be
+estimated as:</p>
+<pre class="programlisting">Compression:   400k + ( 8 x block size )
+
+Decompression: 100k + ( 4 x block size ), or
+               100k + ( 2.5 x block size )</pre>
+<p>Larger block sizes give rapidly diminishing marginal
+returns.  Most of the compression comes from the first two or
+three hundred k of block size, a fact worth bearing in mind when
+using <code class="computeroutput">bzip2</code> on small machines.
+It is also important to appreciate that the decompression memory
+requirement is set at compression time by the choice of block
+size.</p>
+<p>For files compressed with the default 900k block size,
+<code class="computeroutput">bunzip2</code> will require about 3700
+kbytes to decompress.  To support decompression of any file on a
+4 megabyte machine, <code class="computeroutput">bunzip2</code> has
+an option to decompress using approximately half this amount of
+memory, about 2300 kbytes.  Decompression speed is also halved,
+so you should use this option only where necessary.  The relevant
+flag is <code class="computeroutput">-s</code>.</p>
+<p>In general, try and use the largest block size memory
+constraints allow, since that maximises the compression achieved.
+Compression and decompression speed are virtually unaffected by
+block size.</p>
+<p>Another significant point applies to files which fit in a
+single block -- that means most files you'd encounter using a
+large block size.  The amount of real memory touched is
+proportional to the size of the file, since the file is smaller
+than a block.  For example, compressing a file 20,000 bytes long
+with the flag <code class="computeroutput">-9</code> will cause the
+compressor to allocate around 7600k of memory, but only touch
+400k + 20000 * 8 = 560 kbytes of it.  Similarly, the decompressor
+will allocate 3700k but only touch 100k + 20000 * 4 = 180
+kbytes.</p>
+<p>Here is a table which summarises the maximum memory usage
+for different block sizes.  Also recorded is the total compressed
+size for 14 files of the Calgary Text Compression Corpus
+totalling 3,141,622 bytes.  This column gives some feel for how
+compression varies with block size.  These figures tend to
+understate the advantage of larger block sizes for larger files,
+since the Corpus is dominated by smaller files.</p>
+<pre class="programlisting">        Compress   Decompress   Decompress   Corpus
+Flag     usage      usage       -s usage     Size
+
+ -1      1200k       500k         350k      914704
+ -2      2000k       900k         600k      877703
+ -3      2800k      1300k         850k      860338
+ -4      3600k      1700k        1100k      846899
+ -5      4400k      2100k        1350k      845160
+ -6      5200k      2500k        1600k      838626
+ -7      6100k      2900k        1850k      834096
+ -8      6800k      3300k        2100k      828642
+ -9      7600k      3700k        2350k      828642</pre>
+</div>
+<div class="sect1" title="2.6.�RECOVERING DATA FROM DAMAGED FILES">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="recovering"></a>2.6.�RECOVERING DATA FROM DAMAGED FILES</h2></div></div></div>
+<p><code class="computeroutput">bzip2</code> compresses files in
+blocks, usually 900kbytes long.  Each block is handled
+independently.  If a media or transmission error causes a
+multi-block <code class="computeroutput">.bz2</code> file to become
+damaged, it may be possible to recover data from the undamaged
+blocks in the file.</p>
+<p>The compressed representation of each block is delimited by
+a 48-bit pattern, which makes it possible to find the block
+boundaries with reasonable certainty.  Each block also carries
+its own 32-bit CRC, so damaged blocks can be distinguished from
+undamaged ones.</p>
+<p><code class="computeroutput">bzip2recover</code> is a simple
+program whose purpose is to search for blocks in
+<code class="computeroutput">.bz2</code> files, and write each block
+out into its own <code class="computeroutput">.bz2</code> file.  You
+can then use <code class="computeroutput">bzip2 -t</code> to test
+the integrity of the resulting files, and decompress those which
+are undamaged.</p>
+<p><code class="computeroutput">bzip2recover</code> takes a
+single argument, the name of the damaged file, and writes a
+number of files <code class="computeroutput">rec0001file.bz2</code>,
+<code class="computeroutput">rec0002file.bz2</code>, etc, containing
+the extracted blocks.  The output filenames are designed so that
+the use of wildcards in subsequent processing -- for example,
+<code class="computeroutput">bzip2 -dc rec*file.bz2 >
+recovered_data</code> -- lists the files in the correct
+order.</p>
+<p><code class="computeroutput">bzip2recover</code> should be of
+most use dealing with large <code class="computeroutput">.bz2</code>
+files, as these will contain many blocks.  It is clearly futile
+to use it on damaged single-block files, since a damaged block
+cannot be recovered.  If you wish to minimise any potential data
+loss through media or transmission errors, you might consider
+compressing with a smaller block size.</p>
+</div>
+<div class="sect1" title="2.7.�PERFORMANCE NOTES">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="performance"></a>2.7.�PERFORMANCE NOTES</h2></div></div></div>
+<p>The sorting phase of compression gathers together similar
+strings in the file.  Because of this, files containing very long
+runs of repeated symbols, like "aabaabaabaab ..."  (repeated
+several hundred times) may compress more slowly than normal.
+Versions 0.9.5 and above fare much better than previous versions
+in this respect.  The ratio between worst-case and average-case
+compression time is in the region of 10:1.  For previous
+versions, this figure was more like 100:1.  You can use the
+<code class="computeroutput">-vvvv</code> option to monitor progress
+in great detail, if you want.</p>
+<p>Decompression speed is unaffected by these
+phenomena.</p>
+<p><code class="computeroutput">bzip2</code> usually allocates
+several megabytes of memory to operate in, and then charges all
+over it in a fairly random fashion.  This means that performance,
+both for compressing and decompressing, is largely determined by
+the speed at which your machine can service cache misses.
+Because of this, small changes to the code to reduce the miss
+rate have been observed to give disproportionately large
+performance improvements.  I imagine
+<code class="computeroutput">bzip2</code> will perform best on
+machines with very large caches.</p>
+</div>
+<div class="sect1" title="2.8.�CAVEATS">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="caveats"></a>2.8.�CAVEATS</h2></div></div></div>
+<p>I/O error messages are not as helpful as they could be.
+<code class="computeroutput">bzip2</code> tries hard to detect I/O
+errors and exit cleanly, but the details of what the problem is
+sometimes seem rather misleading.</p>
+<p>This manual page pertains to version 1.0.6 of
+<code class="computeroutput">bzip2</code>.  Compressed data created by
+this version is entirely forwards and backwards compatible with the
+previous public releases, versions 0.1pl2, 0.9.0 and 0.9.5, 1.0.0,
+1.0.1, 1.0.2 and 1.0.3, but with the following exception: 0.9.0 and
+above can correctly decompress multiple concatenated compressed files.
+0.1pl2 cannot do this; it will stop after decompressing just the first
+file in the stream.</p>
+<p><code class="computeroutput">bzip2recover</code> versions
+prior to 1.0.2 used 32-bit integers to represent bit positions in
+compressed files, so it could not handle compressed files more
+than 512 megabytes long.  Versions 1.0.2 and above use 64-bit ints
+on some platforms which support them (GNU supported targets, and
+Windows). To establish whether or not
+<code class="computeroutput">bzip2recover</code> was built with such
+a limitation, run it without arguments. In any event you can
+build yourself an unlimited version if you can recompile it with
+<code class="computeroutput">MaybeUInt64</code> set to be an
+unsigned 64-bit integer.</p>
+</div>
+<div class="sect1" title="2.9.�AUTHOR">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="author"></a>2.9.�AUTHOR</h2></div></div></div>
+<p>Julian Seward,
+<code class="computeroutput">jseward at bzip.org</code></p>
+<p>The ideas embodied in
+<code class="computeroutput">bzip2</code> are due to (at least) the
+following people: Michael Burrows and David Wheeler (for the
+block sorting transformation), David Wheeler (again, for the
+Huffman coder), Peter Fenwick (for the structured coding model in
+the original <code class="computeroutput">bzip</code>, and many
+refinements), and Alistair Moffat, Radford Neal and Ian Witten
+(for the arithmetic coder in the original
+<code class="computeroutput">bzip</code>).  I am much indebted for
+their help, support and advice.  See the manual in the source
+distribution for pointers to sources of documentation.  Christian
+von Roques encouraged me to look for faster sorting algorithms,
+so as to speed up compression.  Bela Lubkin encouraged me to
+improve the worst-case compression performance.  
+Donna Robinson XMLised the documentation.
+Many people sent
+patches, helped with portability problems, lent machines, gave
+advice and were generally helpful.</p>
+</div>
+</div>
+<div class="chapter" title="3.� Programming with libbzip2">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="libprog"></a>3.�
+Programming with <code class="computeroutput">libbzip2</code>
+</h2></div></div></div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="sect1"><a href="#top-level">3.1. Top-level structure</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#ll-summary">3.1.1. Low-level summary</a></span></dt>
+<dt><span class="sect2"><a href="#hl-summary">3.1.2. High-level summary</a></span></dt>
+<dt><span class="sect2"><a href="#util-fns-summary">3.1.3. Utility functions summary</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#err-handling">3.2. Error handling</a></span></dt>
+<dt><span class="sect1"><a href="#low-level">3.3. Low-level interface</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#bzcompress-init">3.3.1. BZ2_bzCompressInit</a></span></dt>
+<dt><span class="sect2"><a href="#bzCompress">3.3.2. BZ2_bzCompress</a></span></dt>
+<dt><span class="sect2"><a href="#bzCompress-end">3.3.3. BZ2_bzCompressEnd</a></span></dt>
+<dt><span class="sect2"><a href="#bzDecompress-init">3.3.4. BZ2_bzDecompressInit</a></span></dt>
+<dt><span class="sect2"><a href="#bzDecompress">3.3.5. BZ2_bzDecompress</a></span></dt>
+<dt><span class="sect2"><a href="#bzDecompress-end">3.3.6. BZ2_bzDecompressEnd</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#hl-interface">3.4. High-level interface</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#bzreadopen">3.4.1. BZ2_bzReadOpen</a></span></dt>
+<dt><span class="sect2"><a href="#bzread">3.4.2. BZ2_bzRead</a></span></dt>
+<dt><span class="sect2"><a href="#bzreadgetunused">3.4.3. BZ2_bzReadGetUnused</a></span></dt>
+<dt><span class="sect2"><a href="#bzreadclose">3.4.4. BZ2_bzReadClose</a></span></dt>
+<dt><span class="sect2"><a href="#bzwriteopen">3.4.5. BZ2_bzWriteOpen</a></span></dt>
+<dt><span class="sect2"><a href="#bzwrite">3.4.6. BZ2_bzWrite</a></span></dt>
+<dt><span class="sect2"><a href="#bzwriteclose">3.4.7. BZ2_bzWriteClose</a></span></dt>
+<dt><span class="sect2"><a href="#embed">3.4.8. Handling embedded compressed data streams</a></span></dt>
+<dt><span class="sect2"><a href="#std-rdwr">3.4.9. Standard file-reading/writing code</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#util-fns">3.5. Utility functions</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#bzbufftobuffcompress">3.5.1. BZ2_bzBuffToBuffCompress</a></span></dt>
+<dt><span class="sect2"><a href="#bzbufftobuffdecompress">3.5.2. BZ2_bzBuffToBuffDecompress</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#zlib-compat">3.6. zlib compatibility functions</a></span></dt>
+<dt><span class="sect1"><a href="#stdio-free">3.7. Using the library in a stdio-free environment</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#stdio-bye">3.7.1. Getting rid of stdio</a></span></dt>
+<dt><span class="sect2"><a href="#critical-error">3.7.2. Critical error handling</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#win-dll">3.8. Making a Windows DLL</a></span></dt>
+</dl>
+</div>
+<p>This chapter describes the programming interface to
+<code class="computeroutput">libbzip2</code>.</p>
+<p>For general background information, particularly about
+memory use and performance aspects, you'd be well advised to read
+<a class="xref" href="#using" title="2.�How to use bzip2">How to use bzip2</a> as well.</p>
+<div class="sect1" title="3.1.�Top-level structure">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="top-level"></a>3.1.�Top-level structure</h2></div></div></div>
+<p><code class="computeroutput">libbzip2</code> is a flexible
+library for compressing and decompressing data in the
+<code class="computeroutput">bzip2</code> data format.  Although
+packaged as a single entity, it helps to regard the library as
+three separate parts: the low level interface, and the high level
+interface, and some utility functions.</p>
+<p>The structure of
+<code class="computeroutput">libbzip2</code>'s interfaces is similar
+to that of Jean-loup Gailly's and Mark Adler's excellent
+<code class="computeroutput">zlib</code> library.</p>
+<p>All externally visible symbols have names beginning
+<code class="computeroutput">BZ2_</code>.  This is new in version
+1.0.  The intention is to minimise pollution of the namespaces of
+library clients.</p>
+<p>To use any part of the library, you need to
+<code class="computeroutput">#include <bzlib.h></code>
+into your sources.</p>
+<div class="sect2" title="3.1.1.�Low-level summary">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="ll-summary"></a>3.1.1.�Low-level summary</h3></div></div></div>
+<p>This interface provides services for compressing and
+decompressing data in memory.  There's no provision for dealing
+with files, streams or any other I/O mechanisms, just straight
+memory-to-memory work.  In fact, this part of the library can be
+compiled without inclusion of
+<code class="computeroutput">stdio.h</code>, which may be helpful
+for embedded applications.</p>
+<p>The low-level part of the library has no global variables
+and is therefore thread-safe.</p>
+<p>Six routines make up the low level interface:
+<code class="computeroutput">BZ2_bzCompressInit</code>,
+<code class="computeroutput">BZ2_bzCompress</code>, and
+<code class="computeroutput">BZ2_bzCompressEnd</code> for
+compression, and a corresponding trio
+<code class="computeroutput">BZ2_bzDecompressInit</code>,
+<code class="computeroutput">BZ2_bzDecompress</code> and
+<code class="computeroutput">BZ2_bzDecompressEnd</code> for
+decompression.  The <code class="computeroutput">*Init</code>
+functions allocate memory for compression/decompression and do
+other initialisations, whilst the
+<code class="computeroutput">*End</code> functions close down
+operations and release memory.</p>
+<p>The real work is done by
+<code class="computeroutput">BZ2_bzCompress</code> and
+<code class="computeroutput">BZ2_bzDecompress</code>.  These
+compress and decompress data from a user-supplied input buffer to
+a user-supplied output buffer.  These buffers can be any size;
+arbitrary quantities of data are handled by making repeated calls
+to these functions.  This is a flexible mechanism allowing a
+consumer-pull style of activity, or producer-push, or a mixture
+of both.</p>
+</div>
+<div class="sect2" title="3.1.2.�High-level summary">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="hl-summary"></a>3.1.2.�High-level summary</h3></div></div></div>
+<p>This interface provides some handy wrappers around the
+low-level interface to facilitate reading and writing
+<code class="computeroutput">bzip2</code> format files
+(<code class="computeroutput">.bz2</code> files).  The routines
+provide hooks to facilitate reading files in which the
+<code class="computeroutput">bzip2</code> data stream is embedded
+within some larger-scale file structure, or where there are
+multiple <code class="computeroutput">bzip2</code> data streams
+concatenated end-to-end.</p>
+<p>For reading files,
+<code class="computeroutput">BZ2_bzReadOpen</code>,
+<code class="computeroutput">BZ2_bzRead</code>,
+<code class="computeroutput">BZ2_bzReadClose</code> and 
+<code class="computeroutput">BZ2_bzReadGetUnused</code> are
+supplied.  For writing files,
+<code class="computeroutput">BZ2_bzWriteOpen</code>,
+<code class="computeroutput">BZ2_bzWrite</code> and
+<code class="computeroutput">BZ2_bzWriteFinish</code> are
+available.</p>
+<p>As with the low-level library, no global variables are used
+so the library is per se thread-safe.  However, if I/O errors
+occur whilst reading or writing the underlying compressed files,
+you may have to consult <code class="computeroutput">errno</code> to
+determine the cause of the error.  In that case, you'd need a C
+library which correctly supports
+<code class="computeroutput">errno</code> in a multithreaded
+environment.</p>
+<p>To make the library a little simpler and more portable,
+<code class="computeroutput">BZ2_bzReadOpen</code> and
+<code class="computeroutput">BZ2_bzWriteOpen</code> require you to
+pass them file handles (<code class="computeroutput">FILE*</code>s)
+which have previously been opened for reading or writing
+respectively.  That avoids portability problems associated with
+file operations and file attributes, whilst not being much of an
+imposition on the programmer.</p>
+</div>
+<div class="sect2" title="3.1.3.�Utility functions summary">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="util-fns-summary"></a>3.1.3.�Utility functions summary</h3></div></div></div>
+<p>For very simple needs,
+<code class="computeroutput">BZ2_bzBuffToBuffCompress</code> and
+<code class="computeroutput">BZ2_bzBuffToBuffDecompress</code> are
+provided.  These compress data in memory from one buffer to
+another buffer in a single function call.  You should assess
+whether these functions fulfill your memory-to-memory
+compression/decompression requirements before investing effort in
+understanding the more general but more complex low-level
+interface.</p>
+<p>Yoshioka Tsuneo
+(<code class="computeroutput">tsuneo at rr.iij4u.or.jp</code>) has
+contributed some functions to give better
+<code class="computeroutput">zlib</code> compatibility.  These
+functions are <code class="computeroutput">BZ2_bzopen</code>,
+<code class="computeroutput">BZ2_bzread</code>,
+<code class="computeroutput">BZ2_bzwrite</code>,
+<code class="computeroutput">BZ2_bzflush</code>,
+<code class="computeroutput">BZ2_bzclose</code>,
+<code class="computeroutput">BZ2_bzerror</code> and
+<code class="computeroutput">BZ2_bzlibVersion</code>.  You may find
+these functions more convenient for simple file reading and
+writing, than those in the high-level interface.  These functions
+are not (yet) officially part of the library, and are minimally
+documented here.  If they break, you get to keep all the pieces.
+I hope to document them properly when time permits.</p>
+<p>Yoshioka also contributed modifications to allow the
+library to be built as a Windows DLL.</p>
+</div>
+</div>
+<div class="sect1" title="3.2.�Error handling">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="err-handling"></a>3.2.�Error handling</h2></div></div></div>
+<p>The library is designed to recover cleanly in all
+situations, including the worst-case situation of decompressing
+random data.  I'm not 100% sure that it can always do this, so
+you might want to add a signal handler to catch segmentation
+violations during decompression if you are feeling especially
+paranoid.  I would be interested in hearing more about the
+robustness of the library to corrupted compressed data.</p>
+<p>Version 1.0.3 more robust in this respect than any
+previous version.  Investigations with Valgrind (a tool for detecting
+problems with memory management) indicate
+that, at least for the few files I tested, all single-bit errors
+in the decompressed data are caught properly, with no
+segmentation faults, no uses of uninitialised data, no out of
+range reads or writes, and no infinite looping in the decompressor.
+So it's certainly pretty robust, although
+I wouldn't claim it to be totally bombproof.</p>
+<p>The file <code class="computeroutput">bzlib.h</code> contains
+all definitions needed to use the library.  In particular, you
+should definitely not include
+<code class="computeroutput">bzlib_private.h</code>.</p>
+<p>In <code class="computeroutput">bzlib.h</code>, the various
+return values are defined.  The following list is not intended as
+an exhaustive description of the circumstances in which a given
+value may be returned -- those descriptions are given later.
+Rather, it is intended to convey the rough meaning of each return
+value.  The first five actions are normal and not intended to
+denote an error situation.</p>
+<div class="variablelist"><dl>
+<dt><span class="term"><code class="computeroutput">BZ_OK</code></span></dt>
+<dd><p>The requested action was completed
+   successfully.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_RUN_OK, BZ_FLUSH_OK,
+    BZ_FINISH_OK</code></span></dt>
+<dd><p>In 
+   <code class="computeroutput">BZ2_bzCompress</code>, the requested
+   flush/finish/nothing-special action was completed
+   successfully.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_STREAM_END</code></span></dt>
+<dd><p>Compression of data was completed, or the
+   logical stream end was detected during
+   decompression.</p></dd>
+</dl></div>
+<p>The following return values indicate an error of some
+kind.</p>
+<div class="variablelist"><dl>
+<dt><span class="term"><code class="computeroutput">BZ_CONFIG_ERROR</code></span></dt>
+<dd><p>Indicates that the library has been improperly
+   compiled on your platform -- a major configuration error.
+   Specifically, it means that
+   <code class="computeroutput">sizeof(char)</code>,
+   <code class="computeroutput">sizeof(short)</code> and
+   <code class="computeroutput">sizeof(int)</code> are not 1, 2 and
+   4 respectively, as they should be.  Note that the library
+   should still work properly on 64-bit platforms which follow
+   the LP64 programming model -- that is, where
+   <code class="computeroutput">sizeof(long)</code> and
+   <code class="computeroutput">sizeof(void*)</code> are 8.  Under
+   LP64, <code class="computeroutput">sizeof(int)</code> is still 4,
+   so <code class="computeroutput">libbzip2</code>, which doesn't
+   use the <code class="computeroutput">long</code> type, is
+   OK.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_SEQUENCE_ERROR</code></span></dt>
+<dd><p>When using the library, it is important to call
+   the functions in the correct sequence and with data structures
+   (buffers etc) in the correct states.
+   <code class="computeroutput">libbzip2</code> checks as much as it
+   can to ensure this is happening, and returns
+   <code class="computeroutput">BZ_SEQUENCE_ERROR</code> if not.
+   Code which complies precisely with the function semantics, as
+   detailed below, should never receive this value; such an event
+   denotes buggy code which you should
+   investigate.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_PARAM_ERROR</code></span></dt>
+<dd><p>Returned when a parameter to a function call is
+   out of range or otherwise manifestly incorrect.  As with
+   <code class="computeroutput">BZ_SEQUENCE_ERROR</code>, this
+   denotes a bug in the client code.  The distinction between
+   <code class="computeroutput">BZ_PARAM_ERROR</code> and
+   <code class="computeroutput">BZ_SEQUENCE_ERROR</code> is a bit
+   hazy, but still worth making.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_MEM_ERROR</code></span></dt>
+<dd><p>Returned when a request to allocate memory
+   failed.  Note that the quantity of memory needed to decompress
+   a stream cannot be determined until the stream's header has
+   been read.  So
+   <code class="computeroutput">BZ2_bzDecompress</code> and
+   <code class="computeroutput">BZ2_bzRead</code> may return
+   <code class="computeroutput">BZ_MEM_ERROR</code> even though some
+   of the compressed data has been read.  The same is not true
+   for compression; once
+   <code class="computeroutput">BZ2_bzCompressInit</code> or
+   <code class="computeroutput">BZ2_bzWriteOpen</code> have
+   successfully completed,
+   <code class="computeroutput">BZ_MEM_ERROR</code> cannot
+   occur.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_DATA_ERROR</code></span></dt>
+<dd><p>Returned when a data integrity error is
+   detected during decompression.  Most importantly, this means
+   when stored and computed CRCs for the data do not match.  This
+   value is also returned upon detection of any other anomaly in
+   the compressed data.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_DATA_ERROR_MAGIC</code></span></dt>
+<dd><p>As a special case of
+   <code class="computeroutput">BZ_DATA_ERROR</code>, it is
+   sometimes useful to know when the compressed stream does not
+   start with the correct magic bytes (<code class="computeroutput">'B' 'Z'
+   'h'</code>).</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_IO_ERROR</code></span></dt>
+<dd><p>Returned by
+   <code class="computeroutput">BZ2_bzRead</code> and
+   <code class="computeroutput">BZ2_bzWrite</code> when there is an
+   error reading or writing in the compressed file, and by
+   <code class="computeroutput">BZ2_bzReadOpen</code> and
+   <code class="computeroutput">BZ2_bzWriteOpen</code> for attempts
+   to use a file for which the error indicator (viz,
+   <code class="computeroutput">ferror(f)</code>) is set.  On
+   receipt of <code class="computeroutput">BZ_IO_ERROR</code>, the
+   caller should consult <code class="computeroutput">errno</code>
+   and/or <code class="computeroutput">perror</code> to acquire
+   operating-system specific information about the
+   problem.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_UNEXPECTED_EOF</code></span></dt>
+<dd><p>Returned by
+   <code class="computeroutput">BZ2_bzRead</code> when the
+   compressed file finishes before the logical end of stream is
+   detected.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_OUTBUFF_FULL</code></span></dt>
+<dd><p>Returned by
+   <code class="computeroutput">BZ2_bzBuffToBuffCompress</code> and
+   <code class="computeroutput">BZ2_bzBuffToBuffDecompress</code> to
+   indicate that the output data will not fit into the output
+   buffer provided.</p></dd>
+</dl></div>
+</div>
+<div class="sect1" title="3.3.�Low-level interface">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="low-level"></a>3.3.�Low-level interface</h2></div></div></div>
+<div class="sect2" title="3.3.1.�BZ2_bzCompressInit">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzcompress-init"></a>3.3.1.�BZ2_bzCompressInit</h3></div></div></div>
+<pre class="programlisting">typedef struct {
+  char *next_in;
+  unsigned int avail_in;
+  unsigned int total_in_lo32;
+  unsigned int total_in_hi32;
+
+  char *next_out;
+  unsigned int avail_out;
+  unsigned int total_out_lo32;
+  unsigned int total_out_hi32;
+
+  void *state;
+
+  void *(*bzalloc)(void *,int,int);
+  void (*bzfree)(void *,void *);
+  void *opaque;
+} bz_stream;
+
+int BZ2_bzCompressInit ( bz_stream *strm, 
+                         int blockSize100k, 
+                         int verbosity,
+                         int workFactor );</pre>
+<p>Prepares for compression.  The
+<code class="computeroutput">bz_stream</code> structure holds all
+data pertaining to the compression activity.  A
+<code class="computeroutput">bz_stream</code> structure should be
+allocated and initialised prior to the call.  The fields of
+<code class="computeroutput">bz_stream</code> comprise the entirety
+of the user-visible data.  <code class="computeroutput">state</code>
+is a pointer to the private data structures required for
+compression.</p>
+<p>Custom memory allocators are supported, via fields
+<code class="computeroutput">bzalloc</code>,
+<code class="computeroutput">bzfree</code>, and
+<code class="computeroutput">opaque</code>.  The value
+<code class="computeroutput">opaque</code> is passed to as the first
+argument to all calls to <code class="computeroutput">bzalloc</code>
+and <code class="computeroutput">bzfree</code>, but is otherwise
+ignored by the library.  The call <code class="computeroutput">bzalloc (
+opaque, n, m )</code> is expected to return a pointer
+<code class="computeroutput">p</code> to <code class="computeroutput">n *
+m</code> bytes of memory, and <code class="computeroutput">bzfree (
+opaque, p )</code> should free that memory.</p>
+<p>If you don't want to use a custom memory allocator, set
+<code class="computeroutput">bzalloc</code>,
+<code class="computeroutput">bzfree</code> and
+<code class="computeroutput">opaque</code> to
+<code class="computeroutput">NULL</code>, and the library will then
+use the standard <code class="computeroutput">malloc</code> /
+<code class="computeroutput">free</code> routines.</p>
+<p>Before calling
+<code class="computeroutput">BZ2_bzCompressInit</code>, fields
+<code class="computeroutput">bzalloc</code>,
+<code class="computeroutput">bzfree</code> and
+<code class="computeroutput">opaque</code> should be filled
+appropriately, as just described.  Upon return, the internal
+state will have been allocated and initialised, and
+<code class="computeroutput">total_in_lo32</code>,
+<code class="computeroutput">total_in_hi32</code>,
+<code class="computeroutput">total_out_lo32</code> and
+<code class="computeroutput">total_out_hi32</code> will have been
+set to zero.  These four fields are used by the library to inform
+the caller of the total amount of data passed into and out of the
+library, respectively.  You should not try to change them.  As of
+version 1.0, 64-bit counts are maintained, even on 32-bit
+platforms, using the <code class="computeroutput">_hi32</code>
+fields to store the upper 32 bits of the count.  So, for example,
+the total amount of data in is <code class="computeroutput">(total_in_hi32
+<< 32) + total_in_lo32</code>.</p>
+<p>Parameter <code class="computeroutput">blockSize100k</code>
+specifies the block size to be used for compression.  It should
+be a value between 1 and 9 inclusive, and the actual block size
+used is 100000 x this figure.  9 gives the best compression but
+takes most memory.</p>
+<p>Parameter <code class="computeroutput">verbosity</code> should
+be set to a number between 0 and 4 inclusive.  0 is silent, and
+greater numbers give increasingly verbose monitoring/debugging
+output.  If the library has been compiled with
+<code class="computeroutput">-DBZ_NO_STDIO</code>, no such output
+will appear for any verbosity setting.</p>
+<p>Parameter <code class="computeroutput">workFactor</code>
+controls how the compression phase behaves when presented with
+worst case, highly repetitive, input data.  If compression runs
+into difficulties caused by repetitive data, the library switches
+from the standard sorting algorithm to a fallback algorithm.  The
+fallback is slower than the standard algorithm by perhaps a
+factor of three, but always behaves reasonably, no matter how bad
+the input.</p>
+<p>Lower values of <code class="computeroutput">workFactor</code>
+reduce the amount of effort the standard algorithm will expend
+before resorting to the fallback.  You should set this parameter
+carefully; too low, and many inputs will be handled by the
+fallback algorithm and so compress rather slowly, too high, and
+your average-to-worst case compression times can become very
+large.  The default value of 30 gives reasonable behaviour over a
+wide range of circumstances.</p>
+<p>Allowable values range from 0 to 250 inclusive.  0 is a
+special case, equivalent to using the default value of 30.</p>
+<p>Note that the compressed output generated is the same
+regardless of whether or not the fallback algorithm is
+used.</p>
+<p>Be aware also that this parameter may disappear entirely in
+future versions of the library.  In principle it should be
+possible to devise a good way to automatically choose which
+algorithm to use.  Such a mechanism would render the parameter
+obsolete.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if strm is NULL 
+  or blockSize < 1 or blockSize > 9
+  or verbosity < 0 or verbosity > 4
+  or workFactor < 0 or workFactor > 250
+BZ_MEM_ERROR 
+  if not enough memory is available
+BZ_OK 
+  otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">BZ2_bzCompress
+  if BZ_OK is returned
+  no specific action needed in case of error</pre>
+</div>
+<div class="sect2" title="3.3.2.�BZ2_bzCompress">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzCompress"></a>3.3.2.�BZ2_bzCompress</h3></div></div></div>
+<pre class="programlisting">int BZ2_bzCompress ( bz_stream *strm, int action );</pre>
+<p>Provides more input and/or output buffer space for the
+library.  The caller maintains input and output buffers, and
+calls <code class="computeroutput">BZ2_bzCompress</code> to transfer
+data between them.</p>
+<p>Before each call to
+<code class="computeroutput">BZ2_bzCompress</code>,
+<code class="computeroutput">next_in</code> should point at the data
+to be compressed, and <code class="computeroutput">avail_in</code>
+should indicate how many bytes the library may read.
+<code class="computeroutput">BZ2_bzCompress</code> updates
+<code class="computeroutput">next_in</code>,
+<code class="computeroutput">avail_in</code> and
+<code class="computeroutput">total_in</code> to reflect the number
+of bytes it has read.</p>
+<p>Similarly, <code class="computeroutput">next_out</code> should
+point to a buffer in which the compressed data is to be placed,
+with <code class="computeroutput">avail_out</code> indicating how
+much output space is available.
+<code class="computeroutput">BZ2_bzCompress</code> updates
+<code class="computeroutput">next_out</code>,
+<code class="computeroutput">avail_out</code> and
+<code class="computeroutput">total_out</code> to reflect the number
+of bytes output.</p>
+<p>You may provide and remove as little or as much data as you
+like on each call of
+<code class="computeroutput">BZ2_bzCompress</code>.  In the limit,
+it is acceptable to supply and remove data one byte at a time,
+although this would be terribly inefficient.  You should always
+ensure that at least one byte of output space is available at
+each call.</p>
+<p>A second purpose of
+<code class="computeroutput">BZ2_bzCompress</code> is to request a
+change of mode of the compressed stream.</p>
+<p>Conceptually, a compressed stream can be in one of four
+states: IDLE, RUNNING, FLUSHING and FINISHING.  Before
+initialisation
+(<code class="computeroutput">BZ2_bzCompressInit</code>) and after
+termination (<code class="computeroutput">BZ2_bzCompressEnd</code>),
+a stream is regarded as IDLE.</p>
+<p>Upon initialisation
+(<code class="computeroutput">BZ2_bzCompressInit</code>), the stream
+is placed in the RUNNING state.  Subsequent calls to
+<code class="computeroutput">BZ2_bzCompress</code> should pass
+<code class="computeroutput">BZ_RUN</code> as the requested action;
+other actions are illegal and will result in
+<code class="computeroutput">BZ_SEQUENCE_ERROR</code>.</p>
+<p>At some point, the calling program will have provided all
+the input data it wants to.  It will then want to finish up -- in
+effect, asking the library to process any data it might have
+buffered internally.  In this state,
+<code class="computeroutput">BZ2_bzCompress</code> will no longer
+attempt to read data from
+<code class="computeroutput">next_in</code>, but it will want to
+write data to <code class="computeroutput">next_out</code>.  Because
+the output buffer supplied by the user can be arbitrarily small,
+the finishing-up operation cannot necessarily be done with a
+single call of
+<code class="computeroutput">BZ2_bzCompress</code>.</p>
+<p>Instead, the calling program passes
+<code class="computeroutput">BZ_FINISH</code> as an action to
+<code class="computeroutput">BZ2_bzCompress</code>.  This changes
+the stream's state to FINISHING.  Any remaining input (ie,
+<code class="computeroutput">next_in[0 .. avail_in-1]</code>) is
+compressed and transferred to the output buffer.  To do this,
+<code class="computeroutput">BZ2_bzCompress</code> must be called
+repeatedly until all the output has been consumed.  At that
+point, <code class="computeroutput">BZ2_bzCompress</code> returns
+<code class="computeroutput">BZ_STREAM_END</code>, and the stream's
+state is set back to IDLE.
+<code class="computeroutput">BZ2_bzCompressEnd</code> should then be
+called.</p>
+<p>Just to make sure the calling program does not cheat, the
+library makes a note of <code class="computeroutput">avail_in</code>
+at the time of the first call to
+<code class="computeroutput">BZ2_bzCompress</code> which has
+<code class="computeroutput">BZ_FINISH</code> as an action (ie, at
+the time the program has announced its intention to not supply
+any more input).  By comparing this value with that of
+<code class="computeroutput">avail_in</code> over subsequent calls
+to <code class="computeroutput">BZ2_bzCompress</code>, the library
+can detect any attempts to slip in more data to compress.  Any
+calls for which this is detected will return
+<code class="computeroutput">BZ_SEQUENCE_ERROR</code>.  This
+indicates a programming mistake which should be corrected.</p>
+<p>Instead of asking to finish, the calling program may ask
+<code class="computeroutput">BZ2_bzCompress</code> to take all the
+remaining input, compress it and terminate the current
+(Burrows-Wheeler) compression block.  This could be useful for
+error control purposes.  The mechanism is analogous to that for
+finishing: call <code class="computeroutput">BZ2_bzCompress</code>
+with an action of <code class="computeroutput">BZ_FLUSH</code>,
+remove output data, and persist with the
+<code class="computeroutput">BZ_FLUSH</code> action until the value
+<code class="computeroutput">BZ_RUN</code> is returned.  As with
+finishing, <code class="computeroutput">BZ2_bzCompress</code>
+detects any attempt to provide more input data once the flush has
+begun.</p>
+<p>Once the flush is complete, the stream returns to the
+normal RUNNING state.</p>
+<p>This all sounds pretty complex, but isn't really.  Here's a
+table which shows which actions are allowable in each state, what
+action will be taken, what the next state is, and what the
+non-error return values are.  Note that you can't explicitly ask
+what state the stream is in, but nor do you need to -- it can be
+inferred from the values returned by
+<code class="computeroutput">BZ2_bzCompress</code>.</p>
+<pre class="programlisting">IDLE/any
+  Illegal.  IDLE state only exists after BZ2_bzCompressEnd or
+  before BZ2_bzCompressInit.
+  Return value = BZ_SEQUENCE_ERROR
+
+RUNNING/BZ_RUN
+  Compress from next_in to next_out as much as possible.
+  Next state = RUNNING
+  Return value = BZ_RUN_OK
+
+RUNNING/BZ_FLUSH
+  Remember current value of next_in. Compress from next_in
+  to next_out as much as possible, but do not accept any more input.
+  Next state = FLUSHING
+  Return value = BZ_FLUSH_OK
+
+RUNNING/BZ_FINISH
+  Remember current value of next_in. Compress from next_in
+  to next_out as much as possible, but do not accept any more input.
+  Next state = FINISHING
+  Return value = BZ_FINISH_OK
+
+FLUSHING/BZ_FLUSH
+  Compress from next_in to next_out as much as possible, 
+  but do not accept any more input.
+  If all the existing input has been used up and all compressed
+  output has been removed
+    Next state = RUNNING; Return value = BZ_RUN_OK
+  else
+    Next state = FLUSHING; Return value = BZ_FLUSH_OK
+
+FLUSHING/other     
+  Illegal.
+  Return value = BZ_SEQUENCE_ERROR
+
+FINISHING/BZ_FINISH
+  Compress from next_in to next_out as much as possible,
+  but to not accept any more input.  
+  If all the existing input has been used up and all compressed
+  output has been removed
+    Next state = IDLE; Return value = BZ_STREAM_END
+  else
+    Next state = FINISHING; Return value = BZ_FINISH_OK
+
+FINISHING/other
+  Illegal.
+  Return value = BZ_SEQUENCE_ERROR</pre>
+<p>That still looks complicated?  Well, fair enough.  The
+usual sequence of calls for compressing a load of data is:</p>
+<div class="orderedlist"><ol class="orderedlist" type="1">
+<li class="listitem"><p>Get started with
+  <code class="computeroutput">BZ2_bzCompressInit</code>.</p></li>
+<li class="listitem"><p>Shovel data in and shlurp out its compressed form
+  using zero or more calls of
+  <code class="computeroutput">BZ2_bzCompress</code> with action =
+  <code class="computeroutput">BZ_RUN</code>.</p></li>
+<li class="listitem"><p>Finish up. Repeatedly call
+  <code class="computeroutput">BZ2_bzCompress</code> with action =
+  <code class="computeroutput">BZ_FINISH</code>, copying out the
+  compressed output, until
+  <code class="computeroutput">BZ_STREAM_END</code> is
+  returned.</p></li>
+<li class="listitem"><p>Close up and go home.  Call
+  <code class="computeroutput">BZ2_bzCompressEnd</code>.</p></li>
+</ol></div>
+<p>If the data you want to compress fits into your input
+buffer all at once, you can skip the calls of
+<code class="computeroutput">BZ2_bzCompress ( ..., BZ_RUN )</code>
+and just do the <code class="computeroutput">BZ2_bzCompress ( ..., BZ_FINISH
+)</code> calls.</p>
+<p>All required memory is allocated by
+<code class="computeroutput">BZ2_bzCompressInit</code>.  The
+compression library can accept any data at all (obviously).  So
+you shouldn't get any error return values from the
+<code class="computeroutput">BZ2_bzCompress</code> calls.  If you
+do, they will be
+<code class="computeroutput">BZ_SEQUENCE_ERROR</code>, and indicate
+a bug in your programming.</p>
+<p>Trivial other possible return values:</p>
+<pre class="programlisting">BZ_PARAM_ERROR
+  if strm is NULL, or strm->s is NULL</pre>
+</div>
+<div class="sect2" title="3.3.3.�BZ2_bzCompressEnd">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzCompress-end"></a>3.3.3.�BZ2_bzCompressEnd</h3></div></div></div>
+<pre class="programlisting">int BZ2_bzCompressEnd ( bz_stream *strm );</pre>
+<p>Releases all memory associated with a compression
+stream.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_PARAM_ERROR  if strm is NULL or strm->s is NULL
+BZ_OK           otherwise</pre>
+</div>
+<div class="sect2" title="3.3.4.�BZ2_bzDecompressInit">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzDecompress-init"></a>3.3.4.�BZ2_bzDecompressInit</h3></div></div></div>
+<pre class="programlisting">int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );</pre>
+<p>Prepares for decompression.  As with
+<code class="computeroutput">BZ2_bzCompressInit</code>, a
+<code class="computeroutput">bz_stream</code> record should be
+allocated and initialised before the call.  Fields
+<code class="computeroutput">bzalloc</code>,
+<code class="computeroutput">bzfree</code> and
+<code class="computeroutput">opaque</code> should be set if a custom
+memory allocator is required, or made
+<code class="computeroutput">NULL</code> for the normal
+<code class="computeroutput">malloc</code> /
+<code class="computeroutput">free</code> routines.  Upon return, the
+internal state will have been initialised, and
+<code class="computeroutput">total_in</code> and
+<code class="computeroutput">total_out</code> will be zero.</p>
+<p>For the meaning of parameter
+<code class="computeroutput">verbosity</code>, see
+<code class="computeroutput">BZ2_bzCompressInit</code>.</p>
+<p>If <code class="computeroutput">small</code> is nonzero, the
+library will use an alternative decompression algorithm which
+uses less memory but at the cost of decompressing more slowly
+(roughly speaking, half the speed, but the maximum memory
+requirement drops to around 2300k).  See <a class="xref" href="#using" title="2.�How to use bzip2">How to use bzip2</a>
+for more information on memory management.</p>
+<p>Note that the amount of memory needed to decompress a
+stream cannot be determined until the stream's header has been
+read, so even if
+<code class="computeroutput">BZ2_bzDecompressInit</code> succeeds, a
+subsequent <code class="computeroutput">BZ2_bzDecompress</code>
+could fail with
+<code class="computeroutput">BZ_MEM_ERROR</code>.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if ( small != 0 && small != 1 )
+  or (verbosity <; 0 || verbosity > 4)
+BZ_MEM_ERROR
+  if insufficient memory is available</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">BZ2_bzDecompress
+  if BZ_OK was returned
+  no specific action required in case of error</pre>
+</div>
+<div class="sect2" title="3.3.5.�BZ2_bzDecompress">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzDecompress"></a>3.3.5.�BZ2_bzDecompress</h3></div></div></div>
+<pre class="programlisting">int BZ2_bzDecompress ( bz_stream *strm );</pre>
+<p>Provides more input and/out output buffer space for the
+library.  The caller maintains input and output buffers, and uses
+<code class="computeroutput">BZ2_bzDecompress</code> to transfer
+data between them.</p>
+<p>Before each call to
+<code class="computeroutput">BZ2_bzDecompress</code>,
+<code class="computeroutput">next_in</code> should point at the
+compressed data, and <code class="computeroutput">avail_in</code>
+should indicate how many bytes the library may read.
+<code class="computeroutput">BZ2_bzDecompress</code> updates
+<code class="computeroutput">next_in</code>,
+<code class="computeroutput">avail_in</code> and
+<code class="computeroutput">total_in</code> to reflect the number
+of bytes it has read.</p>
+<p>Similarly, <code class="computeroutput">next_out</code> should
+point to a buffer in which the uncompressed output is to be
+placed, with <code class="computeroutput">avail_out</code>
+indicating how much output space is available.
+<code class="computeroutput">BZ2_bzCompress</code> updates
+<code class="computeroutput">next_out</code>,
+<code class="computeroutput">avail_out</code> and
+<code class="computeroutput">total_out</code> to reflect the number
+of bytes output.</p>
+<p>You may provide and remove as little or as much data as you
+like on each call of
+<code class="computeroutput">BZ2_bzDecompress</code>.  In the limit,
+it is acceptable to supply and remove data one byte at a time,
+although this would be terribly inefficient.  You should always
+ensure that at least one byte of output space is available at
+each call.</p>
+<p>Use of <code class="computeroutput">BZ2_bzDecompress</code> is
+simpler than
+<code class="computeroutput">BZ2_bzCompress</code>.</p>
+<p>You should provide input and remove output as described
+above, and repeatedly call
+<code class="computeroutput">BZ2_bzDecompress</code> until
+<code class="computeroutput">BZ_STREAM_END</code> is returned.
+Appearance of <code class="computeroutput">BZ_STREAM_END</code>
+denotes that <code class="computeroutput">BZ2_bzDecompress</code>
+has detected the logical end of the compressed stream.
+<code class="computeroutput">BZ2_bzDecompress</code> will not
+produce <code class="computeroutput">BZ_STREAM_END</code> until all
+output data has been placed into the output buffer, so once
+<code class="computeroutput">BZ_STREAM_END</code> appears, you are
+guaranteed to have available all the decompressed output, and
+<code class="computeroutput">BZ2_bzDecompressEnd</code> can safely
+be called.</p>
+<p>If case of an error return value, you should call
+<code class="computeroutput">BZ2_bzDecompressEnd</code> to clean up
+and release memory.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_PARAM_ERROR
+  if strm is NULL or strm->s is NULL
+  or strm->avail_out < 1
+BZ_DATA_ERROR
+  if a data integrity error is detected in the compressed stream
+BZ_DATA_ERROR_MAGIC
+  if the compressed stream doesn't begin with the right magic bytes
+BZ_MEM_ERROR
+  if there wasn't enough memory available
+BZ_STREAM_END
+  if the logical end of the data stream was detected and all
+  output in has been consumed, eg s-->avail_out > 0
+BZ_OK
+  otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">BZ2_bzDecompress
+  if BZ_OK was returned
+BZ2_bzDecompressEnd
+  otherwise</pre>
+</div>
+<div class="sect2" title="3.3.6.�BZ2_bzDecompressEnd">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzDecompress-end"></a>3.3.6.�BZ2_bzDecompressEnd</h3></div></div></div>
+<pre class="programlisting">int BZ2_bzDecompressEnd ( bz_stream *strm );</pre>
+<p>Releases all memory associated with a decompression
+stream.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_PARAM_ERROR
+  if strm is NULL or strm->s is NULL
+BZ_OK
+  otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">  None.</pre>
+</div>
+</div>
+<div class="sect1" title="3.4.�High-level interface">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="hl-interface"></a>3.4.�High-level interface</h2></div></div></div>
+<p>This interface provides functions for reading and writing
+<code class="computeroutput">bzip2</code> format files.  First, some
+general points.</p>
+<div class="itemizedlist"><ul class="itemizedlist" type="bullet">
+<li class="listitem" style="list-style-type: disc"><p>All of the functions take an
+  <code class="computeroutput">int*</code> first argument,
+  <code class="computeroutput">bzerror</code>.  After each call,
+  <code class="computeroutput">bzerror</code> should be consulted
+  first to determine the outcome of the call.  If
+  <code class="computeroutput">bzerror</code> is
+  <code class="computeroutput">BZ_OK</code>, the call completed
+  successfully, and only then should the return value of the
+  function (if any) be consulted.  If
+  <code class="computeroutput">bzerror</code> is
+  <code class="computeroutput">BZ_IO_ERROR</code>, there was an
+  error reading/writing the underlying compressed file, and you
+  should then consult <code class="computeroutput">errno</code> /
+  <code class="computeroutput">perror</code> to determine the cause
+  of the difficulty.  <code class="computeroutput">bzerror</code>
+  may also be set to various other values; precise details are
+  given on a per-function basis below.</p></li>
+<li class="listitem" style="list-style-type: disc"><p>If <code class="computeroutput">bzerror</code> indicates
+  an error (ie, anything except
+  <code class="computeroutput">BZ_OK</code> and
+  <code class="computeroutput">BZ_STREAM_END</code>), you should
+  immediately call
+  <code class="computeroutput">BZ2_bzReadClose</code> (or
+  <code class="computeroutput">BZ2_bzWriteClose</code>, depending on
+  whether you are attempting to read or to write) to free up all
+  resources associated with the stream.  Once an error has been
+  indicated, behaviour of all calls except
+  <code class="computeroutput">BZ2_bzReadClose</code>
+  (<code class="computeroutput">BZ2_bzWriteClose</code>) is
+  undefined.  The implication is that (1)
+  <code class="computeroutput">bzerror</code> should be checked
+  after each call, and (2) if
+  <code class="computeroutput">bzerror</code> indicates an error,
+  <code class="computeroutput">BZ2_bzReadClose</code>
+  (<code class="computeroutput">BZ2_bzWriteClose</code>) should then
+  be called to clean up.</p></li>
+<li class="listitem" style="list-style-type: disc"><p>The <code class="computeroutput">FILE*</code> arguments
+  passed to <code class="computeroutput">BZ2_bzReadOpen</code> /
+  <code class="computeroutput">BZ2_bzWriteOpen</code> should be set
+  to binary mode.  Most Unix systems will do this by default, but
+  other platforms, including Windows and Mac, will not.  If you
+  omit this, you may encounter problems when moving code to new
+  platforms.</p></li>
+<li class="listitem" style="list-style-type: disc"><p>Memory allocation requests are handled by
+  <code class="computeroutput">malloc</code> /
+  <code class="computeroutput">free</code>.  At present there is no
+  facility for user-defined memory allocators in the file I/O
+  functions (could easily be added, though).</p></li>
+</ul></div>
+<div class="sect2" title="3.4.1.�BZ2_bzReadOpen">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzreadopen"></a>3.4.1.�BZ2_bzReadOpen</h3></div></div></div>
+<pre class="programlisting">typedef void BZFILE;
+
+BZFILE *BZ2_bzReadOpen( int *bzerror, FILE *f, 
+                        int verbosity, int small,
+                        void *unused, int nUnused );</pre>
+<p>Prepare to read compressed data from file handle
+<code class="computeroutput">f</code>.
+<code class="computeroutput">f</code> should refer to a file which
+has been opened for reading, and for which the error indicator
+(<code class="computeroutput">ferror(f)</code>)is not set.  If
+<code class="computeroutput">small</code> is 1, the library will try
+to decompress using less memory, at the expense of speed.</p>
+<p>For reasons explained below,
+<code class="computeroutput">BZ2_bzRead</code> will decompress the
+<code class="computeroutput">nUnused</code> bytes starting at
+<code class="computeroutput">unused</code>, before starting to read
+from the file <code class="computeroutput">f</code>.  At most
+<code class="computeroutput">BZ_MAX_UNUSED</code> bytes may be
+supplied like this.  If this facility is not required, you should
+pass <code class="computeroutput">NULL</code> and
+<code class="computeroutput">0</code> for
+<code class="computeroutput">unused</code> and
+n<code class="computeroutput">Unused</code> respectively.</p>
+<p>For the meaning of parameters
+<code class="computeroutput">small</code> and
+<code class="computeroutput">verbosity</code>, see
+<code class="computeroutput">BZ2_bzDecompressInit</code>.</p>
+<p>The amount of memory needed to decompress a file cannot be
+determined until the file's header has been read.  So it is
+possible that <code class="computeroutput">BZ2_bzReadOpen</code>
+returns <code class="computeroutput">BZ_OK</code> but a subsequent
+call of <code class="computeroutput">BZ2_bzRead</code> will return
+<code class="computeroutput">BZ_MEM_ERROR</code>.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if f is NULL
+  or small is neither 0 nor 1
+  or ( unused == NULL && nUnused != 0 )
+  or ( unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED) )
+BZ_IO_ERROR
+  if ferror(f) is nonzero
+BZ_MEM_ERROR
+  if insufficient memory is available
+BZ_OK
+  otherwise.</pre>
+<p>Possible return values:</p>
+<pre class="programlisting">Pointer to an abstract BZFILE
+  if bzerror is BZ_OK
+NULL
+  otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">BZ2_bzRead
+  if bzerror is BZ_OK
+BZ2_bzClose
+  otherwise</pre>
+</div>
+<div class="sect2" title="3.4.2.�BZ2_bzRead">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzread"></a>3.4.2.�BZ2_bzRead</h3></div></div></div>
+<pre class="programlisting">int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );</pre>
+<p>Reads up to <code class="computeroutput">len</code>
+(uncompressed) bytes from the compressed file
+<code class="computeroutput">b</code> into the buffer
+<code class="computeroutput">buf</code>.  If the read was
+successful, <code class="computeroutput">bzerror</code> is set to
+<code class="computeroutput">BZ_OK</code> and the number of bytes
+read is returned.  If the logical end-of-stream was detected,
+<code class="computeroutput">bzerror</code> will be set to
+<code class="computeroutput">BZ_STREAM_END</code>, and the number of
+bytes read is returned.  All other
+<code class="computeroutput">bzerror</code> values denote an
+error.</p>
+<p><code class="computeroutput">BZ2_bzRead</code> will supply
+<code class="computeroutput">len</code> bytes, unless the logical
+stream end is detected or an error occurs.  Because of this, it
+is possible to detect the stream end by observing when the number
+of bytes returned is less than the number requested.
+Nevertheless, this is regarded as inadvisable; you should instead
+check <code class="computeroutput">bzerror</code> after every call
+and watch out for
+<code class="computeroutput">BZ_STREAM_END</code>.</p>
+<p>Internally, <code class="computeroutput">BZ2_bzRead</code>
+copies data from the compressed file in chunks of size
+<code class="computeroutput">BZ_MAX_UNUSED</code> bytes before
+decompressing it.  If the file contains more bytes than strictly
+needed to reach the logical end-of-stream,
+<code class="computeroutput">BZ2_bzRead</code> will almost certainly
+read some of the trailing data before signalling
+<code class="computeroutput">BZ_SEQUENCE_END</code>.  To collect the
+read but unused data once
+<code class="computeroutput">BZ_SEQUENCE_END</code> has appeared,
+call <code class="computeroutput">BZ2_bzReadGetUnused</code>
+immediately before
+<code class="computeroutput">BZ2_bzReadClose</code>.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_PARAM_ERROR
+  if b is NULL or buf is NULL or len < 0
+BZ_SEQUENCE_ERROR
+  if b was opened with BZ2_bzWriteOpen
+BZ_IO_ERROR
+  if there is an error reading from the compressed file
+BZ_UNEXPECTED_EOF
+  if the compressed file ended before 
+  the logical end-of-stream was detected
+BZ_DATA_ERROR
+  if a data integrity error was detected in the compressed stream
+BZ_DATA_ERROR_MAGIC
+  if the stream does not begin with the requisite header bytes 
+  (ie, is not a bzip2 data file).  This is really 
+  a special case of BZ_DATA_ERROR.
+BZ_MEM_ERROR
+  if insufficient memory was available
+BZ_STREAM_END
+  if the logical end of stream was detected.
+BZ_OK
+  otherwise.</pre>
+<p>Possible return values:</p>
+<pre class="programlisting">number of bytes read
+  if bzerror is BZ_OK or BZ_STREAM_END
+undefined
+  otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">collect data from buf, then BZ2_bzRead or BZ2_bzReadClose
+  if bzerror is BZ_OK
+collect data from buf, then BZ2_bzReadClose or BZ2_bzReadGetUnused
+  if bzerror is BZ_SEQUENCE_END
+BZ2_bzReadClose
+  otherwise</pre>
+</div>
+<div class="sect2" title="3.4.3.�BZ2_bzReadGetUnused">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzreadgetunused"></a>3.4.3.�BZ2_bzReadGetUnused</h3></div></div></div>
+<pre class="programlisting">void BZ2_bzReadGetUnused( int* bzerror, BZFILE *b, 
+                          void** unused, int* nUnused );</pre>
+<p>Returns data which was read from the compressed file but
+was not needed to get to the logical end-of-stream.
+<code class="computeroutput">*unused</code> is set to the address of
+the data, and <code class="computeroutput">*nUnused</code> to the
+number of bytes.  <code class="computeroutput">*nUnused</code> will
+be set to a value between <code class="computeroutput">0</code> and
+<code class="computeroutput">BZ_MAX_UNUSED</code> inclusive.</p>
+<p>This function may only be called once
+<code class="computeroutput">BZ2_bzRead</code> has signalled
+<code class="computeroutput">BZ_STREAM_END</code> but before
+<code class="computeroutput">BZ2_bzReadClose</code>.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_PARAM_ERROR
+  if b is NULL
+  or unused is NULL or nUnused is NULL
+BZ_SEQUENCE_ERROR
+  if BZ_STREAM_END has not been signalled
+  or if b was opened with BZ2_bzWriteOpen
+BZ_OK
+  otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">BZ2_bzReadClose</pre>
+</div>
+<div class="sect2" title="3.4.4.�BZ2_bzReadClose">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzreadclose"></a>3.4.4.�BZ2_bzReadClose</h3></div></div></div>
+<pre class="programlisting">void BZ2_bzReadClose ( int *bzerror, BZFILE *b );</pre>
+<p>Releases all memory pertaining to the compressed file
+<code class="computeroutput">b</code>.
+<code class="computeroutput">BZ2_bzReadClose</code> does not call
+<code class="computeroutput">fclose</code> on the underlying file
+handle, so you should do that yourself if appropriate.
+<code class="computeroutput">BZ2_bzReadClose</code> should be called
+to clean up after all error situations.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_SEQUENCE_ERROR
+  if b was opened with BZ2_bzOpenWrite
+BZ_OK
+  otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">none</pre>
+</div>
+<div class="sect2" title="3.4.5.�BZ2_bzWriteOpen">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzwriteopen"></a>3.4.5.�BZ2_bzWriteOpen</h3></div></div></div>
+<pre class="programlisting">BZFILE *BZ2_bzWriteOpen( int *bzerror, FILE *f, 
+                         int blockSize100k, int verbosity,
+                         int workFactor );</pre>
+<p>Prepare to write compressed data to file handle
+<code class="computeroutput">f</code>.
+<code class="computeroutput">f</code> should refer to a file which
+has been opened for writing, and for which the error indicator
+(<code class="computeroutput">ferror(f)</code>)is not set.</p>
+<p>For the meaning of parameters
+<code class="computeroutput">blockSize100k</code>,
+<code class="computeroutput">verbosity</code> and
+<code class="computeroutput">workFactor</code>, see
+<code class="computeroutput">BZ2_bzCompressInit</code>.</p>
+<p>All required memory is allocated at this stage, so if the
+call completes successfully,
+<code class="computeroutput">BZ_MEM_ERROR</code> cannot be signalled
+by a subsequent call to
+<code class="computeroutput">BZ2_bzWrite</code>.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if f is NULL
+  or blockSize100k < 1 or blockSize100k > 9
+BZ_IO_ERROR
+  if ferror(f) is nonzero
+BZ_MEM_ERROR
+  if insufficient memory is available
+BZ_OK
+  otherwise</pre>
+<p>Possible return values:</p>
+<pre class="programlisting">Pointer to an abstract BZFILE
+  if bzerror is BZ_OK
+NULL
+  otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">BZ2_bzWrite
+  if bzerror is BZ_OK
+  (you could go directly to BZ2_bzWriteClose, but this would be pretty pointless)
+BZ2_bzWriteClose
+  otherwise</pre>
+</div>
+<div class="sect2" title="3.4.6.�BZ2_bzWrite">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzwrite"></a>3.4.6.�BZ2_bzWrite</h3></div></div></div>
+<pre class="programlisting">void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );</pre>
+<p>Absorbs <code class="computeroutput">len</code> bytes from the
+buffer <code class="computeroutput">buf</code>, eventually to be
+compressed and written to the file.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_PARAM_ERROR
+  if b is NULL or buf is NULL or len < 0
+BZ_SEQUENCE_ERROR
+  if b was opened with BZ2_bzReadOpen
+BZ_IO_ERROR
+  if there is an error writing the compressed file.
+BZ_OK
+  otherwise</pre>
+</div>
+<div class="sect2" title="3.4.7.�BZ2_bzWriteClose">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzwriteclose"></a>3.4.7.�BZ2_bzWriteClose</h3></div></div></div>
+<pre class="programlisting">void BZ2_bzWriteClose( int *bzerror, BZFILE* f,
+                       int abandon,
+                       unsigned int* nbytes_in,
+                       unsigned int* nbytes_out );
+
+void BZ2_bzWriteClose64( int *bzerror, BZFILE* f,
+                         int abandon,
+                         unsigned int* nbytes_in_lo32,
+                         unsigned int* nbytes_in_hi32,
+                         unsigned int* nbytes_out_lo32,
+                         unsigned int* nbytes_out_hi32 );</pre>
+<p>Compresses and flushes to the compressed file all data so
+far supplied by <code class="computeroutput">BZ2_bzWrite</code>.
+The logical end-of-stream markers are also written, so subsequent
+calls to <code class="computeroutput">BZ2_bzWrite</code> are
+illegal.  All memory associated with the compressed file
+<code class="computeroutput">b</code> is released.
+<code class="computeroutput">fflush</code> is called on the
+compressed file, but it is not
+<code class="computeroutput">fclose</code>'d.</p>
+<p>If <code class="computeroutput">BZ2_bzWriteClose</code> is
+called to clean up after an error, the only action is to release
+the memory.  The library records the error codes issued by
+previous calls, so this situation will be detected automatically.
+There is no attempt to complete the compression operation, nor to
+<code class="computeroutput">fflush</code> the compressed file.  You
+can force this behaviour to happen even in the case of no error,
+by passing a nonzero value to
+<code class="computeroutput">abandon</code>.</p>
+<p>If <code class="computeroutput">nbytes_in</code> is non-null,
+<code class="computeroutput">*nbytes_in</code> will be set to be the
+total volume of uncompressed data handled.  Similarly,
+<code class="computeroutput">nbytes_out</code> will be set to the
+total volume of compressed data written.  For compatibility with
+older versions of the library,
+<code class="computeroutput">BZ2_bzWriteClose</code> only yields the
+lower 32 bits of these counts.  Use
+<code class="computeroutput">BZ2_bzWriteClose64</code> if you want
+the full 64 bit counts.  These two functions are otherwise
+absolutely identical.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_SEQUENCE_ERROR
+  if b was opened with BZ2_bzReadOpen
+BZ_IO_ERROR
+  if there is an error writing the compressed file
+BZ_OK
+  otherwise</pre>
+</div>
+<div class="sect2" title="3.4.8.�Handling embedded compressed data streams">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="embed"></a>3.4.8.�Handling embedded compressed data streams</h3></div></div></div>
+<p>The high-level library facilitates use of
+<code class="computeroutput">bzip2</code> data streams which form
+some part of a surrounding, larger data stream.</p>
+<div class="itemizedlist"><ul class="itemizedlist" type="bullet">
+<li class="listitem" style="list-style-type: disc"><p>For writing, the library takes an open file handle,
+  writes compressed data to it,
+  <code class="computeroutput">fflush</code>es it but does not
+  <code class="computeroutput">fclose</code> it.  The calling
+  application can write its own data before and after the
+  compressed data stream, using that same file handle.</p></li>
+<li class="listitem" style="list-style-type: disc"><p>Reading is more complex, and the facilities are not as
+  general as they could be since generality is hard to reconcile
+  with efficiency.  <code class="computeroutput">BZ2_bzRead</code>
+  reads from the compressed file in blocks of size
+  <code class="computeroutput">BZ_MAX_UNUSED</code> bytes, and in
+  doing so probably will overshoot the logical end of compressed
+  stream.  To recover this data once decompression has ended,
+  call <code class="computeroutput">BZ2_bzReadGetUnused</code> after
+  the last call of <code class="computeroutput">BZ2_bzRead</code>
+  (the one returning
+  <code class="computeroutput">BZ_STREAM_END</code>) but before
+  calling
+  <code class="computeroutput">BZ2_bzReadClose</code>.</p></li>
+</ul></div>
+<p>This mechanism makes it easy to decompress multiple
+<code class="computeroutput">bzip2</code> streams placed end-to-end.
+As the end of one stream, when
+<code class="computeroutput">BZ2_bzRead</code> returns
+<code class="computeroutput">BZ_STREAM_END</code>, call
+<code class="computeroutput">BZ2_bzReadGetUnused</code> to collect
+the unused data (copy it into your own buffer somewhere).  That
+data forms the start of the next compressed stream.  To start
+uncompressing that next stream, call
+<code class="computeroutput">BZ2_bzReadOpen</code> again, feeding in
+the unused data via the <code class="computeroutput">unused</code> /
+<code class="computeroutput">nUnused</code> parameters.  Keep doing
+this until <code class="computeroutput">BZ_STREAM_END</code> return
+coincides with the physical end of file
+(<code class="computeroutput">feof(f)</code>).  In this situation
+<code class="computeroutput">BZ2_bzReadGetUnused</code> will of
+course return no data.</p>
+<p>This should give some feel for how the high-level interface
+can be used.  If you require extra flexibility, you'll have to
+bite the bullet and get to grips with the low-level
+interface.</p>
+</div>
+<div class="sect2" title="3.4.9.�Standard file-reading/writing code">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="std-rdwr"></a>3.4.9.�Standard file-reading/writing code</h3></div></div></div>
+<p>Here's how you'd write data to a compressed file:</p>
+<pre class="programlisting">FILE*   f;
+BZFILE* b;
+int     nBuf;
+char    buf[ /* whatever size you like */ ];
+int     bzerror;
+int     nWritten;
+
+f = fopen ( "myfile.bz2", "w" );
+if ( !f ) {
+ /* handle error */
+}
+b = BZ2_bzWriteOpen( &bzerror, f, 9 );
+if (bzerror != BZ_OK) {
+ BZ2_bzWriteClose ( b );
+ /* handle error */
+}
+
+while ( /* condition */ ) {
+ /* get data to write into buf, and set nBuf appropriately */
+ nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf );
+ if (bzerror == BZ_IO_ERROR) { 
+   BZ2_bzWriteClose ( &bzerror, b );
+   /* handle error */
+ }
+}
+
+BZ2_bzWriteClose( &bzerror, b );
+if (bzerror == BZ_IO_ERROR) {
+ /* handle error */
+}</pre>
+<p>And to read from a compressed file:</p>
+<pre class="programlisting">FILE*   f;
+BZFILE* b;
+int     nBuf;
+char    buf[ /* whatever size you like */ ];
+int     bzerror;
+int     nWritten;
+
+f = fopen ( "myfile.bz2", "r" );
+if ( !f ) {
+  /* handle error */
+}
+b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 );
+if ( bzerror != BZ_OK ) {
+  BZ2_bzReadClose ( &bzerror, b );
+  /* handle error */
+}
+
+bzerror = BZ_OK;
+while ( bzerror == BZ_OK && /* arbitrary other conditions */) {
+  nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ );
+  if ( bzerror == BZ_OK ) {
+    /* do something with buf[0 .. nBuf-1] */
+  }
+}
+if ( bzerror != BZ_STREAM_END ) {
+   BZ2_bzReadClose ( &bzerror, b );
+   /* handle error */
+} else {
+   BZ2_bzReadClose ( &bzerror, b );
+}</pre>
+</div>
+</div>
+<div class="sect1" title="3.5.�Utility functions">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="util-fns"></a>3.5.�Utility functions</h2></div></div></div>
+<div class="sect2" title="3.5.1.�BZ2_bzBuffToBuffCompress">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzbufftobuffcompress"></a>3.5.1.�BZ2_bzBuffToBuffCompress</h3></div></div></div>
+<pre class="programlisting">int BZ2_bzBuffToBuffCompress( char*         dest,
+                              unsigned int* destLen,
+                              char*         source,
+                              unsigned int  sourceLen,
+                              int           blockSize100k,
+                              int           verbosity,
+                              int           workFactor );</pre>
+<p>Attempts to compress the data in <code class="computeroutput">source[0
+.. sourceLen-1]</code> into the destination buffer,
+<code class="computeroutput">dest[0 .. *destLen-1]</code>.  If the
+destination buffer is big enough,
+<code class="computeroutput">*destLen</code> is set to the size of
+the compressed data, and <code class="computeroutput">BZ_OK</code>
+is returned.  If the compressed data won't fit,
+<code class="computeroutput">*destLen</code> is unchanged, and
+<code class="computeroutput">BZ_OUTBUFF_FULL</code> is
+returned.</p>
+<p>Compression in this manner is a one-shot event, done with a
+single call to this function.  The resulting compressed data is a
+complete <code class="computeroutput">bzip2</code> format data
+stream.  There is no mechanism for making additional calls to
+provide extra input data.  If you want that kind of mechanism,
+use the low-level interface.</p>
+<p>For the meaning of parameters
+<code class="computeroutput">blockSize100k</code>,
+<code class="computeroutput">verbosity</code> and
+<code class="computeroutput">workFactor</code>, see
+<code class="computeroutput">BZ2_bzCompressInit</code>.</p>
+<p>To guarantee that the compressed data will fit in its
+buffer, allocate an output buffer of size 1% larger than the
+uncompressed data, plus six hundred extra bytes.</p>
+<p><code class="computeroutput">BZ2_bzBuffToBuffDecompress</code>
+will not write data at or beyond
+<code class="computeroutput">dest[*destLen]</code>, even in case of
+buffer overflow.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if dest is NULL or destLen is NULL
+  or blockSize100k < 1 or blockSize100k > 9
+  or verbosity < 0 or verbosity > 4
+  or workFactor < 0 or workFactor > 250
+BZ_MEM_ERROR
+  if insufficient memory is available 
+BZ_OUTBUFF_FULL
+  if the size of the compressed data exceeds *destLen
+BZ_OK
+  otherwise</pre>
+</div>
+<div class="sect2" title="3.5.2.�BZ2_bzBuffToBuffDecompress">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzbufftobuffdecompress"></a>3.5.2.�BZ2_bzBuffToBuffDecompress</h3></div></div></div>
+<pre class="programlisting">int BZ2_bzBuffToBuffDecompress( char*         dest,
+                                unsigned int* destLen,
+                                char*         source,
+                                unsigned int  sourceLen,
+                                int           small,
+                                int           verbosity );</pre>
+<p>Attempts to decompress the data in <code class="computeroutput">source[0
+.. sourceLen-1]</code> into the destination buffer,
+<code class="computeroutput">dest[0 .. *destLen-1]</code>.  If the
+destination buffer is big enough,
+<code class="computeroutput">*destLen</code> is set to the size of
+the uncompressed data, and <code class="computeroutput">BZ_OK</code>
+is returned.  If the compressed data won't fit,
+<code class="computeroutput">*destLen</code> is unchanged, and
+<code class="computeroutput">BZ_OUTBUFF_FULL</code> is
+returned.</p>
+<p><code class="computeroutput">source</code> is assumed to hold
+a complete <code class="computeroutput">bzip2</code> format data
+stream.
+<code class="computeroutput">BZ2_bzBuffToBuffDecompress</code> tries
+to decompress the entirety of the stream into the output
+buffer.</p>
+<p>For the meaning of parameters
+<code class="computeroutput">small</code> and
+<code class="computeroutput">verbosity</code>, see
+<code class="computeroutput">BZ2_bzDecompressInit</code>.</p>
+<p>Because the compression ratio of the compressed data cannot
+be known in advance, there is no easy way to guarantee that the
+output buffer will be big enough.  You may of course make
+arrangements in your code to record the size of the uncompressed
+data, but such a mechanism is beyond the scope of this
+library.</p>
+<p><code class="computeroutput">BZ2_bzBuffToBuffDecompress</code>
+will not write data at or beyond
+<code class="computeroutput">dest[*destLen]</code>, even in case of
+buffer overflow.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if dest is NULL or destLen is NULL
+  or small != 0 && small != 1
+  or verbosity < 0 or verbosity > 4
+BZ_MEM_ERROR
+  if insufficient memory is available 
+BZ_OUTBUFF_FULL
+  if the size of the compressed data exceeds *destLen
+BZ_DATA_ERROR
+  if a data integrity error was detected in the compressed data
+BZ_DATA_ERROR_MAGIC
+  if the compressed data doesn't begin with the right magic bytes
+BZ_UNEXPECTED_EOF
+  if the compressed data ends unexpectedly
+BZ_OK
+  otherwise</pre>
+</div>
+</div>
+<div class="sect1" title="3.6.�zlib compatibility functions">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="zlib-compat"></a>3.6.�zlib compatibility functions</h2></div></div></div>
+<p>Yoshioka Tsuneo has contributed some functions to give
+better <code class="computeroutput">zlib</code> compatibility.
+These functions are <code class="computeroutput">BZ2_bzopen</code>,
+<code class="computeroutput">BZ2_bzread</code>,
+<code class="computeroutput">BZ2_bzwrite</code>,
+<code class="computeroutput">BZ2_bzflush</code>,
+<code class="computeroutput">BZ2_bzclose</code>,
+<code class="computeroutput">BZ2_bzerror</code> and
+<code class="computeroutput">BZ2_bzlibVersion</code>.  These
+functions are not (yet) officially part of the library.  If they
+break, you get to keep all the pieces.  Nevertheless, I think
+they work ok.</p>
+<pre class="programlisting">typedef void BZFILE;
+
+const char * BZ2_bzlibVersion ( void );</pre>
+<p>Returns a string indicating the library version.</p>
+<pre class="programlisting">BZFILE * BZ2_bzopen  ( const char *path, const char *mode );
+BZFILE * BZ2_bzdopen ( int        fd,    const char *mode );</pre>
+<p>Opens a <code class="computeroutput">.bz2</code> file for
+reading or writing, using either its name or a pre-existing file
+descriptor.  Analogous to <code class="computeroutput">fopen</code>
+and <code class="computeroutput">fdopen</code>.</p>
+<pre class="programlisting">int BZ2_bzread  ( BZFILE* b, void* buf, int len );
+int BZ2_bzwrite ( BZFILE* b, void* buf, int len );</pre>
+<p>Reads/writes data from/to a previously opened
+<code class="computeroutput">BZFILE</code>.  Analogous to
+<code class="computeroutput">fread</code> and
+<code class="computeroutput">fwrite</code>.</p>
+<pre class="programlisting">int  BZ2_bzflush ( BZFILE* b );
+void BZ2_bzclose ( BZFILE* b );</pre>
+<p>Flushes/closes a <code class="computeroutput">BZFILE</code>.
+<code class="computeroutput">BZ2_bzflush</code> doesn't actually do
+anything.  Analogous to <code class="computeroutput">fflush</code>
+and <code class="computeroutput">fclose</code>.</p>
+<pre class="programlisting">const char * BZ2_bzerror ( BZFILE *b, int *errnum )</pre>
+<p>Returns a string describing the more recent error status of
+<code class="computeroutput">b</code>, and also sets
+<code class="computeroutput">*errnum</code> to its numerical
+value.</p>
+</div>
+<div class="sect1" title="3.7.�Using the library in a stdio-free environment">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="stdio-free"></a>3.7.�Using the library in a stdio-free environment</h2></div></div></div>
+<div class="sect2" title="3.7.1.�Getting rid of stdio">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="stdio-bye"></a>3.7.1.�Getting rid of stdio</h3></div></div></div>
+<p>In a deeply embedded application, you might want to use
+just the memory-to-memory functions.  You can do this
+conveniently by compiling the library with preprocessor symbol
+<code class="computeroutput">BZ_NO_STDIO</code> defined.  Doing this
+gives you a library containing only the following eight
+functions:</p>
+<p><code class="computeroutput">BZ2_bzCompressInit</code>,
+<code class="computeroutput">BZ2_bzCompress</code>,
+<code class="computeroutput">BZ2_bzCompressEnd</code>
+<code class="computeroutput">BZ2_bzDecompressInit</code>,
+<code class="computeroutput">BZ2_bzDecompress</code>,
+<code class="computeroutput">BZ2_bzDecompressEnd</code>
+<code class="computeroutput">BZ2_bzBuffToBuffCompress</code>,
+<code class="computeroutput">BZ2_bzBuffToBuffDecompress</code></p>
+<p>When compiled like this, all functions will ignore
+<code class="computeroutput">verbosity</code> settings.</p>
+</div>
+<div class="sect2" title="3.7.2.�Critical error handling">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="critical-error"></a>3.7.2.�Critical error handling</h3></div></div></div>
+<p><code class="computeroutput">libbzip2</code> contains a number
+of internal assertion checks which should, needless to say, never
+be activated.  Nevertheless, if an assertion should fail,
+behaviour depends on whether or not the library was compiled with
+<code class="computeroutput">BZ_NO_STDIO</code> set.</p>
+<p>For a normal compile, an assertion failure yields the
+message:</p>
+<div class="blockquote"><blockquote class="blockquote">
+<p>bzip2/libbzip2: internal error number N.</p>
+<p>This is a bug in bzip2/libbzip2, 1.0.6 of 6 September 2010.
+Please report it to me at: jseward at bzip.org.  If this happened
+when you were using some program which uses libbzip2 as a
+component, you should also report this bug to the author(s)
+of that program.  Please make an effort to report this bug;
+timely and accurate bug reports eventually lead to higher
+quality software.  Thanks.  Julian Seward, 6 September 2010.
+</p>
+</blockquote></div>
+<p>where <code class="computeroutput">N</code> is some error code
+number.  If <code class="computeroutput">N == 1007</code>, it also
+prints some extra text advising the reader that unreliable memory
+is often associated with internal error 1007. (This is a
+frequently-observed-phenomenon with versions 1.0.0/1.0.1).</p>
+<p><code class="computeroutput">exit(3)</code> is then
+called.</p>
+<p>For a <code class="computeroutput">stdio</code>-free library,
+assertion failures result in a call to a function declared
+as:</p>
+<pre class="programlisting">extern void bz_internal_error ( int errcode );</pre>
+<p>The relevant code is passed as a parameter.  You should
+supply such a function.</p>
+<p>In either case, once an assertion failure has occurred, any
+<code class="computeroutput">bz_stream</code> records involved can
+be regarded as invalid.  You should not attempt to resume normal
+operation with them.</p>
+<p>You may, of course, change critical error handling to suit
+your needs.  As I said above, critical errors indicate bugs in
+the library and should not occur.  All "normal" error situations
+are indicated via error return codes from functions, and can be
+recovered from.</p>
+</div>
+</div>
+<div class="sect1" title="3.8.�Making a Windows DLL">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="win-dll"></a>3.8.�Making a Windows DLL</h2></div></div></div>
+<p>Everything related to Windows has been contributed by
+Yoshioka Tsuneo
+(<code class="computeroutput">tsuneo at rr.iij4u.or.jp</code>), so
+you should send your queries to him (but perhaps Cc: me,
+<code class="computeroutput">jseward at bzip.org</code>).</p>
+<p>My vague understanding of what to do is: using Visual C++
+5.0, open the project file
+<code class="computeroutput">libbz2.dsp</code>, and build.  That's
+all.</p>
+<p>If you can't open the project file for some reason, make a
+new one, naming these files:
+<code class="computeroutput">blocksort.c</code>,
+<code class="computeroutput">bzlib.c</code>,
+<code class="computeroutput">compress.c</code>,
+<code class="computeroutput">crctable.c</code>,
+<code class="computeroutput">decompress.c</code>,
+<code class="computeroutput">huffman.c</code>,
+<code class="computeroutput">randtable.c</code> and
+<code class="computeroutput">libbz2.def</code>.  You will also need
+to name the header files <code class="computeroutput">bzlib.h</code>
+and <code class="computeroutput">bzlib_private.h</code>.</p>
+<p>If you don't use VC++, you may need to define the
+proprocessor symbol
+<code class="computeroutput">_WIN32</code>.</p>
+<p>Finally, <code class="computeroutput">dlltest.c</code> is a
+sample program using the DLL.  It has a project file,
+<code class="computeroutput">dlltest.dsp</code>.</p>
+<p>If you just want a makefile for Visual C, have a look at
+<code class="computeroutput">makefile.msc</code>.</p>
+<p>Be aware that if you compile
+<code class="computeroutput">bzip2</code> itself on Win32, you must
+set <code class="computeroutput">BZ_UNIX</code> to 0 and
+<code class="computeroutput">BZ_LCCWIN32</code> to 1, in the file
+<code class="computeroutput">bzip2.c</code>, before compiling.
+Otherwise the resulting binary won't work correctly.</p>
+<p>I haven't tried any of this stuff myself, but it all looks
+plausible.</p>
+</div>
+</div>
+<div class="chapter" title="4.�Miscellanea">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="misc"></a>4.�Miscellanea</h2></div></div></div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="sect1"><a href="#limits">4.1. Limitations of the compressed file format</a></span></dt>
+<dt><span class="sect1"><a href="#port-issues">4.2. Portability issues</a></span></dt>
+<dt><span class="sect1"><a href="#bugs">4.3. Reporting bugs</a></span></dt>
+<dt><span class="sect1"><a href="#package">4.4. Did you get the right package?</a></span></dt>
+<dt><span class="sect1"><a href="#reading">4.5. Further Reading</a></span></dt>
+</dl>
+</div>
+<p>These are just some random thoughts of mine.  Your mileage
+may vary.</p>
+<div class="sect1" title="4.1.�Limitations of the compressed file format">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="limits"></a>4.1.�Limitations of the compressed file format</h2></div></div></div>
+<p><code class="computeroutput">bzip2-1.0.X</code>,
+<code class="computeroutput">0.9.5</code> and
+<code class="computeroutput">0.9.0</code> use exactly the same file
+format as the original version,
+<code class="computeroutput">bzip2-0.1</code>.  This decision was
+made in the interests of stability.  Creating yet another
+incompatible compressed file format would create further
+confusion and disruption for users.</p>
+<p>Nevertheless, this is not a painless decision.  Development
+work since the release of
+<code class="computeroutput">bzip2-0.1</code> in August 1997 has
+shown complexities in the file format which slow down
+decompression and, in retrospect, are unnecessary.  These
+are:</p>
+<div class="itemizedlist"><ul class="itemizedlist" type="bullet">
+<li class="listitem" style="list-style-type: disc"><p>The run-length encoder, which is the first of the
+   compression transformations, is entirely irrelevant.  The
+   original purpose was to protect the sorting algorithm from the
+   very worst case input: a string of repeated symbols.  But
+   algorithm steps Q6a and Q6b in the original Burrows-Wheeler
+   technical report (SRC-124) show how repeats can be handled
+   without difficulty in block sorting.</p></li>
+<li class="listitem" style="list-style-type: disc">
+<p>The randomisation mechanism doesn't really need to be
+   there.  Udi Manber and Gene Myers published a suffix array
+   construction algorithm a few years back, which can be employed
+   to sort any block, no matter how repetitive, in O(N log N)
+   time.  Subsequent work by Kunihiko Sadakane has produced a
+   derivative O(N (log N)^2) algorithm which usually outperforms
+   the Manber-Myers algorithm.</p>
+<p>I could have changed to Sadakane's algorithm, but I find
+   it to be slower than <code class="computeroutput">bzip2</code>'s
+   existing algorithm for most inputs, and the randomisation
+   mechanism protects adequately against bad cases.  I didn't
+   think it was a good tradeoff to make.  Partly this is due to
+   the fact that I was not flooded with email complaints about
+   <code class="computeroutput">bzip2-0.1</code>'s performance on
+   repetitive data, so perhaps it isn't a problem for real
+   inputs.</p>
+<p>Probably the best long-term solution, and the one I have
+   incorporated into 0.9.5 and above, is to use the existing
+   sorting algorithm initially, and fall back to a O(N (log N)^2)
+   algorithm if the standard algorithm gets into
+   difficulties.</p>
+</li>
+<li class="listitem" style="list-style-type: disc"><p>The compressed file format was never designed to be
+   handled by a library, and I have had to jump though some hoops
+   to produce an efficient implementation of decompression.  It's
+   a bit hairy.  Try passing
+   <code class="computeroutput">decompress.c</code> through the C
+   preprocessor and you'll see what I mean.  Much of this
+   complexity could have been avoided if the compressed size of
+   each block of data was recorded in the data stream.</p></li>
+<li class="listitem" style="list-style-type: disc"><p>An Adler-32 checksum, rather than a CRC32 checksum,
+   would be faster to compute.</p></li>
+</ul></div>
+<p>It would be fair to say that the
+<code class="computeroutput">bzip2</code> format was frozen before I
+properly and fully understood the performance consequences of
+doing so.</p>
+<p>Improvements which I was able to incorporate into 0.9.0,
+despite using the same file format, are:</p>
+<div class="itemizedlist"><ul class="itemizedlist" type="bullet">
+<li class="listitem" style="list-style-type: disc"><p>Single array implementation of the inverse BWT.  This
+  significantly speeds up decompression, presumably because it
+  reduces the number of cache misses.</p></li>
+<li class="listitem" style="list-style-type: disc"><p>Faster inverse MTF transform for large MTF values.
+  The new implementation is based on the notion of sliding blocks
+  of values.</p></li>
+<li class="listitem" style="list-style-type: disc"><p><code class="computeroutput">bzip2-0.9.0</code> now reads
+  and writes files with <code class="computeroutput">fread</code>
+  and <code class="computeroutput">fwrite</code>; version 0.1 used
+  <code class="computeroutput">putc</code> and
+  <code class="computeroutput">getc</code>.  Duh!  Well, you live
+  and learn.</p></li>
+</ul></div>
+<p>Further ahead, it would be nice to be able to do random
+access into files.  This will require some careful design of
+compressed file formats.</p>
+</div>
+<div class="sect1" title="4.2.�Portability issues">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="port-issues"></a>4.2.�Portability issues</h2></div></div></div>
+<p>After some consideration, I have decided not to use GNU
+<code class="computeroutput">autoconf</code> to configure 0.9.5 or
+1.0.</p>
+<p><code class="computeroutput">autoconf</code>, admirable and
+wonderful though it is, mainly assists with portability problems
+between Unix-like platforms.  But
+<code class="computeroutput">bzip2</code> doesn't have much in the
+way of portability problems on Unix; most of the difficulties
+appear when porting to the Mac, or to Microsoft's operating
+systems.  <code class="computeroutput">autoconf</code> doesn't help
+in those cases, and brings in a whole load of new
+complexity.</p>
+<p>Most people should be able to compile the library and
+program under Unix straight out-of-the-box, so to speak,
+especially if you have a version of GNU C available.</p>
+<p>There are a couple of
+<code class="computeroutput">__inline__</code> directives in the
+code.  GNU C (<code class="computeroutput">gcc</code>) should be
+able to handle them.  If you're not using GNU C, your C compiler
+shouldn't see them at all.  If your compiler does, for some
+reason, see them and doesn't like them, just
+<code class="computeroutput">#define</code>
+<code class="computeroutput">__inline__</code> to be
+<code class="computeroutput">/* */</code>.  One easy way to do this
+is to compile with the flag
+<code class="computeroutput">-D__inline__=</code>, which should be
+understood by most Unix compilers.</p>
+<p>If you still have difficulties, try compiling with the
+macro <code class="computeroutput">BZ_STRICT_ANSI</code> defined.
+This should enable you to build the library in a strictly ANSI
+compliant environment.  Building the program itself like this is
+dangerous and not supported, since you remove
+<code class="computeroutput">bzip2</code>'s checks against
+compressing directories, symbolic links, devices, and other
+not-really-a-file entities.  This could cause filesystem
+corruption!</p>
+<p>One other thing: if you create a
+<code class="computeroutput">bzip2</code> binary for public distribution,
+please consider linking it statically (<code class="computeroutput">gcc
+-static</code>).  This avoids all sorts of library-version
+issues that others may encounter later on.</p>
+<p>If you build <code class="computeroutput">bzip2</code> on
+Win32, you must set <code class="computeroutput">BZ_UNIX</code> to 0
+and <code class="computeroutput">BZ_LCCWIN32</code> to 1, in the
+file <code class="computeroutput">bzip2.c</code>, before compiling.
+Otherwise the resulting binary won't work correctly.</p>
+</div>
+<div class="sect1" title="4.3.�Reporting bugs">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="bugs"></a>4.3.�Reporting bugs</h2></div></div></div>
+<p>I tried pretty hard to make sure
+<code class="computeroutput">bzip2</code> is bug free, both by
+design and by testing.  Hopefully you'll never need to read this
+section for real.</p>
+<p>Nevertheless, if <code class="computeroutput">bzip2</code> dies
+with a segmentation fault, a bus error or an internal assertion
+failure, it will ask you to email me a bug report.  Experience from
+years of feedback of bzip2 users indicates that almost all these
+problems can be traced to either compiler bugs or hardware
+problems.</p>
+<div class="itemizedlist"><ul class="itemizedlist" type="bullet">
+<li class="listitem" style="list-style-type: disc">
+<p>Recompile the program with no optimisation, and
+  see if it works.  And/or try a different compiler.  I heard all
+  sorts of stories about various flavours of GNU C (and other
+  compilers) generating bad code for
+  <code class="computeroutput">bzip2</code>, and I've run across two
+  such examples myself.</p>
+<p>2.7.X versions of GNU C are known to generate bad code
+  from time to time, at high optimisation levels.  If you get
+  problems, try using the flags
+  <code class="computeroutput">-O2</code>
+  <code class="computeroutput">-fomit-frame-pointer</code>
+  <code class="computeroutput">-fno-strength-reduce</code>.  You
+  should specifically <span class="emphasis"><em>not</em></span> use
+  <code class="computeroutput">-funroll-loops</code>.</p>
+<p>You may notice that the Makefile runs six tests as part
+  of the build process.  If the program passes all of these, it's
+  a pretty good (but not 100%) indication that the compiler has
+  done its job correctly.</p>
+</li>
+<li class="listitem" style="list-style-type: disc">
+<p>If <code class="computeroutput">bzip2</code>
+  crashes randomly, and the crashes are not repeatable, you may
+  have a flaky memory subsystem.
+  <code class="computeroutput">bzip2</code> really hammers your
+  memory hierarchy, and if it's a bit marginal, you may get these
+  problems.  Ditto if your disk or I/O subsystem is slowly
+  failing.  Yup, this really does happen.</p>
+<p>Try using a different machine of the same type, and see
+  if you can repeat the problem.</p>
+</li>
+<li class="listitem" style="list-style-type: disc"><p>This isn't really a bug, but ... If
+  <code class="computeroutput">bzip2</code> tells you your file is
+  corrupted on decompression, and you obtained the file via FTP,
+  there is a possibility that you forgot to tell FTP to do a
+  binary mode transfer.  That absolutely will cause the file to
+  be non-decompressible.  You'll have to transfer it
+  again.</p></li>
+</ul></div>
+<p>If you've incorporated
+<code class="computeroutput">libbzip2</code> into your own program
+and are getting problems, please, please, please, check that the
+parameters you are passing in calls to the library, are correct,
+and in accordance with what the documentation says is allowable.
+I have tried to make the library robust against such problems,
+but I'm sure I haven't succeeded.</p>
+<p>Finally, if the above comments don't help, you'll have to
+send me a bug report.  Now, it's just amazing how many people
+will send me a bug report saying something like:</p>
+<pre class="programlisting">bzip2 crashed with segmentation fault on my machine</pre>
+<p>and absolutely nothing else.  Needless to say, a such a
+report is <span class="emphasis"><em>totally, utterly, completely and
+comprehensively 100% useless; a waste of your time, my time, and
+net bandwidth</em></span>.  With no details at all, there's no way
+I can possibly begin to figure out what the problem is.</p>
+<p>The rules of the game are: facts, facts, facts.  Don't omit
+them because "oh, they won't be relevant".  At the bare
+minimum:</p>
+<pre class="programlisting">Machine type.  Operating system version.  
+Exact version of bzip2 (do bzip2 -V).  
+Exact version of the compiler used.  
+Flags passed to the compiler.</pre>
+<p>However, the most important single thing that will help me
+is the file that you were trying to compress or decompress at the
+time the problem happened.  Without that, my ability to do
+anything more than speculate about the cause, is limited.</p>
+</div>
+<div class="sect1" title="4.4.�Did you get the right package?">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="package"></a>4.4.�Did you get the right package?</h2></div></div></div>
+<p><code class="computeroutput">bzip2</code> is a resource hog.
+It soaks up large amounts of CPU cycles and memory.  Also, it
+gives very large latencies.  In the worst case, you can feed many
+megabytes of uncompressed data into the library before getting
+any compressed output, so this probably rules out applications
+requiring interactive behaviour.</p>
+<p>These aren't faults of my implementation, I hope, but more
+an intrinsic property of the Burrows-Wheeler transform
+(unfortunately).  Maybe this isn't what you want.</p>
+<p>If you want a compressor and/or library which is faster,
+uses less memory but gets pretty good compression, and has
+minimal latency, consider Jean-loup Gailly's and Mark Adler's
+work, <code class="computeroutput">zlib-1.2.1</code> and
+<code class="computeroutput">gzip-1.2.4</code>.  Look for them at 
+<a class="ulink" href="http://www.zlib.org" target="_top">http://www.zlib.org</a> and 
+<a class="ulink" href="http://www.gzip.org" target="_top">http://www.gzip.org</a>
+respectively.</p>
+<p>For something faster and lighter still, you might try Markus F
+X J Oberhumer's <code class="computeroutput">LZO</code> real-time
+compression/decompression library, at 
+<a class="ulink" href="http://www.oberhumer.com/opensource" target="_top">http://www.oberhumer.com/opensource</a>.</p>
+</div>
+<div class="sect1" title="4.5.�Further Reading">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="reading"></a>4.5.�Further Reading</h2></div></div></div>
+<p><code class="computeroutput">bzip2</code> is not research
+work, in the sense that it doesn't present any new ideas.
+Rather, it's an engineering exercise based on existing
+ideas.</p>
+<p>Four documents describe essentially all the ideas behind
+<code class="computeroutput">bzip2</code>:</p>
+<div class="literallayout"><p>Michael�Burrows�and�D.�J.�Wheeler:<br>
+��"A�block-sorting�lossless�data�compression�algorithm"<br>
+���10th�May�1994.�<br>
+���Digital�SRC�Research�Report�124.<br>
+���ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz<br>
+���If�you�have�trouble�finding�it,�try�searching�at�the<br>
+���New�Zealand�Digital�Library,�http://www.nzdl.org.<br>
+<br>
+Daniel�S.�Hirschberg�and�Debra�A.�LeLewer<br>
+��"Efficient�Decoding�of�Prefix�Codes"<br>
+���Communications�of�the�ACM,�April�1990,�Vol�33,�Number�4.<br>
+���You�might�be�able�to�get�an�electronic�copy�of�this<br>
+���from�the�ACM�Digital�Library.<br>
+<br>
+David�J.�Wheeler<br>
+���Program�bred3.c�and�accompanying�document�bred3.ps.<br>
+���This�contains�the�idea�behind�the�multi-table�Huffman�coding�scheme.<br>
+���ftp://ftp.cl.cam.ac.uk/users/djw3/<br>
+<br>
+Jon�L.�Bentley�and�Robert�Sedgewick<br>
+��"Fast�Algorithms�for�Sorting�and�Searching�Strings"<br>
+���Available�from�Sedgewick's�web�page,<br>
+���www.cs.princeton.edu/~rs<br>
+</p></div>
+<p>The following paper gives valuable additional insights into
+the algorithm, but is not immediately the basis of any code used
+in bzip2.</p>
+<div class="literallayout"><p>Peter�Fenwick:<br>
+���Block�Sorting�Text�Compression<br>
+���Proceedings�of�the�19th�Australasian�Computer�Science�Conference,<br>
+�����Melbourne,�Australia.��Jan�31�-�Feb�2,�1996.<br>
+���ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps</p></div>
+<p>Kunihiko Sadakane's sorting algorithm, mentioned above, is
+available from:</p>
+<div class="literallayout"><p>http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz<br>
+</p></div>
+<p>The Manber-Myers suffix array construction algorithm is
+described in a paper available from:</p>
+<div class="literallayout"><p>http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps<br>
+</p></div>
+<p>Finally, the following papers document some
+investigations I made into the performance of sorting
+and decompression algorithms:</p>
+<div class="literallayout"><p>Julian�Seward<br>
+���On�the�Performance�of�BWT�Sorting�Algorithms<br>
+���Proceedings�of�the�IEEE�Data�Compression�Conference�2000<br>
+�����Snowbird,�Utah.��28-30�March�2000.<br>
+<br>
+Julian�Seward<br>
+���Space-time�Tradeoffs�in�the�Inverse�B-W�Transform<br>
+���Proceedings�of�the�IEEE�Data�Compression�Conference�2001<br>
+�����Snowbird,�Utah.��27-29�March�2001.<br>
+</p></div>
+</div>
+</div>
+</div></body>
+</html>
diff --git a/c++/src/util/compress/bzip2/manual.pdf b/c++/src/util/compress/bzip2/manual.pdf
index 9be5d6d..f1c31a0 100644
Binary files a/c++/src/util/compress/bzip2/manual.pdf and b/c++/src/util/compress/bzip2/manual.pdf differ
diff --git a/c++/src/util/compress/bzip2/manual.texi b/c++/src/util/compress/bzip2/manual.texi
deleted file mode 100644
index 5bc27d5..0000000
--- a/c++/src/util/compress/bzip2/manual.texi
+++ /dev/null
@@ -1,2243 +0,0 @@
-\input texinfo  @c                                  -*- Texinfo -*-
- at setfilename bzip2.info
-
- at ignore
-This file documents bzip2 version 1.0.2, and associated library
-libbzip2, written by Julian Seward (jseward at acm.org).
-
-Copyright (C) 1996-2002 Julian R Seward
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for verbatim copies.
- at end ignore
-
- at ifinfo
- at format
-START-INFO-DIR-ENTRY
-* Bzip2: (bzip2).		A program and library for data compression.
-END-INFO-DIR-ENTRY
- at end format
-
- at end ifinfo
-
- at iftex
- at c @finalout
- at settitle bzip2 and libbzip2
- at titlepage
- at title bzip2 and libbzip2
- at subtitle a program and library for data compression
- at subtitle copyright (C) 1996-2002 Julian Seward
- at subtitle version 1.0.2 of 30 December 2001
- at author Julian Seward
-
- at end titlepage
-
- at parindent 0mm
- at parskip 2mm
-
- at end iftex
- at node Top,,, (dir)
-
-The following text is the License for this software.  You should
-find it identical to that contained in the file LICENSE in the 
-source distribution.
-
- at bf{------------------ START OF THE LICENSE ------------------}
-
-This program, @code{bzip2}, 
-and associated library @code{libbzip2}, are
-Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- at itemize @bullet
- at item
-   Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
- at item
-   The origin of this software must not be misrepresented; you must 
-   not claim that you wrote the original software.  If you use this 
-   software in a product, an acknowledgment in the product 
-   documentation would be appreciated but is not required.
- at item
-   Altered source versions must be plainly marked as such, and must
-   not be misrepresented as being the original software.
- at item
-   The name of the author may not be used to endorse or promote 
-   products derived from this software without specific prior written 
-   permission.
- at end itemize
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Julian Seward, Cambridge, UK.
-
- at code{jseward@@acm.org}
-
- at code{bzip2}/@code{libbzip2} version 1.0.2 of 30 December 2001.
-
- at bf{------------------ END OF THE LICENSE ------------------}
-
-Web sites:
-
- at code{http://sources.redhat.com/bzip2}
-
- at code{http://www.cacheprof.org}
-
-PATENTS: To the best of my knowledge, @code{bzip2} does not use any patented
-algorithms.  However, I do not have the resources available to carry out
-a full patent search.  Therefore I cannot give any guarantee of the
-above statement.
-
-
-
-
-
-
-
- at chapter Introduction
-
- at code{bzip2}  compresses  files  using the Burrows-Wheeler 
-block-sorting text compression algorithm,  and  Huffman  coding.
-Compression  is  generally  considerably  better than that
-achieved by more conventional LZ77/LZ78-based compressors,
-and  approaches  the performance of the PPM family of statistical compressors.
-
- at code{bzip2} is built on top of @code{libbzip2}, a flexible library
-for handling compressed data in the @code{bzip2} format.  This manual
-describes both how to use the program and 
-how to work with the library interface.  Most of the
-manual is devoted to this library, not the program, 
-which is good news if your interest is only in the program.
-
-Chapter 2 describes how to use @code{bzip2}; this is the only part 
-you need to read if you just want to know how to operate the program.
-Chapter 3 describes the programming interfaces in detail, and
-Chapter 4 records some miscellaneous notes which I thought
-ought to be recorded somewhere.
-
-
- at chapter How to use @code{bzip2}
-
-This chapter contains a copy of the @code{bzip2} man page,
-and nothing else.
-
- at quotation
-
- at unnumberedsubsubsec NAME
- at itemize
- at item @code{bzip2}, @code{bunzip2}
-- a block-sorting file compressor, v1.0.2
- at item @code{bzcat} 
-- decompresses files to stdout
- at item @code{bzip2recover}
-- recovers data from damaged bzip2 files
- at end itemize
-
- at unnumberedsubsubsec SYNOPSIS
- at itemize
- at item @code{bzip2} [ -cdfkqstvzVL123456789 ] [ filenames ...  ]
- at item @code{bunzip2} [ -fkvsVL ] [ filenames ...  ]
- at item @code{bzcat} [ -s ] [ filenames ...  ]
- at item @code{bzip2recover} filename
- at end itemize
-
- at unnumberedsubsubsec DESCRIPTION
-
- at code{bzip2} compresses files using the Burrows-Wheeler block sorting
-text compression algorithm, and Huffman coding.  Compression is
-generally considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of the PPM
-family of statistical compressors.
-
-The command-line options are deliberately very similar to those of GNU
- at code{gzip}, but they are not identical.
-
- at code{bzip2} expects a list of file names to accompany the command-line
-flags.  Each file is replaced by a compressed version of itself, with
-the name @code{original_name.bz2}.  Each compressed file has the same
-modification date, permissions, and, when possible, ownership as the
-corresponding original, so that these properties can be correctly
-restored at decompression time.  File name handling is naive in the
-sense that there is no mechanism for preserving original file names,
-permissions, ownerships or dates in filesystems which lack these
-concepts, or have serious file name length restrictions, such as MS-DOS.
-
- at code{bzip2} and @code{bunzip2} will by default not overwrite existing
-files.  If you want this to happen, specify the @code{-f} flag.
-
-If no file names are specified, @code{bzip2} compresses from standard
-input to standard output.  In this case, @code{bzip2} will decline to
-write compressed output to a terminal, as this would be entirely
-incomprehensible and therefore pointless.
-
- at code{bunzip2} (or @code{bzip2 -d}) decompresses all
-specified files.  Files which were not created by @code{bzip2}
-will be detected and ignored, and a warning issued.  
- at code{bzip2} attempts to guess the filename for the decompressed file 
-from that of the compressed file as follows:
- at itemize
- at item @code{filename.bz2 } becomes @code{filename}
- at item @code{filename.bz  } becomes @code{filename}
- at item @code{filename.tbz2} becomes @code{filename.tar}
- at item @code{filename.tbz } becomes @code{filename.tar}
- at item @code{anyothername } becomes @code{anyothername.out}
- at end itemize
-If the file does not end in one of the recognised endings, 
- at code{.bz2}, @code{.bz}, 
- at code{.tbz2} or @code{.tbz}, @code{bzip2} complains that it cannot
-guess the name of the original file, and uses the original name
-with @code{.out} appended.
-
-As with compression, supplying no
-filenames causes decompression from standard input to standard output.
-
- at code{bunzip2} will correctly decompress a file which is the
-concatenation of two or more compressed files.  The result is the
-concatenation of the corresponding uncompressed files.  Integrity
-testing (@code{-t}) of concatenated compressed files is also supported.
-
-You can also compress or decompress files to the standard output by
-giving the @code{-c} flag.  Multiple files may be compressed and
-decompressed like this.  The resulting outputs are fed sequentially to
-stdout.  Compression of multiple files in this manner generates a stream
-containing multiple compressed file representations.  Such a stream
-can be decompressed correctly only by @code{bzip2} version 0.9.0 or
-later.  Earlier versions of @code{bzip2} will stop after decompressing
-the first file in the stream.
-
- at code{bzcat} (or @code{bzip2 -dc}) decompresses all specified files to
-the standard output.
-
- at code{bzip2} will read arguments from the environment variables
- at code{BZIP2} and @code{BZIP}, in that order, and will process them
-before any arguments read from the command line.  This gives a 
-convenient way to supply default arguments.
-
-Compression is always performed, even if the compressed file is slightly
-larger than the original.  Files of less than about one hundred bytes
-tend to get larger, since the compression mechanism has a constant
-overhead in the region of 50 bytes.  Random data (including the output
-of most file compressors) is coded at about 8.05 bits per byte, giving
-an expansion of around 0.5%.
-
-As a self-check for your protection, @code{bzip2} uses 32-bit CRCs to
-make sure that the decompressed version of a file is identical to the
-original.  This guards against corruption of the compressed data, and
-against undetected bugs in @code{bzip2} (hopefully very unlikely).  The
-chances of data corruption going undetected is microscopic, about one
-chance in four billion for each file processed.  Be aware, though, that
-the check occurs upon decompression, so it can only tell you that
-something is wrong.  It can't help you recover the original uncompressed
-data.  You can use @code{bzip2recover} to try to recover data from
-damaged files.
-
-Return values: 0 for a normal exit, 1 for environmental problems (file
-not found, invalid flags, I/O errors, &c), 2 to indicate a corrupt
-compressed file, 3 for an internal consistency error (eg, bug) which
-caused @code{bzip2} to panic.
-
-
- at unnumberedsubsubsec OPTIONS
- at table @code
- at item -c  --stdout
-Compress or decompress to standard output.
- at item -d  --decompress
-Force decompression.  @code{bzip2}, @code{bunzip2} and @code{bzcat} are
-really the same program, and the decision about what actions to take is
-done on the basis of which name is used.  This flag overrides that
-mechanism, and forces bzip2 to decompress.
- at item -z --compress
-The complement to @code{-d}: forces compression, regardless of the
-invokation name.
- at item -t --test
-Check integrity of the specified file(s), but don't decompress them.
-This really performs a trial decompression and throws away the result.
- at item -f --force
-Force overwrite of output files.  Normally, @code{bzip2} will not overwrite
-existing output files.  Also forces @code{bzip2} to break hard links
-to files, which it otherwise wouldn't do.
-
- at code{bzip2} normally declines to decompress files which don't have the
-correct magic header bytes.  If forced (@code{-f}), however, it will
-pass such files through unmodified.  This is how GNU @code{gzip}
-behaves.
- at item -k --keep
-Keep (don't delete) input files during compression
-or decompression.
- at item -s --small
-Reduce memory usage, for compression, decompression and testing.  Files
-are decompressed and tested using a modified algorithm which only
-requires 2.5 bytes per block byte.  This means any file can be
-decompressed in 2300k of memory, albeit at about half the normal speed.
-
-During compression, @code{-s} selects a block size of 200k, which limits
-memory use to around the same figure, at the expense of your compression
-ratio.  In short, if your machine is low on memory (8 megabytes or
-less), use -s for everything.  See MEMORY MANAGEMENT below.
- at item -q --quiet
-Suppress non-essential warning messages.  Messages pertaining to
-I/O errors and other critical events will not be suppressed.
- at item -v --verbose
-Verbose mode -- show the compression ratio for each file processed.
-Further @code{-v}'s increase the verbosity level, spewing out lots of
-information which is primarily of interest for diagnostic purposes.
- at item -L --license -V --version
-Display the software version, license terms and conditions.
- at item -1 (or --fast) to -9 (or --best)
-Set the block size to 100 k, 200 k ..  900 k when compressing.  Has no
-effect when decompressing.  See MEMORY MANAGEMENT below.
-The @code{--fast} and @code{--best} aliases are primarily for GNU
- at code{gzip} compatibility.  In particular, @code{--fast} doesn't make
-things significantly faster.  And @code{--best} merely selects the
-default behaviour.
- at item --
-Treats all subsequent arguments as file names, even if they start
-with a dash.  This is so you can handle files with names beginning
-with a dash, for example: @code{bzip2 -- -myfilename}.
- at item --repetitive-fast 
- at item --repetitive-best
-These flags are redundant in versions 0.9.5 and above.  They provided
-some coarse control over the behaviour of the sorting algorithm in
-earlier versions, which was sometimes useful.  0.9.5 and above have an
-improved algorithm which renders these flags irrelevant.
- at end table
-
-
- at unnumberedsubsubsec MEMORY MANAGEMENT
-
- at code{bzip2} compresses large files in blocks.  The block size affects
-both the compression ratio achieved, and the amount of memory needed for
-compression and decompression.  The flags @code{-1} through @code{-9}
-specify the block size to be 100,000 bytes through 900,000 bytes (the
-default) respectively.  At decompression time, the block size used for
-compression is read from the header of the compressed file, and
- at code{bunzip2} then allocates itself just enough memory to decompress
-the file.  Since block sizes are stored in compressed files, it follows
-that the flags @code{-1} to @code{-9} are irrelevant to and so ignored
-during decompression.
-
-Compression and decompression requirements, in bytes, can be estimated
-as:
- at example
-     Compression:   400k + ( 8 x block size )
-
-     Decompression: 100k + ( 4 x block size ), or
-                    100k + ( 2.5 x block size )
- at end example
-Larger block sizes give rapidly diminishing marginal returns.  Most of
-the compression comes from the first two or three hundred k of block
-size, a fact worth bearing in mind when using @code{bzip2} on small machines.
-It is also important to appreciate that the decompression memory
-requirement is set at compression time by the choice of block size.
-
-For files compressed with the default 900k block size, @code{bunzip2}
-will require about 3700 kbytes to decompress.  To support decompression
-of any file on a 4 megabyte machine, @code{bunzip2} has an option to
-decompress using approximately half this amount of memory, about 2300
-kbytes.  Decompression speed is also halved, so you should use this
-option only where necessary.  The relevant flag is @code{-s}.
-
-In general, try and use the largest block size memory constraints allow,
-since that maximises the compression achieved.  Compression and
-decompression speed are virtually unaffected by block size.
-
-Another significant point applies to files which fit in a single block
--- that means most files you'd encounter using a large block size.  The
-amount of real memory touched is proportional to the size of the file,
-since the file is smaller than a block.  For example, compressing a file
-20,000 bytes long with the flag @code{-9} will cause the compressor to
-allocate around 7600k of memory, but only touch 400k + 20000 * 8 = 560
-kbytes of it.  Similarly, the decompressor will allocate 3700k but only
-touch 100k + 20000 * 4 = 180 kbytes.
-
-Here is a table which summarises the maximum memory usage for different
-block sizes.  Also recorded is the total compressed size for 14 files of
-the Calgary Text Compression Corpus totalling 3,141,622 bytes.  This
-column gives some feel for how compression varies with block size.
-These figures tend to understate the advantage of larger block sizes for
-larger files, since the Corpus is dominated by smaller files.
- at example
-          Compress   Decompress   Decompress   Corpus
-   Flag     usage      usage       -s usage     Size
-
-    -1      1200k       500k         350k      914704
-    -2      2000k       900k         600k      877703
-    -3      2800k      1300k         850k      860338
-    -4      3600k      1700k        1100k      846899
-    -5      4400k      2100k        1350k      845160
-    -6      5200k      2500k        1600k      838626
-    -7      6100k      2900k        1850k      834096
-    -8      6800k      3300k        2100k      828642
-    -9      7600k      3700k        2350k      828642
- at end example
-
- at unnumberedsubsubsec RECOVERING DATA FROM DAMAGED FILES
-
- at code{bzip2} compresses files in blocks, usually 900kbytes long.  Each
-block is handled independently.  If a media or transmission error causes
-a multi-block @code{.bz2} file to become damaged, it may be possible to
-recover data from the undamaged blocks in the file.
-
-The compressed representation of each block is delimited by a 48-bit
-pattern, which makes it possible to find the block boundaries with
-reasonable certainty.  Each block also carries its own 32-bit CRC, so
-damaged blocks can be distinguished from undamaged ones.
-
- at code{bzip2recover} is a simple program whose purpose is to search for
-blocks in @code{.bz2} files, and write each block out into its own
- at code{.bz2} file.  You can then use @code{bzip2 -t} to test the
-integrity of the resulting files, and decompress those which are
-undamaged.
-
- at code{bzip2recover} 
-takes a single argument, the name of the damaged file, and writes a
-number of files @code{rec00001file.bz2}, @code{rec00002file.bz2}, etc,
-containing the extracted blocks.  The output filenames are designed so
-that the use of wildcards in subsequent processing -- for example,
- at code{bzip2 -dc rec*file.bz2 > recovered_data} -- processes the files in
-the correct order.
-
- at code{bzip2recover} should be of most use dealing with large @code{.bz2}
-files, as these will contain many blocks.  It is clearly futile to use
-it on damaged single-block files, since a damaged block cannot be
-recovered.  If you wish to minimise any potential data loss through
-media or transmission errors, you might consider compressing with a
-smaller block size.
-
-
- at unnumberedsubsubsec PERFORMANCE NOTES
-
-The sorting phase of compression gathers together similar strings in the
-file.  Because of this, files containing very long runs of repeated
-symbols, like "aabaabaabaab ..."  (repeated several hundred times) may
-compress more slowly than normal.  Versions 0.9.5 and above fare much
-better than previous versions in this respect.  The ratio between
-worst-case and average-case compression time is in the region of 10:1.
-For previous versions, this figure was more like 100:1.  You can use the
- at code{-vvvv} option to monitor progress in great detail, if you want.
-
-Decompression speed is unaffected by these phenomena.
-
- at code{bzip2} usually allocates several megabytes of memory to operate
-in, and then charges all over it in a fairly random fashion.  This means
-that performance, both for compressing and decompressing, is largely
-determined by the speed at which your machine can service cache misses.
-Because of this, small changes to the code to reduce the miss rate have
-been observed to give disproportionately large performance improvements.
-I imagine @code{bzip2} will perform best on machines with very large
-caches.
-
-
- at unnumberedsubsubsec CAVEATS
-
-I/O error messages are not as helpful as they could be.  @code{bzip2}
-tries hard to detect I/O errors and exit cleanly, but the details of
-what the problem is sometimes seem rather misleading.
-
-This manual page pertains to version 1.0.2 of @code{bzip2}.  Compressed
-data created by this version is entirely forwards and backwards
-compatible with the previous public releases, versions 0.1pl2, 0.9.0,
-0.9.5, 1.0.0 and 1.0.1, but with the following exception: 0.9.0 and
-above can correctly decompress multiple concatenated compressed files.
-0.1pl2 cannot do this; it will stop after decompressing just the first
-file in the stream.
-
- at code{bzip2recover} versions prior to this one, 1.0.2, used 32-bit
-integers to represent bit positions in compressed files, so it could not
-handle compressed files more than 512 megabytes long.  Version 1.0.2 and
-above uses 64-bit ints on some platforms which support them (GNU
-supported targets, and Windows).  To establish whether or not
- at code{bzip2recover} was built with such a limitation, run it without
-arguments.  In any event you can build yourself an unlimited version if
-you can recompile it with @code{MaybeUInt64} set to be an unsigned
-64-bit integer.
-
-
-
- at unnumberedsubsubsec AUTHOR
-Julian Seward, @code{jseward@@acm.org}.
-
- at code{http://sources.redhat.com/bzip2}
-
-The ideas embodied in @code{bzip2} are due to (at least) the following
-people: Michael Burrows and David Wheeler (for the block sorting
-transformation), David Wheeler (again, for the Huffman coder), Peter
-Fenwick (for the structured coding model in the original @code{bzip},
-and many refinements), and Alistair Moffat, Radford Neal and Ian Witten
-(for the arithmetic coder in the original @code{bzip}).  I am much
-indebted for their help, support and advice.  See the manual in the
-source distribution for pointers to sources of documentation.  Christian
-von Roques encouraged me to look for faster sorting algorithms, so as to
-speed up compression.  Bela Lubkin encouraged me to improve the
-worst-case compression performance.  The @code{bz*} scripts are derived
-from those of GNU @code{gzip}.  Many people sent patches, helped with
-portability problems, lent machines, gave advice and were generally
-helpful.
-
- at end quotation
-
-
-
-
- at chapter Programming with @code{libbzip2}
-
-This chapter describes the programming interface to @code{libbzip2}.
-
-For general background information, particularly about memory
-use and performance aspects, you'd be well advised to read Chapter 2
-as well.
-
- at section Top-level structure
-
- at code{libbzip2} is a flexible library for compressing and decompressing
-data in the @code{bzip2} data format.  Although packaged as a single
-entity, it helps to regard the library as three separate parts: the low
-level interface, and the high level interface, and some utility
-functions.
-
-The structure of @code{libbzip2}'s interfaces is similar to
-that of Jean-loup Gailly's and Mark Adler's excellent @code{zlib} 
-library.
-
-All externally visible symbols have names beginning @code{BZ2_}.
-This is new in version 1.0.  The intention is to minimise pollution
-of the namespaces of library clients.
-
- at subsection Low-level summary
-
-This interface provides services for compressing and decompressing
-data in memory.  There's no provision for dealing with files, streams
-or any other I/O mechanisms, just straight memory-to-memory work.
-In fact, this part of the library can be compiled without inclusion
-of @code{stdio.h}, which may be helpful for embedded applications.
-
-The low-level part of the library has no global variables and
-is therefore thread-safe.
-
-Six routines make up the low level interface: 
- at code{BZ2_bzCompressInit}, @code{BZ2_bzCompress}, and @* @code{BZ2_bzCompressEnd}
-for compression,
-and a corresponding trio @code{BZ2_bzDecompressInit}, @* @code{BZ2_bzDecompress}
-and @code{BZ2_bzDecompressEnd} for decompression.  
-The @code{*Init} functions allocate
-memory for compression/decompression and do other
-initialisations, whilst the @code{*End} functions close down operations
-and release memory.
-
-The real work is done by @code{BZ2_bzCompress} and @code{BZ2_bzDecompress}.  
-These compress and decompress data from a user-supplied input buffer
-to a user-supplied output buffer.  These buffers can be any size;
-arbitrary quantities of data are handled by making repeated calls
-to these functions.  This is a flexible mechanism allowing a 
-consumer-pull style of activity, or producer-push, or a mixture of
-both.
-
-
-
- at subsection High-level summary
-
-This interface provides some handy wrappers around the low-level
-interface to facilitate reading and writing @code{bzip2} format
-files (@code{.bz2} files).  The routines provide hooks to facilitate
-reading files in which the @code{bzip2} data stream is embedded 
-within some larger-scale file structure, or where there are
-multiple @code{bzip2} data streams concatenated end-to-end.
-
-For reading files, @code{BZ2_bzReadOpen}, @code{BZ2_bzRead},
- at code{BZ2_bzReadClose} and @* @code{BZ2_bzReadGetUnused} are supplied.  For
-writing files, @code{BZ2_bzWriteOpen}, @code{BZ2_bzWrite} and
- at code{BZ2_bzWriteFinish} are available.
-
-As with the low-level library, no global variables are used
-so the library is per se thread-safe.  However, if I/O errors
-occur whilst reading or writing the underlying compressed files,
-you may have to consult @code{errno} to determine the cause of
-the error.  In that case, you'd need a C library which correctly
-supports @code{errno} in a multithreaded environment.
-
-To make the library a little simpler and more portable,
- at code{BZ2_bzReadOpen} and @code{BZ2_bzWriteOpen} require you to pass them file
-handles (@code{FILE*}s) which have previously been opened for reading or
-writing respectively.  That avoids portability problems associated with
-file operations and file attributes, whilst not being much of an
-imposition on the programmer.
-
-
-
- at subsection Utility functions summary
-For very simple needs, @code{BZ2_bzBuffToBuffCompress} and
- at code{BZ2_bzBuffToBuffDecompress} are provided.  These compress
-data in memory from one buffer to another buffer in a single
-function call.  You should assess whether these functions
-fulfill your memory-to-memory compression/decompression
-requirements before investing effort in understanding the more
-general but more complex low-level interface.
-
-Yoshioka Tsuneo (@code{QWF00133@@niftyserve.or.jp} /
- at code{tsuneo-y@@is.aist-nara.ac.jp}) has contributed some functions to
-give better @code{zlib} compatibility.  These functions are
- at code{BZ2_bzopen}, @code{BZ2_bzread}, @code{BZ2_bzwrite}, @code{BZ2_bzflush},
- at code{BZ2_bzclose},
- at code{BZ2_bzerror} and @code{BZ2_bzlibVersion}.  You may find these functions
-more convenient for simple file reading and writing, than those in the
-high-level interface.  These functions are not (yet) officially part of
-the library, and are minimally documented here.  If they break, you
-get to keep all the pieces.  I hope to document them properly when time
-permits.
-
-Yoshioka also contributed modifications to allow the library to be
-built as a Windows DLL.
-
-
- at section Error handling
-
-The library is designed to recover cleanly in all situations, including
-the worst-case situation of decompressing random data.  I'm not 
-100% sure that it can always do this, so you might want to add
-a signal handler to catch segmentation violations during decompression
-if you are feeling especially paranoid.  I would be interested in
-hearing more about the robustness of the library to corrupted
-compressed data.
-
-Version 1.0 is much more robust in this respect than
-0.9.0 or 0.9.5.  Investigations with Checker (a tool for 
-detecting problems with memory management, similar to Purify)
-indicate that, at least for the few files I tested, all single-bit
-errors in the decompressed data are caught properly, with no
-segmentation faults, no reads of uninitialised data and no 
-out of range reads or writes.  So it's certainly much improved,
-although I wouldn't claim it to be totally bombproof.
-
-The file @code{bzlib.h} contains all definitions needed to use
-the library.  In particular, you should definitely not include
- at code{bzlib_private.h}.
-
-In @code{bzlib.h}, the various return values are defined.  The following
-list is not intended as an exhaustive description of the circumstances 
-in which a given value may be returned -- those descriptions are given
-later.  Rather, it is intended to convey the rough meaning of each
-return value.  The first five actions are normal and not intended to 
-denote an error situation.
- at table @code
- at item BZ_OK
-The requested action was completed successfully.
- at item BZ_RUN_OK
- at itemx BZ_FLUSH_OK
- at itemx BZ_FINISH_OK
-In @code{BZ2_bzCompress}, the requested flush/finish/nothing-special action
-was completed successfully.
- at item BZ_STREAM_END
-Compression of data was completed, or the logical stream end was
-detected during decompression.
- at end table
-
-The following return values indicate an error of some kind.
- at table @code
- at item BZ_CONFIG_ERROR
-Indicates that the library has been improperly compiled on your
-platform -- a major configuration error.  Specifically, it means
-that @code{sizeof(char)}, @code{sizeof(short)} and @code{sizeof(int)}
-are not 1, 2 and 4 respectively, as they should be.  Note that the 
-library should still work properly on 64-bit platforms which follow
-the LP64 programming model -- that is, where @code{sizeof(long)}
-and @code{sizeof(void*)} are 8.  Under LP64, @code{sizeof(int)} is
-still 4, so @code{libbzip2}, which doesn't use the @code{long} type,
-is OK.
- at item BZ_SEQUENCE_ERROR
-When using the library, it is important to call the functions in the
-correct sequence and with data structures (buffers etc) in the correct
-states.  @code{libbzip2} checks as much as it can to ensure this is
-happening, and returns @code{BZ_SEQUENCE_ERROR} if not.  Code which
-complies precisely with the function semantics, as detailed below,
-should never receive this value; such an event denotes buggy code
-which you should investigate.
- at item BZ_PARAM_ERROR
-Returned when a parameter to a function call is out of range 
-or otherwise manifestly incorrect.  As with @code{BZ_SEQUENCE_ERROR},
-this denotes a bug in the client code.  The distinction between
- at code{BZ_PARAM_ERROR} and @code{BZ_SEQUENCE_ERROR} is a bit hazy, but still worth
-making.
- at item BZ_MEM_ERROR
-Returned when a request to allocate memory failed.  Note that the
-quantity of memory needed to decompress a stream cannot be determined
-until the stream's header has been read.  So @code{BZ2_bzDecompress} and
- at code{BZ2_bzRead} may return @code{BZ_MEM_ERROR} even though some of
-the compressed data has been read.  The same is not true for
-compression; once @code{BZ2_bzCompressInit} or @code{BZ2_bzWriteOpen} have
-successfully completed, @code{BZ_MEM_ERROR} cannot occur.
- at item BZ_DATA_ERROR
-Returned when a data integrity error is detected during decompression.
-Most importantly, this means when stored and computed CRCs for the
-data do not match.  This value is also returned upon detection of any
-other anomaly in the compressed data.
- at item BZ_DATA_ERROR_MAGIC
-As a special case of @code{BZ_DATA_ERROR}, it is sometimes useful to
-know when the compressed stream does not start with the correct
-magic bytes (@code{'B' 'Z' 'h'}).  
- at item BZ_IO_ERROR
-Returned by @code{BZ2_bzRead} and @code{BZ2_bzWrite} when there is an error
-reading or writing in the compressed file, and by @code{BZ2_bzReadOpen}
-and @code{BZ2_bzWriteOpen} for attempts to use a file for which the
-error indicator (viz, @code{ferror(f)}) is set.
-On receipt of @code{BZ_IO_ERROR}, the caller should consult
- at code{errno} and/or @code{perror} to acquire operating-system
-specific information about the problem.
- at item BZ_UNEXPECTED_EOF
-Returned by @code{BZ2_bzRead} when the compressed file finishes
-before the logical end of stream is detected.
- at item BZ_OUTBUFF_FULL
-Returned by @code{BZ2_bzBuffToBuffCompress} and
- at code{BZ2_bzBuffToBuffDecompress} to indicate that the output data
-will not fit into the output buffer provided.
- at end table
-
-
-
- at section Low-level interface
-
- at subsection @code{BZ2_bzCompressInit}
- at example
-typedef 
-   struct @{
-      char *next_in;
-      unsigned int avail_in;
-      unsigned int total_in_lo32;
-      unsigned int total_in_hi32;
-
-      char *next_out;
-      unsigned int avail_out;
-      unsigned int total_out_lo32;
-      unsigned int total_out_hi32;
-
-      void *state;
-
-      void *(*bzalloc)(void *,int,int);
-      void (*bzfree)(void *,void *);
-      void *opaque;
-   @} 
-   bz_stream;
-
-int BZ2_bzCompressInit ( bz_stream *strm, 
-                         int blockSize100k, 
-                         int verbosity,
-                         int workFactor );
-
- at end example
-
-Prepares for compression.  The @code{bz_stream} structure
-holds all data pertaining to the compression activity.  
-A @code{bz_stream} structure should be allocated and initialised
-prior to the call.
-The fields of @code{bz_stream}
-comprise the entirety of the user-visible data.  @code{state}
-is a pointer to the private data structures required for compression.
-
-Custom memory allocators are supported, via fields @code{bzalloc}, 
- at code{bzfree},
-and @code{opaque}.  The value 
- at code{opaque} is passed to as the first argument to
-all calls to @code{bzalloc} and @code{bzfree}, but is 
-otherwise ignored by the library.
-The call @code{bzalloc ( opaque, n, m )} is expected to return a 
-pointer @code{p} to
- at code{n * m} bytes of memory, and @code{bzfree ( opaque, p )} 
-should free
-that memory.
-
-If you don't want to use a custom memory allocator, set @code{bzalloc}, 
- at code{bzfree} and
- at code{opaque} to @code{NULL}, 
-and the library will then use the standard @code{malloc}/@code{free}
-routines.
-
-Before calling @code{BZ2_bzCompressInit}, fields @code{bzalloc}, 
- at code{bzfree} and @code{opaque} should
-be filled appropriately, as just described.  Upon return, the internal
-state will have been allocated and initialised, and @code{total_in_lo32}, 
- at code{total_in_hi32}, @code{total_out_lo32} and 
- at code{total_out_hi32} will have been set to zero.  
-These four fields are used by the library
-to inform the caller of the total amount of data passed into and out of
-the library, respectively.  You should not try to change them.
-As of version 1.0, 64-bit counts are maintained, even on 32-bit
-platforms, using the @code{_hi32} fields to store the upper 32 bits
-of the count.  So, for example, the total amount of data in
-is @code{(total_in_hi32 << 32) + total_in_lo32}.
-
-Parameter @code{blockSize100k} specifies the block size to be used for
-compression.  It should be a value between 1 and 9 inclusive, and the
-actual block size used is 100000 x this figure.  9 gives the best
-compression but takes most memory.
-
-Parameter @code{verbosity} should be set to a number between 0 and 4
-inclusive.  0 is silent, and greater numbers give increasingly verbose
-monitoring/debugging output.  If the library has been compiled with
- at code{-DBZ_NO_STDIO}, no such output will appear for any verbosity
-setting.
-
-Parameter @code{workFactor} controls how the compression phase behaves
-when presented with worst case, highly repetitive, input data.  If
-compression runs into difficulties caused by repetitive data, the
-library switches from the standard sorting algorithm to a fallback
-algorithm.  The fallback is slower than the standard algorithm by
-perhaps a factor of three, but always behaves reasonably, no matter how
-bad the input.
-
-Lower values of @code{workFactor} reduce the amount of effort the
-standard algorithm will expend before resorting to the fallback.  You
-should set this parameter carefully; too low, and many inputs will be
-handled by the fallback algorithm and so compress rather slowly, too
-high, and your average-to-worst case compression times can become very
-large.  The default value of 30 gives reasonable behaviour over a wide
-range of circumstances.
-
-Allowable values range from 0 to 250 inclusive.  0 is a special case,
-equivalent to using the default value of 30.
-
-Note that the compressed output generated is the same regardless of
-whether or not the fallback algorithm is used.
-
-Be aware also that this parameter may disappear entirely in future
-versions of the library.  In principle it should be possible to devise a
-good way to automatically choose which algorithm to use.  Such a
-mechanism would render the parameter obsolete.
-
-Possible return values:
- at display
-      @code{BZ_CONFIG_ERROR}
-         if the library has been mis-compiled
-      @code{BZ_PARAM_ERROR} 
-         if @code{strm} is @code{NULL} 
-         or @code{blockSize} < 1 or @code{blockSize} > 9
-         or @code{verbosity} < 0 or @code{verbosity} > 4
-         or @code{workFactor} < 0 or @code{workFactor} > 250
-      @code{BZ_MEM_ERROR} 
-         if not enough memory is available
-      @code{BZ_OK} 
-         otherwise
- at end display
-Allowable next actions:
- at display
-      @code{BZ2_bzCompress} 
-         if @code{BZ_OK} is returned
-      no specific action needed in case of error
- at end display
-
- at subsection @code{BZ2_bzCompress}
- at example
-   int BZ2_bzCompress ( bz_stream *strm, int action );
- at end example
-Provides more input and/or output buffer space for the library.  The
-caller maintains input and output buffers, and calls @code{BZ2_bzCompress} to
-transfer data between them.
-
-Before each call to @code{BZ2_bzCompress}, @code{next_in} should point at
-the data to be compressed, and @code{avail_in} should indicate how many
-bytes the library may read.  @code{BZ2_bzCompress} updates @code{next_in},
- at code{avail_in} and @code{total_in} to reflect the number of bytes it
-has read.
-
-Similarly, @code{next_out} should point to a buffer in which the
-compressed data is to be placed, with @code{avail_out} indicating how
-much output space is available.  @code{BZ2_bzCompress} updates
- at code{next_out}, @code{avail_out} and @code{total_out} to reflect the
-number of bytes output.
-
-You may provide and remove as little or as much data as you like on each
-call of @code{BZ2_bzCompress}.  In the limit, it is acceptable to supply and
-remove data one byte at a time, although this would be terribly
-inefficient.  You should always ensure that at least one byte of output
-space is available at each call.
-
-A second purpose of @code{BZ2_bzCompress} is to request a change of mode of the
-compressed stream.  
-
-Conceptually, a compressed stream can be in one of four states: IDLE,
-RUNNING, FLUSHING and FINISHING.  Before initialisation
-(@code{BZ2_bzCompressInit}) and after termination (@code{BZ2_bzCompressEnd}), a
-stream is regarded as IDLE.
-
-Upon initialisation (@code{BZ2_bzCompressInit}), the stream is placed in the
-RUNNING state.  Subsequent calls to @code{BZ2_bzCompress} should pass
- at code{BZ_RUN} as the requested action; other actions are illegal and
-will result in @code{BZ_SEQUENCE_ERROR}.
-
-At some point, the calling program will have provided all the input data
-it wants to.  It will then want to finish up -- in effect, asking the
-library to process any data it might have buffered internally.  In this
-state, @code{BZ2_bzCompress} will no longer attempt to read data from
- at code{next_in}, but it will want to write data to @code{next_out}.
-Because the output buffer supplied by the user can be arbitrarily small,
-the finishing-up operation cannot necessarily be done with a single call
-of @code{BZ2_bzCompress}.
-
-Instead, the calling program passes @code{BZ_FINISH} as an action to
- at code{BZ2_bzCompress}.  This changes the stream's state to FINISHING.  Any
-remaining input (ie, @code{next_in[0 .. avail_in-1]}) is compressed and
-transferred to the output buffer.  To do this, @code{BZ2_bzCompress} must be
-called repeatedly until all the output has been consumed.  At that
-point, @code{BZ2_bzCompress} returns @code{BZ_STREAM_END}, and the stream's
-state is set back to IDLE.  @code{BZ2_bzCompressEnd} should then be
-called.
-
-Just to make sure the calling program does not cheat, the library makes
-a note of @code{avail_in} at the time of the first call to
- at code{BZ2_bzCompress} which has @code{BZ_FINISH} as an action (ie, at the
-time the program has announced its intention to not supply any more
-input).  By comparing this value with that of @code{avail_in} over
-subsequent calls to @code{BZ2_bzCompress}, the library can detect any
-attempts to slip in more data to compress.  Any calls for which this is
-detected will return @code{BZ_SEQUENCE_ERROR}.  This indicates a
-programming mistake which should be corrected.
-
-Instead of asking to finish, the calling program may ask
- at code{BZ2_bzCompress} to take all the remaining input, compress it and
-terminate the current (Burrows-Wheeler) compression block.  This could
-be useful for error control purposes.  The mechanism is analogous to
-that for finishing: call @code{BZ2_bzCompress} with an action of
- at code{BZ_FLUSH}, remove output data, and persist with the
- at code{BZ_FLUSH} action until the value @code{BZ_RUN} is returned.  As
-with finishing, @code{BZ2_bzCompress} detects any attempt to provide more
-input data once the flush has begun.
-
-Once the flush is complete, the stream returns to the normal RUNNING
-state.
-
-This all sounds pretty complex, but isn't really.  Here's a table
-which shows which actions are allowable in each state, what action
-will be taken, what the next state is, and what the non-error return
-values are.  Note that you can't explicitly ask what state the
-stream is in, but nor do you need to -- it can be inferred from the
-values returned by @code{BZ2_bzCompress}.
- at display
-IDLE/@code{any}           
-      Illegal.  IDLE state only exists after @code{BZ2_bzCompressEnd} or
-      before @code{BZ2_bzCompressInit}.
-      Return value = @code{BZ_SEQUENCE_ERROR}
-
-RUNNING/@code{BZ_RUN}     
-      Compress from @code{next_in} to @code{next_out} as much as possible.
-      Next state = RUNNING
-      Return value = @code{BZ_RUN_OK}
-
-RUNNING/@code{BZ_FLUSH}   
-      Remember current value of @code{next_in}.  Compress from @code{next_in}
-      to @code{next_out} as much as possible, but do not accept any more input.  
-      Next state = FLUSHING
-      Return value = @code{BZ_FLUSH_OK}
-
-RUNNING/@code{BZ_FINISH}  
-      Remember current value of @code{next_in}.  Compress from @code{next_in}
-      to @code{next_out} as much as possible, but do not accept any more input.
-      Next state = FINISHING
-      Return value = @code{BZ_FINISH_OK}
-
-FLUSHING/@code{BZ_FLUSH}  
-      Compress from @code{next_in} to @code{next_out} as much as possible, 
-      but do not accept any more input.  
-      If all the existing input has been used up and all compressed
-      output has been removed
-         Next state = RUNNING; Return value = @code{BZ_RUN_OK}
-      else
-         Next state = FLUSHING; Return value = @code{BZ_FLUSH_OK}
-
-FLUSHING/other     
-      Illegal.
-      Return value = @code{BZ_SEQUENCE_ERROR}
-
-FINISHING/@code{BZ_FINISH}  
-      Compress from @code{next_in} to @code{next_out} as much as possible,
-      but to not accept any more input.  
-      If all the existing input has been used up and all compressed
-      output has been removed
-         Next state = IDLE; Return value = @code{BZ_STREAM_END}
-      else
-         Next state = FINISHING; Return value = @code{BZ_FINISHING}
-
-FINISHING/other
-      Illegal.
-      Return value = @code{BZ_SEQUENCE_ERROR}
- at end display
-
-That still looks complicated?  Well, fair enough.  The usual sequence
-of calls for compressing a load of data is:
- at itemize @bullet
- at item Get started with @code{BZ2_bzCompressInit}.
- at item Shovel data in and shlurp out its compressed form using zero or more
-calls of @code{BZ2_bzCompress} with action = @code{BZ_RUN}.
- at item Finish up.  
-Repeatedly call @code{BZ2_bzCompress} with action = @code{BZ_FINISH}, 
-copying out the compressed output, until @code{BZ_STREAM_END} is returned.
- at item Close up and go home.  Call @code{BZ2_bzCompressEnd}.
- at end itemize
-If the data you want to compress fits into your input buffer all
-at once, you can skip the calls of @code{BZ2_bzCompress ( ..., BZ_RUN )} and 
-just do the @code{BZ2_bzCompress ( ..., BZ_FINISH )} calls.
-
-All required memory is allocated by @code{BZ2_bzCompressInit}.  The
-compression library can accept any data at all (obviously).  So you
-shouldn't get any error return values from the @code{BZ2_bzCompress} calls.
-If you do, they will be @code{BZ_SEQUENCE_ERROR}, and indicate a bug in
-your programming.
-
-Trivial other possible return values:
- at display
-      @code{BZ_PARAM_ERROR}   
-         if @code{strm} is @code{NULL}, or @code{strm->s} is @code{NULL}
- at end display
-
- at subsection @code{BZ2_bzCompressEnd}
- at example
-int BZ2_bzCompressEnd ( bz_stream *strm );
- at end example
-Releases all memory associated with a compression stream.
-
-Possible return values:
- at display
-   @code{BZ_PARAM_ERROR}    if @code{strm} is @code{NULL} or @code{strm->s} is @code{NULL}
-   @code{BZ_OK}    otherwise
- at end display
-
-
- at subsection @code{BZ2_bzDecompressInit}
- at example
-int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );
- at end example
-Prepares for decompression.  As with @code{BZ2_bzCompressInit}, a
- at code{bz_stream} record should be allocated and initialised before the
-call.  Fields @code{bzalloc}, @code{bzfree} and @code{opaque} should be
-set if a custom memory allocator is required, or made @code{NULL} for
-the normal @code{malloc}/@code{free} routines.  Upon return, the internal
-state will have been initialised, and @code{total_in} and
- at code{total_out} will be zero.
-
-For the meaning of parameter @code{verbosity}, see @code{BZ2_bzCompressInit}.
-
-If @code{small} is nonzero, the library will use an alternative
-decompression algorithm which uses less memory but at the cost of
-decompressing more slowly (roughly speaking, half the speed, but the
-maximum memory requirement drops to around 2300k).  See Chapter 2 for
-more information on memory management.
-
-Note that the amount of memory needed to decompress
-a stream cannot be determined until the stream's header has been read,
-so even if @code{BZ2_bzDecompressInit} succeeds, a subsequent
- at code{BZ2_bzDecompress} could fail with @code{BZ_MEM_ERROR}.
-
-Possible return values:
- at display
-      @code{BZ_CONFIG_ERROR}
-         if the library has been mis-compiled
-      @code{BZ_PARAM_ERROR}
-         if @code{(small != 0 && small != 1)}
-         or @code{(verbosity < 0 || verbosity > 4)}
-      @code{BZ_MEM_ERROR}
-         if insufficient memory is available
- at end display
-
-Allowable next actions:
- at display
-      @code{BZ2_bzDecompress}
-         if @code{BZ_OK} was returned
-      no specific action required in case of error
- at end display
-
- 
-
- at subsection @code{BZ2_bzDecompress}
- at example
-int BZ2_bzDecompress ( bz_stream *strm );
- at end example
-Provides more input and/out output buffer space for the library.  The
-caller maintains input and output buffers, and uses @code{BZ2_bzDecompress}
-to transfer data between them.
-
-Before each call to @code{BZ2_bzDecompress}, @code{next_in} 
-should point at the compressed data,
-and @code{avail_in} should indicate how many bytes the library
-may read.  @code{BZ2_bzDecompress} updates @code{next_in}, @code{avail_in} 
-and @code{total_in}
-to reflect the number of bytes it has read.
-
-Similarly, @code{next_out} should point to a buffer in which the uncompressed
-output is to be placed, with @code{avail_out} indicating how much output space
-is available.  @code{BZ2_bzCompress} updates @code{next_out},
- at code{avail_out} and @code{total_out} to reflect
-the number of bytes output.
-
-You may provide and remove as little or as much data as you like on
-each call of @code{BZ2_bzDecompress}.  
-In the limit, it is acceptable to
-supply and remove data one byte at a time, although this would be
-terribly inefficient.  You should always ensure that at least one
-byte of output space is available at each call.
-
-Use of @code{BZ2_bzDecompress} is simpler than @code{BZ2_bzCompress}.
-
-You should provide input and remove output as described above, and
-repeatedly call @code{BZ2_bzDecompress} until @code{BZ_STREAM_END} is
-returned.  Appearance of @code{BZ_STREAM_END} denotes that
- at code{BZ2_bzDecompress} has detected the logical end of the compressed
-stream.  @code{BZ2_bzDecompress} will not produce @code{BZ_STREAM_END} until
-all output data has been placed into the output buffer, so once
- at code{BZ_STREAM_END} appears, you are guaranteed to have available all
-the decompressed output, and @code{BZ2_bzDecompressEnd} can safely be
-called.
-
-If case of an error return value, you should call @code{BZ2_bzDecompressEnd}
-to clean up and release memory.
-
-Possible return values:
- at display
-      @code{BZ_PARAM_ERROR}
-         if @code{strm} is @code{NULL} or @code{strm->s} is @code{NULL}
-         or @code{strm->avail_out < 1}
-      @code{BZ_DATA_ERROR}
-         if a data integrity error is detected in the compressed stream
-      @code{BZ_DATA_ERROR_MAGIC}
-         if the compressed stream doesn't begin with the right magic bytes
-      @code{BZ_MEM_ERROR}
-         if there wasn't enough memory available
-      @code{BZ_STREAM_END}
-         if the logical end of the data stream was detected and all
-         output in has been consumed, eg @code{s->avail_out > 0}
-      @code{BZ_OK}
-         otherwise
- at end display
-Allowable next actions:
- at display
-      @code{BZ2_bzDecompress}
-         if @code{BZ_OK} was returned
-      @code{BZ2_bzDecompressEnd}
-         otherwise
- at end display
-
-
- at subsection @code{BZ2_bzDecompressEnd}
- at example
-int BZ2_bzDecompressEnd ( bz_stream *strm );
- at end example
-Releases all memory associated with a decompression stream.
-
-Possible return values:
- at display
-      @code{BZ_PARAM_ERROR}
-         if @code{strm} is @code{NULL} or @code{strm->s} is @code{NULL}
-      @code{BZ_OK}
-         otherwise
- at end display
-
-Allowable next actions:
- at display
-      None.
- at end display
-
-
- at section High-level interface
-
-This interface provides functions for reading and writing 
- at code{bzip2} format files.  First, some general points.
-
- at itemize @bullet
- at item All of the functions take an @code{int*} first argument,
-  @code{bzerror}.
-  After each call, @code{bzerror} should be consulted first to determine
-  the outcome of the call.  If @code{bzerror} is @code{BZ_OK}, 
-  the call completed
-  successfully, and only then should the return value of the function
-  (if any) be consulted.  If @code{bzerror} is @code{BZ_IO_ERROR}, 
-  there was an error
-  reading/writing the underlying compressed file, and you should
-  then consult @code{errno}/@code{perror} to determine the 
-  cause of the difficulty.
-  @code{bzerror} may also be set to various other values; precise details are
-  given on a per-function basis below.
- at item If @code{bzerror} indicates an error 
-  (ie, anything except @code{BZ_OK} and @code{BZ_STREAM_END}),
-  you should immediately call @code{BZ2_bzReadClose} (or @code{BZ2_bzWriteClose},
-  depending on whether you are attempting to read or to write)
-  to free up all resources associated
-  with the stream.  Once an error has been indicated, behaviour of all calls
-  except @code{BZ2_bzReadClose} (@code{BZ2_bzWriteClose}) is undefined.  
-  The implication is that (1) @code{bzerror} should
-  be checked after each call, and (2) if @code{bzerror} indicates an error, 
-  @code{BZ2_bzReadClose} (@code{BZ2_bzWriteClose}) should then be called to clean up.
- at item The @code{FILE*} arguments passed to
-   @code{BZ2_bzReadOpen}/@code{BZ2_bzWriteOpen}  
-  should be set to binary mode.
-  Most Unix systems will do this by default, but other platforms,
-  including Windows and Mac, will not.  If you omit this, you may
-  encounter problems when moving code to new platforms.
- at item Memory allocation requests are handled by
-  @code{malloc}/@code{free}.  
-  At present
-  there is no facility for user-defined memory allocators in the file I/O
-  functions (could easily be added, though).
- at end itemize
-
-
-
- at subsection @code{BZ2_bzReadOpen}
- at example
-   typedef void BZFILE;
-
-   BZFILE *BZ2_bzReadOpen ( int *bzerror, FILE *f, 
-                            int small, int verbosity,
-                            void *unused, int nUnused );
- at end example
-Prepare to read compressed data from file handle @code{f}.  @code{f}
-should refer to a file which has been opened for reading, and for which
-the error indicator (@code{ferror(f)})is not set.  If @code{small} is 1,
-the library will try to decompress using less memory, at the expense of
-speed.
-
-For reasons explained below, @code{BZ2_bzRead} will decompress the
- at code{nUnused} bytes starting at @code{unused}, before starting to read
-from the file @code{f}.  At most @code{BZ_MAX_UNUSED} bytes may be
-supplied like this.  If this facility is not required, you should pass
- at code{NULL} and @code{0} for @code{unused} and n at code{Unused}
-respectively.
-
-For the meaning of parameters @code{small} and @code{verbosity},
-see @code{BZ2_bzDecompressInit}.
-
-The amount of memory needed to decompress a file cannot be determined
-until the file's header has been read.  So it is possible that
- at code{BZ2_bzReadOpen} returns @code{BZ_OK} but a subsequent call of
- at code{BZ2_bzRead} will return @code{BZ_MEM_ERROR}.
-
-Possible assignments to @code{bzerror}:
- at display
-      @code{BZ_CONFIG_ERROR}
-         if the library has been mis-compiled
-      @code{BZ_PARAM_ERROR}
-         if @code{f} is @code{NULL} 
-         or @code{small} is neither @code{0} nor @code{1}                 
-         or @code{(unused == NULL && nUnused != 0)}
-         or @code{(unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED))}
-      @code{BZ_IO_ERROR}    
-         if @code{ferror(f)} is nonzero
-      @code{BZ_MEM_ERROR}   
-         if insufficient memory is available
-      @code{BZ_OK}
-         otherwise.
- at end display
-
-Possible return values:
- at display
-      Pointer to an abstract @code{BZFILE}        
-         if @code{bzerror} is @code{BZ_OK}   
-      @code{NULL}
-         otherwise
- at end display
-
-Allowable next actions:
- at display
-      @code{BZ2_bzRead}
-         if @code{bzerror} is @code{BZ_OK}   
-      @code{BZ2_bzClose} 
-         otherwise
- at end display
-
-
- at subsection @code{BZ2_bzRead}
- at example
-   int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );
- at end example
-Reads up to @code{len} (uncompressed) bytes from the compressed file 
- at code{b} into
-the buffer @code{buf}.  If the read was successful, 
- at code{bzerror} is set to @code{BZ_OK}
-and the number of bytes read is returned.  If the logical end-of-stream
-was detected, @code{bzerror} will be set to @code{BZ_STREAM_END}, 
-and the number
-of bytes read is returned.  All other @code{bzerror} values denote an error.
-
- at code{BZ2_bzRead} will supply @code{len} bytes,
-unless the logical stream end is detected
-or an error occurs.  Because of this, it is possible to detect the 
-stream end by observing when the number of bytes returned is 
-less than the number
-requested.  Nevertheless, this is regarded as inadvisable; you should
-instead check @code{bzerror} after every call and watch out for
- at code{BZ_STREAM_END}.
-
-Internally, @code{BZ2_bzRead} copies data from the compressed file in chunks
-of size @code{BZ_MAX_UNUSED} bytes
-before decompressing it.  If the file contains more bytes than strictly
-needed to reach the logical end-of-stream, @code{BZ2_bzRead} will almost certainly
-read some of the trailing data before signalling @code{BZ_SEQUENCE_END}.
-To collect the read but unused data once @code{BZ_SEQUENCE_END} has 
-appeared, call @code{BZ2_bzReadGetUnused} immediately before @code{BZ2_bzReadClose}.
-
-Possible assignments to @code{bzerror}:
- at display
-      @code{BZ_PARAM_ERROR}
-         if @code{b} is @code{NULL} or @code{buf} is @code{NULL} or @code{len < 0}
-      @code{BZ_SEQUENCE_ERROR} 
-         if @code{b} was opened with @code{BZ2_bzWriteOpen}
-      @code{BZ_IO_ERROR} 
-         if there is an error reading from the compressed file
-      @code{BZ_UNEXPECTED_EOF} 
-         if the compressed file ended before the logical end-of-stream was detected
-      @code{BZ_DATA_ERROR} 
-         if a data integrity error was detected in the compressed stream
-      @code{BZ_DATA_ERROR_MAGIC}
-         if the stream does not begin with the requisite header bytes (ie, is not 
-         a @code{bzip2} data file).  This is really a special case of @code{BZ_DATA_ERROR}.
-      @code{BZ_MEM_ERROR} 
-         if insufficient memory was available
-      @code{BZ_STREAM_END} 
-         if the logical end of stream was detected.
-      @code{BZ_OK}
-         otherwise.
- at end display
-
-Possible return values:
- at display
-      number of bytes read
-         if @code{bzerror} is @code{BZ_OK} or @code{BZ_STREAM_END}
-      undefined
-         otherwise
- at end display
-
-Allowable next actions:
- at display
-      collect data from @code{buf}, then @code{BZ2_bzRead} or @code{BZ2_bzReadClose}
-         if @code{bzerror} is @code{BZ_OK} 
-      collect data from @code{buf}, then @code{BZ2_bzReadClose} or @code{BZ2_bzReadGetUnused} 
-         if @code{bzerror} is @code{BZ_SEQUENCE_END}   
-      @code{BZ2_bzReadClose} 
-         otherwise
- at end display
-
-
-
- at subsection @code{BZ2_bzReadGetUnused}
- at example
-   void BZ2_bzReadGetUnused ( int* bzerror, BZFILE *b, 
-                              void** unused, int* nUnused );
- at end example
-Returns data which was read from the compressed file but was not needed
-to get to the logical end-of-stream.  @code{*unused} is set to the address
-of the data, and @code{*nUnused} to the number of bytes.  @code{*nUnused} will
-be set to a value between @code{0} and @code{BZ_MAX_UNUSED} inclusive.
-
-This function may only be called once @code{BZ2_bzRead} has signalled 
- at code{BZ_STREAM_END} but before @code{BZ2_bzReadClose}.
-
-Possible assignments to @code{bzerror}:
- at display
-      @code{BZ_PARAM_ERROR} 
-         if @code{b} is @code{NULL} 
-         or @code{unused} is @code{NULL} or @code{nUnused} is @code{NULL}
-      @code{BZ_SEQUENCE_ERROR} 
-         if @code{BZ_STREAM_END} has not been signalled
-         or if @code{b} was opened with @code{BZ2_bzWriteOpen}
-     @code{BZ_OK}
-         otherwise
- at end display
-
-Allowable next actions:
- at display 
-      @code{BZ2_bzReadClose}
- at end display
-
-
- at subsection @code{BZ2_bzReadClose}
- at example
-   void BZ2_bzReadClose ( int *bzerror, BZFILE *b );
- at end example
-Releases all memory pertaining to the compressed file @code{b}.  
- at code{BZ2_bzReadClose} does not call @code{fclose} on the underlying file
-handle, so you should do that yourself if appropriate.
- at code{BZ2_bzReadClose} should be called to clean up after all error
-situations.
-
-Possible assignments to @code{bzerror}:
- at display
-      @code{BZ_SEQUENCE_ERROR} 
-         if @code{b} was opened with @code{BZ2_bzOpenWrite} 
-      @code{BZ_OK} 
-         otherwise
- at end display
-
-Allowable next actions:
- at display
-      none
- at end display
-
-
-
- at subsection @code{BZ2_bzWriteOpen}
- at example
-   BZFILE *BZ2_bzWriteOpen ( int *bzerror, FILE *f, 
-                             int blockSize100k, int verbosity,
-                             int workFactor );
- at end example
-Prepare to write compressed data to file handle @code{f}.  
- at code{f} should refer to
-a file which has been opened for writing, and for which the error
-indicator (@code{ferror(f)})is not set.  
-
-For the meaning of parameters @code{blockSize100k},
- at code{verbosity} and @code{workFactor}, see
-@* @code{BZ2_bzCompressInit}.
-
-All required memory is allocated at this stage, so if the call
-completes successfully, @code{BZ_MEM_ERROR} cannot be signalled by a
-subsequent call to @code{BZ2_bzWrite}.
-
-Possible assignments to @code{bzerror}:
- at display 
-      @code{BZ_CONFIG_ERROR}
-         if the library has been mis-compiled
-      @code{BZ_PARAM_ERROR} 
-         if @code{f} is @code{NULL} 
-         or @code{blockSize100k < 1} or @code{blockSize100k > 9}
-      @code{BZ_IO_ERROR} 
-         if @code{ferror(f)} is nonzero
-      @code{BZ_MEM_ERROR} 
-         if insufficient memory is available
-      @code{BZ_OK} 
-         otherwise
- at end display
-
-Possible return values:
- at display
-      Pointer to an abstract @code{BZFILE}  
-         if @code{bzerror} is @code{BZ_OK}   
-      @code{NULL} 
-         otherwise
- at end display
-
-Allowable next actions:
- at display
-      @code{BZ2_bzWrite} 
-         if @code{bzerror} is @code{BZ_OK} 
-         (you could go directly to @code{BZ2_bzWriteClose}, but this would be pretty pointless)
-      @code{BZ2_bzWriteClose} 
-         otherwise
- at end display
-
-
-
- at subsection @code{BZ2_bzWrite}
- at example
-   void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );
- at end example
-Absorbs @code{len} bytes from the buffer @code{buf}, eventually to be
-compressed and written to the file.
-
-Possible assignments to @code{bzerror}:
- at display
-      @code{BZ_PARAM_ERROR} 
-         if @code{b} is @code{NULL} or @code{buf} is @code{NULL} or @code{len < 0}
-      @code{BZ_SEQUENCE_ERROR} 
-         if b was opened with @code{BZ2_bzReadOpen}
-      @code{BZ_IO_ERROR} 
-         if there is an error writing the compressed file.
-      @code{BZ_OK} 
-         otherwise
- at end display
-
-
-
-
- at subsection @code{BZ2_bzWriteClose}
- at example
-   void BZ2_bzWriteClose ( int *bzerror, BZFILE* f,
-                           int abandon,
-                           unsigned int* nbytes_in,
-                           unsigned int* nbytes_out );
-
-   void BZ2_bzWriteClose64 ( int *bzerror, BZFILE* f,
-                             int abandon,
-                             unsigned int* nbytes_in_lo32,
-                             unsigned int* nbytes_in_hi32,
-                             unsigned int* nbytes_out_lo32,
-                             unsigned int* nbytes_out_hi32 );
- at end example
-
-Compresses and flushes to the compressed file all data so far supplied
-by @code{BZ2_bzWrite}.  The logical end-of-stream markers are also written, so
-subsequent calls to @code{BZ2_bzWrite} are illegal.  All memory associated 
-with the compressed file @code{b} is released.  
- at code{fflush} is called on the
-compressed file, but it is not @code{fclose}'d.
-
-If @code{BZ2_bzWriteClose} is called to clean up after an error, the only
-action is to release the memory.  The library records the error codes
-issued by previous calls, so this situation will be detected
-automatically.  There is no attempt to complete the compression
-operation, nor to @code{fflush} the compressed file.  You can force this
-behaviour to happen even in the case of no error, by passing a nonzero
-value to @code{abandon}.
-
-If @code{nbytes_in} is non-null, @code{*nbytes_in} will be set to be the
-total volume of uncompressed data handled.  Similarly, @code{nbytes_out}
-will be set to the total volume of compressed data written.  For 
-compatibility with older versions of the library, @code{BZ2_bzWriteClose}
-only yields the lower 32 bits of these counts.  Use
- at code{BZ2_bzWriteClose64} if you want the full 64 bit counts.  These
-two functions are otherwise absolutely identical.
-
-
-Possible assignments to @code{bzerror}:
- at display
-      @code{BZ_SEQUENCE_ERROR} 
-         if @code{b} was opened with @code{BZ2_bzReadOpen}
-      @code{BZ_IO_ERROR} 
-         if there is an error writing the compressed file
-      @code{BZ_OK} 
-         otherwise
- at end display
-
- at subsection Handling embedded compressed data streams
-
-The high-level library facilitates use of
- at code{bzip2} data streams which form some part of a surrounding, larger
-data stream.
- at itemize @bullet
- at item For writing, the library takes an open file handle, writes
-compressed data to it, @code{fflush}es it but does not @code{fclose} it.
-The calling application can write its own data before and after the
-compressed data stream, using that same file handle.
- at item Reading is more complex, and the facilities are not as general
-as they could be since generality is hard to reconcile with efficiency.
- at code{BZ2_bzRead} reads from the compressed file in blocks of size
- at code{BZ_MAX_UNUSED} bytes, and in doing so probably will overshoot
-the logical end of compressed stream.
-To recover this data once decompression has
-ended, call @code{BZ2_bzReadGetUnused} after the last call of @code{BZ2_bzRead}
-(the one returning @code{BZ_STREAM_END}) but before calling
- at code{BZ2_bzReadClose}.
- at end itemize
-
-This mechanism makes it easy to decompress multiple @code{bzip2}
-streams placed end-to-end.  As the end of one stream, when @code{BZ2_bzRead}
-returns @code{BZ_STREAM_END}, call @code{BZ2_bzReadGetUnused} to collect the
-unused data (copy it into your own buffer somewhere).  
-That data forms the start of the next compressed stream.
-To start uncompressing that next stream, call @code{BZ2_bzReadOpen} again,
-feeding in the unused data via the @code{unused}/@code{nUnused}
-parameters.
-Keep doing this until @code{BZ_STREAM_END} return coincides with the
-physical end of file (@code{feof(f)}).  In this situation
- at code{BZ2_bzReadGetUnused}
-will of course return no data.
-
-This should give some feel for how the high-level interface can be used.
-If you require extra flexibility, you'll have to bite the bullet and get
-to grips with the low-level interface.
-
- at subsection Standard file-reading/writing code
-Here's how you'd write data to a compressed file:
- at example @code
-FILE*   f;
-BZFILE* b;
-int     nBuf;
-char    buf[ /* whatever size you like */ ];
-int     bzerror;
-int     nWritten;
-
-f = fopen ( "myfile.bz2", "w" );
-if (!f) @{
-   /* handle error */
-@}
-b = BZ2_bzWriteOpen ( &bzerror, f, 9 );
-if (bzerror != BZ_OK) @{
-   BZ2_bzWriteClose ( b );
-   /* handle error */
-@}
-
-while ( /* condition */ ) @{
-   /* get data to write into buf, and set nBuf appropriately */
-   nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf );
-   if (bzerror == BZ_IO_ERROR) @{ 
-      BZ2_bzWriteClose ( &bzerror, b );
-      /* handle error */
-   @}
-@}
-
-BZ2_bzWriteClose ( &bzerror, b );
-if (bzerror == BZ_IO_ERROR) @{
-   /* handle error */
-@}
- at end example
-And to read from a compressed file:
- at example
-FILE*   f;
-BZFILE* b;
-int     nBuf;
-char    buf[ /* whatever size you like */ ];
-int     bzerror;
-int     nWritten;
-
-f = fopen ( "myfile.bz2", "r" );
-if (!f) @{
-   /* handle error */
-@}
-b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 );
-if (bzerror != BZ_OK) @{
-   BZ2_bzReadClose ( &bzerror, b );
-   /* handle error */
-@}
-
-bzerror = BZ_OK;
-while (bzerror == BZ_OK && /* arbitrary other conditions */) @{
-   nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ );
-   if (bzerror == BZ_OK) @{
-      /* do something with buf[0 .. nBuf-1] */
-   @}
-@}
-if (bzerror != BZ_STREAM_END) @{
-   BZ2_bzReadClose ( &bzerror, b );
-   /* handle error */
-@} else @{
-   BZ2_bzReadClose ( &bzerror );
-@}
- at end example
-
-
-
- at section Utility functions
- at subsection @code{BZ2_bzBuffToBuffCompress}
- at example
-   int BZ2_bzBuffToBuffCompress( char*         dest,
-                                 unsigned int* destLen,
-                                 char*         source,
-                                 unsigned int  sourceLen,
-                                 int           blockSize100k,
-                                 int           verbosity,
-                                 int           workFactor );
- at end example
-Attempts to compress the data in @code{source[0 .. sourceLen-1]}
-into the destination buffer, @code{dest[0 .. *destLen-1]}.
-If the destination buffer is big enough, @code{*destLen} is
-set to the size of the compressed data, and @code{BZ_OK} is
-returned.  If the compressed data won't fit, @code{*destLen}
-is unchanged, and @code{BZ_OUTBUFF_FULL} is returned.
-
-Compression in this manner is a one-shot event, done with a single call
-to this function.  The resulting compressed data is a complete
- at code{bzip2} format data stream.  There is no mechanism for making
-additional calls to provide extra input data.  If you want that kind of
-mechanism, use the low-level interface.
-
-For the meaning of parameters @code{blockSize100k}, @code{verbosity}
-and @code{workFactor}, @* see @code{BZ2_bzCompressInit}.
-
-To guarantee that the compressed data will fit in its buffer, allocate
-an output buffer of size 1% larger than the uncompressed data, plus
-six hundred extra bytes.
-
- at code{BZ2_bzBuffToBuffDecompress} will not write data at or
-beyond @code{dest[*destLen]}, even in case of buffer overflow.
-
-Possible return values:
- at display
-      @code{BZ_CONFIG_ERROR}
-         if the library has been mis-compiled
-      @code{BZ_PARAM_ERROR} 
-         if @code{dest} is @code{NULL} or @code{destLen} is @code{NULL}
-         or @code{blockSize100k < 1} or @code{blockSize100k > 9}
-         or @code{verbosity < 0} or @code{verbosity > 4} 
-         or @code{workFactor < 0} or @code{workFactor > 250}
-      @code{BZ_MEM_ERROR}
-         if insufficient memory is available 
-      @code{BZ_OUTBUFF_FULL}
-         if the size of the compressed data exceeds @code{*destLen}
-      @code{BZ_OK} 
-         otherwise
- at end display
-
-
-
- at subsection @code{BZ2_bzBuffToBuffDecompress}
- at example
-   int BZ2_bzBuffToBuffDecompress ( char*         dest,
-                                    unsigned int* destLen,
-                                    char*         source,
-                                    unsigned int  sourceLen,
-                                    int           small,
-                                    int           verbosity );
- at end example
-Attempts to decompress the data in @code{source[0 .. sourceLen-1]}
-into the destination buffer, @code{dest[0 .. *destLen-1]}.
-If the destination buffer is big enough, @code{*destLen} is
-set to the size of the uncompressed data, and @code{BZ_OK} is
-returned.  If the compressed data won't fit, @code{*destLen}
-is unchanged, and @code{BZ_OUTBUFF_FULL} is returned.
-
- at code{source} is assumed to hold a complete @code{bzip2} format
-data stream.  @* @code{BZ2_bzBuffToBuffDecompress} tries to decompress
-the entirety of the stream into the output buffer.
-
-For the meaning of parameters @code{small} and @code{verbosity},
-see @code{BZ2_bzDecompressInit}.
-
-Because the compression ratio of the compressed data cannot be known in
-advance, there is no easy way to guarantee that the output buffer will
-be big enough.  You may of course make arrangements in your code to
-record the size of the uncompressed data, but such a mechanism is beyond
-the scope of this library.
-
- at code{BZ2_bzBuffToBuffDecompress} will not write data at or
-beyond @code{dest[*destLen]}, even in case of buffer overflow.
-
-Possible return values:
- at display
-      @code{BZ_CONFIG_ERROR}
-         if the library has been mis-compiled
-      @code{BZ_PARAM_ERROR} 
-         if @code{dest} is @code{NULL} or @code{destLen} is @code{NULL}
-         or @code{small != 0 && small != 1}
-         or @code{verbosity < 0} or @code{verbosity > 4} 
-      @code{BZ_MEM_ERROR}
-         if insufficient memory is available 
-      @code{BZ_OUTBUFF_FULL}
-         if the size of the compressed data exceeds @code{*destLen}
-      @code{BZ_DATA_ERROR}
-         if a data integrity error was detected in the compressed data
-      @code{BZ_DATA_ERROR_MAGIC}
-         if the compressed data doesn't begin with the right magic bytes
-      @code{BZ_UNEXPECTED_EOF}
-         if the compressed data ends unexpectedly
-      @code{BZ_OK} 
-         otherwise
- at end display
-
-
-
- at section @code{zlib} compatibility functions
-Yoshioka Tsuneo has contributed some functions to
-give better @code{zlib} compatibility.  These functions are
- at code{BZ2_bzopen}, @code{BZ2_bzread}, @code{BZ2_bzwrite}, @code{BZ2_bzflush},
- at code{BZ2_bzclose},
- at code{BZ2_bzerror} and @code{BZ2_bzlibVersion}.
-These functions are not (yet) officially part of
-the library.  If they break, you get to keep all the pieces.
-Nevertheless, I think they work ok.
- at example
-typedef void BZFILE;
-
-const char * BZ2_bzlibVersion ( void );
- at end example
-Returns a string indicating the library version.
- at example
-BZFILE * BZ2_bzopen  ( const char *path, const char *mode );
-BZFILE * BZ2_bzdopen ( int        fd,    const char *mode );
- at end example
-Opens a @code{.bz2} file for reading or writing, using either its name
-or a pre-existing file descriptor. 
-Analogous to @code{fopen} and @code{fdopen}.
- at example         
-int BZ2_bzread  ( BZFILE* b, void* buf, int len );
-int BZ2_bzwrite ( BZFILE* b, void* buf, int len );
- at end example
-Reads/writes data from/to a previously opened @code{BZFILE}.
-Analogous to @code{fread} and @code{fwrite}.
- at example
-int  BZ2_bzflush ( BZFILE* b );
-void BZ2_bzclose ( BZFILE* b );
- at end example
-Flushes/closes a @code{BZFILE}.  @code{BZ2_bzflush} doesn't actually do
-anything.  Analogous to @code{fflush} and @code{fclose}.
-
- at example 
-const char * BZ2_bzerror ( BZFILE *b, int *errnum )
- at end example
-Returns a string describing the more recent error status of
- at code{b}, and also sets @code{*errnum} to its numerical value.
-
-
- at section Using the library in a @code{stdio}-free environment
-
- at subsection Getting rid of @code{stdio}
-
-In a deeply embedded application, you might want to use just
-the memory-to-memory functions.  You can do this conveniently
-by compiling the library with preprocessor symbol @code{BZ_NO_STDIO}
-defined.  Doing this gives you a library containing only the following
-eight functions:
-
- at code{BZ2_bzCompressInit}, @code{BZ2_bzCompress}, @code{BZ2_bzCompressEnd} @*
- at code{BZ2_bzDecompressInit}, @code{BZ2_bzDecompress}, @code{BZ2_bzDecompressEnd} @*
- at code{BZ2_bzBuffToBuffCompress}, @code{BZ2_bzBuffToBuffDecompress}
-
-When compiled like this, all functions will ignore @code{verbosity}
-settings.
-
- at subsection Critical error handling
- at code{libbzip2} contains a number of internal assertion checks which
-should, needless to say, never be activated.  Nevertheless, if an
-assertion should fail, behaviour depends on whether or not the library
-was compiled with @code{BZ_NO_STDIO} set.
-
-For a normal compile, an assertion failure yields the message
- at example
-   bzip2/libbzip2: internal error number N.
-   This is a bug in bzip2/libbzip2, 1.0.2, 30-Dec-2001.
-   Please report it to me at: jseward@@acm.org.  If this happened
-   when you were using some program which uses libbzip2 as a
-   component, you should also report this bug to the author(s)
-   of that program.  Please make an effort to report this bug;
-   timely and accurate bug reports eventually lead to higher
-   quality software.  Thanks.  Julian Seward, 30 December 2001.
- at end example
-where @code{N} is some error code number.  If @code{N == 1007}, it also
-prints some extra text advising the reader that unreliable memory is
-often associated with internal error 1007.  (This is a
-frequently-observed-phenomenon with versions 1.0.0/1.0.1).
-
- at code{exit(3)} is then called.
-
-For a @code{stdio}-free library, assertion failures result
-in a call to a function declared as:
- at example
-   extern void bz_internal_error ( int errcode );
- at end example
-The relevant code is passed as a parameter.  You should supply
-such a function.
-
-In either case, once an assertion failure has occurred, any 
- at code{bz_stream} records involved can be regarded as invalid.
-You should not attempt to resume normal operation with them.
-
-You may, of course, change critical error handling to suit
-your needs.  As I said above, critical errors indicate bugs
-in the library and should not occur.  All "normal" error
-situations are indicated via error return codes from functions,
-and can be recovered from.
-
-
- at section Making a Windows DLL
-Everything related to Windows has been contributed by Yoshioka Tsuneo
-@* (@code{QWF00133@@niftyserve.or.jp} /
- at code{tsuneo-y@@is.aist-nara.ac.jp}), so you should send your queries to
-him (but perhaps Cc: me, @code{jseward@@acm.org}).
-
-My vague understanding of what to do is: using Visual C++ 5.0,
-open the project file @code{libbz2.dsp}, and build.  That's all.
-
-If you can't
-open the project file for some reason, make a new one, naming these files:
- at code{blocksort.c}, @code{bzlib.c}, @code{compress.c}, 
- at code{crctable.c}, @code{decompress.c}, @code{huffman.c}, @*
- at code{randtable.c} and @code{libbz2.def}.  You will also need
-to name the header files @code{bzlib.h} and @code{bzlib_private.h}.
-
-If you don't use VC++, you may need to define the proprocessor symbol
- at code{_WIN32}. 
-
-Finally, @code{dlltest.c} is a sample program using the DLL.  It has a
-project file, @code{dlltest.dsp}.
-
-If you just want a makefile for Visual C, have a look at
- at code{makefile.msc}.
-
-Be aware that if you compile @code{bzip2} itself on Win32, you must set
- at code{BZ_UNIX} to 0 and @code{BZ_LCCWIN32} to 1, in the file
- at code{bzip2.c}, before compiling.  Otherwise the resulting binary won't
-work correctly.
-
-I haven't tried any of this stuff myself, but it all looks plausible.
-
-
-
- at chapter Miscellanea
-
-These are just some random thoughts of mine.  Your mileage may
-vary.
-
- at section Limitations of the compressed file format
- at code{bzip2-1.0}, @code{0.9.5} and @code{0.9.0}
-use exactly the same file format as the previous
-version, @code{bzip2-0.1}.  This decision was made in the interests of
-stability.  Creating yet another incompatible compressed file format
-would create further confusion and disruption for users.
-
-Nevertheless, this is not a painless decision.  Development
-work since the release of @code{bzip2-0.1} in August 1997
-has shown complexities in the file format which slow down
-decompression and, in retrospect, are unnecessary.  These are:
- at itemize @bullet
- at item The run-length encoder, which is the first of the 
-      compression transformations, is entirely irrelevant.
-      The original purpose was to protect the sorting algorithm
-      from the very worst case input: a string of repeated
-      symbols.  But algorithm steps Q6a and Q6b in the original
-      Burrows-Wheeler technical report (SRC-124) show how
-      repeats can be handled without difficulty in block
-      sorting.
- at item The randomisation mechanism doesn't really need to be
-      there.  Udi Manber and Gene Myers published a suffix
-      array construction algorithm a few years back, which
-      can be employed to sort any block, no matter how 
-      repetitive, in O(N log N) time.  Subsequent work by
-      Kunihiko Sadakane has produced a derivative O(N (log N)^2) 
-      algorithm which usually outperforms the Manber-Myers
-      algorithm.
-
-      I could have changed to Sadakane's algorithm, but I find
-      it to be slower than @code{bzip2}'s existing algorithm for
-      most inputs, and the randomisation mechanism protects
-      adequately against bad cases.  I didn't think it was
-      a good tradeoff to make.  Partly this is due to the fact
-      that I was not flooded with email complaints about
-      @code{bzip2-0.1}'s performance on repetitive data, so
-      perhaps it isn't a problem for real inputs.
-
-      Probably the best long-term solution,
-      and the one I have incorporated into 0.9.5 and above,
-      is to use the existing sorting
-      algorithm initially, and fall back to a O(N (log N)^2)
-      algorithm if the standard algorithm gets into difficulties.
- at item The compressed file format was never designed to be
-      handled by a library, and I have had to jump though
-      some hoops to produce an efficient implementation of
-      decompression.  It's a bit hairy.  Try passing
-      @code{decompress.c} through the C preprocessor 
-      and you'll see what I mean.  Much of this complexity
-      could have been avoided if the compressed size of
-      each block of data was recorded in the data stream.
- at item An Adler-32 checksum, rather than a CRC32 checksum,
-      would be faster to compute.
- at end itemize
-It would be fair to say that the @code{bzip2} format was frozen
-before I properly and fully understood the performance
-consequences of doing so.
-
-Improvements which I was able to incorporate into
-0.9.0, despite using the same file format, are:
- at itemize @bullet
- at item Single array implementation of the inverse BWT.  This
-      significantly speeds up decompression, presumably
-      because it reduces the number of cache misses.
- at item Faster inverse MTF transform for large MTF values.  The
-      new implementation is based on the notion of sliding blocks
-      of values.
- at item @code{bzip2-0.9.0} now reads and writes files with @code{fread}
-      and @code{fwrite}; version 0.1 used @code{putc} and @code{getc}.
-      Duh!  Well, you live and learn.
-
- at end itemize
-Further ahead, it would be nice 
-to be able to do random access into files.  This will 
-require some careful design of compressed file formats.
-
-
-
- at section Portability issues
-After some consideration, I have decided not to use
-GNU @code{autoconf} to configure 0.9.5 or 1.0.
-
- at code{autoconf}, admirable and wonderful though it is, 
-mainly assists with portability problems between Unix-like
-platforms.  But @code{bzip2} doesn't have much in the way
-of portability problems on Unix; most of the difficulties appear
-when porting to the Mac, or to Microsoft's operating systems.
- at code{autoconf} doesn't help in those cases, and brings in a 
-whole load of new complexity.
-
-Most people should be able to compile the library and program
-under Unix straight out-of-the-box, so to speak, especially 
-if you have a version of GNU C available.
-
-There are a couple of @code{__inline__} directives in the code.  GNU C
-(@code{gcc}) should be able to handle them.  If you're not using
-GNU C, your C compiler shouldn't see them at all.
-If your compiler does, for some reason, see them and doesn't
-like them, just @code{#define} @code{__inline__} to be @code{/* */}.  One
-easy way to do this is to compile with the flag @code{-D__inline__=}, 
-which should be understood by most Unix compilers.
-
-If you still have difficulties, try compiling with the macro
- at code{BZ_STRICT_ANSI} defined.  This should enable you to build the
-library in a strictly ANSI compliant environment.  Building the program
-itself like this is dangerous and not supported, since you remove
- at code{bzip2}'s checks against compressing directories, symbolic links,
-devices, and other not-really-a-file entities.  This could cause
-filesystem corruption!
-
-One other thing: if you create a @code{bzip2} binary for public
-distribution, please try and link it statically (@code{gcc -s}).  This
-avoids all sorts of library-version issues that others may encounter
-later on.
-
-If you build @code{bzip2} on Win32, you must set @code{BZ_UNIX} to 0 and
- at code{BZ_LCCWIN32} to 1, in the file @code{bzip2.c}, before compiling.
-Otherwise the resulting binary won't work correctly.
-
-
-
- at section Reporting bugs
-I tried pretty hard to make sure @code{bzip2} is
-bug free, both by design and by testing.  Hopefully
-you'll never need to read this section for real.
-
-Nevertheless, if @code{bzip2} dies with a segmentation
-fault, a bus error or an internal assertion failure, it
-will ask you to email me a bug report.  Experience with
-version 0.1 shows that almost all these problems can
-be traced to either compiler bugs or hardware problems.
- at itemize @bullet
- at item
-Recompile the program with no optimisation, and see if it
-works.  And/or try a different compiler.
-I heard all sorts of stories about various flavours
-of GNU C (and other compilers) generating bad code for
- at code{bzip2}, and I've run across two such examples myself.
-
-2.7.X versions of GNU C are known to generate bad code from
-time to time, at high optimisation levels.  
-If you get problems, try using the flags
- at code{-O2} @code{-fomit-frame-pointer} @code{-fno-strength-reduce}.
-You should specifically @emph{not} use @code{-funroll-loops}.
-
-You may notice that the Makefile runs six tests as part of
-the build process.  If the program passes all of these, it's
-a pretty good (but not 100%) indication that the compiler has
-done its job correctly.
- at item
-If @code{bzip2} crashes randomly, and the crashes are not
-repeatable, you may have a flaky memory subsystem.  @code{bzip2}
-really hammers your memory hierarchy, and if it's a bit marginal,
-you may get these problems.  Ditto if your disk or I/O subsystem
-is slowly failing.  Yup, this really does happen.
-
-Try using a different machine of the same type, and see if
-you can repeat the problem.
- at item This isn't really a bug, but ... If @code{bzip2} tells
-you your file is corrupted on decompression, and you
-obtained the file via FTP, there is a possibility that you
-forgot to tell FTP to do a binary mode transfer.  That absolutely
-will cause the file to be non-decompressible.  You'll have to transfer
-it again.
- at end itemize
-
-If you've incorporated @code{libbzip2} into your own program
-and are getting problems, please, please, please, check that the 
-parameters you are passing in calls to the library, are
-correct, and in accordance with what the documentation says
-is allowable.  I have tried to make the library robust against
-such problems, but I'm sure I haven't succeeded.
-
-Finally, if the above comments don't help, you'll have to send
-me a bug report.  Now, it's just amazing how many people will 
-send me a bug report saying something like
- at display
-   bzip2 crashed with segmentation fault on my machine
- at end display
-and absolutely nothing else.  Needless to say, a such a report
-is @emph{totally, utterly, completely and comprehensively 100% useless; 
-a waste of your time, my time, and net bandwidth}.
-With no details at all, there's no way I can possibly begin
-to figure out what the problem is.
-
-The rules of the game are: facts, facts, facts.  Don't omit
-them because "oh, they won't be relevant".  At the bare 
-minimum:
- at display
-   Machine type.  Operating system version.  
-   Exact version of @code{bzip2} (do @code{bzip2 -V}).  
-   Exact version of the compiler used.  
-   Flags passed to the compiler.
- at end display
-However, the most important single thing that will help me is
-the file that you were trying to compress or decompress at the
-time the problem happened.  Without that, my ability to do anything
-more than speculate about the cause, is limited.
-
-Please remember that I connect to the Internet with a modem, so
-you should contact me before mailing me huge files.
-
-
- at section Did you get the right package?
-
- at code{bzip2} is a resource hog.  It soaks up large amounts of CPU cycles
-and memory.  Also, it gives very large latencies.  In the worst case, you
-can feed many megabytes of uncompressed data into the library before
-getting any compressed output, so this probably rules out applications
-requiring interactive behaviour.
-
-These aren't faults of my implementation, I hope, but more
-an intrinsic property of the Burrows-Wheeler transform (unfortunately).  
-Maybe this isn't what you want.
-
-If you want a compressor and/or library which is faster, uses less
-memory but gets pretty good compression, and has minimal latency,
-consider Jean-loup
-Gailly's and Mark Adler's work, @code{zlib-1.1.3} and
- at code{gzip-1.2.4}.  Look for them at
-
- at code{http://www.zlib.org} and
- at code{http://www.gzip.org} respectively.
-
-For something faster and lighter still, you might try Markus F X J
-Oberhumer's @code{LZO} real-time compression/decompression library, at
-@* @code{http://wildsau.idv.uni-linz.ac.at/mfx/lzo.html}.
-
-If you want to use the @code{bzip2} algorithms to compress small blocks
-of data, 64k bytes or smaller, for example on an on-the-fly disk
-compressor, you'd be well advised not to use this library.  Instead,
-I've made a special library tuned for that kind of use.  It's part of
- at code{e2compr-0.40}, an on-the-fly disk compressor for the Linux
- at code{ext2} filesystem.  Look at
- at code{http://www.netspace.net.au/~reiter/e2compr}.
-
-
-
- at section Testing
-
-A record of the tests I've done.
-
-First, some data sets:
- at itemize @bullet
- at item B: a directory containing 6001 files, one for every length in the
-      range 0 to 6000 bytes.  The files contain random lowercase
-      letters.  18.7 megabytes.
- at item H: my home directory tree.  Documents, source code, mail files,
-      compressed data.  H contains B, and also a directory of 
-      files designed as boundary cases for the sorting; mostly very
-      repetitive, nasty files.  565 megabytes.
- at item A: directory tree holding various applications built from source:
-      @code{egcs}, @code{gcc-2.8.1}, KDE, GTK, Octave, etc.
-      2200 megabytes.
- at end itemize
-The tests conducted are as follows.  Each test means compressing 
-(a copy of) each file in the data set, decompressing it and
-comparing it against the original.
-
-First, a bunch of tests with block sizes and internal buffer
-sizes set very small, 
-to detect any problems with the
-blocking and buffering mechanisms.  
-This required modifying the source code so as to try to 
-break it.
- at enumerate
- at item Data set H, with
-      buffer size of 1 byte, and block size of 23 bytes.
- at item Data set B, buffer sizes 1 byte, block size 1 byte.
- at item As (2) but small-mode decompression.
- at item As (2) with block size 2 bytes.
- at item As (2) with block size 3 bytes.
- at item As (2) with block size 4 bytes.
- at item As (2) with block size 5 bytes.
- at item As (2) with block size 6 bytes and small-mode decompression.
- at item H with buffer size of 1 byte, but normal block
-      size (up to 900000 bytes).
- at end enumerate
-Then some tests with unmodified source code.
- at enumerate
- at item H, all settings normal.
- at item As (1), with small-mode decompress.
- at item H, compress with flag @code{-1}.
- at item H, compress with flag @code{-s}, decompress with flag @code{-s}.
- at item Forwards compatibility: H, @code{bzip2-0.1pl2} compressing,
-      @code{bzip2-0.9.5} decompressing, all settings normal.
- at item Backwards compatibility:  H, @code{bzip2-0.9.5} compressing,
-      @code{bzip2-0.1pl2} decompressing, all settings normal.
- at item Bigger tests: A, all settings normal.
- at item As (7), using the fallback (Sadakane-like) sorting algorithm.
- at item As (8), compress with flag @code{-1}, decompress with flag
-      @code{-s}.
- at item H, using the fallback sorting algorithm.
- at item Forwards compatibility: A, @code{bzip2-0.1pl2} compressing,
-      @code{bzip2-0.9.5} decompressing, all settings normal.
- at item Backwards compatibility:  A, @code{bzip2-0.9.5} compressing,
-      @code{bzip2-0.1pl2} decompressing, all settings normal.
- at item Misc test: about 400 megabytes of @code{.tar} files with
-      @code{bzip2} compiled with Checker (a memory access error
-       detector, like Purify).
- at item Misc tests to make sure it builds and runs ok on non-Linux/x86
-      platforms.
- at end enumerate
-These tests were conducted on a 225 MHz IDT WinChip machine, running
-Linux 2.0.36.  They represent nearly a week of continuous computation.
-All tests completed successfully.
-
-
- at section Further reading
- at code{bzip2} is not research work, in the sense that it doesn't present
-any new ideas.  Rather, it's an engineering exercise based on existing
-ideas.
-
-Four documents describe essentially all the ideas behind @code{bzip2}:
- at example
-Michael Burrows and D. J. Wheeler:
-  "A block-sorting lossless data compression algorithm"
-   10th May 1994. 
-   Digital SRC Research Report 124.
-   ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz
-   If you have trouble finding it, try searching at the
-   New Zealand Digital Library, http://www.nzdl.org.
-
-Daniel S. Hirschberg and Debra A. LeLewer
-  "Efficient Decoding of Prefix Codes"
-   Communications of the ACM, April 1990, Vol 33, Number 4.
-   You might be able to get an electronic copy of this
-      from the ACM Digital Library.
-
-David J. Wheeler
-   Program bred3.c and accompanying document bred3.ps.
-   This contains the idea behind the multi-table Huffman
-   coding scheme.
-   ftp://ftp.cl.cam.ac.uk/users/djw3/
-
-Jon L. Bentley and Robert Sedgewick
-  "Fast Algorithms for Sorting and Searching Strings"
-   Available from Sedgewick's web page,
-   www.cs.princeton.edu/~rs
- at end example
-The following paper gives valuable additional insights into the
-algorithm, but is not immediately the basis of any code
-used in bzip2.
- at example
-Peter Fenwick:
-   Block Sorting Text Compression
-   Proceedings of the 19th Australasian Computer Science Conference,
-     Melbourne, Australia.  Jan 31 - Feb 2, 1996.
-   ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps
- at end example
-Kunihiko Sadakane's sorting algorithm, mentioned above,
-is available from:
- at example
-http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz
- at end example
-The Manber-Myers suffix array construction
-algorithm is described in a paper
-available from:
- at example
-http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps
- at end example
-Finally, the following paper documents some recent investigations
-I made into the performance of sorting algorithms:
- at example
-Julian Seward:
-   On the Performance of BWT Sorting Algorithms
-   Proceedings of the IEEE Data Compression Conference 2000
-     Snowbird, Utah.  28-30 March 2000.
- at end example
-
-
- at contents
-
- at bye
-
diff --git a/c++/src/util/compress/bzip2/manual.xml b/c++/src/util/compress/bzip2/manual.xml
new file mode 100644
index 0000000..a7fbcb3
--- /dev/null
+++ b/c++/src/util/compress/bzip2/manual.xml
@@ -0,0 +1,2964 @@
+<?xml version="1.0"?> <!-- -*- sgml -*- -->
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"[
+
+<!-- various strings, dates etc. common to all docs -->
+<!ENTITY % common-ents SYSTEM "entities.xml"> %common-ents;
+]>
+
+<book lang="en" id="userman" xreflabel="bzip2 Manual">
+
+ <bookinfo>
+  <title>bzip2 and libbzip2, version 1.0.6</title>
+  <subtitle>A program and library for data compression</subtitle>
+  <copyright>
+   <year>&bz-lifespan;</year>
+   <holder>Julian Seward</holder>
+  </copyright>
+  <releaseinfo>Version &bz-version; of &bz-date;</releaseinfo>
+
+  <authorgroup>
+   <author>
+    <firstname>Julian</firstname>
+    <surname>Seward</surname>
+    <affiliation>
+     <orgname>&bz-url;</orgname>
+    </affiliation>
+   </author>
+  </authorgroup>
+
+  <legalnotice>
+
+  <para>This program, <computeroutput>bzip2</computeroutput>, the
+  associated library <computeroutput>libbzip2</computeroutput>, and
+  all documentation, are copyright © &bz-lifespan; Julian Seward.
+  All rights reserved.</para>
+
+  <para>Redistribution and use in source and binary forms, with
+  or without modification, are permitted provided that the
+  following conditions are met:</para>
+
+  <itemizedlist mark='bullet'>
+
+   <listitem><para>Redistributions of source code must retain the
+   above copyright notice, this list of conditions and the
+   following disclaimer.</para></listitem>
+
+   <listitem><para>The origin of this software must not be
+   misrepresented; you must not claim that you wrote the original
+   software.  If you use this software in a product, an
+   acknowledgment in the product documentation would be
+   appreciated but is not required.</para></listitem>
+
+   <listitem><para>Altered source versions must be plainly marked
+   as such, and must not be misrepresented as being the original
+   software.</para></listitem>
+
+   <listitem><para>The name of the author may not be used to
+   endorse or promote products derived from this software without
+   specific prior written permission.</para></listitem>
+
+  </itemizedlist>
+
+  <para>THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY
+  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+  AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+  THE POSSIBILITY OF SUCH DAMAGE.</para>
+
+ <para>PATENTS: To the best of my knowledge,
+ <computeroutput>bzip2</computeroutput> and
+ <computeroutput>libbzip2</computeroutput> do not use any patented
+ algorithms.  However, I do not have the resources to carry
+ out a patent search.  Therefore I cannot give any guarantee of
+ the above statement.
+ </para>
+
+</legalnotice>
+
+</bookinfo>
+
+
+
+<chapter id="intro" xreflabel="Introduction">
+<title>Introduction</title>
+
+<para><computeroutput>bzip2</computeroutput> compresses files
+using the Burrows-Wheeler block-sorting text compression
+algorithm, and Huffman coding.  Compression is generally
+considerably better than that achieved by more conventional
+LZ77/LZ78-based compressors, and approaches the performance of
+the PPM family of statistical compressors.</para>
+
+<para><computeroutput>bzip2</computeroutput> is built on top of
+<computeroutput>libbzip2</computeroutput>, a flexible library for
+handling compressed data in the
+<computeroutput>bzip2</computeroutput> format.  This manual
+describes both how to use the program and how to work with the
+library interface.  Most of the manual is devoted to this
+library, not the program, which is good news if your interest is
+only in the program.</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para><xref linkend="using"/> describes how to use
+ <computeroutput>bzip2</computeroutput>; this is the only part
+ you need to read if you just want to know how to operate the
+ program.</para></listitem>
+
+ <listitem><para><xref linkend="libprog"/> describes the
+ programming interfaces in detail, and</para></listitem>
+
+ <listitem><para><xref linkend="misc"/> records some
+ miscellaneous notes which I thought ought to be recorded
+ somewhere.</para></listitem>
+
+</itemizedlist>
+
+</chapter>
+
+
+<chapter id="using" xreflabel="How to use bzip2">
+<title>How to use bzip2</title>
+
+<para>This chapter contains a copy of the
+<computeroutput>bzip2</computeroutput> man page, and nothing
+else.</para>
+
+<sect1 id="name" xreflabel="NAME">
+<title>NAME</title>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para><computeroutput>bzip2</computeroutput>,
+  <computeroutput>bunzip2</computeroutput> - a block-sorting file
+  compressor, v1.0.6</para></listitem>
+
+ <listitem><para><computeroutput>bzcat</computeroutput> -
+   decompresses files to stdout</para></listitem>
+
+ <listitem><para><computeroutput>bzip2recover</computeroutput> -
+   recovers data from damaged bzip2 files</para></listitem>
+
+</itemizedlist>
+
+</sect1>
+
+
+<sect1 id="synopsis" xreflabel="SYNOPSIS">
+<title>SYNOPSIS</title>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para><computeroutput>bzip2</computeroutput> [
+  -cdfkqstvzVL123456789 ] [ filenames ...  ]</para></listitem>
+
+ <listitem><para><computeroutput>bunzip2</computeroutput> [
+  -fkvsVL ] [ filenames ...  ]</para></listitem>
+
+ <listitem><para><computeroutput>bzcat</computeroutput> [ -s ] [
+  filenames ...  ]</para></listitem>
+
+ <listitem><para><computeroutput>bzip2recover</computeroutput>
+  filename</para></listitem>
+
+</itemizedlist>
+
+</sect1>
+
+
+<sect1 id="description" xreflabel="DESCRIPTION">
+<title>DESCRIPTION</title>
+
+<para><computeroutput>bzip2</computeroutput> compresses files
+using the Burrows-Wheeler block sorting text compression
+algorithm, and Huffman coding.  Compression is generally
+considerably better than that achieved by more conventional
+LZ77/LZ78-based compressors, and approaches the performance of
+the PPM family of statistical compressors.</para>
+
+<para>The command-line options are deliberately very similar to
+those of GNU <computeroutput>gzip</computeroutput>, but they are
+not identical.</para>
+
+<para><computeroutput>bzip2</computeroutput> expects a list of
+file names to accompany the command-line flags.  Each file is
+replaced by a compressed version of itself, with the name
+<computeroutput>original_name.bz2</computeroutput>.  Each
+compressed file has the same modification date, permissions, and,
+when possible, ownership as the corresponding original, so that
+these properties can be correctly restored at decompression time.
+File name handling is naive in the sense that there is no
+mechanism for preserving original file names, permissions,
+ownerships or dates in filesystems which lack these concepts, or
+have serious file name length restrictions, such as
+MS-DOS.</para>
+
+<para><computeroutput>bzip2</computeroutput> and
+<computeroutput>bunzip2</computeroutput> will by default not
+overwrite existing files.  If you want this to happen, specify
+the <computeroutput>-f</computeroutput> flag.</para>
+
+<para>If no file names are specified,
+<computeroutput>bzip2</computeroutput> compresses from standard
+input to standard output.  In this case,
+<computeroutput>bzip2</computeroutput> will decline to write
+compressed output to a terminal, as this would be entirely
+incomprehensible and therefore pointless.</para>
+
+<para><computeroutput>bunzip2</computeroutput> (or
+<computeroutput>bzip2 -d</computeroutput>) decompresses all
+specified files.  Files which were not created by
+<computeroutput>bzip2</computeroutput> will be detected and
+ignored, and a warning issued.
+<computeroutput>bzip2</computeroutput> attempts to guess the
+filename for the decompressed file from that of the compressed
+file as follows:</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para><computeroutput>filename.bz2 </computeroutput>
+  becomes
+  <computeroutput>filename</computeroutput></para></listitem>
+
+ <listitem><para><computeroutput>filename.bz </computeroutput>
+  becomes
+  <computeroutput>filename</computeroutput></para></listitem>
+
+ <listitem><para><computeroutput>filename.tbz2</computeroutput>
+  becomes
+  <computeroutput>filename.tar</computeroutput></para></listitem>
+
+ <listitem><para><computeroutput>filename.tbz </computeroutput>
+  becomes
+  <computeroutput>filename.tar</computeroutput></para></listitem>
+
+ <listitem><para><computeroutput>anyothername </computeroutput>
+  becomes
+  <computeroutput>anyothername.out</computeroutput></para></listitem>
+
+</itemizedlist>
+
+<para>If the file does not end in one of the recognised endings,
+<computeroutput>.bz2</computeroutput>,
+<computeroutput>.bz</computeroutput>,
+<computeroutput>.tbz2</computeroutput> or
+<computeroutput>.tbz</computeroutput>,
+<computeroutput>bzip2</computeroutput> complains that it cannot
+guess the name of the original file, and uses the original name
+with <computeroutput>.out</computeroutput> appended.</para>
+
+<para>As with compression, supplying no filenames causes
+decompression from standard input to standard output.</para>
+
+<para><computeroutput>bunzip2</computeroutput> will correctly
+decompress a file which is the concatenation of two or more
+compressed files.  The result is the concatenation of the
+corresponding uncompressed files.  Integrity testing
+(<computeroutput>-t</computeroutput>) of concatenated compressed
+files is also supported.</para>
+
+<para>You can also compress or decompress files to the standard
+output by giving the <computeroutput>-c</computeroutput> flag.
+Multiple files may be compressed and decompressed like this.  The
+resulting outputs are fed sequentially to stdout.  Compression of
+multiple files in this manner generates a stream containing
+multiple compressed file representations.  Such a stream can be
+decompressed correctly only by
+<computeroutput>bzip2</computeroutput> version 0.9.0 or later.
+Earlier versions of <computeroutput>bzip2</computeroutput> will
+stop after decompressing the first file in the stream.</para>
+
+<para><computeroutput>bzcat</computeroutput> (or
+<computeroutput>bzip2 -dc</computeroutput>) decompresses all
+specified files to the standard output.</para>
+
+<para><computeroutput>bzip2</computeroutput> will read arguments
+from the environment variables
+<computeroutput>BZIP2</computeroutput> and
+<computeroutput>BZIP</computeroutput>, in that order, and will
+process them before any arguments read from the command line.
+This gives a convenient way to supply default arguments.</para>
+
+<para>Compression is always performed, even if the compressed
+file is slightly larger than the original.  Files of less than
+about one hundred bytes tend to get larger, since the compression
+mechanism has a constant overhead in the region of 50 bytes.
+Random data (including the output of most file compressors) is
+coded at about 8.05 bits per byte, giving an expansion of around
+0.5%.</para>
+
+<para>As a self-check for your protection,
+<computeroutput>bzip2</computeroutput> uses 32-bit CRCs to make
+sure that the decompressed version of a file is identical to the
+original.  This guards against corruption of the compressed data,
+and against undetected bugs in
+<computeroutput>bzip2</computeroutput> (hopefully very unlikely).
+The chances of data corruption going undetected is microscopic,
+about one chance in four billion for each file processed.  Be
+aware, though, that the check occurs upon decompression, so it
+can only tell you that something is wrong.  It can't help you
+recover the original uncompressed data.  You can use
+<computeroutput>bzip2recover</computeroutput> to try to recover
+data from damaged files.</para>
+
+<para>Return values: 0 for a normal exit, 1 for environmental
+problems (file not found, invalid flags, I/O errors, etc.), 2
+to indicate a corrupt compressed file, 3 for an internal
+consistency error (eg, bug) which caused
+<computeroutput>bzip2</computeroutput> to panic.</para>
+
+</sect1>
+
+
+<sect1 id="options" xreflabel="OPTIONS">
+<title>OPTIONS</title>
+
+<variablelist>
+
+ <varlistentry>
+ <term><computeroutput>-c --stdout</computeroutput></term>
+ <listitem><para>Compress or decompress to standard
+  output.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-d --decompress</computeroutput></term>
+ <listitem><para>Force decompression.
+  <computeroutput>bzip2</computeroutput>,
+  <computeroutput>bunzip2</computeroutput> and
+  <computeroutput>bzcat</computeroutput> are really the same
+  program, and the decision about what actions to take is done on
+  the basis of which name is used.  This flag overrides that
+  mechanism, and forces bzip2 to decompress.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-z --compress</computeroutput></term>
+ <listitem><para>The complement to
+  <computeroutput>-d</computeroutput>: forces compression,
+  regardless of the invokation name.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-t --test</computeroutput></term>
+ <listitem><para>Check integrity of the specified file(s), but
+  don't decompress them.  This really performs a trial
+  decompression and throws away the result.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-f --force</computeroutput></term>
+ <listitem><para>Force overwrite of output files.  Normally,
+  <computeroutput>bzip2</computeroutput> will not overwrite
+  existing output files.  Also forces
+  <computeroutput>bzip2</computeroutput> to break hard links to
+  files, which it otherwise wouldn't do.</para>
+  <para><computeroutput>bzip2</computeroutput> normally declines
+  to decompress files which don't have the correct magic header
+  bytes. If forced (<computeroutput>-f</computeroutput>),
+  however, it will pass such files through unmodified. This is
+  how GNU <computeroutput>gzip</computeroutput> behaves.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-k --keep</computeroutput></term>
+ <listitem><para>Keep (don't delete) input files during
+  compression or decompression.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-s --small</computeroutput></term>
+ <listitem><para>Reduce memory usage, for compression,
+  decompression and testing.  Files are decompressed and tested
+  using a modified algorithm which only requires 2.5 bytes per
+  block byte.  This means any file can be decompressed in 2300k
+  of memory, albeit at about half the normal speed.</para>
+  <para>During compression, <computeroutput>-s</computeroutput>
+  selects a block size of 200k, which limits memory use to around
+  the same figure, at the expense of your compression ratio.  In
+  short, if your machine is low on memory (8 megabytes or less),
+  use <computeroutput>-s</computeroutput> for everything.  See
+  <xref linkend="memory-management"/> below.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-q --quiet</computeroutput></term>
+ <listitem><para>Suppress non-essential warning messages.
+  Messages pertaining to I/O errors and other critical events
+  will not be suppressed.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-v --verbose</computeroutput></term>
+ <listitem><para>Verbose mode -- show the compression ratio for
+  each file processed.  Further
+  <computeroutput>-v</computeroutput>'s increase the verbosity
+  level, spewing out lots of information which is primarily of
+  interest for diagnostic purposes.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-L --license -V --version</computeroutput></term>
+ <listitem><para>Display the software version, license terms and
+  conditions.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-1</computeroutput> (or
+ <computeroutput>--fast</computeroutput>) to
+ <computeroutput>-9</computeroutput> (or
+ <computeroutput>-best</computeroutput>)</term>
+ <listitem><para>Set the block size to 100 k, 200 k ...  900 k
+  when compressing.  Has no effect when decompressing.  See <xref
+  linkend="memory-management" /> below.  The
+  <computeroutput>--fast</computeroutput> and
+  <computeroutput>--best</computeroutput> aliases are primarily
+  for GNU <computeroutput>gzip</computeroutput> compatibility.
+  In particular, <computeroutput>--fast</computeroutput> doesn't
+  make things significantly faster.  And
+  <computeroutput>--best</computeroutput> merely selects the
+  default behaviour.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>--</computeroutput></term>
+ <listitem><para>Treats all subsequent arguments as file names,
+  even if they start with a dash.  This is so you can handle
+  files with names beginning with a dash, for example:
+  <computeroutput>bzip2 --
+  -myfilename</computeroutput>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>--repetitive-fast</computeroutput></term>
+ <term><computeroutput>--repetitive-best</computeroutput></term>
+ <listitem><para>These flags are redundant in versions 0.9.5 and
+  above.  They provided some coarse control over the behaviour of
+  the sorting algorithm in earlier versions, which was sometimes
+  useful.  0.9.5 and above have an improved algorithm which
+  renders these flags irrelevant.</para></listitem>
+ </varlistentry>
+
+</variablelist>
+
+</sect1>
+
+
+<sect1 id="memory-management" xreflabel="MEMORY MANAGEMENT">
+<title>MEMORY MANAGEMENT</title>
+
+<para><computeroutput>bzip2</computeroutput> compresses large
+files in blocks.  The block size affects both the compression
+ratio achieved, and the amount of memory needed for compression
+and decompression.  The flags <computeroutput>-1</computeroutput>
+through <computeroutput>-9</computeroutput> specify the block
+size to be 100,000 bytes through 900,000 bytes (the default)
+respectively.  At decompression time, the block size used for
+compression is read from the header of the compressed file, and
+<computeroutput>bunzip2</computeroutput> then allocates itself
+just enough memory to decompress the file.  Since block sizes are
+stored in compressed files, it follows that the flags
+<computeroutput>-1</computeroutput> to
+<computeroutput>-9</computeroutput> are irrelevant to and so
+ignored during decompression.</para>
+
+<para>Compression and decompression requirements, in bytes, can be
+estimated as:</para>
+<programlisting>
+Compression:   400k + ( 8 x block size )
+
+Decompression: 100k + ( 4 x block size ), or
+               100k + ( 2.5 x block size )
+</programlisting>
+
+<para>Larger block sizes give rapidly diminishing marginal
+returns.  Most of the compression comes from the first two or
+three hundred k of block size, a fact worth bearing in mind when
+using <computeroutput>bzip2</computeroutput> on small machines.
+It is also important to appreciate that the decompression memory
+requirement is set at compression time by the choice of block
+size.</para>
+
+<para>For files compressed with the default 900k block size,
+<computeroutput>bunzip2</computeroutput> will require about 3700
+kbytes to decompress.  To support decompression of any file on a
+4 megabyte machine, <computeroutput>bunzip2</computeroutput> has
+an option to decompress using approximately half this amount of
+memory, about 2300 kbytes.  Decompression speed is also halved,
+so you should use this option only where necessary.  The relevant
+flag is <computeroutput>-s</computeroutput>.</para>
+
+<para>In general, try and use the largest block size memory
+constraints allow, since that maximises the compression achieved.
+Compression and decompression speed are virtually unaffected by
+block size.</para>
+
+<para>Another significant point applies to files which fit in a
+single block -- that means most files you'd encounter using a
+large block size.  The amount of real memory touched is
+proportional to the size of the file, since the file is smaller
+than a block.  For example, compressing a file 20,000 bytes long
+with the flag <computeroutput>-9</computeroutput> will cause the
+compressor to allocate around 7600k of memory, but only touch
+400k + 20000 * 8 = 560 kbytes of it.  Similarly, the decompressor
+will allocate 3700k but only touch 100k + 20000 * 4 = 180
+kbytes.</para>
+
+<para>Here is a table which summarises the maximum memory usage
+for different block sizes.  Also recorded is the total compressed
+size for 14 files of the Calgary Text Compression Corpus
+totalling 3,141,622 bytes.  This column gives some feel for how
+compression varies with block size.  These figures tend to
+understate the advantage of larger block sizes for larger files,
+since the Corpus is dominated by smaller files.</para>
+
+<programlisting>
+        Compress   Decompress   Decompress   Corpus
+Flag     usage      usage       -s usage     Size
+
+ -1      1200k       500k         350k      914704
+ -2      2000k       900k         600k      877703
+ -3      2800k      1300k         850k      860338
+ -4      3600k      1700k        1100k      846899
+ -5      4400k      2100k        1350k      845160
+ -6      5200k      2500k        1600k      838626
+ -7      6100k      2900k        1850k      834096
+ -8      6800k      3300k        2100k      828642
+ -9      7600k      3700k        2350k      828642
+</programlisting>
+
+</sect1>
+
+
+<sect1 id="recovering" xreflabel="RECOVERING DATA FROM DAMAGED FILES">
+<title>RECOVERING DATA FROM DAMAGED FILES</title>
+
+<para><computeroutput>bzip2</computeroutput> compresses files in
+blocks, usually 900kbytes long.  Each block is handled
+independently.  If a media or transmission error causes a
+multi-block <computeroutput>.bz2</computeroutput> file to become
+damaged, it may be possible to recover data from the undamaged
+blocks in the file.</para>
+
+<para>The compressed representation of each block is delimited by
+a 48-bit pattern, which makes it possible to find the block
+boundaries with reasonable certainty.  Each block also carries
+its own 32-bit CRC, so damaged blocks can be distinguished from
+undamaged ones.</para>
+
+<para><computeroutput>bzip2recover</computeroutput> is a simple
+program whose purpose is to search for blocks in
+<computeroutput>.bz2</computeroutput> files, and write each block
+out into its own <computeroutput>.bz2</computeroutput> file.  You
+can then use <computeroutput>bzip2 -t</computeroutput> to test
+the integrity of the resulting files, and decompress those which
+are undamaged.</para>
+
+<para><computeroutput>bzip2recover</computeroutput> takes a
+single argument, the name of the damaged file, and writes a
+number of files <computeroutput>rec0001file.bz2</computeroutput>,
+<computeroutput>rec0002file.bz2</computeroutput>, etc, containing
+the extracted blocks.  The output filenames are designed so that
+the use of wildcards in subsequent processing -- for example,
+<computeroutput>bzip2 -dc rec*file.bz2 >
+recovered_data</computeroutput> -- lists the files in the correct
+order.</para>
+
+<para><computeroutput>bzip2recover</computeroutput> should be of
+most use dealing with large <computeroutput>.bz2</computeroutput>
+files, as these will contain many blocks.  It is clearly futile
+to use it on damaged single-block files, since a damaged block
+cannot be recovered.  If you wish to minimise any potential data
+loss through media or transmission errors, you might consider
+compressing with a smaller block size.</para>
+
+</sect1>
+
+
+<sect1 id="performance" xreflabel="PERFORMANCE NOTES">
+<title>PERFORMANCE NOTES</title>
+
+<para>The sorting phase of compression gathers together similar
+strings in the file.  Because of this, files containing very long
+runs of repeated symbols, like "aabaabaabaab ..."  (repeated
+several hundred times) may compress more slowly than normal.
+Versions 0.9.5 and above fare much better than previous versions
+in this respect.  The ratio between worst-case and average-case
+compression time is in the region of 10:1.  For previous
+versions, this figure was more like 100:1.  You can use the
+<computeroutput>-vvvv</computeroutput> option to monitor progress
+in great detail, if you want.</para>
+
+<para>Decompression speed is unaffected by these
+phenomena.</para>
+
+<para><computeroutput>bzip2</computeroutput> usually allocates
+several megabytes of memory to operate in, and then charges all
+over it in a fairly random fashion.  This means that performance,
+both for compressing and decompressing, is largely determined by
+the speed at which your machine can service cache misses.
+Because of this, small changes to the code to reduce the miss
+rate have been observed to give disproportionately large
+performance improvements.  I imagine
+<computeroutput>bzip2</computeroutput> will perform best on
+machines with very large caches.</para>
+
+</sect1>
+
+
+
+<sect1 id="caveats" xreflabel="CAVEATS">
+<title>CAVEATS</title>
+
+<para>I/O error messages are not as helpful as they could be.
+<computeroutput>bzip2</computeroutput> tries hard to detect I/O
+errors and exit cleanly, but the details of what the problem is
+sometimes seem rather misleading.</para>
+
+<para>This manual page pertains to version &bz-version; of
+<computeroutput>bzip2</computeroutput>.  Compressed data created by
+this version is entirely forwards and backwards compatible with the
+previous public releases, versions 0.1pl2, 0.9.0 and 0.9.5, 1.0.0,
+1.0.1, 1.0.2 and 1.0.3, but with the following exception: 0.9.0 and
+above can correctly decompress multiple concatenated compressed files.
+0.1pl2 cannot do this; it will stop after decompressing just the first
+file in the stream.</para>
+
+<para><computeroutput>bzip2recover</computeroutput> versions
+prior to 1.0.2 used 32-bit integers to represent bit positions in
+compressed files, so it could not handle compressed files more
+than 512 megabytes long.  Versions 1.0.2 and above use 64-bit ints
+on some platforms which support them (GNU supported targets, and
+Windows). To establish whether or not
+<computeroutput>bzip2recover</computeroutput> was built with such
+a limitation, run it without arguments. In any event you can
+build yourself an unlimited version if you can recompile it with
+<computeroutput>MaybeUInt64</computeroutput> set to be an
+unsigned 64-bit integer.</para>
+
+</sect1>
+
+
+
+<sect1 id="author" xreflabel="AUTHOR">
+<title>AUTHOR</title>
+
+<para>Julian Seward,
+<computeroutput>&bz-email;</computeroutput></para>
+
+<para>The ideas embodied in
+<computeroutput>bzip2</computeroutput> are due to (at least) the
+following people: Michael Burrows and David Wheeler (for the
+block sorting transformation), David Wheeler (again, for the
+Huffman coder), Peter Fenwick (for the structured coding model in
+the original <computeroutput>bzip</computeroutput>, and many
+refinements), and Alistair Moffat, Radford Neal and Ian Witten
+(for the arithmetic coder in the original
+<computeroutput>bzip</computeroutput>).  I am much indebted for
+their help, support and advice.  See the manual in the source
+distribution for pointers to sources of documentation.  Christian
+von Roques encouraged me to look for faster sorting algorithms,
+so as to speed up compression.  Bela Lubkin encouraged me to
+improve the worst-case compression performance.  
+Donna Robinson XMLised the documentation.
+Many people sent
+patches, helped with portability problems, lent machines, gave
+advice and were generally helpful.</para>
+
+</sect1>
+
+</chapter>
+
+
+
+<chapter id="libprog" xreflabel="Programming with libbzip2">
+<title>
+Programming with <computeroutput>libbzip2</computeroutput>
+</title>
+
+<para>This chapter describes the programming interface to
+<computeroutput>libbzip2</computeroutput>.</para>
+
+<para>For general background information, particularly about
+memory use and performance aspects, you'd be well advised to read
+<xref linkend="using"/> as well.</para>
+
+
+<sect1 id="top-level" xreflabel="Top-level structure">
+<title>Top-level structure</title>
+
+<para><computeroutput>libbzip2</computeroutput> is a flexible
+library for compressing and decompressing data in the
+<computeroutput>bzip2</computeroutput> data format.  Although
+packaged as a single entity, it helps to regard the library as
+three separate parts: the low level interface, and the high level
+interface, and some utility functions.</para>
+
+<para>The structure of
+<computeroutput>libbzip2</computeroutput>'s interfaces is similar
+to that of Jean-loup Gailly's and Mark Adler's excellent
+<computeroutput>zlib</computeroutput> library.</para>
+
+<para>All externally visible symbols have names beginning
+<computeroutput>BZ2_</computeroutput>.  This is new in version
+1.0.  The intention is to minimise pollution of the namespaces of
+library clients.</para>
+
+<para>To use any part of the library, you need to
+<computeroutput>#include <bzlib.h></computeroutput>
+into your sources.</para>
+
+
+
+<sect2 id="ll-summary" xreflabel="Low-level summary">
+<title>Low-level summary</title>
+
+<para>This interface provides services for compressing and
+decompressing data in memory.  There's no provision for dealing
+with files, streams or any other I/O mechanisms, just straight
+memory-to-memory work.  In fact, this part of the library can be
+compiled without inclusion of
+<computeroutput>stdio.h</computeroutput>, which may be helpful
+for embedded applications.</para>
+
+<para>The low-level part of the library has no global variables
+and is therefore thread-safe.</para>
+
+<para>Six routines make up the low level interface:
+<computeroutput>BZ2_bzCompressInit</computeroutput>,
+<computeroutput>BZ2_bzCompress</computeroutput>, and
+<computeroutput>BZ2_bzCompressEnd</computeroutput> for
+compression, and a corresponding trio
+<computeroutput>BZ2_bzDecompressInit</computeroutput>,
+<computeroutput>BZ2_bzDecompress</computeroutput> and
+<computeroutput>BZ2_bzDecompressEnd</computeroutput> for
+decompression.  The <computeroutput>*Init</computeroutput>
+functions allocate memory for compression/decompression and do
+other initialisations, whilst the
+<computeroutput>*End</computeroutput> functions close down
+operations and release memory.</para>
+
+<para>The real work is done by
+<computeroutput>BZ2_bzCompress</computeroutput> and
+<computeroutput>BZ2_bzDecompress</computeroutput>.  These
+compress and decompress data from a user-supplied input buffer to
+a user-supplied output buffer.  These buffers can be any size;
+arbitrary quantities of data are handled by making repeated calls
+to these functions.  This is a flexible mechanism allowing a
+consumer-pull style of activity, or producer-push, or a mixture
+of both.</para>
+
+</sect2>
+
+
+<sect2 id="hl-summary" xreflabel="High-level summary">
+<title>High-level summary</title>
+
+<para>This interface provides some handy wrappers around the
+low-level interface to facilitate reading and writing
+<computeroutput>bzip2</computeroutput> format files
+(<computeroutput>.bz2</computeroutput> files).  The routines
+provide hooks to facilitate reading files in which the
+<computeroutput>bzip2</computeroutput> data stream is embedded
+within some larger-scale file structure, or where there are
+multiple <computeroutput>bzip2</computeroutput> data streams
+concatenated end-to-end.</para>
+
+<para>For reading files,
+<computeroutput>BZ2_bzReadOpen</computeroutput>,
+<computeroutput>BZ2_bzRead</computeroutput>,
+<computeroutput>BZ2_bzReadClose</computeroutput> and 
+<computeroutput>BZ2_bzReadGetUnused</computeroutput> are
+supplied.  For writing files,
+<computeroutput>BZ2_bzWriteOpen</computeroutput>,
+<computeroutput>BZ2_bzWrite</computeroutput> and
+<computeroutput>BZ2_bzWriteFinish</computeroutput> are
+available.</para>
+
+<para>As with the low-level library, no global variables are used
+so the library is per se thread-safe.  However, if I/O errors
+occur whilst reading or writing the underlying compressed files,
+you may have to consult <computeroutput>errno</computeroutput> to
+determine the cause of the error.  In that case, you'd need a C
+library which correctly supports
+<computeroutput>errno</computeroutput> in a multithreaded
+environment.</para>
+
+<para>To make the library a little simpler and more portable,
+<computeroutput>BZ2_bzReadOpen</computeroutput> and
+<computeroutput>BZ2_bzWriteOpen</computeroutput> require you to
+pass them file handles (<computeroutput>FILE*</computeroutput>s)
+which have previously been opened for reading or writing
+respectively.  That avoids portability problems associated with
+file operations and file attributes, whilst not being much of an
+imposition on the programmer.</para>
+
+</sect2>
+
+
+<sect2 id="util-fns-summary" xreflabel="Utility functions summary">
+<title>Utility functions summary</title>
+
+<para>For very simple needs,
+<computeroutput>BZ2_bzBuffToBuffCompress</computeroutput> and
+<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> are
+provided.  These compress data in memory from one buffer to
+another buffer in a single function call.  You should assess
+whether these functions fulfill your memory-to-memory
+compression/decompression requirements before investing effort in
+understanding the more general but more complex low-level
+interface.</para>
+
+<para>Yoshioka Tsuneo
+(<computeroutput>tsuneo at rr.iij4u.or.jp</computeroutput>) has
+contributed some functions to give better
+<computeroutput>zlib</computeroutput> compatibility.  These
+functions are <computeroutput>BZ2_bzopen</computeroutput>,
+<computeroutput>BZ2_bzread</computeroutput>,
+<computeroutput>BZ2_bzwrite</computeroutput>,
+<computeroutput>BZ2_bzflush</computeroutput>,
+<computeroutput>BZ2_bzclose</computeroutput>,
+<computeroutput>BZ2_bzerror</computeroutput> and
+<computeroutput>BZ2_bzlibVersion</computeroutput>.  You may find
+these functions more convenient for simple file reading and
+writing, than those in the high-level interface.  These functions
+are not (yet) officially part of the library, and are minimally
+documented here.  If they break, you get to keep all the pieces.
+I hope to document them properly when time permits.</para>
+
+<para>Yoshioka also contributed modifications to allow the
+library to be built as a Windows DLL.</para>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 id="err-handling" xreflabel="Error handling">
+<title>Error handling</title>
+
+<para>The library is designed to recover cleanly in all
+situations, including the worst-case situation of decompressing
+random data.  I'm not 100% sure that it can always do this, so
+you might want to add a signal handler to catch segmentation
+violations during decompression if you are feeling especially
+paranoid.  I would be interested in hearing more about the
+robustness of the library to corrupted compressed data.</para>
+
+<para>Version 1.0.3 more robust in this respect than any
+previous version.  Investigations with Valgrind (a tool for detecting
+problems with memory management) indicate
+that, at least for the few files I tested, all single-bit errors
+in the decompressed data are caught properly, with no
+segmentation faults, no uses of uninitialised data, no out of
+range reads or writes, and no infinite looping in the decompressor.
+So it's certainly pretty robust, although
+I wouldn't claim it to be totally bombproof.</para>
+
+<para>The file <computeroutput>bzlib.h</computeroutput> contains
+all definitions needed to use the library.  In particular, you
+should definitely not include
+<computeroutput>bzlib_private.h</computeroutput>.</para>
+
+<para>In <computeroutput>bzlib.h</computeroutput>, the various
+return values are defined.  The following list is not intended as
+an exhaustive description of the circumstances in which a given
+value may be returned -- those descriptions are given later.
+Rather, it is intended to convey the rough meaning of each return
+value.  The first five actions are normal and not intended to
+denote an error situation.</para>
+
+<variablelist>
+
+ <varlistentry>
+  <term><computeroutput>BZ_OK</computeroutput></term>
+  <listitem><para>The requested action was completed
+   successfully.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term><computeroutput>BZ_RUN_OK, BZ_FLUSH_OK,
+    BZ_FINISH_OK</computeroutput></term>
+  <listitem><para>In 
+   <computeroutput>BZ2_bzCompress</computeroutput>, the requested
+   flush/finish/nothing-special action was completed
+   successfully.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term><computeroutput>BZ_STREAM_END</computeroutput></term>
+  <listitem><para>Compression of data was completed, or the
+   logical stream end was detected during
+   decompression.</para></listitem>
+ </varlistentry>
+
+</variablelist>
+
+<para>The following return values indicate an error of some
+kind.</para>
+
+<variablelist>
+
+ <varlistentry>
+  <term><computeroutput>BZ_CONFIG_ERROR</computeroutput></term>
+  <listitem><para>Indicates that the library has been improperly
+   compiled on your platform -- a major configuration error.
+   Specifically, it means that
+   <computeroutput>sizeof(char)</computeroutput>,
+   <computeroutput>sizeof(short)</computeroutput> and
+   <computeroutput>sizeof(int)</computeroutput> are not 1, 2 and
+   4 respectively, as they should be.  Note that the library
+   should still work properly on 64-bit platforms which follow
+   the LP64 programming model -- that is, where
+   <computeroutput>sizeof(long)</computeroutput> and
+   <computeroutput>sizeof(void*)</computeroutput> are 8.  Under
+   LP64, <computeroutput>sizeof(int)</computeroutput> is still 4,
+   so <computeroutput>libbzip2</computeroutput>, which doesn't
+   use the <computeroutput>long</computeroutput> type, is
+   OK.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term><computeroutput>BZ_SEQUENCE_ERROR</computeroutput></term>
+  <listitem><para>When using the library, it is important to call
+   the functions in the correct sequence and with data structures
+   (buffers etc) in the correct states.
+   <computeroutput>libbzip2</computeroutput> checks as much as it
+   can to ensure this is happening, and returns
+   <computeroutput>BZ_SEQUENCE_ERROR</computeroutput> if not.
+   Code which complies precisely with the function semantics, as
+   detailed below, should never receive this value; such an event
+   denotes buggy code which you should
+   investigate.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term><computeroutput>BZ_PARAM_ERROR</computeroutput></term>
+  <listitem><para>Returned when a parameter to a function call is
+   out of range or otherwise manifestly incorrect.  As with
+   <computeroutput>BZ_SEQUENCE_ERROR</computeroutput>, this
+   denotes a bug in the client code.  The distinction between
+   <computeroutput>BZ_PARAM_ERROR</computeroutput> and
+   <computeroutput>BZ_SEQUENCE_ERROR</computeroutput> is a bit
+   hazy, but still worth making.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term><computeroutput>BZ_MEM_ERROR</computeroutput></term>
+  <listitem><para>Returned when a request to allocate memory
+   failed.  Note that the quantity of memory needed to decompress
+   a stream cannot be determined until the stream's header has
+   been read.  So
+   <computeroutput>BZ2_bzDecompress</computeroutput> and
+   <computeroutput>BZ2_bzRead</computeroutput> may return
+   <computeroutput>BZ_MEM_ERROR</computeroutput> even though some
+   of the compressed data has been read.  The same is not true
+   for compression; once
+   <computeroutput>BZ2_bzCompressInit</computeroutput> or
+   <computeroutput>BZ2_bzWriteOpen</computeroutput> have
+   successfully completed,
+   <computeroutput>BZ_MEM_ERROR</computeroutput> cannot
+   occur.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term><computeroutput>BZ_DATA_ERROR</computeroutput></term>
+  <listitem><para>Returned when a data integrity error is
+   detected during decompression.  Most importantly, this means
+   when stored and computed CRCs for the data do not match.  This
+   value is also returned upon detection of any other anomaly in
+   the compressed data.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term><computeroutput>BZ_DATA_ERROR_MAGIC</computeroutput></term>
+  <listitem><para>As a special case of
+   <computeroutput>BZ_DATA_ERROR</computeroutput>, it is
+   sometimes useful to know when the compressed stream does not
+   start with the correct magic bytes (<computeroutput>'B' 'Z'
+   'h'</computeroutput>).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term><computeroutput>BZ_IO_ERROR</computeroutput></term>
+  <listitem><para>Returned by
+   <computeroutput>BZ2_bzRead</computeroutput> and
+   <computeroutput>BZ2_bzWrite</computeroutput> when there is an
+   error reading or writing in the compressed file, and by
+   <computeroutput>BZ2_bzReadOpen</computeroutput> and
+   <computeroutput>BZ2_bzWriteOpen</computeroutput> for attempts
+   to use a file for which the error indicator (viz,
+   <computeroutput>ferror(f)</computeroutput>) is set.  On
+   receipt of <computeroutput>BZ_IO_ERROR</computeroutput>, the
+   caller should consult <computeroutput>errno</computeroutput>
+   and/or <computeroutput>perror</computeroutput> to acquire
+   operating-system specific information about the
+   problem.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term><computeroutput>BZ_UNEXPECTED_EOF</computeroutput></term>
+  <listitem><para>Returned by
+   <computeroutput>BZ2_bzRead</computeroutput> when the
+   compressed file finishes before the logical end of stream is
+   detected.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term><computeroutput>BZ_OUTBUFF_FULL</computeroutput></term>
+  <listitem><para>Returned by
+   <computeroutput>BZ2_bzBuffToBuffCompress</computeroutput> and
+   <computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> to
+   indicate that the output data will not fit into the output
+   buffer provided.</para></listitem>
+ </varlistentry>
+
+</variablelist>
+
+</sect1>
+
+
+
+<sect1 id="low-level" xreflabel=">Low-level interface">
+<title>Low-level interface</title>
+
+
+<sect2 id="bzcompress-init" xreflabel="BZ2_bzCompressInit">
+<title>BZ2_bzCompressInit</title>
+
+<programlisting>
+typedef struct {
+  char *next_in;
+  unsigned int avail_in;
+  unsigned int total_in_lo32;
+  unsigned int total_in_hi32;
+
+  char *next_out;
+  unsigned int avail_out;
+  unsigned int total_out_lo32;
+  unsigned int total_out_hi32;
+
+  void *state;
+
+  void *(*bzalloc)(void *,int,int);
+  void (*bzfree)(void *,void *);
+  void *opaque;
+} bz_stream;
+
+int BZ2_bzCompressInit ( bz_stream *strm, 
+                         int blockSize100k, 
+                         int verbosity,
+                         int workFactor );
+</programlisting>
+
+<para>Prepares for compression.  The
+<computeroutput>bz_stream</computeroutput> structure holds all
+data pertaining to the compression activity.  A
+<computeroutput>bz_stream</computeroutput> structure should be
+allocated and initialised prior to the call.  The fields of
+<computeroutput>bz_stream</computeroutput> comprise the entirety
+of the user-visible data.  <computeroutput>state</computeroutput>
+is a pointer to the private data structures required for
+compression.</para>
+
+<para>Custom memory allocators are supported, via fields
+<computeroutput>bzalloc</computeroutput>,
+<computeroutput>bzfree</computeroutput>, and
+<computeroutput>opaque</computeroutput>.  The value
+<computeroutput>opaque</computeroutput> is passed to as the first
+argument to all calls to <computeroutput>bzalloc</computeroutput>
+and <computeroutput>bzfree</computeroutput>, but is otherwise
+ignored by the library.  The call <computeroutput>bzalloc (
+opaque, n, m )</computeroutput> is expected to return a pointer
+<computeroutput>p</computeroutput> to <computeroutput>n *
+m</computeroutput> bytes of memory, and <computeroutput>bzfree (
+opaque, p )</computeroutput> should free that memory.</para>
+
+<para>If you don't want to use a custom memory allocator, set
+<computeroutput>bzalloc</computeroutput>,
+<computeroutput>bzfree</computeroutput> and
+<computeroutput>opaque</computeroutput> to
+<computeroutput>NULL</computeroutput>, and the library will then
+use the standard <computeroutput>malloc</computeroutput> /
+<computeroutput>free</computeroutput> routines.</para>
+
+<para>Before calling
+<computeroutput>BZ2_bzCompressInit</computeroutput>, fields
+<computeroutput>bzalloc</computeroutput>,
+<computeroutput>bzfree</computeroutput> and
+<computeroutput>opaque</computeroutput> should be filled
+appropriately, as just described.  Upon return, the internal
+state will have been allocated and initialised, and
+<computeroutput>total_in_lo32</computeroutput>,
+<computeroutput>total_in_hi32</computeroutput>,
+<computeroutput>total_out_lo32</computeroutput> and
+<computeroutput>total_out_hi32</computeroutput> will have been
+set to zero.  These four fields are used by the library to inform
+the caller of the total amount of data passed into and out of the
+library, respectively.  You should not try to change them.  As of
+version 1.0, 64-bit counts are maintained, even on 32-bit
+platforms, using the <computeroutput>_hi32</computeroutput>
+fields to store the upper 32 bits of the count.  So, for example,
+the total amount of data in is <computeroutput>(total_in_hi32
+<< 32) + total_in_lo32</computeroutput>.</para>
+
+<para>Parameter <computeroutput>blockSize100k</computeroutput>
+specifies the block size to be used for compression.  It should
+be a value between 1 and 9 inclusive, and the actual block size
+used is 100000 x this figure.  9 gives the best compression but
+takes most memory.</para>
+
+<para>Parameter <computeroutput>verbosity</computeroutput> should
+be set to a number between 0 and 4 inclusive.  0 is silent, and
+greater numbers give increasingly verbose monitoring/debugging
+output.  If the library has been compiled with
+<computeroutput>-DBZ_NO_STDIO</computeroutput>, no such output
+will appear for any verbosity setting.</para>
+
+<para>Parameter <computeroutput>workFactor</computeroutput>
+controls how the compression phase behaves when presented with
+worst case, highly repetitive, input data.  If compression runs
+into difficulties caused by repetitive data, the library switches
+from the standard sorting algorithm to a fallback algorithm.  The
+fallback is slower than the standard algorithm by perhaps a
+factor of three, but always behaves reasonably, no matter how bad
+the input.</para>
+
+<para>Lower values of <computeroutput>workFactor</computeroutput>
+reduce the amount of effort the standard algorithm will expend
+before resorting to the fallback.  You should set this parameter
+carefully; too low, and many inputs will be handled by the
+fallback algorithm and so compress rather slowly, too high, and
+your average-to-worst case compression times can become very
+large.  The default value of 30 gives reasonable behaviour over a
+wide range of circumstances.</para>
+
+<para>Allowable values range from 0 to 250 inclusive.  0 is a
+special case, equivalent to using the default value of 30.</para>
+
+<para>Note that the compressed output generated is the same
+regardless of whether or not the fallback algorithm is
+used.</para>
+
+<para>Be aware also that this parameter may disappear entirely in
+future versions of the library.  In principle it should be
+possible to devise a good way to automatically choose which
+algorithm to use.  Such a mechanism would render the parameter
+obsolete.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if strm is NULL 
+  or blockSize < 1 or blockSize > 9
+  or verbosity < 0 or verbosity > 4
+  or workFactor < 0 or workFactor > 250
+BZ_MEM_ERROR 
+  if not enough memory is available
+BZ_OK 
+  otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+BZ2_bzCompress
+  if BZ_OK is returned
+  no specific action needed in case of error
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzCompress" xreflabel="BZ2_bzCompress">
+<title>BZ2_bzCompress</title>
+
+<programlisting>
+int BZ2_bzCompress ( bz_stream *strm, int action );
+</programlisting>
+
+<para>Provides more input and/or output buffer space for the
+library.  The caller maintains input and output buffers, and
+calls <computeroutput>BZ2_bzCompress</computeroutput> to transfer
+data between them.</para>
+
+<para>Before each call to
+<computeroutput>BZ2_bzCompress</computeroutput>,
+<computeroutput>next_in</computeroutput> should point at the data
+to be compressed, and <computeroutput>avail_in</computeroutput>
+should indicate how many bytes the library may read.
+<computeroutput>BZ2_bzCompress</computeroutput> updates
+<computeroutput>next_in</computeroutput>,
+<computeroutput>avail_in</computeroutput> and
+<computeroutput>total_in</computeroutput> to reflect the number
+of bytes it has read.</para>
+
+<para>Similarly, <computeroutput>next_out</computeroutput> should
+point to a buffer in which the compressed data is to be placed,
+with <computeroutput>avail_out</computeroutput> indicating how
+much output space is available.
+<computeroutput>BZ2_bzCompress</computeroutput> updates
+<computeroutput>next_out</computeroutput>,
+<computeroutput>avail_out</computeroutput> and
+<computeroutput>total_out</computeroutput> to reflect the number
+of bytes output.</para>
+
+<para>You may provide and remove as little or as much data as you
+like on each call of
+<computeroutput>BZ2_bzCompress</computeroutput>.  In the limit,
+it is acceptable to supply and remove data one byte at a time,
+although this would be terribly inefficient.  You should always
+ensure that at least one byte of output space is available at
+each call.</para>
+
+<para>A second purpose of
+<computeroutput>BZ2_bzCompress</computeroutput> is to request a
+change of mode of the compressed stream.</para>
+
+<para>Conceptually, a compressed stream can be in one of four
+states: IDLE, RUNNING, FLUSHING and FINISHING.  Before
+initialisation
+(<computeroutput>BZ2_bzCompressInit</computeroutput>) and after
+termination (<computeroutput>BZ2_bzCompressEnd</computeroutput>),
+a stream is regarded as IDLE.</para>
+
+<para>Upon initialisation
+(<computeroutput>BZ2_bzCompressInit</computeroutput>), the stream
+is placed in the RUNNING state.  Subsequent calls to
+<computeroutput>BZ2_bzCompress</computeroutput> should pass
+<computeroutput>BZ_RUN</computeroutput> as the requested action;
+other actions are illegal and will result in
+<computeroutput>BZ_SEQUENCE_ERROR</computeroutput>.</para>
+
+<para>At some point, the calling program will have provided all
+the input data it wants to.  It will then want to finish up -- in
+effect, asking the library to process any data it might have
+buffered internally.  In this state,
+<computeroutput>BZ2_bzCompress</computeroutput> will no longer
+attempt to read data from
+<computeroutput>next_in</computeroutput>, but it will want to
+write data to <computeroutput>next_out</computeroutput>.  Because
+the output buffer supplied by the user can be arbitrarily small,
+the finishing-up operation cannot necessarily be done with a
+single call of
+<computeroutput>BZ2_bzCompress</computeroutput>.</para>
+
+<para>Instead, the calling program passes
+<computeroutput>BZ_FINISH</computeroutput> as an action to
+<computeroutput>BZ2_bzCompress</computeroutput>.  This changes
+the stream's state to FINISHING.  Any remaining input (ie,
+<computeroutput>next_in[0 .. avail_in-1]</computeroutput>) is
+compressed and transferred to the output buffer.  To do this,
+<computeroutput>BZ2_bzCompress</computeroutput> must be called
+repeatedly until all the output has been consumed.  At that
+point, <computeroutput>BZ2_bzCompress</computeroutput> returns
+<computeroutput>BZ_STREAM_END</computeroutput>, and the stream's
+state is set back to IDLE.
+<computeroutput>BZ2_bzCompressEnd</computeroutput> should then be
+called.</para>
+
+<para>Just to make sure the calling program does not cheat, the
+library makes a note of <computeroutput>avail_in</computeroutput>
+at the time of the first call to
+<computeroutput>BZ2_bzCompress</computeroutput> which has
+<computeroutput>BZ_FINISH</computeroutput> as an action (ie, at
+the time the program has announced its intention to not supply
+any more input).  By comparing this value with that of
+<computeroutput>avail_in</computeroutput> over subsequent calls
+to <computeroutput>BZ2_bzCompress</computeroutput>, the library
+can detect any attempts to slip in more data to compress.  Any
+calls for which this is detected will return
+<computeroutput>BZ_SEQUENCE_ERROR</computeroutput>.  This
+indicates a programming mistake which should be corrected.</para>
+
+<para>Instead of asking to finish, the calling program may ask
+<computeroutput>BZ2_bzCompress</computeroutput> to take all the
+remaining input, compress it and terminate the current
+(Burrows-Wheeler) compression block.  This could be useful for
+error control purposes.  The mechanism is analogous to that for
+finishing: call <computeroutput>BZ2_bzCompress</computeroutput>
+with an action of <computeroutput>BZ_FLUSH</computeroutput>,
+remove output data, and persist with the
+<computeroutput>BZ_FLUSH</computeroutput> action until the value
+<computeroutput>BZ_RUN</computeroutput> is returned.  As with
+finishing, <computeroutput>BZ2_bzCompress</computeroutput>
+detects any attempt to provide more input data once the flush has
+begun.</para>
+
+<para>Once the flush is complete, the stream returns to the
+normal RUNNING state.</para>
+
+<para>This all sounds pretty complex, but isn't really.  Here's a
+table which shows which actions are allowable in each state, what
+action will be taken, what the next state is, and what the
+non-error return values are.  Note that you can't explicitly ask
+what state the stream is in, but nor do you need to -- it can be
+inferred from the values returned by
+<computeroutput>BZ2_bzCompress</computeroutput>.</para>
+
+<programlisting>
+IDLE/any
+  Illegal.  IDLE state only exists after BZ2_bzCompressEnd or
+  before BZ2_bzCompressInit.
+  Return value = BZ_SEQUENCE_ERROR
+
+RUNNING/BZ_RUN
+  Compress from next_in to next_out as much as possible.
+  Next state = RUNNING
+  Return value = BZ_RUN_OK
+
+RUNNING/BZ_FLUSH
+  Remember current value of next_in. Compress from next_in
+  to next_out as much as possible, but do not accept any more input.
+  Next state = FLUSHING
+  Return value = BZ_FLUSH_OK
+
+RUNNING/BZ_FINISH
+  Remember current value of next_in. Compress from next_in
+  to next_out as much as possible, but do not accept any more input.
+  Next state = FINISHING
+  Return value = BZ_FINISH_OK
+
+FLUSHING/BZ_FLUSH
+  Compress from next_in to next_out as much as possible, 
+  but do not accept any more input.
+  If all the existing input has been used up and all compressed
+  output has been removed
+    Next state = RUNNING; Return value = BZ_RUN_OK
+  else
+    Next state = FLUSHING; Return value = BZ_FLUSH_OK
+
+FLUSHING/other     
+  Illegal.
+  Return value = BZ_SEQUENCE_ERROR
+
+FINISHING/BZ_FINISH
+  Compress from next_in to next_out as much as possible,
+  but to not accept any more input.  
+  If all the existing input has been used up and all compressed
+  output has been removed
+    Next state = IDLE; Return value = BZ_STREAM_END
+  else
+    Next state = FINISHING; Return value = BZ_FINISH_OK
+
+FINISHING/other
+  Illegal.
+  Return value = BZ_SEQUENCE_ERROR
+</programlisting>
+
+
+<para>That still looks complicated?  Well, fair enough.  The
+usual sequence of calls for compressing a load of data is:</para>
+
+<orderedlist>
+
+ <listitem><para>Get started with
+  <computeroutput>BZ2_bzCompressInit</computeroutput>.</para></listitem>
+
+ <listitem><para>Shovel data in and shlurp out its compressed form
+  using zero or more calls of
+  <computeroutput>BZ2_bzCompress</computeroutput> with action =
+  <computeroutput>BZ_RUN</computeroutput>.</para></listitem>
+
+ <listitem><para>Finish up. Repeatedly call
+  <computeroutput>BZ2_bzCompress</computeroutput> with action =
+  <computeroutput>BZ_FINISH</computeroutput>, copying out the
+  compressed output, until
+  <computeroutput>BZ_STREAM_END</computeroutput> is
+  returned.</para></listitem> <listitem><para>Close up and go home.  Call
+  <computeroutput>BZ2_bzCompressEnd</computeroutput>.</para></listitem>
+
+</orderedlist>
+
+<para>If the data you want to compress fits into your input
+buffer all at once, you can skip the calls of
+<computeroutput>BZ2_bzCompress ( ..., BZ_RUN )</computeroutput>
+and just do the <computeroutput>BZ2_bzCompress ( ..., BZ_FINISH
+)</computeroutput> calls.</para>
+
+<para>All required memory is allocated by
+<computeroutput>BZ2_bzCompressInit</computeroutput>.  The
+compression library can accept any data at all (obviously).  So
+you shouldn't get any error return values from the
+<computeroutput>BZ2_bzCompress</computeroutput> calls.  If you
+do, they will be
+<computeroutput>BZ_SEQUENCE_ERROR</computeroutput>, and indicate
+a bug in your programming.</para>
+
+<para>Trivial other possible return values:</para>
+
+<programlisting>
+BZ_PARAM_ERROR
+  if strm is NULL, or strm->s is NULL
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzCompress-end" xreflabel="BZ2_bzCompressEnd">
+<title>BZ2_bzCompressEnd</title>
+
+<programlisting>
+int BZ2_bzCompressEnd ( bz_stream *strm );
+</programlisting>
+
+<para>Releases all memory associated with a compression
+stream.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_PARAM_ERROR  if strm is NULL or strm->s is NULL
+BZ_OK           otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzDecompress-init" xreflabel="BZ2_bzDecompressInit">
+<title>BZ2_bzDecompressInit</title>
+
+<programlisting>
+int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );
+</programlisting>
+
+<para>Prepares for decompression.  As with
+<computeroutput>BZ2_bzCompressInit</computeroutput>, a
+<computeroutput>bz_stream</computeroutput> record should be
+allocated and initialised before the call.  Fields
+<computeroutput>bzalloc</computeroutput>,
+<computeroutput>bzfree</computeroutput> and
+<computeroutput>opaque</computeroutput> should be set if a custom
+memory allocator is required, or made
+<computeroutput>NULL</computeroutput> for the normal
+<computeroutput>malloc</computeroutput> /
+<computeroutput>free</computeroutput> routines.  Upon return, the
+internal state will have been initialised, and
+<computeroutput>total_in</computeroutput> and
+<computeroutput>total_out</computeroutput> will be zero.</para>
+
+<para>For the meaning of parameter
+<computeroutput>verbosity</computeroutput>, see
+<computeroutput>BZ2_bzCompressInit</computeroutput>.</para>
+
+<para>If <computeroutput>small</computeroutput> is nonzero, the
+library will use an alternative decompression algorithm which
+uses less memory but at the cost of decompressing more slowly
+(roughly speaking, half the speed, but the maximum memory
+requirement drops to around 2300k).  See <xref linkend="using"/>
+for more information on memory management.</para>
+
+<para>Note that the amount of memory needed to decompress a
+stream cannot be determined until the stream's header has been
+read, so even if
+<computeroutput>BZ2_bzDecompressInit</computeroutput> succeeds, a
+subsequent <computeroutput>BZ2_bzDecompress</computeroutput>
+could fail with
+<computeroutput>BZ_MEM_ERROR</computeroutput>.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if ( small != 0 && small != 1 )
+  or (verbosity <; 0 || verbosity > 4)
+BZ_MEM_ERROR
+  if insufficient memory is available
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+BZ2_bzDecompress
+  if BZ_OK was returned
+  no specific action required in case of error
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzDecompress" xreflabel="BZ2_bzDecompress">
+<title>BZ2_bzDecompress</title>
+
+<programlisting>
+int BZ2_bzDecompress ( bz_stream *strm );
+</programlisting>
+
+<para>Provides more input and/out output buffer space for the
+library.  The caller maintains input and output buffers, and uses
+<computeroutput>BZ2_bzDecompress</computeroutput> to transfer
+data between them.</para>
+
+<para>Before each call to
+<computeroutput>BZ2_bzDecompress</computeroutput>,
+<computeroutput>next_in</computeroutput> should point at the
+compressed data, and <computeroutput>avail_in</computeroutput>
+should indicate how many bytes the library may read.
+<computeroutput>BZ2_bzDecompress</computeroutput> updates
+<computeroutput>next_in</computeroutput>,
+<computeroutput>avail_in</computeroutput> and
+<computeroutput>total_in</computeroutput> to reflect the number
+of bytes it has read.</para>
+
+<para>Similarly, <computeroutput>next_out</computeroutput> should
+point to a buffer in which the uncompressed output is to be
+placed, with <computeroutput>avail_out</computeroutput>
+indicating how much output space is available.
+<computeroutput>BZ2_bzCompress</computeroutput> updates
+<computeroutput>next_out</computeroutput>,
+<computeroutput>avail_out</computeroutput> and
+<computeroutput>total_out</computeroutput> to reflect the number
+of bytes output.</para>
+
+<para>You may provide and remove as little or as much data as you
+like on each call of
+<computeroutput>BZ2_bzDecompress</computeroutput>.  In the limit,
+it is acceptable to supply and remove data one byte at a time,
+although this would be terribly inefficient.  You should always
+ensure that at least one byte of output space is available at
+each call.</para>
+
+<para>Use of <computeroutput>BZ2_bzDecompress</computeroutput> is
+simpler than
+<computeroutput>BZ2_bzCompress</computeroutput>.</para>
+
+<para>You should provide input and remove output as described
+above, and repeatedly call
+<computeroutput>BZ2_bzDecompress</computeroutput> until
+<computeroutput>BZ_STREAM_END</computeroutput> is returned.
+Appearance of <computeroutput>BZ_STREAM_END</computeroutput>
+denotes that <computeroutput>BZ2_bzDecompress</computeroutput>
+has detected the logical end of the compressed stream.
+<computeroutput>BZ2_bzDecompress</computeroutput> will not
+produce <computeroutput>BZ_STREAM_END</computeroutput> until all
+output data has been placed into the output buffer, so once
+<computeroutput>BZ_STREAM_END</computeroutput> appears, you are
+guaranteed to have available all the decompressed output, and
+<computeroutput>BZ2_bzDecompressEnd</computeroutput> can safely
+be called.</para>
+
+<para>If case of an error return value, you should call
+<computeroutput>BZ2_bzDecompressEnd</computeroutput> to clean up
+and release memory.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_PARAM_ERROR
+  if strm is NULL or strm->s is NULL
+  or strm->avail_out < 1
+BZ_DATA_ERROR
+  if a data integrity error is detected in the compressed stream
+BZ_DATA_ERROR_MAGIC
+  if the compressed stream doesn't begin with the right magic bytes
+BZ_MEM_ERROR
+  if there wasn't enough memory available
+BZ_STREAM_END
+  if the logical end of the data stream was detected and all
+  output in has been consumed, eg s-->avail_out > 0
+BZ_OK
+  otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+BZ2_bzDecompress
+  if BZ_OK was returned
+BZ2_bzDecompressEnd
+  otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzDecompress-end" xreflabel="BZ2_bzDecompressEnd">
+<title>BZ2_bzDecompressEnd</title>
+
+<programlisting>
+int BZ2_bzDecompressEnd ( bz_stream *strm );
+</programlisting>
+
+<para>Releases all memory associated with a decompression
+stream.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_PARAM_ERROR
+  if strm is NULL or strm->s is NULL
+BZ_OK
+  otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+  None.
+</programlisting>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 id="hl-interface" xreflabel="High-level interface">
+<title>High-level interface</title>
+
+<para>This interface provides functions for reading and writing
+<computeroutput>bzip2</computeroutput> format files.  First, some
+general points.</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para>All of the functions take an
+  <computeroutput>int*</computeroutput> first argument,
+  <computeroutput>bzerror</computeroutput>.  After each call,
+  <computeroutput>bzerror</computeroutput> should be consulted
+  first to determine the outcome of the call.  If
+  <computeroutput>bzerror</computeroutput> is
+  <computeroutput>BZ_OK</computeroutput>, the call completed
+  successfully, and only then should the return value of the
+  function (if any) be consulted.  If
+  <computeroutput>bzerror</computeroutput> is
+  <computeroutput>BZ_IO_ERROR</computeroutput>, there was an
+  error reading/writing the underlying compressed file, and you
+  should then consult <computeroutput>errno</computeroutput> /
+  <computeroutput>perror</computeroutput> to determine the cause
+  of the difficulty.  <computeroutput>bzerror</computeroutput>
+  may also be set to various other values; precise details are
+  given on a per-function basis below.</para></listitem>
+
+ <listitem><para>If <computeroutput>bzerror</computeroutput> indicates
+  an error (ie, anything except
+  <computeroutput>BZ_OK</computeroutput> and
+  <computeroutput>BZ_STREAM_END</computeroutput>), you should
+  immediately call
+  <computeroutput>BZ2_bzReadClose</computeroutput> (or
+  <computeroutput>BZ2_bzWriteClose</computeroutput>, depending on
+  whether you are attempting to read or to write) to free up all
+  resources associated with the stream.  Once an error has been
+  indicated, behaviour of all calls except
+  <computeroutput>BZ2_bzReadClose</computeroutput>
+  (<computeroutput>BZ2_bzWriteClose</computeroutput>) is
+  undefined.  The implication is that (1)
+  <computeroutput>bzerror</computeroutput> should be checked
+  after each call, and (2) if
+  <computeroutput>bzerror</computeroutput> indicates an error,
+  <computeroutput>BZ2_bzReadClose</computeroutput>
+  (<computeroutput>BZ2_bzWriteClose</computeroutput>) should then
+  be called to clean up.</para></listitem>
+
+ <listitem><para>The <computeroutput>FILE*</computeroutput> arguments
+  passed to <computeroutput>BZ2_bzReadOpen</computeroutput> /
+  <computeroutput>BZ2_bzWriteOpen</computeroutput> should be set
+  to binary mode.  Most Unix systems will do this by default, but
+  other platforms, including Windows and Mac, will not.  If you
+  omit this, you may encounter problems when moving code to new
+  platforms.</para></listitem>
+
+ <listitem><para>Memory allocation requests are handled by
+  <computeroutput>malloc</computeroutput> /
+  <computeroutput>free</computeroutput>.  At present there is no
+  facility for user-defined memory allocators in the file I/O
+  functions (could easily be added, though).</para></listitem>
+
+</itemizedlist>
+
+
+
+<sect2 id="bzreadopen" xreflabel="BZ2_bzReadOpen">
+<title>BZ2_bzReadOpen</title>
+
+<programlisting>
+typedef void BZFILE;
+
+BZFILE *BZ2_bzReadOpen( int *bzerror, FILE *f, 
+                        int verbosity, int small,
+                        void *unused, int nUnused );
+</programlisting>
+
+<para>Prepare to read compressed data from file handle
+<computeroutput>f</computeroutput>.
+<computeroutput>f</computeroutput> should refer to a file which
+has been opened for reading, and for which the error indicator
+(<computeroutput>ferror(f)</computeroutput>)is not set.  If
+<computeroutput>small</computeroutput> is 1, the library will try
+to decompress using less memory, at the expense of speed.</para>
+
+<para>For reasons explained below,
+<computeroutput>BZ2_bzRead</computeroutput> will decompress the
+<computeroutput>nUnused</computeroutput> bytes starting at
+<computeroutput>unused</computeroutput>, before starting to read
+from the file <computeroutput>f</computeroutput>.  At most
+<computeroutput>BZ_MAX_UNUSED</computeroutput> bytes may be
+supplied like this.  If this facility is not required, you should
+pass <computeroutput>NULL</computeroutput> and
+<computeroutput>0</computeroutput> for
+<computeroutput>unused</computeroutput> and
+n<computeroutput>Unused</computeroutput> respectively.</para>
+
+<para>For the meaning of parameters
+<computeroutput>small</computeroutput> and
+<computeroutput>verbosity</computeroutput>, see
+<computeroutput>BZ2_bzDecompressInit</computeroutput>.</para>
+
+<para>The amount of memory needed to decompress a file cannot be
+determined until the file's header has been read.  So it is
+possible that <computeroutput>BZ2_bzReadOpen</computeroutput>
+returns <computeroutput>BZ_OK</computeroutput> but a subsequent
+call of <computeroutput>BZ2_bzRead</computeroutput> will return
+<computeroutput>BZ_MEM_ERROR</computeroutput>.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if f is NULL
+  or small is neither 0 nor 1
+  or ( unused == NULL && nUnused != 0 )
+  or ( unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED) )
+BZ_IO_ERROR
+  if ferror(f) is nonzero
+BZ_MEM_ERROR
+  if insufficient memory is available
+BZ_OK
+  otherwise.
+</programlisting>
+
+<para>Possible return values:</para>
+
+<programlisting>
+Pointer to an abstract BZFILE
+  if bzerror is BZ_OK
+NULL
+  otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+BZ2_bzRead
+  if bzerror is BZ_OK
+BZ2_bzClose
+  otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzread" xreflabel="BZ2_bzRead">
+<title>BZ2_bzRead</title>
+
+<programlisting>
+int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );
+</programlisting>
+
+<para>Reads up to <computeroutput>len</computeroutput>
+(uncompressed) bytes from the compressed file
+<computeroutput>b</computeroutput> into the buffer
+<computeroutput>buf</computeroutput>.  If the read was
+successful, <computeroutput>bzerror</computeroutput> is set to
+<computeroutput>BZ_OK</computeroutput> and the number of bytes
+read is returned.  If the logical end-of-stream was detected,
+<computeroutput>bzerror</computeroutput> will be set to
+<computeroutput>BZ_STREAM_END</computeroutput>, and the number of
+bytes read is returned.  All other
+<computeroutput>bzerror</computeroutput> values denote an
+error.</para>
+
+<para><computeroutput>BZ2_bzRead</computeroutput> will supply
+<computeroutput>len</computeroutput> bytes, unless the logical
+stream end is detected or an error occurs.  Because of this, it
+is possible to detect the stream end by observing when the number
+of bytes returned is less than the number requested.
+Nevertheless, this is regarded as inadvisable; you should instead
+check <computeroutput>bzerror</computeroutput> after every call
+and watch out for
+<computeroutput>BZ_STREAM_END</computeroutput>.</para>
+
+<para>Internally, <computeroutput>BZ2_bzRead</computeroutput>
+copies data from the compressed file in chunks of size
+<computeroutput>BZ_MAX_UNUSED</computeroutput> bytes before
+decompressing it.  If the file contains more bytes than strictly
+needed to reach the logical end-of-stream,
+<computeroutput>BZ2_bzRead</computeroutput> will almost certainly
+read some of the trailing data before signalling
+<computeroutput>BZ_SEQUENCE_END</computeroutput>.  To collect the
+read but unused data once
+<computeroutput>BZ_SEQUENCE_END</computeroutput> has appeared,
+call <computeroutput>BZ2_bzReadGetUnused</computeroutput>
+immediately before
+<computeroutput>BZ2_bzReadClose</computeroutput>.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_PARAM_ERROR
+  if b is NULL or buf is NULL or len < 0
+BZ_SEQUENCE_ERROR
+  if b was opened with BZ2_bzWriteOpen
+BZ_IO_ERROR
+  if there is an error reading from the compressed file
+BZ_UNEXPECTED_EOF
+  if the compressed file ended before 
+  the logical end-of-stream was detected
+BZ_DATA_ERROR
+  if a data integrity error was detected in the compressed stream
+BZ_DATA_ERROR_MAGIC
+  if the stream does not begin with the requisite header bytes 
+  (ie, is not a bzip2 data file).  This is really 
+  a special case of BZ_DATA_ERROR.
+BZ_MEM_ERROR
+  if insufficient memory was available
+BZ_STREAM_END
+  if the logical end of stream was detected.
+BZ_OK
+  otherwise.
+</programlisting>
+
+<para>Possible return values:</para>
+
+<programlisting>
+number of bytes read
+  if bzerror is BZ_OK or BZ_STREAM_END
+undefined
+  otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+collect data from buf, then BZ2_bzRead or BZ2_bzReadClose
+  if bzerror is BZ_OK
+collect data from buf, then BZ2_bzReadClose or BZ2_bzReadGetUnused
+  if bzerror is BZ_SEQUENCE_END
+BZ2_bzReadClose
+  otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzreadgetunused" xreflabel="BZ2_bzReadGetUnused">
+<title>BZ2_bzReadGetUnused</title>
+
+<programlisting>
+void BZ2_bzReadGetUnused( int* bzerror, BZFILE *b, 
+                          void** unused, int* nUnused );
+</programlisting>
+
+<para>Returns data which was read from the compressed file but
+was not needed to get to the logical end-of-stream.
+<computeroutput>*unused</computeroutput> is set to the address of
+the data, and <computeroutput>*nUnused</computeroutput> to the
+number of bytes.  <computeroutput>*nUnused</computeroutput> will
+be set to a value between <computeroutput>0</computeroutput> and
+<computeroutput>BZ_MAX_UNUSED</computeroutput> inclusive.</para>
+
+<para>This function may only be called once
+<computeroutput>BZ2_bzRead</computeroutput> has signalled
+<computeroutput>BZ_STREAM_END</computeroutput> but before
+<computeroutput>BZ2_bzReadClose</computeroutput>.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_PARAM_ERROR
+  if b is NULL
+  or unused is NULL or nUnused is NULL
+BZ_SEQUENCE_ERROR
+  if BZ_STREAM_END has not been signalled
+  or if b was opened with BZ2_bzWriteOpen
+BZ_OK
+  otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+BZ2_bzReadClose
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzreadclose" xreflabel="BZ2_bzReadClose">
+<title>BZ2_bzReadClose</title>
+
+<programlisting>
+void BZ2_bzReadClose ( int *bzerror, BZFILE *b );
+</programlisting>
+
+<para>Releases all memory pertaining to the compressed file
+<computeroutput>b</computeroutput>.
+<computeroutput>BZ2_bzReadClose</computeroutput> does not call
+<computeroutput>fclose</computeroutput> on the underlying file
+handle, so you should do that yourself if appropriate.
+<computeroutput>BZ2_bzReadClose</computeroutput> should be called
+to clean up after all error situations.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_SEQUENCE_ERROR
+  if b was opened with BZ2_bzOpenWrite
+BZ_OK
+  otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+none
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzwriteopen" xreflabel="BZ2_bzWriteOpen">
+<title>BZ2_bzWriteOpen</title>
+
+<programlisting>
+BZFILE *BZ2_bzWriteOpen( int *bzerror, FILE *f, 
+                         int blockSize100k, int verbosity,
+                         int workFactor );
+</programlisting>
+
+<para>Prepare to write compressed data to file handle
+<computeroutput>f</computeroutput>.
+<computeroutput>f</computeroutput> should refer to a file which
+has been opened for writing, and for which the error indicator
+(<computeroutput>ferror(f)</computeroutput>)is not set.</para>
+
+<para>For the meaning of parameters
+<computeroutput>blockSize100k</computeroutput>,
+<computeroutput>verbosity</computeroutput> and
+<computeroutput>workFactor</computeroutput>, see
+<computeroutput>BZ2_bzCompressInit</computeroutput>.</para>
+
+<para>All required memory is allocated at this stage, so if the
+call completes successfully,
+<computeroutput>BZ_MEM_ERROR</computeroutput> cannot be signalled
+by a subsequent call to
+<computeroutput>BZ2_bzWrite</computeroutput>.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if f is NULL
+  or blockSize100k < 1 or blockSize100k > 9
+BZ_IO_ERROR
+  if ferror(f) is nonzero
+BZ_MEM_ERROR
+  if insufficient memory is available
+BZ_OK
+  otherwise
+</programlisting>
+
+<para>Possible return values:</para>
+
+<programlisting>
+Pointer to an abstract BZFILE
+  if bzerror is BZ_OK
+NULL
+  otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+BZ2_bzWrite
+  if bzerror is BZ_OK
+  (you could go directly to BZ2_bzWriteClose, but this would be pretty pointless)
+BZ2_bzWriteClose
+  otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzwrite" xreflabel="BZ2_bzWrite">
+<title>BZ2_bzWrite</title>
+
+<programlisting>
+void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );
+</programlisting>
+
+<para>Absorbs <computeroutput>len</computeroutput> bytes from the
+buffer <computeroutput>buf</computeroutput>, eventually to be
+compressed and written to the file.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_PARAM_ERROR
+  if b is NULL or buf is NULL or len < 0
+BZ_SEQUENCE_ERROR
+  if b was opened with BZ2_bzReadOpen
+BZ_IO_ERROR
+  if there is an error writing the compressed file.
+BZ_OK
+  otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzwriteclose" xreflabel="BZ2_bzWriteClose">
+<title>BZ2_bzWriteClose</title>
+
+<programlisting>
+void BZ2_bzWriteClose( int *bzerror, BZFILE* f,
+                       int abandon,
+                       unsigned int* nbytes_in,
+                       unsigned int* nbytes_out );
+
+void BZ2_bzWriteClose64( int *bzerror, BZFILE* f,
+                         int abandon,
+                         unsigned int* nbytes_in_lo32,
+                         unsigned int* nbytes_in_hi32,
+                         unsigned int* nbytes_out_lo32,
+                         unsigned int* nbytes_out_hi32 );
+</programlisting>
+
+<para>Compresses and flushes to the compressed file all data so
+far supplied by <computeroutput>BZ2_bzWrite</computeroutput>.
+The logical end-of-stream markers are also written, so subsequent
+calls to <computeroutput>BZ2_bzWrite</computeroutput> are
+illegal.  All memory associated with the compressed file
+<computeroutput>b</computeroutput> is released.
+<computeroutput>fflush</computeroutput> is called on the
+compressed file, but it is not
+<computeroutput>fclose</computeroutput>'d.</para>
+
+<para>If <computeroutput>BZ2_bzWriteClose</computeroutput> is
+called to clean up after an error, the only action is to release
+the memory.  The library records the error codes issued by
+previous calls, so this situation will be detected automatically.
+There is no attempt to complete the compression operation, nor to
+<computeroutput>fflush</computeroutput> the compressed file.  You
+can force this behaviour to happen even in the case of no error,
+by passing a nonzero value to
+<computeroutput>abandon</computeroutput>.</para>
+
+<para>If <computeroutput>nbytes_in</computeroutput> is non-null,
+<computeroutput>*nbytes_in</computeroutput> will be set to be the
+total volume of uncompressed data handled.  Similarly,
+<computeroutput>nbytes_out</computeroutput> will be set to the
+total volume of compressed data written.  For compatibility with
+older versions of the library,
+<computeroutput>BZ2_bzWriteClose</computeroutput> only yields the
+lower 32 bits of these counts.  Use
+<computeroutput>BZ2_bzWriteClose64</computeroutput> if you want
+the full 64 bit counts.  These two functions are otherwise
+absolutely identical.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_SEQUENCE_ERROR
+  if b was opened with BZ2_bzReadOpen
+BZ_IO_ERROR
+  if there is an error writing the compressed file
+BZ_OK
+  otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="embed" xreflabel="Handling embedded compressed data streams">
+<title>Handling embedded compressed data streams</title>
+
+<para>The high-level library facilitates use of
+<computeroutput>bzip2</computeroutput> data streams which form
+some part of a surrounding, larger data stream.</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para>For writing, the library takes an open file handle,
+  writes compressed data to it,
+  <computeroutput>fflush</computeroutput>es it but does not
+  <computeroutput>fclose</computeroutput> it.  The calling
+  application can write its own data before and after the
+  compressed data stream, using that same file handle.</para></listitem>
+
+ <listitem><para>Reading is more complex, and the facilities are not as
+  general as they could be since generality is hard to reconcile
+  with efficiency.  <computeroutput>BZ2_bzRead</computeroutput>
+  reads from the compressed file in blocks of size
+  <computeroutput>BZ_MAX_UNUSED</computeroutput> bytes, and in
+  doing so probably will overshoot the logical end of compressed
+  stream.  To recover this data once decompression has ended,
+  call <computeroutput>BZ2_bzReadGetUnused</computeroutput> after
+  the last call of <computeroutput>BZ2_bzRead</computeroutput>
+  (the one returning
+  <computeroutput>BZ_STREAM_END</computeroutput>) but before
+  calling
+  <computeroutput>BZ2_bzReadClose</computeroutput>.</para></listitem>
+
+</itemizedlist>
+
+<para>This mechanism makes it easy to decompress multiple
+<computeroutput>bzip2</computeroutput> streams placed end-to-end.
+As the end of one stream, when
+<computeroutput>BZ2_bzRead</computeroutput> returns
+<computeroutput>BZ_STREAM_END</computeroutput>, call
+<computeroutput>BZ2_bzReadGetUnused</computeroutput> to collect
+the unused data (copy it into your own buffer somewhere).  That
+data forms the start of the next compressed stream.  To start
+uncompressing that next stream, call
+<computeroutput>BZ2_bzReadOpen</computeroutput> again, feeding in
+the unused data via the <computeroutput>unused</computeroutput> /
+<computeroutput>nUnused</computeroutput> parameters.  Keep doing
+this until <computeroutput>BZ_STREAM_END</computeroutput> return
+coincides with the physical end of file
+(<computeroutput>feof(f)</computeroutput>).  In this situation
+<computeroutput>BZ2_bzReadGetUnused</computeroutput> will of
+course return no data.</para>
+
+<para>This should give some feel for how the high-level interface
+can be used.  If you require extra flexibility, you'll have to
+bite the bullet and get to grips with the low-level
+interface.</para>
+
+</sect2>
+
+
+<sect2 id="std-rdwr" xreflabel="Standard file-reading/writing code">
+<title>Standard file-reading/writing code</title>
+
+<para>Here's how you'd write data to a compressed file:</para>
+
+<programlisting>
+FILE*   f;
+BZFILE* b;
+int     nBuf;
+char    buf[ /* whatever size you like */ ];
+int     bzerror;
+int     nWritten;
+
+f = fopen ( "myfile.bz2", "w" );
+if ( !f ) {
+ /* handle error */
+}
+b = BZ2_bzWriteOpen( &bzerror, f, 9 );
+if (bzerror != BZ_OK) {
+ BZ2_bzWriteClose ( b );
+ /* handle error */
+}
+
+while ( /* condition */ ) {
+ /* get data to write into buf, and set nBuf appropriately */
+ nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf );
+ if (bzerror == BZ_IO_ERROR) { 
+   BZ2_bzWriteClose ( &bzerror, b );
+   /* handle error */
+ }
+}
+
+BZ2_bzWriteClose( &bzerror, b );
+if (bzerror == BZ_IO_ERROR) {
+ /* handle error */
+}
+</programlisting>
+
+<para>And to read from a compressed file:</para>
+
+<programlisting>
+FILE*   f;
+BZFILE* b;
+int     nBuf;
+char    buf[ /* whatever size you like */ ];
+int     bzerror;
+int     nWritten;
+
+f = fopen ( "myfile.bz2", "r" );
+if ( !f ) {
+  /* handle error */
+}
+b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 );
+if ( bzerror != BZ_OK ) {
+  BZ2_bzReadClose ( &bzerror, b );
+  /* handle error */
+}
+
+bzerror = BZ_OK;
+while ( bzerror == BZ_OK && /* arbitrary other conditions */) {
+  nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ );
+  if ( bzerror == BZ_OK ) {
+    /* do something with buf[0 .. nBuf-1] */
+  }
+}
+if ( bzerror != BZ_STREAM_END ) {
+   BZ2_bzReadClose ( &bzerror, b );
+   /* handle error */
+} else {
+   BZ2_bzReadClose ( &bzerror, b );
+}
+</programlisting>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 id="util-fns" xreflabel="Utility functions">
+<title>Utility functions</title>
+
+
+<sect2 id="bzbufftobuffcompress" xreflabel="BZ2_bzBuffToBuffCompress">
+<title>BZ2_bzBuffToBuffCompress</title>
+
+<programlisting>
+int BZ2_bzBuffToBuffCompress( char*         dest,
+                              unsigned int* destLen,
+                              char*         source,
+                              unsigned int  sourceLen,
+                              int           blockSize100k,
+                              int           verbosity,
+                              int           workFactor );
+</programlisting>
+
+<para>Attempts to compress the data in <computeroutput>source[0
+.. sourceLen-1]</computeroutput> into the destination buffer,
+<computeroutput>dest[0 .. *destLen-1]</computeroutput>.  If the
+destination buffer is big enough,
+<computeroutput>*destLen</computeroutput> is set to the size of
+the compressed data, and <computeroutput>BZ_OK</computeroutput>
+is returned.  If the compressed data won't fit,
+<computeroutput>*destLen</computeroutput> is unchanged, and
+<computeroutput>BZ_OUTBUFF_FULL</computeroutput> is
+returned.</para>
+
+<para>Compression in this manner is a one-shot event, done with a
+single call to this function.  The resulting compressed data is a
+complete <computeroutput>bzip2</computeroutput> format data
+stream.  There is no mechanism for making additional calls to
+provide extra input data.  If you want that kind of mechanism,
+use the low-level interface.</para>
+
+<para>For the meaning of parameters
+<computeroutput>blockSize100k</computeroutput>,
+<computeroutput>verbosity</computeroutput> and
+<computeroutput>workFactor</computeroutput>, see
+<computeroutput>BZ2_bzCompressInit</computeroutput>.</para>
+
+<para>To guarantee that the compressed data will fit in its
+buffer, allocate an output buffer of size 1% larger than the
+uncompressed data, plus six hundred extra bytes.</para>
+
+<para><computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput>
+will not write data at or beyond
+<computeroutput>dest[*destLen]</computeroutput>, even in case of
+buffer overflow.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if dest is NULL or destLen is NULL
+  or blockSize100k < 1 or blockSize100k > 9
+  or verbosity < 0 or verbosity > 4
+  or workFactor < 0 or workFactor > 250
+BZ_MEM_ERROR
+  if insufficient memory is available 
+BZ_OUTBUFF_FULL
+  if the size of the compressed data exceeds *destLen
+BZ_OK
+  otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzbufftobuffdecompress" xreflabel="BZ2_bzBuffToBuffDecompress">
+<title>BZ2_bzBuffToBuffDecompress</title>
+
+<programlisting>
+int BZ2_bzBuffToBuffDecompress( char*         dest,
+                                unsigned int* destLen,
+                                char*         source,
+                                unsigned int  sourceLen,
+                                int           small,
+                                int           verbosity );
+</programlisting>
+
+<para>Attempts to decompress the data in <computeroutput>source[0
+.. sourceLen-1]</computeroutput> into the destination buffer,
+<computeroutput>dest[0 .. *destLen-1]</computeroutput>.  If the
+destination buffer is big enough,
+<computeroutput>*destLen</computeroutput> is set to the size of
+the uncompressed data, and <computeroutput>BZ_OK</computeroutput>
+is returned.  If the compressed data won't fit,
+<computeroutput>*destLen</computeroutput> is unchanged, and
+<computeroutput>BZ_OUTBUFF_FULL</computeroutput> is
+returned.</para>
+
+<para><computeroutput>source</computeroutput> is assumed to hold
+a complete <computeroutput>bzip2</computeroutput> format data
+stream.
+<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> tries
+to decompress the entirety of the stream into the output
+buffer.</para>
+
+<para>For the meaning of parameters
+<computeroutput>small</computeroutput> and
+<computeroutput>verbosity</computeroutput>, see
+<computeroutput>BZ2_bzDecompressInit</computeroutput>.</para>
+
+<para>Because the compression ratio of the compressed data cannot
+be known in advance, there is no easy way to guarantee that the
+output buffer will be big enough.  You may of course make
+arrangements in your code to record the size of the uncompressed
+data, but such a mechanism is beyond the scope of this
+library.</para>
+
+<para><computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput>
+will not write data at or beyond
+<computeroutput>dest[*destLen]</computeroutput>, even in case of
+buffer overflow.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_CONFIG_ERROR
+  if the library has been mis-compiled
+BZ_PARAM_ERROR
+  if dest is NULL or destLen is NULL
+  or small != 0 && small != 1
+  or verbosity < 0 or verbosity > 4
+BZ_MEM_ERROR
+  if insufficient memory is available 
+BZ_OUTBUFF_FULL
+  if the size of the compressed data exceeds *destLen
+BZ_DATA_ERROR
+  if a data integrity error was detected in the compressed data
+BZ_DATA_ERROR_MAGIC
+  if the compressed data doesn't begin with the right magic bytes
+BZ_UNEXPECTED_EOF
+  if the compressed data ends unexpectedly
+BZ_OK
+  otherwise
+</programlisting>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 id="zlib-compat" xreflabel="zlib compatibility functions">
+<title>zlib compatibility functions</title>
+
+<para>Yoshioka Tsuneo has contributed some functions to give
+better <computeroutput>zlib</computeroutput> compatibility.
+These functions are <computeroutput>BZ2_bzopen</computeroutput>,
+<computeroutput>BZ2_bzread</computeroutput>,
+<computeroutput>BZ2_bzwrite</computeroutput>,
+<computeroutput>BZ2_bzflush</computeroutput>,
+<computeroutput>BZ2_bzclose</computeroutput>,
+<computeroutput>BZ2_bzerror</computeroutput> and
+<computeroutput>BZ2_bzlibVersion</computeroutput>.  These
+functions are not (yet) officially part of the library.  If they
+break, you get to keep all the pieces.  Nevertheless, I think
+they work ok.</para>
+
+<programlisting>
+typedef void BZFILE;
+
+const char * BZ2_bzlibVersion ( void );
+</programlisting>
+
+<para>Returns a string indicating the library version.</para>
+
+<programlisting>
+BZFILE * BZ2_bzopen  ( const char *path, const char *mode );
+BZFILE * BZ2_bzdopen ( int        fd,    const char *mode );
+</programlisting>
+
+<para>Opens a <computeroutput>.bz2</computeroutput> file for
+reading or writing, using either its name or a pre-existing file
+descriptor.  Analogous to <computeroutput>fopen</computeroutput>
+and <computeroutput>fdopen</computeroutput>.</para>
+
+<programlisting>
+int BZ2_bzread  ( BZFILE* b, void* buf, int len );
+int BZ2_bzwrite ( BZFILE* b, void* buf, int len );
+</programlisting>
+
+<para>Reads/writes data from/to a previously opened
+<computeroutput>BZFILE</computeroutput>.  Analogous to
+<computeroutput>fread</computeroutput> and
+<computeroutput>fwrite</computeroutput>.</para>
+
+<programlisting>
+int  BZ2_bzflush ( BZFILE* b );
+void BZ2_bzclose ( BZFILE* b );
+</programlisting>
+
+<para>Flushes/closes a <computeroutput>BZFILE</computeroutput>.
+<computeroutput>BZ2_bzflush</computeroutput> doesn't actually do
+anything.  Analogous to <computeroutput>fflush</computeroutput>
+and <computeroutput>fclose</computeroutput>.</para>
+
+<programlisting>
+const char * BZ2_bzerror ( BZFILE *b, int *errnum )
+</programlisting>
+
+<para>Returns a string describing the more recent error status of
+<computeroutput>b</computeroutput>, and also sets
+<computeroutput>*errnum</computeroutput> to its numerical
+value.</para>
+
+</sect1>
+
+
+<sect1 id="stdio-free" 
+       xreflabel="Using the library in a stdio-free environment">
+<title>Using the library in a stdio-free environment</title>
+
+
+<sect2 id="stdio-bye" xreflabel="Getting rid of stdio">
+<title>Getting rid of stdio</title>
+
+<para>In a deeply embedded application, you might want to use
+just the memory-to-memory functions.  You can do this
+conveniently by compiling the library with preprocessor symbol
+<computeroutput>BZ_NO_STDIO</computeroutput> defined.  Doing this
+gives you a library containing only the following eight
+functions:</para>
+
+<para><computeroutput>BZ2_bzCompressInit</computeroutput>,
+<computeroutput>BZ2_bzCompress</computeroutput>,
+<computeroutput>BZ2_bzCompressEnd</computeroutput>
+<computeroutput>BZ2_bzDecompressInit</computeroutput>,
+<computeroutput>BZ2_bzDecompress</computeroutput>,
+<computeroutput>BZ2_bzDecompressEnd</computeroutput>
+<computeroutput>BZ2_bzBuffToBuffCompress</computeroutput>,
+<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput></para>
+
+<para>When compiled like this, all functions will ignore
+<computeroutput>verbosity</computeroutput> settings.</para>
+
+</sect2>
+
+
+<sect2 id="critical-error" xreflabel="Critical error handling">
+<title>Critical error handling</title>
+
+<para><computeroutput>libbzip2</computeroutput> contains a number
+of internal assertion checks which should, needless to say, never
+be activated.  Nevertheless, if an assertion should fail,
+behaviour depends on whether or not the library was compiled with
+<computeroutput>BZ_NO_STDIO</computeroutput> set.</para>
+
+<para>For a normal compile, an assertion failure yields the
+message:</para>
+
+<blockquote>
+<para>bzip2/libbzip2: internal error number N.</para>
+<para>This is a bug in bzip2/libbzip2, &bz-version; of &bz-date;.
+Please report it to me at: &bz-email;.  If this happened
+when you were using some program which uses libbzip2 as a
+component, you should also report this bug to the author(s)
+of that program.  Please make an effort to report this bug;
+timely and accurate bug reports eventually lead to higher
+quality software.  Thanks.  Julian Seward, &bz-date;.
+</para></blockquote>
+
+<para>where <computeroutput>N</computeroutput> is some error code
+number.  If <computeroutput>N == 1007</computeroutput>, it also
+prints some extra text advising the reader that unreliable memory
+is often associated with internal error 1007. (This is a
+frequently-observed-phenomenon with versions 1.0.0/1.0.1).</para>
+
+<para><computeroutput>exit(3)</computeroutput> is then
+called.</para>
+
+<para>For a <computeroutput>stdio</computeroutput>-free library,
+assertion failures result in a call to a function declared
+as:</para>
+
+<programlisting>
+extern void bz_internal_error ( int errcode );
+</programlisting>
+
+<para>The relevant code is passed as a parameter.  You should
+supply such a function.</para>
+
+<para>In either case, once an assertion failure has occurred, any
+<computeroutput>bz_stream</computeroutput> records involved can
+be regarded as invalid.  You should not attempt to resume normal
+operation with them.</para>
+
+<para>You may, of course, change critical error handling to suit
+your needs.  As I said above, critical errors indicate bugs in
+the library and should not occur.  All "normal" error situations
+are indicated via error return codes from functions, and can be
+recovered from.</para>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 id="win-dll" xreflabel="Making a Windows DLL">
+<title>Making a Windows DLL</title>
+
+<para>Everything related to Windows has been contributed by
+Yoshioka Tsuneo
+(<computeroutput>tsuneo at rr.iij4u.or.jp</computeroutput>), so
+you should send your queries to him (but perhaps Cc: me,
+<computeroutput>&bz-email;</computeroutput>).</para>
+
+<para>My vague understanding of what to do is: using Visual C++
+5.0, open the project file
+<computeroutput>libbz2.dsp</computeroutput>, and build.  That's
+all.</para>
+
+<para>If you can't open the project file for some reason, make a
+new one, naming these files:
+<computeroutput>blocksort.c</computeroutput>,
+<computeroutput>bzlib.c</computeroutput>,
+<computeroutput>compress.c</computeroutput>,
+<computeroutput>crctable.c</computeroutput>,
+<computeroutput>decompress.c</computeroutput>,
+<computeroutput>huffman.c</computeroutput>,
+<computeroutput>randtable.c</computeroutput> and
+<computeroutput>libbz2.def</computeroutput>.  You will also need
+to name the header files <computeroutput>bzlib.h</computeroutput>
+and <computeroutput>bzlib_private.h</computeroutput>.</para>
+
+<para>If you don't use VC++, you may need to define the
+proprocessor symbol
+<computeroutput>_WIN32</computeroutput>.</para>
+
+<para>Finally, <computeroutput>dlltest.c</computeroutput> is a
+sample program using the DLL.  It has a project file,
+<computeroutput>dlltest.dsp</computeroutput>.</para>
+
+<para>If you just want a makefile for Visual C, have a look at
+<computeroutput>makefile.msc</computeroutput>.</para>
+
+<para>Be aware that if you compile
+<computeroutput>bzip2</computeroutput> itself on Win32, you must
+set <computeroutput>BZ_UNIX</computeroutput> to 0 and
+<computeroutput>BZ_LCCWIN32</computeroutput> to 1, in the file
+<computeroutput>bzip2.c</computeroutput>, before compiling.
+Otherwise the resulting binary won't work correctly.</para>
+
+<para>I haven't tried any of this stuff myself, but it all looks
+plausible.</para>
+
+</sect1>
+
+</chapter>
+
+
+
+<chapter id="misc" xreflabel="Miscellanea">
+<title>Miscellanea</title>
+
+<para>These are just some random thoughts of mine.  Your mileage
+may vary.</para>
+
+
+<sect1 id="limits" xreflabel="Limitations of the compressed file format">
+<title>Limitations of the compressed file format</title>
+
+<para><computeroutput>bzip2-1.0.X</computeroutput>,
+<computeroutput>0.9.5</computeroutput> and
+<computeroutput>0.9.0</computeroutput> use exactly the same file
+format as the original version,
+<computeroutput>bzip2-0.1</computeroutput>.  This decision was
+made in the interests of stability.  Creating yet another
+incompatible compressed file format would create further
+confusion and disruption for users.</para>
+
+<para>Nevertheless, this is not a painless decision.  Development
+work since the release of
+<computeroutput>bzip2-0.1</computeroutput> in August 1997 has
+shown complexities in the file format which slow down
+decompression and, in retrospect, are unnecessary.  These
+are:</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para>The run-length encoder, which is the first of the
+   compression transformations, is entirely irrelevant.  The
+   original purpose was to protect the sorting algorithm from the
+   very worst case input: a string of repeated symbols.  But
+   algorithm steps Q6a and Q6b in the original Burrows-Wheeler
+   technical report (SRC-124) show how repeats can be handled
+   without difficulty in block sorting.</para></listitem>
+
+ <listitem><para>The randomisation mechanism doesn't really need to be
+   there.  Udi Manber and Gene Myers published a suffix array
+   construction algorithm a few years back, which can be employed
+   to sort any block, no matter how repetitive, in O(N log N)
+   time.  Subsequent work by Kunihiko Sadakane has produced a
+   derivative O(N (log N)^2) algorithm which usually outperforms
+   the Manber-Myers algorithm.</para>
+
+   <para>I could have changed to Sadakane's algorithm, but I find
+   it to be slower than <computeroutput>bzip2</computeroutput>'s
+   existing algorithm for most inputs, and the randomisation
+   mechanism protects adequately against bad cases.  I didn't
+   think it was a good tradeoff to make.  Partly this is due to
+   the fact that I was not flooded with email complaints about
+   <computeroutput>bzip2-0.1</computeroutput>'s performance on
+   repetitive data, so perhaps it isn't a problem for real
+   inputs.</para>
+
+   <para>Probably the best long-term solution, and the one I have
+   incorporated into 0.9.5 and above, is to use the existing
+   sorting algorithm initially, and fall back to a O(N (log N)^2)
+   algorithm if the standard algorithm gets into
+   difficulties.</para></listitem>
+
+  <listitem><para>The compressed file format was never designed to be
+   handled by a library, and I have had to jump though some hoops
+   to produce an efficient implementation of decompression.  It's
+   a bit hairy.  Try passing
+   <computeroutput>decompress.c</computeroutput> through the C
+   preprocessor and you'll see what I mean.  Much of this
+   complexity could have been avoided if the compressed size of
+   each block of data was recorded in the data stream.</para></listitem>
+
+ <listitem><para>An Adler-32 checksum, rather than a CRC32 checksum,
+   would be faster to compute.</para></listitem>
+
+</itemizedlist>
+
+<para>It would be fair to say that the
+<computeroutput>bzip2</computeroutput> format was frozen before I
+properly and fully understood the performance consequences of
+doing so.</para>
+
+<para>Improvements which I was able to incorporate into 0.9.0,
+despite using the same file format, are:</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para>Single array implementation of the inverse BWT.  This
+  significantly speeds up decompression, presumably because it
+  reduces the number of cache misses.</para></listitem>
+
+ <listitem><para>Faster inverse MTF transform for large MTF values.
+  The new implementation is based on the notion of sliding blocks
+  of values.</para></listitem>
+
+ <listitem><para><computeroutput>bzip2-0.9.0</computeroutput> now reads
+  and writes files with <computeroutput>fread</computeroutput>
+  and <computeroutput>fwrite</computeroutput>; version 0.1 used
+  <computeroutput>putc</computeroutput> and
+  <computeroutput>getc</computeroutput>.  Duh!  Well, you live
+  and learn.</para></listitem>
+
+</itemizedlist>
+
+<para>Further ahead, it would be nice to be able to do random
+access into files.  This will require some careful design of
+compressed file formats.</para>
+
+</sect1>
+
+
+<sect1 id="port-issues" xreflabel="Portability issues">
+<title>Portability issues</title>
+
+<para>After some consideration, I have decided not to use GNU
+<computeroutput>autoconf</computeroutput> to configure 0.9.5 or
+1.0.</para>
+
+<para><computeroutput>autoconf</computeroutput>, admirable and
+wonderful though it is, mainly assists with portability problems
+between Unix-like platforms.  But
+<computeroutput>bzip2</computeroutput> doesn't have much in the
+way of portability problems on Unix; most of the difficulties
+appear when porting to the Mac, or to Microsoft's operating
+systems.  <computeroutput>autoconf</computeroutput> doesn't help
+in those cases, and brings in a whole load of new
+complexity.</para>
+
+<para>Most people should be able to compile the library and
+program under Unix straight out-of-the-box, so to speak,
+especially if you have a version of GNU C available.</para>
+
+<para>There are a couple of
+<computeroutput>__inline__</computeroutput> directives in the
+code.  GNU C (<computeroutput>gcc</computeroutput>) should be
+able to handle them.  If you're not using GNU C, your C compiler
+shouldn't see them at all.  If your compiler does, for some
+reason, see them and doesn't like them, just
+<computeroutput>#define</computeroutput>
+<computeroutput>__inline__</computeroutput> to be
+<computeroutput>/* */</computeroutput>.  One easy way to do this
+is to compile with the flag
+<computeroutput>-D__inline__=</computeroutput>, which should be
+understood by most Unix compilers.</para>
+
+<para>If you still have difficulties, try compiling with the
+macro <computeroutput>BZ_STRICT_ANSI</computeroutput> defined.
+This should enable you to build the library in a strictly ANSI
+compliant environment.  Building the program itself like this is
+dangerous and not supported, since you remove
+<computeroutput>bzip2</computeroutput>'s checks against
+compressing directories, symbolic links, devices, and other
+not-really-a-file entities.  This could cause filesystem
+corruption!</para>
+
+<para>One other thing: if you create a
+<computeroutput>bzip2</computeroutput> binary for public distribution,
+please consider linking it statically (<computeroutput>gcc
+-static</computeroutput>).  This avoids all sorts of library-version
+issues that others may encounter later on.</para>
+
+<para>If you build <computeroutput>bzip2</computeroutput> on
+Win32, you must set <computeroutput>BZ_UNIX</computeroutput> to 0
+and <computeroutput>BZ_LCCWIN32</computeroutput> to 1, in the
+file <computeroutput>bzip2.c</computeroutput>, before compiling.
+Otherwise the resulting binary won't work correctly.</para>
+
+</sect1>
+
+
+<sect1 id="bugs" xreflabel="Reporting bugs">
+<title>Reporting bugs</title>
+
+<para>I tried pretty hard to make sure
+<computeroutput>bzip2</computeroutput> is bug free, both by
+design and by testing.  Hopefully you'll never need to read this
+section for real.</para>
+
+<para>Nevertheless, if <computeroutput>bzip2</computeroutput> dies
+with a segmentation fault, a bus error or an internal assertion
+failure, it will ask you to email me a bug report.  Experience from
+years of feedback of bzip2 users indicates that almost all these
+problems can be traced to either compiler bugs or hardware
+problems.</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para>Recompile the program with no optimisation, and
+  see if it works.  And/or try a different compiler.  I heard all
+  sorts of stories about various flavours of GNU C (and other
+  compilers) generating bad code for
+  <computeroutput>bzip2</computeroutput>, and I've run across two
+  such examples myself.</para>
+
+  <para>2.7.X versions of GNU C are known to generate bad code
+  from time to time, at high optimisation levels.  If you get
+  problems, try using the flags
+  <computeroutput>-O2</computeroutput>
+  <computeroutput>-fomit-frame-pointer</computeroutput>
+  <computeroutput>-fno-strength-reduce</computeroutput>.  You
+  should specifically <emphasis>not</emphasis> use
+  <computeroutput>-funroll-loops</computeroutput>.</para>
+
+  <para>You may notice that the Makefile runs six tests as part
+  of the build process.  If the program passes all of these, it's
+  a pretty good (but not 100%) indication that the compiler has
+  done its job correctly.</para></listitem>
+
+ <listitem><para>If <computeroutput>bzip2</computeroutput>
+  crashes randomly, and the crashes are not repeatable, you may
+  have a flaky memory subsystem.
+  <computeroutput>bzip2</computeroutput> really hammers your
+  memory hierarchy, and if it's a bit marginal, you may get these
+  problems.  Ditto if your disk or I/O subsystem is slowly
+  failing.  Yup, this really does happen.</para>
+
+  <para>Try using a different machine of the same type, and see
+  if you can repeat the problem.</para></listitem>
+
+  <listitem><para>This isn't really a bug, but ... If
+  <computeroutput>bzip2</computeroutput> tells you your file is
+  corrupted on decompression, and you obtained the file via FTP,
+  there is a possibility that you forgot to tell FTP to do a
+  binary mode transfer.  That absolutely will cause the file to
+  be non-decompressible.  You'll have to transfer it
+  again.</para></listitem>
+
+</itemizedlist>
+
+<para>If you've incorporated
+<computeroutput>libbzip2</computeroutput> into your own program
+and are getting problems, please, please, please, check that the
+parameters you are passing in calls to the library, are correct,
+and in accordance with what the documentation says is allowable.
+I have tried to make the library robust against such problems,
+but I'm sure I haven't succeeded.</para>
+
+<para>Finally, if the above comments don't help, you'll have to
+send me a bug report.  Now, it's just amazing how many people
+will send me a bug report saying something like:</para>
+
+<programlisting>
+bzip2 crashed with segmentation fault on my machine
+</programlisting>
+
+<para>and absolutely nothing else.  Needless to say, a such a
+report is <emphasis>totally, utterly, completely and
+comprehensively 100% useless; a waste of your time, my time, and
+net bandwidth</emphasis>.  With no details at all, there's no way
+I can possibly begin to figure out what the problem is.</para>
+
+<para>The rules of the game are: facts, facts, facts.  Don't omit
+them because "oh, they won't be relevant".  At the bare
+minimum:</para>
+
+<programlisting>
+Machine type.  Operating system version.  
+Exact version of bzip2 (do bzip2 -V).  
+Exact version of the compiler used.  
+Flags passed to the compiler.
+</programlisting>
+
+<para>However, the most important single thing that will help me
+is the file that you were trying to compress or decompress at the
+time the problem happened.  Without that, my ability to do
+anything more than speculate about the cause, is limited.</para>
+
+</sect1>
+
+
+<sect1 id="package" xreflabel="Did you get the right package?">
+<title>Did you get the right package?</title>
+
+<para><computeroutput>bzip2</computeroutput> is a resource hog.
+It soaks up large amounts of CPU cycles and memory.  Also, it
+gives very large latencies.  In the worst case, you can feed many
+megabytes of uncompressed data into the library before getting
+any compressed output, so this probably rules out applications
+requiring interactive behaviour.</para>
+
+<para>These aren't faults of my implementation, I hope, but more
+an intrinsic property of the Burrows-Wheeler transform
+(unfortunately).  Maybe this isn't what you want.</para>
+
+<para>If you want a compressor and/or library which is faster,
+uses less memory but gets pretty good compression, and has
+minimal latency, consider Jean-loup Gailly's and Mark Adler's
+work, <computeroutput>zlib-1.2.1</computeroutput> and
+<computeroutput>gzip-1.2.4</computeroutput>.  Look for them at 
+<ulink url="http://www.zlib.org">http://www.zlib.org</ulink> and 
+<ulink url="http://www.gzip.org">http://www.gzip.org</ulink>
+respectively.</para>
+
+<para>For something faster and lighter still, you might try Markus F
+X J Oberhumer's <computeroutput>LZO</computeroutput> real-time
+compression/decompression library, at 
+<ulink url="http://www.oberhumer.com/opensource">http://www.oberhumer.com/opensource</ulink>.</para>
+
+</sect1>
+
+
+
+<sect1 id="reading" xreflabel="Further Reading">
+<title>Further Reading</title>
+
+<para><computeroutput>bzip2</computeroutput> is not research
+work, in the sense that it doesn't present any new ideas.
+Rather, it's an engineering exercise based on existing
+ideas.</para>
+
+<para>Four documents describe essentially all the ideas behind
+<computeroutput>bzip2</computeroutput>:</para>
+
+<literallayout>Michael Burrows and D. J. Wheeler:
+  "A block-sorting lossless data compression algorithm"
+   10th May 1994. 
+   Digital SRC Research Report 124.
+   ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz
+   If you have trouble finding it, try searching at the
+   New Zealand Digital Library, http://www.nzdl.org.
+
+Daniel S. Hirschberg and Debra A. LeLewer
+  "Efficient Decoding of Prefix Codes"
+   Communications of the ACM, April 1990, Vol 33, Number 4.
+   You might be able to get an electronic copy of this
+   from the ACM Digital Library.
+
+David J. Wheeler
+   Program bred3.c and accompanying document bred3.ps.
+   This contains the idea behind the multi-table Huffman coding scheme.
+   ftp://ftp.cl.cam.ac.uk/users/djw3/
+
+Jon L. Bentley and Robert Sedgewick
+  "Fast Algorithms for Sorting and Searching Strings"
+   Available from Sedgewick's web page,
+   www.cs.princeton.edu/~rs
+</literallayout>
+
+<para>The following paper gives valuable additional insights into
+the algorithm, but is not immediately the basis of any code used
+in bzip2.</para>
+
+<literallayout>Peter Fenwick:
+   Block Sorting Text Compression
+   Proceedings of the 19th Australasian Computer Science Conference,
+     Melbourne, Australia.  Jan 31 - Feb 2, 1996.
+   ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps</literallayout>
+
+<para>Kunihiko Sadakane's sorting algorithm, mentioned above, is
+available from:</para>
+
+<literallayout>http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz
+</literallayout>
+
+<para>The Manber-Myers suffix array construction algorithm is
+described in a paper available from:</para>
+
+<literallayout>http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps
+</literallayout>
+
+<para>Finally, the following papers document some
+investigations I made into the performance of sorting
+and decompression algorithms:</para>
+
+<literallayout>Julian Seward
+   On the Performance of BWT Sorting Algorithms
+   Proceedings of the IEEE Data Compression Conference 2000
+     Snowbird, Utah.  28-30 March 2000.
+
+Julian Seward
+   Space-time Tradeoffs in the Inverse B-W Transform
+   Proceedings of the IEEE Data Compression Conference 2001
+     Snowbird, Utah.  27-29 March 2001.
+</literallayout>
+
+</sect1>
+
+</chapter>
+
+</book>
diff --git a/c++/src/util/compress/bzip2/manual_1.html b/c++/src/util/compress/bzip2/manual_1.html
deleted file mode 100644
index 15f86c9..0000000
--- a/c++/src/util/compress/bzip2/manual_1.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<HTML>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<!-- Created on January, 5  2002 by texi2html 1.64 -->
-<!-- 
-Written by: Lionel Cons <Lionel.Cons at cern.ch> (original author)
-            Karl Berry  <karl at freefriends.org>
-            Olaf Bachmann <obachman at mathematik.uni-kl.de>
-            and many others.
-Maintained by: Olaf Bachmann <obachman at mathematik.uni-kl.de>
-Send bugs and suggestions to <texi2html at mathematik.uni-kl.de>
- 
--->
-<HEAD>
-<TITLE>Untitled Document: 1. Introduction</TITLE>
-
-<META NAME="description" CONTENT="Untitled Document: 1. Introduction">
-<META NAME="keywords" CONTENT="Untitled Document: 1. Introduction">
-<META NAME="resource-type" CONTENT="document">
-<META NAME="distribution" CONTENT="global">
-<META NAME="Generator" CONTENT="texi2html 1.64">
-
-</HEAD>
-
-<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
-
-<A NAME="SEC1"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC2"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H1> 1. Introduction </H1>
-<!--docid::SEC1::-->
-<P>
-
-<CODE>bzip2</CODE>  compresses  files  using the Burrows-Wheeler 
-block-sorting text compression algorithm,  and  Huffman  coding.
-Compression  is  generally  considerably  better than that
-achieved by more conventional LZ77/LZ78-based compressors,
-and  approaches  the performance of the PPM family of statistical compressors.
-</P><P>
-
-<CODE>bzip2</CODE> is built on top of <CODE>libbzip2</CODE>, a flexible library
-for handling compressed data in the <CODE>bzip2</CODE> format.  This manual
-describes both how to use the program and 
-how to work with the library interface.  Most of the
-manual is devoted to this library, not the program, 
-which is good news if your interest is only in the program.
-</P><P>
-
-Chapter 2 describes how to use <CODE>bzip2</CODE>; this is the only part 
-you need to read if you just want to know how to operate the program.
-Chapter 3 describes the programming interfaces in detail, and
-Chapter 4 records some miscellaneous notes which I thought
-ought to be recorded somewhere.
-</P><P>
-
-<HR SIZE="6">
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<BR>  
-<FONT SIZE="-1">
-This document was generated
-by <I>Julian Seward</I> on <I>January, 5  2002</I>
-using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
-"><I>texi2html</I></A>
-
-</BODY>
-</HTML>
diff --git a/c++/src/util/compress/bzip2/manual_2.html b/c++/src/util/compress/bzip2/manual_2.html
deleted file mode 100644
index a3bebc3..0000000
--- a/c++/src/util/compress/bzip2/manual_2.html
+++ /dev/null
@@ -1,579 +0,0 @@
-<HTML>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<!-- Created on January, 5  2002 by texi2html 1.64 -->
-<!-- 
-Written by: Lionel Cons <Lionel.Cons at cern.ch> (original author)
-            Karl Berry  <karl at freefriends.org>
-            Olaf Bachmann <obachman at mathematik.uni-kl.de>
-            and many others.
-Maintained by: Olaf Bachmann <obachman at mathematik.uni-kl.de>
-Send bugs and suggestions to <texi2html at mathematik.uni-kl.de>
- 
--->
-<HEAD>
-<TITLE>Untitled Document: 2. How to use <CODE>bzip2</CODE></TITLE>
-
-<META NAME="description" CONTENT="Untitled Document: 2. How to use <CODE>bzip2</CODE>">
-<META NAME="keywords" CONTENT="Untitled Document: 2. How to use <CODE>bzip2</CODE>">
-<META NAME="resource-type" CONTENT="document">
-<META NAME="distribution" CONTENT="global">
-<META NAME="Generator" CONTENT="texi2html 1.64">
-
-</HEAD>
-
-<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
-
-<A NAME="SEC2"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_1.html#SEC1"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC3"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H1> 2. How to use <CODE>bzip2</CODE> </H1>
-<!--docid::SEC2::-->
-<P>
-
-This chapter contains a copy of the <CODE>bzip2</CODE> man page,
-and nothing else.
-</P><P>
-
-<BLOCKQUOTE>
-<P>
-
-<HR SIZE="6">
-<A NAME="SEC3"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC2"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC4"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H4> NAME </H4>
-<!--docid::SEC3::-->
-<UL>
-<LI><CODE>bzip2</CODE>, <CODE>bunzip2</CODE>
-- a block-sorting file compressor, v1.0.2
-<LI><CODE>bzcat</CODE>
-- decompresses files to stdout
-<LI><CODE>bzip2recover</CODE>
-- recovers data from damaged bzip2 files
-</UL>
-<P>
-
-<HR SIZE="6">
-<A NAME="SEC4"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC3"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC5"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H4> SYNOPSIS </H4>
-<!--docid::SEC4::-->
-<UL>
-<LI><CODE>bzip2</CODE> [ -cdfkqstvzVL123456789 ] [ filenames ...  ]
-<LI><CODE>bunzip2</CODE> [ -fkvsVL ] [ filenames ...  ]
-<LI><CODE>bzcat</CODE> [ -s ] [ filenames ...  ]
-<LI><CODE>bzip2recover</CODE> filename
-</UL>
-<P>
-
-<HR SIZE="6">
-<A NAME="SEC5"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC4"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC6"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H4> DESCRIPTION </H4>
-<!--docid::SEC5::-->
-<P>
-
-<CODE>bzip2</CODE> compresses files using the Burrows-Wheeler block sorting
-text compression algorithm, and Huffman coding.  Compression is
-generally considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of the PPM
-family of statistical compressors.
-</P><P>
-
-The command-line options are deliberately very similar to those of GNU
-<CODE>gzip</CODE>, but they are not identical.
-</P><P>
-
-<CODE>bzip2</CODE> expects a list of file names to accompany the command-line
-flags.  Each file is replaced by a compressed version of itself, with
-the name <CODE>original_name.bz2</CODE>.  Each compressed file has the same
-modification date, permissions, and, when possible, ownership as the
-corresponding original, so that these properties can be correctly
-restored at decompression time.  File name handling is naive in the
-sense that there is no mechanism for preserving original file names,
-permissions, ownerships or dates in filesystems which lack these
-concepts, or have serious file name length restrictions, such as MS-DOS.
-</P><P>
-
-<CODE>bzip2</CODE> and <CODE>bunzip2</CODE> will by default not overwrite existing
-files.  If you want this to happen, specify the <CODE>-f</CODE> flag.
-</P><P>
-
-If no file names are specified, <CODE>bzip2</CODE> compresses from standard
-input to standard output.  In this case, <CODE>bzip2</CODE> will decline to
-write compressed output to a terminal, as this would be entirely
-incomprehensible and therefore pointless.
-</P><P>
-
-<CODE>bunzip2</CODE> (or <CODE>bzip2 -d</CODE>) decompresses all
-specified files.  Files which were not created by <CODE>bzip2</CODE>
-will be detected and ignored, and a warning issued.  
-<CODE>bzip2</CODE> attempts to guess the filename for the decompressed file 
-from that of the compressed file as follows:
-<UL>
-<LI><CODE>filename.bz2 </CODE> becomes <CODE>filename</CODE>
-<LI><CODE>filename.bz  </CODE> becomes <CODE>filename</CODE>
-<LI><CODE>filename.tbz2</CODE> becomes <CODE>filename.tar</CODE>
-<LI><CODE>filename.tbz </CODE> becomes <CODE>filename.tar</CODE>
-<LI><CODE>anyothername </CODE> becomes <CODE>anyothername.out</CODE>
-</UL>
-If the file does not end in one of the recognised endings, 
-<CODE>.bz2</CODE>, <CODE>.bz</CODE>, 
-<CODE>.tbz2</CODE> or <CODE>.tbz</CODE>, <CODE>bzip2</CODE> complains that it cannot
-guess the name of the original file, and uses the original name
-with <CODE>.out</CODE> appended.
-<P>
-
-As with compression, supplying no
-filenames causes decompression from standard input to standard output.
-</P><P>
-
-<CODE>bunzip2</CODE> will correctly decompress a file which is the
-concatenation of two or more compressed files.  The result is the
-concatenation of the corresponding uncompressed files.  Integrity
-testing (<CODE>-t</CODE>) of concatenated compressed files is also supported.
-</P><P>
-
-You can also compress or decompress files to the standard output by
-giving the <CODE>-c</CODE> flag.  Multiple files may be compressed and
-decompressed like this.  The resulting outputs are fed sequentially to
-stdout.  Compression of multiple files in this manner generates a stream
-containing multiple compressed file representations.  Such a stream
-can be decompressed correctly only by <CODE>bzip2</CODE> version 0.9.0 or
-later.  Earlier versions of <CODE>bzip2</CODE> will stop after decompressing
-the first file in the stream.
-</P><P>
-
-<CODE>bzcat</CODE> (or <CODE>bzip2 -dc</CODE>) decompresses all specified files to
-the standard output.
-</P><P>
-
-<CODE>bzip2</CODE> will read arguments from the environment variables
-<CODE>BZIP2</CODE> and <CODE>BZIP</CODE>, in that order, and will process them
-before any arguments read from the command line.  This gives a 
-convenient way to supply default arguments.
-</P><P>
-
-Compression is always performed, even if the compressed file is slightly
-larger than the original.  Files of less than about one hundred bytes
-tend to get larger, since the compression mechanism has a constant
-overhead in the region of 50 bytes.  Random data (including the output
-of most file compressors) is coded at about 8.05 bits per byte, giving
-an expansion of around 0.5%.
-</P><P>
-
-As a self-check for your protection, <CODE>bzip2</CODE> uses 32-bit CRCs to
-make sure that the decompressed version of a file is identical to the
-original.  This guards against corruption of the compressed data, and
-against undetected bugs in <CODE>bzip2</CODE> (hopefully very unlikely).  The
-chances of data corruption going undetected is microscopic, about one
-chance in four billion for each file processed.  Be aware, though, that
-the check occurs upon decompression, so it can only tell you that
-something is wrong.  It can't help you recover the original uncompressed
-data.  You can use <CODE>bzip2recover</CODE> to try to recover data from
-damaged files.
-</P><P>
-
-Return values: 0 for a normal exit, 1 for environmental problems (file
-not found, invalid flags, I/O errors, &c), 2 to indicate a corrupt
-compressed file, 3 for an internal consistency error (eg, bug) which
-caused <CODE>bzip2</CODE> to panic.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC6"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC5"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC7"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H4> OPTIONS </H4>
-<!--docid::SEC6::-->
-<DL COMPACT>
-<DT><CODE>-c  --stdout</CODE>
-<DD>Compress or decompress to standard output.
-<DT><CODE>-d  --decompress</CODE>
-<DD>Force decompression.  <CODE>bzip2</CODE>, <CODE>bunzip2</CODE> and <CODE>bzcat</CODE> are
-really the same program, and the decision about what actions to take is
-done on the basis of which name is used.  This flag overrides that
-mechanism, and forces bzip2 to decompress.
-<DT><CODE>-z --compress</CODE>
-<DD>The complement to <CODE>-d</CODE>: forces compression, regardless of the
-invokation name.
-<DT><CODE>-t --test</CODE>
-<DD>Check integrity of the specified file(s), but don't decompress them.
-This really performs a trial decompression and throws away the result.
-<DT><CODE>-f --force</CODE>
-<DD>Force overwrite of output files.  Normally, <CODE>bzip2</CODE> will not overwrite
-existing output files.  Also forces <CODE>bzip2</CODE> to break hard links
-to files, which it otherwise wouldn't do.
-<P>
-
-<CODE>bzip2</CODE> normally declines to decompress files which don't have the
-correct magic header bytes.  If forced (<CODE>-f</CODE>), however, it will
-pass such files through unmodified.  This is how GNU <CODE>gzip</CODE>
-behaves.
-<DT><CODE>-k --keep</CODE>
-<DD>Keep (don't delete) input files during compression
-or decompression.
-<DT><CODE>-s --small</CODE>
-<DD>Reduce memory usage, for compression, decompression and testing.  Files
-are decompressed and tested using a modified algorithm which only
-requires 2.5 bytes per block byte.  This means any file can be
-decompressed in 2300k of memory, albeit at about half the normal speed.
-<P>
-
-During compression, <CODE>-s</CODE> selects a block size of 200k, which limits
-memory use to around the same figure, at the expense of your compression
-ratio.  In short, if your machine is low on memory (8 megabytes or
-less), use -s for everything.  See MEMORY MANAGEMENT below.
-<DT><CODE>-q --quiet</CODE>
-<DD>Suppress non-essential warning messages.  Messages pertaining to
-I/O errors and other critical events will not be suppressed.
-<DT><CODE>-v --verbose</CODE>
-<DD>Verbose mode -- show the compression ratio for each file processed.
-Further <CODE>-v</CODE>'s increase the verbosity level, spewing out lots of
-information which is primarily of interest for diagnostic purposes.
-<DT><CODE>-L --license -V --version</CODE>
-<DD>Display the software version, license terms and conditions.
-<DT><CODE>-1 (or --fast) to -9 (or --best)</CODE>
-<DD>Set the block size to 100 k, 200 k ..  900 k when compressing.  Has no
-effect when decompressing.  See MEMORY MANAGEMENT below.
-The <CODE>--fast</CODE> and <CODE>--best</CODE> aliases are primarily for GNU
-<CODE>gzip</CODE> compatibility.  In particular, <CODE>--fast</CODE> doesn't make
-things significantly faster.  And <CODE>--best</CODE> merely selects the
-default behaviour.
-<DT><CODE>--</CODE>
-<DD>Treats all subsequent arguments as file names, even if they start
-with a dash.  This is so you can handle files with names beginning
-with a dash, for example: <CODE>bzip2 -- -myfilename</CODE>.
-<DT><CODE>--repetitive-fast</CODE>
-<DD><DT><CODE>--repetitive-best</CODE>
-<DD>These flags are redundant in versions 0.9.5 and above.  They provided
-some coarse control over the behaviour of the sorting algorithm in
-earlier versions, which was sometimes useful.  0.9.5 and above have an
-improved algorithm which renders these flags irrelevant.
-</DL>
-<P>
-
-<HR SIZE="6">
-<A NAME="SEC7"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC6"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC8"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H4> MEMORY MANAGEMENT </H4>
-<!--docid::SEC7::-->
-<P>
-
-<CODE>bzip2</CODE> compresses large files in blocks.  The block size affects
-both the compression ratio achieved, and the amount of memory needed for
-compression and decompression.  The flags <CODE>-1</CODE> through <CODE>-9</CODE>
-specify the block size to be 100,000 bytes through 900,000 bytes (the
-default) respectively.  At decompression time, the block size used for
-compression is read from the header of the compressed file, and
-<CODE>bunzip2</CODE> then allocates itself just enough memory to decompress
-the file.  Since block sizes are stored in compressed files, it follows
-that the flags <CODE>-1</CODE> to <CODE>-9</CODE> are irrelevant to and so ignored
-during decompression.
-</P><P>
-
-Compression and decompression requirements, in bytes, can be estimated
-as:
-<TABLE><tr><td> </td><td class=example><pre>     Compression:   400k + ( 8 x block size )
-
-     Decompression: 100k + ( 4 x block size ), or
-                    100k + ( 2.5 x block size )
-</pre></td></tr></table>Larger block sizes give rapidly diminishing marginal returns.  Most of
-the compression comes from the first two or three hundred k of block
-size, a fact worth bearing in mind when using <CODE>bzip2</CODE> on small machines.
-It is also important to appreciate that the decompression memory
-requirement is set at compression time by the choice of block size.
-</P><P>
-
-For files compressed with the default 900k block size, <CODE>bunzip2</CODE>
-will require about 3700 kbytes to decompress.  To support decompression
-of any file on a 4 megabyte machine, <CODE>bunzip2</CODE> has an option to
-decompress using approximately half this amount of memory, about 2300
-kbytes.  Decompression speed is also halved, so you should use this
-option only where necessary.  The relevant flag is <CODE>-s</CODE>.
-</P><P>
-
-In general, try and use the largest block size memory constraints allow,
-since that maximises the compression achieved.  Compression and
-decompression speed are virtually unaffected by block size.
-</P><P>
-
-Another significant point applies to files which fit in a single block
--- that means most files you'd encounter using a large block size.  The
-amount of real memory touched is proportional to the size of the file,
-since the file is smaller than a block.  For example, compressing a file
-20,000 bytes long with the flag <CODE>-9</CODE> will cause the compressor to
-allocate around 7600k of memory, but only touch 400k + 20000 * 8 = 560
-kbytes of it.  Similarly, the decompressor will allocate 3700k but only
-touch 100k + 20000 * 4 = 180 kbytes.
-</P><P>
-
-Here is a table which summarises the maximum memory usage for different
-block sizes.  Also recorded is the total compressed size for 14 files of
-the Calgary Text Compression Corpus totalling 3,141,622 bytes.  This
-column gives some feel for how compression varies with block size.
-These figures tend to understate the advantage of larger block sizes for
-larger files, since the Corpus is dominated by smaller files.
-<TABLE><tr><td> </td><td class=example><pre>          Compress   Decompress   Decompress   Corpus
-   Flag     usage      usage       -s usage     Size
-
-    -1      1200k       500k         350k      914704
-    -2      2000k       900k         600k      877703
-    -3      2800k      1300k         850k      860338
-    -4      3600k      1700k        1100k      846899
-    -5      4400k      2100k        1350k      845160
-    -6      5200k      2500k        1600k      838626
-    -7      6100k      2900k        1850k      834096
-    -8      6800k      3300k        2100k      828642
-    -9      7600k      3700k        2350k      828642
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC8"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC7"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC9"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H4> RECOVERING DATA FROM DAMAGED FILES </H4>
-<!--docid::SEC8::-->
-<P>
-
-<CODE>bzip2</CODE> compresses files in blocks, usually 900kbytes long.  Each
-block is handled independently.  If a media or transmission error causes
-a multi-block <CODE>.bz2</CODE> file to become damaged, it may be possible to
-recover data from the undamaged blocks in the file.
-</P><P>
-
-The compressed representation of each block is delimited by a 48-bit
-pattern, which makes it possible to find the block boundaries with
-reasonable certainty.  Each block also carries its own 32-bit CRC, so
-damaged blocks can be distinguished from undamaged ones.
-</P><P>
-
-<CODE>bzip2recover</CODE> is a simple program whose purpose is to search for
-blocks in <CODE>.bz2</CODE> files, and write each block out into its own
-<CODE>.bz2</CODE> file.  You can then use <CODE>bzip2 -t</CODE> to test the
-integrity of the resulting files, and decompress those which are
-undamaged.
-</P><P>
-
-<CODE>bzip2recover</CODE> 
-takes a single argument, the name of the damaged file, and writes a
-number of files <CODE>rec00001file.bz2</CODE>, <CODE>rec00002file.bz2</CODE>, etc,
-containing the extracted blocks.  The output filenames are designed so
-that the use of wildcards in subsequent processing -- for example,
-<CODE>bzip2 -dc rec*file.bz2 > recovered_data</CODE> -- processes the files in
-the correct order.
-</P><P>
-
-<CODE>bzip2recover</CODE> should be of most use dealing with large <CODE>.bz2</CODE>
-files, as these will contain many blocks.  It is clearly futile to use
-it on damaged single-block files, since a damaged block cannot be
-recovered.  If you wish to minimise any potential data loss through
-media or transmission errors, you might consider compressing with a
-smaller block size.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC9"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC8"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC10"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H4> PERFORMANCE NOTES </H4>
-<!--docid::SEC9::-->
-<P>
-
-The sorting phase of compression gathers together similar strings in the
-file.  Because of this, files containing very long runs of repeated
-symbols, like "aabaabaabaab ..."  (repeated several hundred times) may
-compress more slowly than normal.  Versions 0.9.5 and above fare much
-better than previous versions in this respect.  The ratio between
-worst-case and average-case compression time is in the region of 10:1.
-For previous versions, this figure was more like 100:1.  You can use the
-<CODE>-vvvv</CODE> option to monitor progress in great detail, if you want.
-</P><P>
-
-Decompression speed is unaffected by these phenomena.
-</P><P>
-
-<CODE>bzip2</CODE> usually allocates several megabytes of memory to operate
-in, and then charges all over it in a fairly random fashion.  This means
-that performance, both for compressing and decompressing, is largely
-determined by the speed at which your machine can service cache misses.
-Because of this, small changes to the code to reduce the miss rate have
-been observed to give disproportionately large performance improvements.
-I imagine <CODE>bzip2</CODE> will perform best on machines with very large
-caches.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC10"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC9"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC11"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H4> CAVEATS </H4>
-<!--docid::SEC10::-->
-<P>
-
-I/O error messages are not as helpful as they could be.  <CODE>bzip2</CODE>
-tries hard to detect I/O errors and exit cleanly, but the details of
-what the problem is sometimes seem rather misleading.
-</P><P>
-
-This manual page pertains to version 1.0.2 of <CODE>bzip2</CODE>.  Compressed
-data created by this version is entirely forwards and backwards
-compatible with the previous public releases, versions 0.1pl2, 0.9.0,
-0.9.5, 1.0.0 and 1.0.1, but with the following exception: 0.9.0 and
-above can correctly decompress multiple concatenated compressed files.
-0.1pl2 cannot do this; it will stop after decompressing just the first
-file in the stream.
-</P><P>
-
-<CODE>bzip2recover</CODE> versions prior to this one, 1.0.2, used 32-bit
-integers to represent bit positions in compressed files, so it could not
-handle compressed files more than 512 megabytes long.  Version 1.0.2 and
-above uses 64-bit ints on some platforms which support them (GNU
-supported targets, and Windows).  To establish whether or not
-<CODE>bzip2recover</CODE> was built with such a limitation, run it without
-arguments.  In any event you can build yourself an unlimited version if
-you can recompile it with <CODE>MaybeUInt64</CODE> set to be an unsigned
-64-bit integer.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC11"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC10"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC12"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H4> AUTHOR </H4>
-<!--docid::SEC11::-->
-Julian Seward, <CODE>jseward at acm.org</CODE>.
-<P>
-
-<CODE>http://sources.redhat.com/bzip2</CODE>
-</P><P>
-
-The ideas embodied in <CODE>bzip2</CODE> are due to (at least) the following
-people: Michael Burrows and David Wheeler (for the block sorting
-transformation), David Wheeler (again, for the Huffman coder), Peter
-Fenwick (for the structured coding model in the original <CODE>bzip</CODE>,
-and many refinements), and Alistair Moffat, Radford Neal and Ian Witten
-(for the arithmetic coder in the original <CODE>bzip</CODE>).  I am much
-indebted for their help, support and advice.  See the manual in the
-source distribution for pointers to sources of documentation.  Christian
-von Roques encouraged me to look for faster sorting algorithms, so as to
-speed up compression.  Bela Lubkin encouraged me to improve the
-worst-case compression performance.  The <CODE>bz*</CODE> scripts are derived
-from those of GNU <CODE>gzip</CODE>.  Many people sent patches, helped with
-portability problems, lent machines, gave advice and were generally
-helpful.
-</P><P>
-
-</BLOCKQUOTE>
-
-<HR SIZE="6">
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<BR>  
-<FONT SIZE="-1">
-This document was generated
-by <I>Julian Seward</I> on <I>January, 5  2002</I>
-using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
-"><I>texi2html</I></A>
-
-</BODY>
-</HTML>
diff --git a/c++/src/util/compress/bzip2/manual_3.html b/c++/src/util/compress/bzip2/manual_3.html
deleted file mode 100644
index 841d14d..0000000
--- a/c++/src/util/compress/bzip2/manual_3.html
+++ /dev/null
@@ -1,1855 +0,0 @@
-<HTML>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<!-- Created on January, 5  2002 by texi2html 1.64 -->
-<!-- 
-Written by: Lionel Cons <Lionel.Cons at cern.ch> (original author)
-            Karl Berry  <karl at freefriends.org>
-            Olaf Bachmann <obachman at mathematik.uni-kl.de>
-            and many others.
-Maintained by: Olaf Bachmann <obachman at mathematik.uni-kl.de>
-Send bugs and suggestions to <texi2html at mathematik.uni-kl.de>
- 
--->
-<HEAD>
-<TITLE>Untitled Document: 3. Programming with <CODE>libbzip2</CODE></TITLE>
-
-<META NAME="description" CONTENT="Untitled Document: 3. Programming with <CODE>libbzip2</CODE>">
-<META NAME="keywords" CONTENT="Untitled Document: 3. Programming with <CODE>libbzip2</CODE>">
-<META NAME="resource-type" CONTENT="document">
-<META NAME="distribution" CONTENT="global">
-<META NAME="Generator" CONTENT="texi2html 1.64">
-
-</HEAD>
-
-<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
-
-<A NAME="SEC12"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_2.html#SEC11"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC13"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H1> 3. Programming with <CODE>libbzip2</CODE> </H1>
-<!--docid::SEC12::-->
-<P>
-
-This chapter describes the programming interface to <CODE>libbzip2</CODE>.
-</P><P>
-
-For general background information, particularly about memory
-use and performance aspects, you'd be well advised to read Chapter 2
-as well.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC13"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC12"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC14"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 3.1 Top-level structure </H2>
-<!--docid::SEC13::-->
-<P>
-
-<CODE>libbzip2</CODE> is a flexible library for compressing and decompressing
-data in the <CODE>bzip2</CODE> data format.  Although packaged as a single
-entity, it helps to regard the library as three separate parts: the low
-level interface, and the high level interface, and some utility
-functions.
-</P><P>
-
-The structure of <CODE>libbzip2</CODE>'s interfaces is similar to
-that of Jean-loup Gailly's and Mark Adler's excellent <CODE>zlib</CODE> 
-library.
-</P><P>
-
-All externally visible symbols have names beginning <CODE>BZ2_</CODE>.
-This is new in version 1.0.  The intention is to minimise pollution
-of the namespaces of library clients.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC14"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC13"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC15"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.1.1 Low-level summary </H3>
-<!--docid::SEC14::-->
-<P>
-
-This interface provides services for compressing and decompressing
-data in memory.  There's no provision for dealing with files, streams
-or any other I/O mechanisms, just straight memory-to-memory work.
-In fact, this part of the library can be compiled without inclusion
-of <CODE>stdio.h</CODE>, which may be helpful for embedded applications.
-</P><P>
-
-The low-level part of the library has no global variables and
-is therefore thread-safe.
-</P><P>
-
-Six routines make up the low level interface: 
-<CODE>BZ2_bzCompressInit</CODE>, <CODE>BZ2_bzCompress</CODE>, and <BR> <CODE>BZ2_bzCompressEnd</CODE>
-for compression,
-and a corresponding trio <CODE>BZ2_bzDecompressInit</CODE>, <BR> <CODE>BZ2_bzDecompress</CODE>
-and <CODE>BZ2_bzDecompressEnd</CODE> for decompression.  
-The <CODE>*Init</CODE> functions allocate
-memory for compression/decompression and do other
-initialisations, whilst the <CODE>*End</CODE> functions close down operations
-and release memory.
-</P><P>
-
-The real work is done by <CODE>BZ2_bzCompress</CODE> and <CODE>BZ2_bzDecompress</CODE>.  
-These compress and decompress data from a user-supplied input buffer
-to a user-supplied output buffer.  These buffers can be any size;
-arbitrary quantities of data are handled by making repeated calls
-to these functions.  This is a flexible mechanism allowing a 
-consumer-pull style of activity, or producer-push, or a mixture of
-both.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC15"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC14"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC16"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.1.2 High-level summary </H3>
-<!--docid::SEC15::-->
-<P>
-
-This interface provides some handy wrappers around the low-level
-interface to facilitate reading and writing <CODE>bzip2</CODE> format
-files (<CODE>.bz2</CODE> files).  The routines provide hooks to facilitate
-reading files in which the <CODE>bzip2</CODE> data stream is embedded 
-within some larger-scale file structure, or where there are
-multiple <CODE>bzip2</CODE> data streams concatenated end-to-end.
-</P><P>
-
-For reading files, <CODE>BZ2_bzReadOpen</CODE>, <CODE>BZ2_bzRead</CODE>,
-<CODE>BZ2_bzReadClose</CODE> and <BR> <CODE>BZ2_bzReadGetUnused</CODE> are supplied.  For
-writing files, <CODE>BZ2_bzWriteOpen</CODE>, <CODE>BZ2_bzWrite</CODE> and
-<CODE>BZ2_bzWriteFinish</CODE> are available.
-</P><P>
-
-As with the low-level library, no global variables are used
-so the library is per se thread-safe.  However, if I/O errors
-occur whilst reading or writing the underlying compressed files,
-you may have to consult <CODE>errno</CODE> to determine the cause of
-the error.  In that case, you'd need a C library which correctly
-supports <CODE>errno</CODE> in a multithreaded environment.
-</P><P>
-
-To make the library a little simpler and more portable,
-<CODE>BZ2_bzReadOpen</CODE> and <CODE>BZ2_bzWriteOpen</CODE> require you to pass them file
-handles (<CODE>FILE*</CODE>s) which have previously been opened for reading or
-writing respectively.  That avoids portability problems associated with
-file operations and file attributes, whilst not being much of an
-imposition on the programmer.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC16"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC15"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC17"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.1.3 Utility functions summary </H3>
-<!--docid::SEC16::-->
-For very simple needs, <CODE>BZ2_bzBuffToBuffCompress</CODE> and
-<CODE>BZ2_bzBuffToBuffDecompress</CODE> are provided.  These compress
-data in memory from one buffer to another buffer in a single
-function call.  You should assess whether these functions
-fulfill your memory-to-memory compression/decompression
-requirements before investing effort in understanding the more
-general but more complex low-level interface.
-<P>
-
-Yoshioka Tsuneo (<CODE>QWF00133 at niftyserve.or.jp</CODE> /
-<CODE>tsuneo-y at is.aist-nara.ac.jp</CODE>) has contributed some functions to
-give better <CODE>zlib</CODE> compatibility.  These functions are
-<CODE>BZ2_bzopen</CODE>, <CODE>BZ2_bzread</CODE>, <CODE>BZ2_bzwrite</CODE>, <CODE>BZ2_bzflush</CODE>,
-<CODE>BZ2_bzclose</CODE>,
-<CODE>BZ2_bzerror</CODE> and <CODE>BZ2_bzlibVersion</CODE>.  You may find these functions
-more convenient for simple file reading and writing, than those in the
-high-level interface.  These functions are not (yet) officially part of
-the library, and are minimally documented here.  If they break, you
-get to keep all the pieces.  I hope to document them properly when time
-permits.
-</P><P>
-
-Yoshioka also contributed modifications to allow the library to be
-built as a Windows DLL.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC17"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC16"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC18"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 3.2 Error handling </H2>
-<!--docid::SEC17::-->
-<P>
-
-The library is designed to recover cleanly in all situations, including
-the worst-case situation of decompressing random data.  I'm not 
-100% sure that it can always do this, so you might want to add
-a signal handler to catch segmentation violations during decompression
-if you are feeling especially paranoid.  I would be interested in
-hearing more about the robustness of the library to corrupted
-compressed data.
-</P><P>
-
-Version 1.0 is much more robust in this respect than
-0.9.0 or 0.9.5.  Investigations with Checker (a tool for 
-detecting problems with memory management, similar to Purify)
-indicate that, at least for the few files I tested, all single-bit
-errors in the decompressed data are caught properly, with no
-segmentation faults, no reads of uninitialised data and no 
-out of range reads or writes.  So it's certainly much improved,
-although I wouldn't claim it to be totally bombproof.
-</P><P>
-
-The file <CODE>bzlib.h</CODE> contains all definitions needed to use
-the library.  In particular, you should definitely not include
-<CODE>bzlib_private.h</CODE>.
-</P><P>
-
-In <CODE>bzlib.h</CODE>, the various return values are defined.  The following
-list is not intended as an exhaustive description of the circumstances 
-in which a given value may be returned -- those descriptions are given
-later.  Rather, it is intended to convey the rough meaning of each
-return value.  The first five actions are normal and not intended to 
-denote an error situation.
-<DL COMPACT>
-<DT><CODE>BZ_OK</CODE>
-<DD>The requested action was completed successfully.
-<DT><CODE>BZ_RUN_OK</CODE>
-<DD><DT><CODE>BZ_FLUSH_OK</CODE>
-<DD><DT><CODE>BZ_FINISH_OK</CODE>
-<DD>In <CODE>BZ2_bzCompress</CODE>, the requested flush/finish/nothing-special action
-was completed successfully.
-<DT><CODE>BZ_STREAM_END</CODE>
-<DD>Compression of data was completed, or the logical stream end was
-detected during decompression.
-</DL>
-<P>
-
-The following return values indicate an error of some kind.
-<DL COMPACT>
-<DT><CODE>BZ_CONFIG_ERROR</CODE>
-<DD>Indicates that the library has been improperly compiled on your
-platform -- a major configuration error.  Specifically, it means
-that <CODE>sizeof(char)</CODE>, <CODE>sizeof(short)</CODE> and <CODE>sizeof(int)</CODE>
-are not 1, 2 and 4 respectively, as they should be.  Note that the 
-library should still work properly on 64-bit platforms which follow
-the LP64 programming model -- that is, where <CODE>sizeof(long)</CODE>
-and <CODE>sizeof(void*)</CODE> are 8.  Under LP64, <CODE>sizeof(int)</CODE> is
-still 4, so <CODE>libbzip2</CODE>, which doesn't use the <CODE>long</CODE> type,
-is OK.
-<DT><CODE>BZ_SEQUENCE_ERROR</CODE>
-<DD>When using the library, it is important to call the functions in the
-correct sequence and with data structures (buffers etc) in the correct
-states.  <CODE>libbzip2</CODE> checks as much as it can to ensure this is
-happening, and returns <CODE>BZ_SEQUENCE_ERROR</CODE> if not.  Code which
-complies precisely with the function semantics, as detailed below,
-should never receive this value; such an event denotes buggy code
-which you should investigate.
-<DT><CODE>BZ_PARAM_ERROR</CODE>
-<DD>Returned when a parameter to a function call is out of range 
-or otherwise manifestly incorrect.  As with <CODE>BZ_SEQUENCE_ERROR</CODE>,
-this denotes a bug in the client code.  The distinction between
-<CODE>BZ_PARAM_ERROR</CODE> and <CODE>BZ_SEQUENCE_ERROR</CODE> is a bit hazy, but still worth
-making.
-<DT><CODE>BZ_MEM_ERROR</CODE>
-<DD>Returned when a request to allocate memory failed.  Note that the
-quantity of memory needed to decompress a stream cannot be determined
-until the stream's header has been read.  So <CODE>BZ2_bzDecompress</CODE> and
-<CODE>BZ2_bzRead</CODE> may return <CODE>BZ_MEM_ERROR</CODE> even though some of
-the compressed data has been read.  The same is not true for
-compression; once <CODE>BZ2_bzCompressInit</CODE> or <CODE>BZ2_bzWriteOpen</CODE> have
-successfully completed, <CODE>BZ_MEM_ERROR</CODE> cannot occur.
-<DT><CODE>BZ_DATA_ERROR</CODE>
-<DD>Returned when a data integrity error is detected during decompression.
-Most importantly, this means when stored and computed CRCs for the
-data do not match.  This value is also returned upon detection of any
-other anomaly in the compressed data.
-<DT><CODE>BZ_DATA_ERROR_MAGIC</CODE>
-<DD>As a special case of <CODE>BZ_DATA_ERROR</CODE>, it is sometimes useful to
-know when the compressed stream does not start with the correct
-magic bytes (<CODE>'B' 'Z' 'h'</CODE>).  
-<DT><CODE>BZ_IO_ERROR</CODE>
-<DD>Returned by <CODE>BZ2_bzRead</CODE> and <CODE>BZ2_bzWrite</CODE> when there is an error
-reading or writing in the compressed file, and by <CODE>BZ2_bzReadOpen</CODE>
-and <CODE>BZ2_bzWriteOpen</CODE> for attempts to use a file for which the
-error indicator (viz, <CODE>ferror(f)</CODE>) is set.
-On receipt of <CODE>BZ_IO_ERROR</CODE>, the caller should consult
-<CODE>errno</CODE> and/or <CODE>perror</CODE> to acquire operating-system
-specific information about the problem.
-<DT><CODE>BZ_UNEXPECTED_EOF</CODE>
-<DD>Returned by <CODE>BZ2_bzRead</CODE> when the compressed file finishes
-before the logical end of stream is detected.
-<DT><CODE>BZ_OUTBUFF_FULL</CODE>
-<DD>Returned by <CODE>BZ2_bzBuffToBuffCompress</CODE> and
-<CODE>BZ2_bzBuffToBuffDecompress</CODE> to indicate that the output data
-will not fit into the output buffer provided.
-</DL>
-<P>
-
-<HR SIZE="6">
-<A NAME="SEC18"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC17"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC19"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 3.3 Low-level interface </H2>
-<!--docid::SEC18::-->
-<P>
-
-<HR SIZE="6">
-<A NAME="SEC19"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC18"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC20"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.3.1 <CODE>BZ2_bzCompressInit</CODE> </H3>
-<!--docid::SEC19::-->
-<TABLE><tr><td> </td><td class=example><pre>typedef 
-   struct {
-      char *next_in;
-      unsigned int avail_in;
-      unsigned int total_in_lo32;
-      unsigned int total_in_hi32;
-
-      char *next_out;
-      unsigned int avail_out;
-      unsigned int total_out_lo32;
-      unsigned int total_out_hi32;
-
-      void *state;
-
-      void *(*bzalloc)(void *,int,int);
-      void (*bzfree)(void *,void *);
-      void *opaque;
-   } 
-   bz_stream;
-
-int BZ2_bzCompressInit ( bz_stream *strm, 
-                         int blockSize100k, 
-                         int verbosity,
-                         int workFactor );
-
-</pre></td></tr></table><P>
-
-Prepares for compression.  The <CODE>bz_stream</CODE> structure
-holds all data pertaining to the compression activity.  
-A <CODE>bz_stream</CODE> structure should be allocated and initialised
-prior to the call.
-The fields of <CODE>bz_stream</CODE>
-comprise the entirety of the user-visible data.  <CODE>state</CODE>
-is a pointer to the private data structures required for compression.
-</P><P>
-
-Custom memory allocators are supported, via fields <CODE>bzalloc</CODE>, 
-<CODE>bzfree</CODE>,
-and <CODE>opaque</CODE>.  The value 
-<CODE>opaque</CODE> is passed to as the first argument to
-all calls to <CODE>bzalloc</CODE> and <CODE>bzfree</CODE>, but is 
-otherwise ignored by the library.
-The call <CODE>bzalloc ( opaque, n, m )</CODE> is expected to return a 
-pointer <CODE>p</CODE> to
-<CODE>n * m</CODE> bytes of memory, and <CODE>bzfree ( opaque, p )</CODE> 
-should free
-that memory.
-</P><P>
-
-If you don't want to use a custom memory allocator, set <CODE>bzalloc</CODE>, 
-<CODE>bzfree</CODE> and
-<CODE>opaque</CODE> to <CODE>NULL</CODE>, 
-and the library will then use the standard <CODE>malloc</CODE>/<CODE>free</CODE>
-routines.
-</P><P>
-
-Before calling <CODE>BZ2_bzCompressInit</CODE>, fields <CODE>bzalloc</CODE>, 
-<CODE>bzfree</CODE> and <CODE>opaque</CODE> should
-be filled appropriately, as just described.  Upon return, the internal
-state will have been allocated and initialised, and <CODE>total_in_lo32</CODE>, 
-<CODE>total_in_hi32</CODE>, <CODE>total_out_lo32</CODE> and 
-<CODE>total_out_hi32</CODE> will have been set to zero.  
-These four fields are used by the library
-to inform the caller of the total amount of data passed into and out of
-the library, respectively.  You should not try to change them.
-As of version 1.0, 64-bit counts are maintained, even on 32-bit
-platforms, using the <CODE>_hi32</CODE> fields to store the upper 32 bits
-of the count.  So, for example, the total amount of data in
-is <CODE>(total_in_hi32 << 32) + total_in_lo32</CODE>.
-</P><P>
-
-Parameter <CODE>blockSize100k</CODE> specifies the block size to be used for
-compression.  It should be a value between 1 and 9 inclusive, and the
-actual block size used is 100000 x this figure.  9 gives the best
-compression but takes most memory.
-</P><P>
-
-Parameter <CODE>verbosity</CODE> should be set to a number between 0 and 4
-inclusive.  0 is silent, and greater numbers give increasingly verbose
-monitoring/debugging output.  If the library has been compiled with
-<CODE>-DBZ_NO_STDIO</CODE>, no such output will appear for any verbosity
-setting.
-</P><P>
-
-Parameter <CODE>workFactor</CODE> controls how the compression phase behaves
-when presented with worst case, highly repetitive, input data.  If
-compression runs into difficulties caused by repetitive data, the
-library switches from the standard sorting algorithm to a fallback
-algorithm.  The fallback is slower than the standard algorithm by
-perhaps a factor of three, but always behaves reasonably, no matter how
-bad the input.
-</P><P>
-
-Lower values of <CODE>workFactor</CODE> reduce the amount of effort the
-standard algorithm will expend before resorting to the fallback.  You
-should set this parameter carefully; too low, and many inputs will be
-handled by the fallback algorithm and so compress rather slowly, too
-high, and your average-to-worst case compression times can become very
-large.  The default value of 30 gives reasonable behaviour over a wide
-range of circumstances.
-</P><P>
-
-Allowable values range from 0 to 250 inclusive.  0 is a special case,
-equivalent to using the default value of 30.
-</P><P>
-
-Note that the compressed output generated is the same regardless of
-whether or not the fallback algorithm is used.
-</P><P>
-
-Be aware also that this parameter may disappear entirely in future
-versions of the library.  In principle it should be possible to devise a
-good way to automatically choose which algorithm to use.  Such a
-mechanism would render the parameter obsolete.
-</P><P>
-
-Possible return values:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_CONFIG_ERROR</CODE>
-         if the library has been mis-compiled
-      <CODE>BZ_PARAM_ERROR</CODE> 
-         if <CODE>strm</CODE> is <CODE>NULL</CODE> 
-         or <CODE>blockSize</CODE> < 1 or <CODE>blockSize</CODE> > 9
-         or <CODE>verbosity</CODE> < 0 or <CODE>verbosity</CODE> > 4
-         or <CODE>workFactor</CODE> < 0 or <CODE>workFactor</CODE> > 250
-      <CODE>BZ_MEM_ERROR</CODE> 
-         if not enough memory is available
-      <CODE>BZ_OK</CODE> 
-         otherwise
-</pre></td></tr></table>Allowable next actions:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ2_bzCompress</CODE> 
-         if <CODE>BZ_OK</CODE> is returned
-      no specific action needed in case of error
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC20"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC19"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC21"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.3.2 <CODE>BZ2_bzCompress</CODE> </H3>
-<!--docid::SEC20::-->
-<TABLE><tr><td> </td><td class=example><pre>   int BZ2_bzCompress ( bz_stream *strm, int action );
-</pre></td></tr></table>Provides more input and/or output buffer space for the library.  The
-caller maintains input and output buffers, and calls <CODE>BZ2_bzCompress</CODE> to
-transfer data between them.
-<P>
-
-Before each call to <CODE>BZ2_bzCompress</CODE>, <CODE>next_in</CODE> should point at
-the data to be compressed, and <CODE>avail_in</CODE> should indicate how many
-bytes the library may read.  <CODE>BZ2_bzCompress</CODE> updates <CODE>next_in</CODE>,
-<CODE>avail_in</CODE> and <CODE>total_in</CODE> to reflect the number of bytes it
-has read.
-</P><P>
-
-Similarly, <CODE>next_out</CODE> should point to a buffer in which the
-compressed data is to be placed, with <CODE>avail_out</CODE> indicating how
-much output space is available.  <CODE>BZ2_bzCompress</CODE> updates
-<CODE>next_out</CODE>, <CODE>avail_out</CODE> and <CODE>total_out</CODE> to reflect the
-number of bytes output.
-</P><P>
-
-You may provide and remove as little or as much data as you like on each
-call of <CODE>BZ2_bzCompress</CODE>.  In the limit, it is acceptable to supply and
-remove data one byte at a time, although this would be terribly
-inefficient.  You should always ensure that at least one byte of output
-space is available at each call.
-</P><P>
-
-A second purpose of <CODE>BZ2_bzCompress</CODE> is to request a change of mode of the
-compressed stream.  
-</P><P>
-
-Conceptually, a compressed stream can be in one of four states: IDLE,
-RUNNING, FLUSHING and FINISHING.  Before initialisation
-(<CODE>BZ2_bzCompressInit</CODE>) and after termination (<CODE>BZ2_bzCompressEnd</CODE>), a
-stream is regarded as IDLE.
-</P><P>
-
-Upon initialisation (<CODE>BZ2_bzCompressInit</CODE>), the stream is placed in the
-RUNNING state.  Subsequent calls to <CODE>BZ2_bzCompress</CODE> should pass
-<CODE>BZ_RUN</CODE> as the requested action; other actions are illegal and
-will result in <CODE>BZ_SEQUENCE_ERROR</CODE>.
-</P><P>
-
-At some point, the calling program will have provided all the input data
-it wants to.  It will then want to finish up -- in effect, asking the
-library to process any data it might have buffered internally.  In this
-state, <CODE>BZ2_bzCompress</CODE> will no longer attempt to read data from
-<CODE>next_in</CODE>, but it will want to write data to <CODE>next_out</CODE>.
-Because the output buffer supplied by the user can be arbitrarily small,
-the finishing-up operation cannot necessarily be done with a single call
-of <CODE>BZ2_bzCompress</CODE>.
-</P><P>
-
-Instead, the calling program passes <CODE>BZ_FINISH</CODE> as an action to
-<CODE>BZ2_bzCompress</CODE>.  This changes the stream's state to FINISHING.  Any
-remaining input (ie, <CODE>next_in[0 .. avail_in-1]</CODE>) is compressed and
-transferred to the output buffer.  To do this, <CODE>BZ2_bzCompress</CODE> must be
-called repeatedly until all the output has been consumed.  At that
-point, <CODE>BZ2_bzCompress</CODE> returns <CODE>BZ_STREAM_END</CODE>, and the stream's
-state is set back to IDLE.  <CODE>BZ2_bzCompressEnd</CODE> should then be
-called.
-</P><P>
-
-Just to make sure the calling program does not cheat, the library makes
-a note of <CODE>avail_in</CODE> at the time of the first call to
-<CODE>BZ2_bzCompress</CODE> which has <CODE>BZ_FINISH</CODE> as an action (ie, at the
-time the program has announced its intention to not supply any more
-input).  By comparing this value with that of <CODE>avail_in</CODE> over
-subsequent calls to <CODE>BZ2_bzCompress</CODE>, the library can detect any
-attempts to slip in more data to compress.  Any calls for which this is
-detected will return <CODE>BZ_SEQUENCE_ERROR</CODE>.  This indicates a
-programming mistake which should be corrected.
-</P><P>
-
-Instead of asking to finish, the calling program may ask
-<CODE>BZ2_bzCompress</CODE> to take all the remaining input, compress it and
-terminate the current (Burrows-Wheeler) compression block.  This could
-be useful for error control purposes.  The mechanism is analogous to
-that for finishing: call <CODE>BZ2_bzCompress</CODE> with an action of
-<CODE>BZ_FLUSH</CODE>, remove output data, and persist with the
-<CODE>BZ_FLUSH</CODE> action until the value <CODE>BZ_RUN</CODE> is returned.  As
-with finishing, <CODE>BZ2_bzCompress</CODE> detects any attempt to provide more
-input data once the flush has begun.
-</P><P>
-
-Once the flush is complete, the stream returns to the normal RUNNING
-state.
-</P><P>
-
-This all sounds pretty complex, but isn't really.  Here's a table
-which shows which actions are allowable in each state, what action
-will be taken, what the next state is, and what the non-error return
-values are.  Note that you can't explicitly ask what state the
-stream is in, but nor do you need to -- it can be inferred from the
-values returned by <CODE>BZ2_bzCompress</CODE>.
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">IDLE/<CODE>any</CODE>           
-      Illegal.  IDLE state only exists after <CODE>BZ2_bzCompressEnd</CODE> or
-      before <CODE>BZ2_bzCompressInit</CODE>.
-      Return value = <CODE>BZ_SEQUENCE_ERROR</CODE>
-
-RUNNING/<CODE>BZ_RUN</CODE>     
-      Compress from <CODE>next_in</CODE> to <CODE>next_out</CODE> as much as possible.
-      Next state = RUNNING
-      Return value = <CODE>BZ_RUN_OK</CODE>
-
-RUNNING/<CODE>BZ_FLUSH</CODE>   
-      Remember current value of <CODE>next_in</CODE>.  Compress from <CODE>next_in</CODE>
-      to <CODE>next_out</CODE> as much as possible, but do not accept any more input.  
-      Next state = FLUSHING
-      Return value = <CODE>BZ_FLUSH_OK</CODE>
-
-RUNNING/<CODE>BZ_FINISH</CODE>  
-      Remember current value of <CODE>next_in</CODE>.  Compress from <CODE>next_in</CODE>
-      to <CODE>next_out</CODE> as much as possible, but do not accept any more input.
-      Next state = FINISHING
-      Return value = <CODE>BZ_FINISH_OK</CODE>
-
-FLUSHING/<CODE>BZ_FLUSH</CODE>  
-      Compress from <CODE>next_in</CODE> to <CODE>next_out</CODE> as much as possible, 
-      but do not accept any more input.  
-      If all the existing input has been used up and all compressed
-      output has been removed
-         Next state = RUNNING; Return value = <CODE>BZ_RUN_OK</CODE>
-      else
-         Next state = FLUSHING; Return value = <CODE>BZ_FLUSH_OK</CODE>
-
-FLUSHING/other     
-      Illegal.
-      Return value = <CODE>BZ_SEQUENCE_ERROR</CODE>
-
-FINISHING/<CODE>BZ_FINISH</CODE>  
-      Compress from <CODE>next_in</CODE> to <CODE>next_out</CODE> as much as possible,
-      but to not accept any more input.  
-      If all the existing input has been used up and all compressed
-      output has been removed
-         Next state = IDLE; Return value = <CODE>BZ_STREAM_END</CODE>
-      else
-         Next state = FINISHING; Return value = <CODE>BZ_FINISHING</CODE>
-
-FINISHING/other
-      Illegal.
-      Return value = <CODE>BZ_SEQUENCE_ERROR</CODE>
-</pre></td></tr></table></P><P>
-
-That still looks complicated?  Well, fair enough.  The usual sequence
-of calls for compressing a load of data is:
-<UL>
-<LI>Get started with <CODE>BZ2_bzCompressInit</CODE>.
-<LI>Shovel data in and shlurp out its compressed form using zero or more
-calls of <CODE>BZ2_bzCompress</CODE> with action = <CODE>BZ_RUN</CODE>.
-<LI>Finish up.
-Repeatedly call <CODE>BZ2_bzCompress</CODE> with action = <CODE>BZ_FINISH</CODE>, 
-copying out the compressed output, until <CODE>BZ_STREAM_END</CODE> is returned.
-<LI>Close up and go home.  Call <CODE>BZ2_bzCompressEnd</CODE>.
-</UL>
-If the data you want to compress fits into your input buffer all
-at once, you can skip the calls of <CODE>BZ2_bzCompress ( ..., BZ_RUN )</CODE> and 
-just do the <CODE>BZ2_bzCompress ( ..., BZ_FINISH )</CODE> calls.
-<P>
-
-All required memory is allocated by <CODE>BZ2_bzCompressInit</CODE>.  The
-compression library can accept any data at all (obviously).  So you
-shouldn't get any error return values from the <CODE>BZ2_bzCompress</CODE> calls.
-If you do, they will be <CODE>BZ_SEQUENCE_ERROR</CODE>, and indicate a bug in
-your programming.
-</P><P>
-
-Trivial other possible return values:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_PARAM_ERROR</CODE>   
-         if <CODE>strm</CODE> is <CODE>NULL</CODE>, or <CODE>strm->s</CODE> is <CODE>NULL</CODE>
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC21"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC20"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC22"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.3.3 <CODE>BZ2_bzCompressEnd</CODE> </H3>
-<!--docid::SEC21::-->
-<TABLE><tr><td> </td><td class=example><pre>int BZ2_bzCompressEnd ( bz_stream *strm );
-</pre></td></tr></table>Releases all memory associated with a compression stream.
-<P>
-
-Possible return values:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">   <CODE>BZ_PARAM_ERROR</CODE>    if <CODE>strm</CODE> is <CODE>NULL</CODE> or <CODE>strm->s</CODE> is <CODE>NULL</CODE>
-   <CODE>BZ_OK</CODE>    otherwise
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC22"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC21"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC23"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.3.4 <CODE>BZ2_bzDecompressInit</CODE> </H3>
-<!--docid::SEC22::-->
-<TABLE><tr><td> </td><td class=example><pre>int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );
-</pre></td></tr></table>Prepares for decompression.  As with <CODE>BZ2_bzCompressInit</CODE>, a
-<CODE>bz_stream</CODE> record should be allocated and initialised before the
-call.  Fields <CODE>bzalloc</CODE>, <CODE>bzfree</CODE> and <CODE>opaque</CODE> should be
-set if a custom memory allocator is required, or made <CODE>NULL</CODE> for
-the normal <CODE>malloc</CODE>/<CODE>free</CODE> routines.  Upon return, the internal
-state will have been initialised, and <CODE>total_in</CODE> and
-<CODE>total_out</CODE> will be zero.
-<P>
-
-For the meaning of parameter <CODE>verbosity</CODE>, see <CODE>BZ2_bzCompressInit</CODE>.
-</P><P>
-
-If <CODE>small</CODE> is nonzero, the library will use an alternative
-decompression algorithm which uses less memory but at the cost of
-decompressing more slowly (roughly speaking, half the speed, but the
-maximum memory requirement drops to around 2300k).  See Chapter 2 for
-more information on memory management.
-</P><P>
-
-Note that the amount of memory needed to decompress
-a stream cannot be determined until the stream's header has been read,
-so even if <CODE>BZ2_bzDecompressInit</CODE> succeeds, a subsequent
-<CODE>BZ2_bzDecompress</CODE> could fail with <CODE>BZ_MEM_ERROR</CODE>.
-</P><P>
-
-Possible return values:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_CONFIG_ERROR</CODE>
-         if the library has been mis-compiled
-      <CODE>BZ_PARAM_ERROR</CODE>
-         if <CODE>(small != 0 && small != 1)</CODE>
-         or <CODE>(verbosity < 0 || verbosity > 4)</CODE>
-      <CODE>BZ_MEM_ERROR</CODE>
-         if insufficient memory is available
-</pre></td></tr></table></P><P>
-
-Allowable next actions:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ2_bzDecompress</CODE>
-         if <CODE>BZ_OK</CODE> was returned
-      no specific action required in case of error
-</pre></td></tr></table></P><P>
-
- 
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC23"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC22"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC24"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.3.5 <CODE>BZ2_bzDecompress</CODE> </H3>
-<!--docid::SEC23::-->
-<TABLE><tr><td> </td><td class=example><pre>int BZ2_bzDecompress ( bz_stream *strm );
-</pre></td></tr></table>Provides more input and/out output buffer space for the library.  The
-caller maintains input and output buffers, and uses <CODE>BZ2_bzDecompress</CODE>
-to transfer data between them.
-<P>
-
-Before each call to <CODE>BZ2_bzDecompress</CODE>, <CODE>next_in</CODE> 
-should point at the compressed data,
-and <CODE>avail_in</CODE> should indicate how many bytes the library
-may read.  <CODE>BZ2_bzDecompress</CODE> updates <CODE>next_in</CODE>, <CODE>avail_in</CODE> 
-and <CODE>total_in</CODE>
-to reflect the number of bytes it has read.
-</P><P>
-
-Similarly, <CODE>next_out</CODE> should point to a buffer in which the uncompressed
-output is to be placed, with <CODE>avail_out</CODE> indicating how much output space
-is available.  <CODE>BZ2_bzCompress</CODE> updates <CODE>next_out</CODE>,
-<CODE>avail_out</CODE> and <CODE>total_out</CODE> to reflect
-the number of bytes output.
-</P><P>
-
-You may provide and remove as little or as much data as you like on
-each call of <CODE>BZ2_bzDecompress</CODE>.  
-In the limit, it is acceptable to
-supply and remove data one byte at a time, although this would be
-terribly inefficient.  You should always ensure that at least one
-byte of output space is available at each call.
-</P><P>
-
-Use of <CODE>BZ2_bzDecompress</CODE> is simpler than <CODE>BZ2_bzCompress</CODE>.
-</P><P>
-
-You should provide input and remove output as described above, and
-repeatedly call <CODE>BZ2_bzDecompress</CODE> until <CODE>BZ_STREAM_END</CODE> is
-returned.  Appearance of <CODE>BZ_STREAM_END</CODE> denotes that
-<CODE>BZ2_bzDecompress</CODE> has detected the logical end of the compressed
-stream.  <CODE>BZ2_bzDecompress</CODE> will not produce <CODE>BZ_STREAM_END</CODE> until
-all output data has been placed into the output buffer, so once
-<CODE>BZ_STREAM_END</CODE> appears, you are guaranteed to have available all
-the decompressed output, and <CODE>BZ2_bzDecompressEnd</CODE> can safely be
-called.
-</P><P>
-
-If case of an error return value, you should call <CODE>BZ2_bzDecompressEnd</CODE>
-to clean up and release memory.
-</P><P>
-
-Possible return values:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_PARAM_ERROR</CODE>
-         if <CODE>strm</CODE> is <CODE>NULL</CODE> or <CODE>strm->s</CODE> is <CODE>NULL</CODE>
-         or <CODE>strm->avail_out < 1</CODE>
-      <CODE>BZ_DATA_ERROR</CODE>
-         if a data integrity error is detected in the compressed stream
-      <CODE>BZ_DATA_ERROR_MAGIC</CODE>
-         if the compressed stream doesn't begin with the right magic bytes
-      <CODE>BZ_MEM_ERROR</CODE>
-         if there wasn't enough memory available
-      <CODE>BZ_STREAM_END</CODE>
-         if the logical end of the data stream was detected and all
-         output in has been consumed, eg <CODE>s->avail_out > 0</CODE>
-      <CODE>BZ_OK</CODE>
-         otherwise
-</pre></td></tr></table>Allowable next actions:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ2_bzDecompress</CODE>
-         if <CODE>BZ_OK</CODE> was returned
-      <CODE>BZ2_bzDecompressEnd</CODE>
-         otherwise
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC24"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC23"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC25"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.3.6 <CODE>BZ2_bzDecompressEnd</CODE> </H3>
-<!--docid::SEC24::-->
-<TABLE><tr><td> </td><td class=example><pre>int BZ2_bzDecompressEnd ( bz_stream *strm );
-</pre></td></tr></table>Releases all memory associated with a decompression stream.
-<P>
-
-Possible return values:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_PARAM_ERROR</CODE>
-         if <CODE>strm</CODE> is <CODE>NULL</CODE> or <CODE>strm->s</CODE> is <CODE>NULL</CODE>
-      <CODE>BZ_OK</CODE>
-         otherwise
-</pre></td></tr></table></P><P>
-
-Allowable next actions:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      None.
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC25"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC24"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC26"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 3.4 High-level interface </H2>
-<!--docid::SEC25::-->
-<P>
-
-This interface provides functions for reading and writing 
-<CODE>bzip2</CODE> format files.  First, some general points.
-</P><P>
-
-<UL>
-<LI>All of the functions take an <CODE>int*</CODE> first argument,
-  <CODE>bzerror</CODE>.
-  After each call, <CODE>bzerror</CODE> should be consulted first to determine
-  the outcome of the call.  If <CODE>bzerror</CODE> is <CODE>BZ_OK</CODE>, 
-  the call completed
-  successfully, and only then should the return value of the function
-  (if any) be consulted.  If <CODE>bzerror</CODE> is <CODE>BZ_IO_ERROR</CODE>, 
-  there was an error
-  reading/writing the underlying compressed file, and you should
-  then consult <CODE>errno</CODE>/<CODE>perror</CODE> to determine the 
-  cause of the difficulty.
-  <CODE>bzerror</CODE> may also be set to various other values; precise details are
-  given on a per-function basis below.
-<LI>If <CODE>bzerror</CODE> indicates an error
-  (ie, anything except <CODE>BZ_OK</CODE> and <CODE>BZ_STREAM_END</CODE>),
-  you should immediately call <CODE>BZ2_bzReadClose</CODE> (or <CODE>BZ2_bzWriteClose</CODE>,
-  depending on whether you are attempting to read or to write)
-  to free up all resources associated
-  with the stream.  Once an error has been indicated, behaviour of all calls
-  except <CODE>BZ2_bzReadClose</CODE> (<CODE>BZ2_bzWriteClose</CODE>) is undefined.  
-  The implication is that (1) <CODE>bzerror</CODE> should
-  be checked after each call, and (2) if <CODE>bzerror</CODE> indicates an error, 
-  <CODE>BZ2_bzReadClose</CODE> (<CODE>BZ2_bzWriteClose</CODE>) should then be called to clean up.
-<LI>The <CODE>FILE*</CODE> arguments passed to
-   <CODE>BZ2_bzReadOpen</CODE>/<CODE>BZ2_bzWriteOpen</CODE>  
-  should be set to binary mode.
-  Most Unix systems will do this by default, but other platforms,
-  including Windows and Mac, will not.  If you omit this, you may
-  encounter problems when moving code to new platforms.
-<LI>Memory allocation requests are handled by
-  <CODE>malloc</CODE>/<CODE>free</CODE>.  
-  At present
-  there is no facility for user-defined memory allocators in the file I/O
-  functions (could easily be added, though).
-</UL>
-<P>
-
-<HR SIZE="6">
-<A NAME="SEC26"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC25"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC27"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.4.1 <CODE>BZ2_bzReadOpen</CODE> </H3>
-<!--docid::SEC26::-->
-<TABLE><tr><td> </td><td class=example><pre>   typedef void BZFILE;
-
-   BZFILE *BZ2_bzReadOpen ( int *bzerror, FILE *f, 
-                            int small, int verbosity,
-                            void *unused, int nUnused );
-</pre></td></tr></table>Prepare to read compressed data from file handle <CODE>f</CODE>.  <CODE>f</CODE>
-should refer to a file which has been opened for reading, and for which
-the error indicator (<CODE>ferror(f)</CODE>)is not set.  If <CODE>small</CODE> is 1,
-the library will try to decompress using less memory, at the expense of
-speed.
-<P>
-
-For reasons explained below, <CODE>BZ2_bzRead</CODE> will decompress the
-<CODE>nUnused</CODE> bytes starting at <CODE>unused</CODE>, before starting to read
-from the file <CODE>f</CODE>.  At most <CODE>BZ_MAX_UNUSED</CODE> bytes may be
-supplied like this.  If this facility is not required, you should pass
-<CODE>NULL</CODE> and <CODE>0</CODE> for <CODE>unused</CODE> and n<CODE>Unused</CODE>
-respectively.
-</P><P>
-
-For the meaning of parameters <CODE>small</CODE> and <CODE>verbosity</CODE>,
-see <CODE>BZ2_bzDecompressInit</CODE>.
-</P><P>
-
-The amount of memory needed to decompress a file cannot be determined
-until the file's header has been read.  So it is possible that
-<CODE>BZ2_bzReadOpen</CODE> returns <CODE>BZ_OK</CODE> but a subsequent call of
-<CODE>BZ2_bzRead</CODE> will return <CODE>BZ_MEM_ERROR</CODE>.
-</P><P>
-
-Possible assignments to <CODE>bzerror</CODE>:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_CONFIG_ERROR</CODE>
-         if the library has been mis-compiled
-      <CODE>BZ_PARAM_ERROR</CODE>
-         if <CODE>f</CODE> is <CODE>NULL</CODE> 
-         or <CODE>small</CODE> is neither <CODE>0</CODE> nor <CODE>1</CODE>                 
-         or <CODE>(unused == NULL && nUnused != 0)</CODE>
-         or <CODE>(unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED))</CODE>
-      <CODE>BZ_IO_ERROR</CODE>    
-         if <CODE>ferror(f)</CODE> is nonzero
-      <CODE>BZ_MEM_ERROR</CODE>   
-         if insufficient memory is available
-      <CODE>BZ_OK</CODE>
-         otherwise.
-</pre></td></tr></table></P><P>
-
-Possible return values:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      Pointer to an abstract <CODE>BZFILE</CODE>        
-         if <CODE>bzerror</CODE> is <CODE>BZ_OK</CODE>   
-      <CODE>NULL</CODE>
-         otherwise
-</pre></td></tr></table></P><P>
-
-Allowable next actions:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ2_bzRead</CODE>
-         if <CODE>bzerror</CODE> is <CODE>BZ_OK</CODE>   
-      <CODE>BZ2_bzClose</CODE> 
-         otherwise
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC27"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC26"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC28"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.4.2 <CODE>BZ2_bzRead</CODE> </H3>
-<!--docid::SEC27::-->
-<TABLE><tr><td> </td><td class=example><pre>   int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );
-</pre></td></tr></table>Reads up to <CODE>len</CODE> (uncompressed) bytes from the compressed file 
-<CODE>b</CODE> into
-the buffer <CODE>buf</CODE>.  If the read was successful, 
-<CODE>bzerror</CODE> is set to <CODE>BZ_OK</CODE>
-and the number of bytes read is returned.  If the logical end-of-stream
-was detected, <CODE>bzerror</CODE> will be set to <CODE>BZ_STREAM_END</CODE>, 
-and the number
-of bytes read is returned.  All other <CODE>bzerror</CODE> values denote an error.
-<P>
-
-<CODE>BZ2_bzRead</CODE> will supply <CODE>len</CODE> bytes,
-unless the logical stream end is detected
-or an error occurs.  Because of this, it is possible to detect the 
-stream end by observing when the number of bytes returned is 
-less than the number
-requested.  Nevertheless, this is regarded as inadvisable; you should
-instead check <CODE>bzerror</CODE> after every call and watch out for
-<CODE>BZ_STREAM_END</CODE>.
-</P><P>
-
-Internally, <CODE>BZ2_bzRead</CODE> copies data from the compressed file in chunks
-of size <CODE>BZ_MAX_UNUSED</CODE> bytes
-before decompressing it.  If the file contains more bytes than strictly
-needed to reach the logical end-of-stream, <CODE>BZ2_bzRead</CODE> will almost certainly
-read some of the trailing data before signalling <CODE>BZ_SEQUENCE_END</CODE>.
-To collect the read but unused data once <CODE>BZ_SEQUENCE_END</CODE> has 
-appeared, call <CODE>BZ2_bzReadGetUnused</CODE> immediately before <CODE>BZ2_bzReadClose</CODE>.
-</P><P>
-
-Possible assignments to <CODE>bzerror</CODE>:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_PARAM_ERROR</CODE>
-         if <CODE>b</CODE> is <CODE>NULL</CODE> or <CODE>buf</CODE> is <CODE>NULL</CODE> or <CODE>len < 0</CODE>
-      <CODE>BZ_SEQUENCE_ERROR</CODE> 
-         if <CODE>b</CODE> was opened with <CODE>BZ2_bzWriteOpen</CODE>
-      <CODE>BZ_IO_ERROR</CODE> 
-         if there is an error reading from the compressed file
-      <CODE>BZ_UNEXPECTED_EOF</CODE> 
-         if the compressed file ended before the logical end-of-stream was detected
-      <CODE>BZ_DATA_ERROR</CODE> 
-         if a data integrity error was detected in the compressed stream
-      <CODE>BZ_DATA_ERROR_MAGIC</CODE>
-         if the stream does not begin with the requisite header bytes (ie, is not 
-         a <CODE>bzip2</CODE> data file).  This is really a special case of <CODE>BZ_DATA_ERROR</CODE>.
-      <CODE>BZ_MEM_ERROR</CODE> 
-         if insufficient memory was available
-      <CODE>BZ_STREAM_END</CODE> 
-         if the logical end of stream was detected.
-      <CODE>BZ_OK</CODE>
-         otherwise.
-</pre></td></tr></table></P><P>
-
-Possible return values:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      number of bytes read
-         if <CODE>bzerror</CODE> is <CODE>BZ_OK</CODE> or <CODE>BZ_STREAM_END</CODE>
-      undefined
-         otherwise
-</pre></td></tr></table></P><P>
-
-Allowable next actions:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      collect data from <CODE>buf</CODE>, then <CODE>BZ2_bzRead</CODE> or <CODE>BZ2_bzReadClose</CODE>
-         if <CODE>bzerror</CODE> is <CODE>BZ_OK</CODE> 
-      collect data from <CODE>buf</CODE>, then <CODE>BZ2_bzReadClose</CODE> or <CODE>BZ2_bzReadGetUnused</CODE> 
-         if <CODE>bzerror</CODE> is <CODE>BZ_SEQUENCE_END</CODE>   
-      <CODE>BZ2_bzReadClose</CODE> 
-         otherwise
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC28"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC27"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC29"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.4.3 <CODE>BZ2_bzReadGetUnused</CODE> </H3>
-<!--docid::SEC28::-->
-<TABLE><tr><td> </td><td class=example><pre>   void BZ2_bzReadGetUnused ( int* bzerror, BZFILE *b, 
-                              void** unused, int* nUnused );
-</pre></td></tr></table>Returns data which was read from the compressed file but was not needed
-to get to the logical end-of-stream.  <CODE>*unused</CODE> is set to the address
-of the data, and <CODE>*nUnused</CODE> to the number of bytes.  <CODE>*nUnused</CODE> will
-be set to a value between <CODE>0</CODE> and <CODE>BZ_MAX_UNUSED</CODE> inclusive.
-<P>
-
-This function may only be called once <CODE>BZ2_bzRead</CODE> has signalled 
-<CODE>BZ_STREAM_END</CODE> but before <CODE>BZ2_bzReadClose</CODE>.
-</P><P>
-
-Possible assignments to <CODE>bzerror</CODE>:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_PARAM_ERROR</CODE> 
-         if <CODE>b</CODE> is <CODE>NULL</CODE> 
-         or <CODE>unused</CODE> is <CODE>NULL</CODE> or <CODE>nUnused</CODE> is <CODE>NULL</CODE>
-      <CODE>BZ_SEQUENCE_ERROR</CODE> 
-         if <CODE>BZ_STREAM_END</CODE> has not been signalled
-         or if <CODE>b</CODE> was opened with <CODE>BZ2_bzWriteOpen</CODE>
-     <CODE>BZ_OK</CODE>
-         otherwise
-</pre></td></tr></table></P><P>
-
-Allowable next actions:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ2_bzReadClose</CODE>
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC29"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC28"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC30"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.4.4 <CODE>BZ2_bzReadClose</CODE> </H3>
-<!--docid::SEC29::-->
-<TABLE><tr><td> </td><td class=example><pre>   void BZ2_bzReadClose ( int *bzerror, BZFILE *b );
-</pre></td></tr></table>Releases all memory pertaining to the compressed file <CODE>b</CODE>.  
-<CODE>BZ2_bzReadClose</CODE> does not call <CODE>fclose</CODE> on the underlying file
-handle, so you should do that yourself if appropriate.
-<CODE>BZ2_bzReadClose</CODE> should be called to clean up after all error
-situations.
-<P>
-
-Possible assignments to <CODE>bzerror</CODE>:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_SEQUENCE_ERROR</CODE> 
-         if <CODE>b</CODE> was opened with <CODE>BZ2_bzOpenWrite</CODE> 
-      <CODE>BZ_OK</CODE> 
-         otherwise
-</pre></td></tr></table></P><P>
-
-Allowable next actions:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      none
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC30"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC29"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC31"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.4.5 <CODE>BZ2_bzWriteOpen</CODE> </H3>
-<!--docid::SEC30::-->
-<TABLE><tr><td> </td><td class=example><pre>   BZFILE *BZ2_bzWriteOpen ( int *bzerror, FILE *f, 
-                             int blockSize100k, int verbosity,
-                             int workFactor );
-</pre></td></tr></table>Prepare to write compressed data to file handle <CODE>f</CODE>.  
-<CODE>f</CODE> should refer to
-a file which has been opened for writing, and for which the error
-indicator (<CODE>ferror(f)</CODE>)is not set.  
-<P>
-
-For the meaning of parameters <CODE>blockSize100k</CODE>,
-<CODE>verbosity</CODE> and <CODE>workFactor</CODE>, see
-<BR> <CODE>BZ2_bzCompressInit</CODE>.
-</P><P>
-
-All required memory is allocated at this stage, so if the call
-completes successfully, <CODE>BZ_MEM_ERROR</CODE> cannot be signalled by a
-subsequent call to <CODE>BZ2_bzWrite</CODE>.
-</P><P>
-
-Possible assignments to <CODE>bzerror</CODE>:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_CONFIG_ERROR</CODE>
-         if the library has been mis-compiled
-      <CODE>BZ_PARAM_ERROR</CODE> 
-         if <CODE>f</CODE> is <CODE>NULL</CODE> 
-         or <CODE>blockSize100k < 1</CODE> or <CODE>blockSize100k > 9</CODE>
-      <CODE>BZ_IO_ERROR</CODE> 
-         if <CODE>ferror(f)</CODE> is nonzero
-      <CODE>BZ_MEM_ERROR</CODE> 
-         if insufficient memory is available
-      <CODE>BZ_OK</CODE> 
-         otherwise
-</pre></td></tr></table></P><P>
-
-Possible return values:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      Pointer to an abstract <CODE>BZFILE</CODE>  
-         if <CODE>bzerror</CODE> is <CODE>BZ_OK</CODE>   
-      <CODE>NULL</CODE> 
-         otherwise
-</pre></td></tr></table></P><P>
-
-Allowable next actions:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ2_bzWrite</CODE> 
-         if <CODE>bzerror</CODE> is <CODE>BZ_OK</CODE> 
-         (you could go directly to <CODE>BZ2_bzWriteClose</CODE>, but this would be pretty pointless)
-      <CODE>BZ2_bzWriteClose</CODE> 
-         otherwise
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC31"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC30"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC32"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.4.6 <CODE>BZ2_bzWrite</CODE> </H3>
-<!--docid::SEC31::-->
-<TABLE><tr><td> </td><td class=example><pre>   void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );
-</pre></td></tr></table>Absorbs <CODE>len</CODE> bytes from the buffer <CODE>buf</CODE>, eventually to be
-compressed and written to the file.
-<P>
-
-Possible assignments to <CODE>bzerror</CODE>:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_PARAM_ERROR</CODE> 
-         if <CODE>b</CODE> is <CODE>NULL</CODE> or <CODE>buf</CODE> is <CODE>NULL</CODE> or <CODE>len < 0</CODE>
-      <CODE>BZ_SEQUENCE_ERROR</CODE> 
-         if b was opened with <CODE>BZ2_bzReadOpen</CODE>
-      <CODE>BZ_IO_ERROR</CODE> 
-         if there is an error writing the compressed file.
-      <CODE>BZ_OK</CODE> 
-         otherwise
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC32"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC31"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC33"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.4.7 <CODE>BZ2_bzWriteClose</CODE> </H3>
-<!--docid::SEC32::-->
-<TABLE><tr><td> </td><td class=example><pre>   void BZ2_bzWriteClose ( int *bzerror, BZFILE* f,
-                           int abandon,
-                           unsigned int* nbytes_in,
-                           unsigned int* nbytes_out );
-
-   void BZ2_bzWriteClose64 ( int *bzerror, BZFILE* f,
-                             int abandon,
-                             unsigned int* nbytes_in_lo32,
-                             unsigned int* nbytes_in_hi32,
-                             unsigned int* nbytes_out_lo32,
-                             unsigned int* nbytes_out_hi32 );
-</pre></td></tr></table><P>
-
-Compresses and flushes to the compressed file all data so far supplied
-by <CODE>BZ2_bzWrite</CODE>.  The logical end-of-stream markers are also written, so
-subsequent calls to <CODE>BZ2_bzWrite</CODE> are illegal.  All memory associated 
-with the compressed file <CODE>b</CODE> is released.  
-<CODE>fflush</CODE> is called on the
-compressed file, but it is not <CODE>fclose</CODE>'d.
-</P><P>
-
-If <CODE>BZ2_bzWriteClose</CODE> is called to clean up after an error, the only
-action is to release the memory.  The library records the error codes
-issued by previous calls, so this situation will be detected
-automatically.  There is no attempt to complete the compression
-operation, nor to <CODE>fflush</CODE> the compressed file.  You can force this
-behaviour to happen even in the case of no error, by passing a nonzero
-value to <CODE>abandon</CODE>.
-</P><P>
-
-If <CODE>nbytes_in</CODE> is non-null, <CODE>*nbytes_in</CODE> will be set to be the
-total volume of uncompressed data handled.  Similarly, <CODE>nbytes_out</CODE>
-will be set to the total volume of compressed data written.  For 
-compatibility with older versions of the library, <CODE>BZ2_bzWriteClose</CODE>
-only yields the lower 32 bits of these counts.  Use
-<CODE>BZ2_bzWriteClose64</CODE> if you want the full 64 bit counts.  These
-two functions are otherwise absolutely identical.
-</P><P>
-
-Possible assignments to <CODE>bzerror</CODE>:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_SEQUENCE_ERROR</CODE> 
-         if <CODE>b</CODE> was opened with <CODE>BZ2_bzReadOpen</CODE>
-      <CODE>BZ_IO_ERROR</CODE> 
-         if there is an error writing the compressed file
-      <CODE>BZ_OK</CODE> 
-         otherwise
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC33"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC32"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC34"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.4.8 Handling embedded compressed data streams </H3>
-<!--docid::SEC33::-->
-<P>
-
-The high-level library facilitates use of
-<CODE>bzip2</CODE> data streams which form some part of a surrounding, larger
-data stream.
-<UL>
-<LI>For writing, the library takes an open file handle, writes
-compressed data to it, <CODE>fflush</CODE>es it but does not <CODE>fclose</CODE> it.
-The calling application can write its own data before and after the
-compressed data stream, using that same file handle.
-<LI>Reading is more complex, and the facilities are not as general
-as they could be since generality is hard to reconcile with efficiency.
-<CODE>BZ2_bzRead</CODE> reads from the compressed file in blocks of size
-<CODE>BZ_MAX_UNUSED</CODE> bytes, and in doing so probably will overshoot
-the logical end of compressed stream.
-To recover this data once decompression has
-ended, call <CODE>BZ2_bzReadGetUnused</CODE> after the last call of <CODE>BZ2_bzRead</CODE>
-(the one returning <CODE>BZ_STREAM_END</CODE>) but before calling
-<CODE>BZ2_bzReadClose</CODE>.
-</UL>
-<P>
-
-This mechanism makes it easy to decompress multiple <CODE>bzip2</CODE>
-streams placed end-to-end.  As the end of one stream, when <CODE>BZ2_bzRead</CODE>
-returns <CODE>BZ_STREAM_END</CODE>, call <CODE>BZ2_bzReadGetUnused</CODE> to collect the
-unused data (copy it into your own buffer somewhere).  
-That data forms the start of the next compressed stream.
-To start uncompressing that next stream, call <CODE>BZ2_bzReadOpen</CODE> again,
-feeding in the unused data via the <CODE>unused</CODE>/<CODE>nUnused</CODE>
-parameters.
-Keep doing this until <CODE>BZ_STREAM_END</CODE> return coincides with the
-physical end of file (<CODE>feof(f)</CODE>).  In this situation
-<CODE>BZ2_bzReadGetUnused</CODE>
-will of course return no data.
-</P><P>
-
-This should give some feel for how the high-level interface can be used.
-If you require extra flexibility, you'll have to bite the bullet and get
-to grips with the low-level interface.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC34"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC33"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC35"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.4.9 Standard file-reading/writing code </H3>
-<!--docid::SEC34::-->
-Here's how you'd write data to a compressed file:
-<TABLE><tr><td> </td><td class=example><pre>FILE*   f;
-BZFILE* b;
-int     nBuf;
-char    buf[ /* whatever size you like */ ];
-int     bzerror;
-int     nWritten;
-
-f = fopen ( "myfile.bz2", "w" );
-if (!f) {
-   /* handle error */
-}
-b = BZ2_bzWriteOpen ( &bzerror, f, 9 );
-if (bzerror != BZ_OK) {
-   BZ2_bzWriteClose ( b );
-   /* handle error */
-}
-
-while ( /* condition */ ) {
-   /* get data to write into buf, and set nBuf appropriately */
-   nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf );
-   if (bzerror == BZ_IO_ERROR) { 
-      BZ2_bzWriteClose ( &bzerror, b );
-      /* handle error */
-   }
-}
-
-BZ2_bzWriteClose ( &bzerror, b );
-if (bzerror == BZ_IO_ERROR) {
-   /* handle error */
-}
-</pre></td></tr></table>And to read from a compressed file:
-<TABLE><tr><td> </td><td class=example><pre>FILE*   f;
-BZFILE* b;
-int     nBuf;
-char    buf[ /* whatever size you like */ ];
-int     bzerror;
-int     nWritten;
-
-f = fopen ( "myfile.bz2", "r" );
-if (!f) {
-   /* handle error */
-}
-b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 );
-if (bzerror != BZ_OK) {
-   BZ2_bzReadClose ( &bzerror, b );
-   /* handle error */
-}
-
-bzerror = BZ_OK;
-while (bzerror == BZ_OK && /* arbitrary other conditions */) {
-   nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ );
-   if (bzerror == BZ_OK) {
-      /* do something with buf[0 .. nBuf-1] */
-   }
-}
-if (bzerror != BZ_STREAM_END) {
-   BZ2_bzReadClose ( &bzerror, b );
-   /* handle error */
-} else {
-   BZ2_bzReadClose ( &bzerror );
-}
-</pre></td></tr></table><P>
-
-<HR SIZE="6">
-<A NAME="SEC35"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC34"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC36"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 3.5 Utility functions </H2>
-<!--docid::SEC35::-->
-<HR SIZE="6">
-<A NAME="SEC36"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC35"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC37"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.5.1 <CODE>BZ2_bzBuffToBuffCompress</CODE> </H3>
-<!--docid::SEC36::-->
-<TABLE><tr><td> </td><td class=example><pre>   int BZ2_bzBuffToBuffCompress( char*         dest,
-                                 unsigned int* destLen,
-                                 char*         source,
-                                 unsigned int  sourceLen,
-                                 int           blockSize100k,
-                                 int           verbosity,
-                                 int           workFactor );
-</pre></td></tr></table>Attempts to compress the data in <CODE>source[0 .. sourceLen-1]</CODE>
-into the destination buffer, <CODE>dest[0 .. *destLen-1]</CODE>.
-If the destination buffer is big enough, <CODE>*destLen</CODE> is
-set to the size of the compressed data, and <CODE>BZ_OK</CODE> is
-returned.  If the compressed data won't fit, <CODE>*destLen</CODE>
-is unchanged, and <CODE>BZ_OUTBUFF_FULL</CODE> is returned.
-<P>
-
-Compression in this manner is a one-shot event, done with a single call
-to this function.  The resulting compressed data is a complete
-<CODE>bzip2</CODE> format data stream.  There is no mechanism for making
-additional calls to provide extra input data.  If you want that kind of
-mechanism, use the low-level interface.
-</P><P>
-
-For the meaning of parameters <CODE>blockSize100k</CODE>, <CODE>verbosity</CODE>
-and <CODE>workFactor</CODE>, <BR> see <CODE>BZ2_bzCompressInit</CODE>.
-</P><P>
-
-To guarantee that the compressed data will fit in its buffer, allocate
-an output buffer of size 1% larger than the uncompressed data, plus
-six hundred extra bytes.
-</P><P>
-
-<CODE>BZ2_bzBuffToBuffDecompress</CODE> will not write data at or
-beyond <CODE>dest[*destLen]</CODE>, even in case of buffer overflow.
-</P><P>
-
-Possible return values:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_CONFIG_ERROR</CODE>
-         if the library has been mis-compiled
-      <CODE>BZ_PARAM_ERROR</CODE> 
-         if <CODE>dest</CODE> is <CODE>NULL</CODE> or <CODE>destLen</CODE> is <CODE>NULL</CODE>
-         or <CODE>blockSize100k < 1</CODE> or <CODE>blockSize100k > 9</CODE>
-         or <CODE>verbosity < 0</CODE> or <CODE>verbosity > 4</CODE> 
-         or <CODE>workFactor < 0</CODE> or <CODE>workFactor > 250</CODE>
-      <CODE>BZ_MEM_ERROR</CODE>
-         if insufficient memory is available 
-      <CODE>BZ_OUTBUFF_FULL</CODE>
-         if the size of the compressed data exceeds <CODE>*destLen</CODE>
-      <CODE>BZ_OK</CODE> 
-         otherwise
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC37"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC36"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC38"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.5.2 <CODE>BZ2_bzBuffToBuffDecompress</CODE> </H3>
-<!--docid::SEC37::-->
-<TABLE><tr><td> </td><td class=example><pre>   int BZ2_bzBuffToBuffDecompress ( char*         dest,
-                                    unsigned int* destLen,
-                                    char*         source,
-                                    unsigned int  sourceLen,
-                                    int           small,
-                                    int           verbosity );
-</pre></td></tr></table>Attempts to decompress the data in <CODE>source[0 .. sourceLen-1]</CODE>
-into the destination buffer, <CODE>dest[0 .. *destLen-1]</CODE>.
-If the destination buffer is big enough, <CODE>*destLen</CODE> is
-set to the size of the uncompressed data, and <CODE>BZ_OK</CODE> is
-returned.  If the compressed data won't fit, <CODE>*destLen</CODE>
-is unchanged, and <CODE>BZ_OUTBUFF_FULL</CODE> is returned.
-<P>
-
-<CODE>source</CODE> is assumed to hold a complete <CODE>bzip2</CODE> format
-data stream.  <BR> <CODE>BZ2_bzBuffToBuffDecompress</CODE> tries to decompress
-the entirety of the stream into the output buffer.
-</P><P>
-
-For the meaning of parameters <CODE>small</CODE> and <CODE>verbosity</CODE>,
-see <CODE>BZ2_bzDecompressInit</CODE>.
-</P><P>
-
-Because the compression ratio of the compressed data cannot be known in
-advance, there is no easy way to guarantee that the output buffer will
-be big enough.  You may of course make arrangements in your code to
-record the size of the uncompressed data, but such a mechanism is beyond
-the scope of this library.
-</P><P>
-
-<CODE>BZ2_bzBuffToBuffDecompress</CODE> will not write data at or
-beyond <CODE>dest[*destLen]</CODE>, even in case of buffer overflow.
-</P><P>
-
-Possible return values:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">      <CODE>BZ_CONFIG_ERROR</CODE>
-         if the library has been mis-compiled
-      <CODE>BZ_PARAM_ERROR</CODE> 
-         if <CODE>dest</CODE> is <CODE>NULL</CODE> or <CODE>destLen</CODE> is <CODE>NULL</CODE>
-         or <CODE>small != 0 && small != 1</CODE>
-         or <CODE>verbosity < 0</CODE> or <CODE>verbosity > 4</CODE> 
-      <CODE>BZ_MEM_ERROR</CODE>
-         if insufficient memory is available 
-      <CODE>BZ_OUTBUFF_FULL</CODE>
-         if the size of the compressed data exceeds <CODE>*destLen</CODE>
-      <CODE>BZ_DATA_ERROR</CODE>
-         if a data integrity error was detected in the compressed data
-      <CODE>BZ_DATA_ERROR_MAGIC</CODE>
-         if the compressed data doesn't begin with the right magic bytes
-      <CODE>BZ_UNEXPECTED_EOF</CODE>
-         if the compressed data ends unexpectedly
-      <CODE>BZ_OK</CODE> 
-         otherwise
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<A NAME="SEC38"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC37"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC39"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 3.6 <CODE>zlib</CODE> compatibility functions </H2>
-<!--docid::SEC38::-->
-Yoshioka Tsuneo has contributed some functions to
-give better <CODE>zlib</CODE> compatibility.  These functions are
-<CODE>BZ2_bzopen</CODE>, <CODE>BZ2_bzread</CODE>, <CODE>BZ2_bzwrite</CODE>, <CODE>BZ2_bzflush</CODE>,
-<CODE>BZ2_bzclose</CODE>,
-<CODE>BZ2_bzerror</CODE> and <CODE>BZ2_bzlibVersion</CODE>.
-These functions are not (yet) officially part of
-the library.  If they break, you get to keep all the pieces.
-Nevertheless, I think they work ok.
-<TABLE><tr><td> </td><td class=example><pre>typedef void BZFILE;
-
-const char * BZ2_bzlibVersion ( void );
-</pre></td></tr></table>Returns a string indicating the library version.
-<TABLE><tr><td> </td><td class=example><pre>BZFILE * BZ2_bzopen  ( const char *path, const char *mode );
-BZFILE * BZ2_bzdopen ( int        fd,    const char *mode );
-</pre></td></tr></table>Opens a <CODE>.bz2</CODE> file for reading or writing, using either its name
-or a pre-existing file descriptor. 
-Analogous to <CODE>fopen</CODE> and <CODE>fdopen</CODE>.
-<TABLE><tr><td> </td><td class=example><pre>int BZ2_bzread  ( BZFILE* b, void* buf, int len );
-int BZ2_bzwrite ( BZFILE* b, void* buf, int len );
-</pre></td></tr></table>Reads/writes data from/to a previously opened <CODE>BZFILE</CODE>.
-Analogous to <CODE>fread</CODE> and <CODE>fwrite</CODE>.
-<TABLE><tr><td> </td><td class=example><pre>int  BZ2_bzflush ( BZFILE* b );
-void BZ2_bzclose ( BZFILE* b );
-</pre></td></tr></table>Flushes/closes a <CODE>BZFILE</CODE>.  <CODE>BZ2_bzflush</CODE> doesn't actually do
-anything.  Analogous to <CODE>fflush</CODE> and <CODE>fclose</CODE>.
-<P>
-
-<TABLE><tr><td> </td><td class=example><pre>const char * BZ2_bzerror ( BZFILE *b, int *errnum )
-</pre></td></tr></table>Returns a string describing the more recent error status of
-<CODE>b</CODE>, and also sets <CODE>*errnum</CODE> to its numerical value.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC39"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC38"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC40"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 3.7 Using the library in a <CODE>stdio</CODE>-free environment </H2>
-<!--docid::SEC39::-->
-<P>
-
-<HR SIZE="6">
-<A NAME="SEC40"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC39"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC41"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.7.1 Getting rid of <CODE>stdio</CODE> </H3>
-<!--docid::SEC40::-->
-<P>
-
-In a deeply embedded application, you might want to use just
-the memory-to-memory functions.  You can do this conveniently
-by compiling the library with preprocessor symbol <CODE>BZ_NO_STDIO</CODE>
-defined.  Doing this gives you a library containing only the following
-eight functions:
-</P><P>
-
-<CODE>BZ2_bzCompressInit</CODE>, <CODE>BZ2_bzCompress</CODE>, <CODE>BZ2_bzCompressEnd</CODE> <BR>
-<CODE>BZ2_bzDecompressInit</CODE>, <CODE>BZ2_bzDecompress</CODE>, <CODE>BZ2_bzDecompressEnd</CODE> <BR>
-<CODE>BZ2_bzBuffToBuffCompress</CODE>, <CODE>BZ2_bzBuffToBuffDecompress</CODE>
-</P><P>
-
-When compiled like this, all functions will ignore <CODE>verbosity</CODE>
-settings.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC41"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC40"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC42"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H3> 3.7.2 Critical error handling </H3>
-<!--docid::SEC41::-->
-<CODE>libbzip2</CODE> contains a number of internal assertion checks which
-should, needless to say, never be activated.  Nevertheless, if an
-assertion should fail, behaviour depends on whether or not the library
-was compiled with <CODE>BZ_NO_STDIO</CODE> set.
-<P>
-
-For a normal compile, an assertion failure yields the message
-<TABLE><tr><td> </td><td class=example><pre>   bzip2/libbzip2: internal error number N.
-   This is a bug in bzip2/libbzip2, 1.0.2, 30-Dec-2001.
-   Please report it to me at: jseward at acm.org.  If this happened
-   when you were using some program which uses libbzip2 as a
-   component, you should also report this bug to the author(s)
-   of that program.  Please make an effort to report this bug;
-   timely and accurate bug reports eventually lead to higher
-   quality software.  Thanks.  Julian Seward, 30 December 2001.
-</pre></td></tr></table>where <CODE>N</CODE> is some error code number.  If <CODE>N == 1007</CODE>, it also
-prints some extra text advising the reader that unreliable memory is
-often associated with internal error 1007.  (This is a
-frequently-observed-phenomenon with versions 1.0.0/1.0.1).
-</P><P>
-
-<CODE>exit(3)</CODE> is then called.
-</P><P>
-
-For a <CODE>stdio</CODE>-free library, assertion failures result
-in a call to a function declared as:
-<TABLE><tr><td> </td><td class=example><pre>   extern void bz_internal_error ( int errcode );
-</pre></td></tr></table>The relevant code is passed as a parameter.  You should supply
-such a function.
-</P><P>
-
-In either case, once an assertion failure has occurred, any 
-<CODE>bz_stream</CODE> records involved can be regarded as invalid.
-You should not attempt to resume normal operation with them.
-</P><P>
-
-You may, of course, change critical error handling to suit
-your needs.  As I said above, critical errors indicate bugs
-in the library and should not occur.  All "normal" error
-situations are indicated via error return codes from functions,
-and can be recovered from.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC42"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC41"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC43"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 3.8 Making a Windows DLL </H2>
-<!--docid::SEC42::-->
-Everything related to Windows has been contributed by Yoshioka Tsuneo
-<BR> (<CODE>QWF00133 at niftyserve.or.jp</CODE> /
-<CODE>tsuneo-y at is.aist-nara.ac.jp</CODE>), so you should send your queries to
-him (but perhaps Cc: me, <CODE>jseward at acm.org</CODE>).
-<P>
-
-My vague understanding of what to do is: using Visual C++ 5.0,
-open the project file <CODE>libbz2.dsp</CODE>, and build.  That's all.
-</P><P>
-
-If you can't
-open the project file for some reason, make a new one, naming these files:
-<CODE>blocksort.c</CODE>, <CODE>bzlib.c</CODE>, <CODE>compress.c</CODE>, 
-<CODE>crctable.c</CODE>, <CODE>decompress.c</CODE>, <CODE>huffman.c</CODE>, <BR>
-<CODE>randtable.c</CODE> and <CODE>libbz2.def</CODE>.  You will also need
-to name the header files <CODE>bzlib.h</CODE> and <CODE>bzlib_private.h</CODE>.
-</P><P>
-
-If you don't use VC++, you may need to define the proprocessor symbol
-<CODE>_WIN32</CODE>. 
-</P><P>
-
-Finally, <CODE>dlltest.c</CODE> is a sample program using the DLL.  It has a
-project file, <CODE>dlltest.dsp</CODE>.
-</P><P>
-
-If you just want a makefile for Visual C, have a look at
-<CODE>makefile.msc</CODE>.
-</P><P>
-
-Be aware that if you compile <CODE>bzip2</CODE> itself on Win32, you must set
-<CODE>BZ_UNIX</CODE> to 0 and <CODE>BZ_LCCWIN32</CODE> to 1, in the file
-<CODE>bzip2.c</CODE>, before compiling.  Otherwise the resulting binary won't
-work correctly.
-</P><P>
-
-I haven't tried any of this stuff myself, but it all looks plausible.
-</P><P>
-
-<HR SIZE="6">
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<BR>  
-<FONT SIZE="-1">
-This document was generated
-by <I>Julian Seward</I> on <I>January, 5  2002</I>
-using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
-"><I>texi2html</I></A>
-
-</BODY>
-</HTML>
diff --git a/c++/src/util/compress/bzip2/manual_4.html b/c++/src/util/compress/bzip2/manual_4.html
deleted file mode 100644
index fbe3938..0000000
--- a/c++/src/util/compress/bzip2/manual_4.html
+++ /dev/null
@@ -1,530 +0,0 @@
-<HTML>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<!-- Created on January, 5  2002 by texi2html 1.64 -->
-<!-- 
-Written by: Lionel Cons <Lionel.Cons at cern.ch> (original author)
-            Karl Berry  <karl at freefriends.org>
-            Olaf Bachmann <obachman at mathematik.uni-kl.de>
-            and many others.
-Maintained by: Olaf Bachmann <obachman at mathematik.uni-kl.de>
-Send bugs and suggestions to <texi2html at mathematik.uni-kl.de>
- 
--->
-<HEAD>
-<TITLE>Untitled Document: 4. Miscellanea</TITLE>
-
-<META NAME="description" CONTENT="Untitled Document: 4. Miscellanea">
-<META NAME="keywords" CONTENT="Untitled Document: 4. Miscellanea">
-<META NAME="resource-type" CONTENT="document">
-<META NAME="distribution" CONTENT="global">
-<META NAME="Generator" CONTENT="texi2html 1.64">
-
-</HEAD>
-
-<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
-
-<A NAME="SEC43"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_3.html#SEC42"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC44"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H1> 4. Miscellanea </H1>
-<!--docid::SEC43::-->
-<P>
-
-These are just some random thoughts of mine.  Your mileage may
-vary.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC44"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC43"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC45"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 4.1 Limitations of the compressed file format </H2>
-<!--docid::SEC44::-->
-<CODE>bzip2-1.0</CODE>, <CODE>0.9.5</CODE> and <CODE>0.9.0</CODE>
-use exactly the same file format as the previous
-version, <CODE>bzip2-0.1</CODE>.  This decision was made in the interests of
-stability.  Creating yet another incompatible compressed file format
-would create further confusion and disruption for users.
-<P>
-
-Nevertheless, this is not a painless decision.  Development
-work since the release of <CODE>bzip2-0.1</CODE> in August 1997
-has shown complexities in the file format which slow down
-decompression and, in retrospect, are unnecessary.  These are:
-<UL>
-<LI>The run-length encoder, which is the first of the
-      compression transformations, is entirely irrelevant.
-      The original purpose was to protect the sorting algorithm
-      from the very worst case input: a string of repeated
-      symbols.  But algorithm steps Q6a and Q6b in the original
-      Burrows-Wheeler technical report (SRC-124) show how
-      repeats can be handled without difficulty in block
-      sorting.
-<LI>The randomisation mechanism doesn't really need to be
-      there.  Udi Manber and Gene Myers published a suffix
-      array construction algorithm a few years back, which
-      can be employed to sort any block, no matter how 
-      repetitive, in O(N log N) time.  Subsequent work by
-      Kunihiko Sadakane has produced a derivative O(N (log N)^2) 
-      algorithm which usually outperforms the Manber-Myers
-      algorithm.
-<P>
-
-      I could have changed to Sadakane's algorithm, but I find
-      it to be slower than <CODE>bzip2</CODE>'s existing algorithm for
-      most inputs, and the randomisation mechanism protects
-      adequately against bad cases.  I didn't think it was
-      a good tradeoff to make.  Partly this is due to the fact
-      that I was not flooded with email complaints about
-      <CODE>bzip2-0.1</CODE>'s performance on repetitive data, so
-      perhaps it isn't a problem for real inputs.
-</P><P>
-
-      Probably the best long-term solution,
-      and the one I have incorporated into 0.9.5 and above,
-      is to use the existing sorting
-      algorithm initially, and fall back to a O(N (log N)^2)
-      algorithm if the standard algorithm gets into difficulties.
-<LI>The compressed file format was never designed to be
-      handled by a library, and I have had to jump though
-      some hoops to produce an efficient implementation of
-      decompression.  It's a bit hairy.  Try passing
-      <CODE>decompress.c</CODE> through the C preprocessor 
-      and you'll see what I mean.  Much of this complexity
-      could have been avoided if the compressed size of
-      each block of data was recorded in the data stream.
-<LI>An Adler-32 checksum, rather than a CRC32 checksum,
-      would be faster to compute.
-</UL>
-It would be fair to say that the <CODE>bzip2</CODE> format was frozen
-before I properly and fully understood the performance
-consequences of doing so.
-<P>
-
-Improvements which I was able to incorporate into
-0.9.0, despite using the same file format, are:
-<UL>
-<LI>Single array implementation of the inverse BWT.  This
-      significantly speeds up decompression, presumably
-      because it reduces the number of cache misses.
-<LI>Faster inverse MTF transform for large MTF values.  The
-      new implementation is based on the notion of sliding blocks
-      of values.
-<LI><CODE>bzip2-0.9.0</CODE> now reads and writes files with <CODE>fread</CODE>
-      and <CODE>fwrite</CODE>; version 0.1 used <CODE>putc</CODE> and <CODE>getc</CODE>.
-      Duh!  Well, you live and learn.
-<P>
-
-</UL>
-Further ahead, it would be nice 
-to be able to do random access into files.  This will 
-require some careful design of compressed file formats.
-<P>
-
-<HR SIZE="6">
-<A NAME="SEC45"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC44"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC46"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 4.2 Portability issues </H2>
-<!--docid::SEC45::-->
-After some consideration, I have decided not to use
-GNU <CODE>autoconf</CODE> to configure 0.9.5 or 1.0.
-<P>
-
-<CODE>autoconf</CODE>, admirable and wonderful though it is, 
-mainly assists with portability problems between Unix-like
-platforms.  But <CODE>bzip2</CODE> doesn't have much in the way
-of portability problems on Unix; most of the difficulties appear
-when porting to the Mac, or to Microsoft's operating systems.
-<CODE>autoconf</CODE> doesn't help in those cases, and brings in a 
-whole load of new complexity.
-</P><P>
-
-Most people should be able to compile the library and program
-under Unix straight out-of-the-box, so to speak, especially 
-if you have a version of GNU C available.
-</P><P>
-
-There are a couple of <CODE>__inline__</CODE> directives in the code.  GNU C
-(<CODE>gcc</CODE>) should be able to handle them.  If you're not using
-GNU C, your C compiler shouldn't see them at all.
-If your compiler does, for some reason, see them and doesn't
-like them, just <CODE>#define</CODE> <CODE>__inline__</CODE> to be <CODE>/* */</CODE>.  One
-easy way to do this is to compile with the flag <CODE>-D__inline__=</CODE>, 
-which should be understood by most Unix compilers.
-</P><P>
-
-If you still have difficulties, try compiling with the macro
-<CODE>BZ_STRICT_ANSI</CODE> defined.  This should enable you to build the
-library in a strictly ANSI compliant environment.  Building the program
-itself like this is dangerous and not supported, since you remove
-<CODE>bzip2</CODE>'s checks against compressing directories, symbolic links,
-devices, and other not-really-a-file entities.  This could cause
-filesystem corruption!
-</P><P>
-
-One other thing: if you create a <CODE>bzip2</CODE> binary for public
-distribution, please try and link it statically (<CODE>gcc -s</CODE>).  This
-avoids all sorts of library-version issues that others may encounter
-later on.
-</P><P>
-
-If you build <CODE>bzip2</CODE> on Win32, you must set <CODE>BZ_UNIX</CODE> to 0 and
-<CODE>BZ_LCCWIN32</CODE> to 1, in the file <CODE>bzip2.c</CODE>, before compiling.
-Otherwise the resulting binary won't work correctly.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC46"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC45"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC47"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 4.3 Reporting bugs </H2>
-<!--docid::SEC46::-->
-I tried pretty hard to make sure <CODE>bzip2</CODE> is
-bug free, both by design and by testing.  Hopefully
-you'll never need to read this section for real.
-<P>
-
-Nevertheless, if <CODE>bzip2</CODE> dies with a segmentation
-fault, a bus error or an internal assertion failure, it
-will ask you to email me a bug report.  Experience with
-version 0.1 shows that almost all these problems can
-be traced to either compiler bugs or hardware problems.
-<UL>
-<LI>
-Recompile the program with no optimisation, and see if it
-works.  And/or try a different compiler.
-I heard all sorts of stories about various flavours
-of GNU C (and other compilers) generating bad code for
-<CODE>bzip2</CODE>, and I've run across two such examples myself.
-<P>
-
-2.7.X versions of GNU C are known to generate bad code from
-time to time, at high optimisation levels.  
-If you get problems, try using the flags
-<CODE>-O2</CODE> <CODE>-fomit-frame-pointer</CODE> <CODE>-fno-strength-reduce</CODE>.
-You should specifically <EM>not</EM> use <CODE>-funroll-loops</CODE>.
-</P><P>
-
-You may notice that the Makefile runs six tests as part of
-the build process.  If the program passes all of these, it's
-a pretty good (but not 100%) indication that the compiler has
-done its job correctly.
-<LI>
-If <CODE>bzip2</CODE> crashes randomly, and the crashes are not
-repeatable, you may have a flaky memory subsystem.  <CODE>bzip2</CODE>
-really hammers your memory hierarchy, and if it's a bit marginal,
-you may get these problems.  Ditto if your disk or I/O subsystem
-is slowly failing.  Yup, this really does happen.
-<P>
-
-Try using a different machine of the same type, and see if
-you can repeat the problem.
-<LI>This isn't really a bug, but ... If <CODE>bzip2</CODE> tells
-you your file is corrupted on decompression, and you
-obtained the file via FTP, there is a possibility that you
-forgot to tell FTP to do a binary mode transfer.  That absolutely
-will cause the file to be non-decompressible.  You'll have to transfer
-it again.
-</UL>
-<P>
-
-If you've incorporated <CODE>libbzip2</CODE> into your own program
-and are getting problems, please, please, please, check that the 
-parameters you are passing in calls to the library, are
-correct, and in accordance with what the documentation says
-is allowable.  I have tried to make the library robust against
-such problems, but I'm sure I haven't succeeded.
-</P><P>
-
-Finally, if the above comments don't help, you'll have to send
-me a bug report.  Now, it's just amazing how many people will 
-send me a bug report saying something like
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">   bzip2 crashed with segmentation fault on my machine
-</pre></td></tr></table>and absolutely nothing else.  Needless to say, a such a report
-is <EM>totally, utterly, completely and comprehensively 100% useless; 
-a waste of your time, my time, and net bandwidth</EM>.
-With no details at all, there's no way I can possibly begin
-to figure out what the problem is.
-</P><P>
-
-The rules of the game are: facts, facts, facts.  Don't omit
-them because "oh, they won't be relevant".  At the bare 
-minimum:
-<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">   Machine type.  Operating system version.  
-   Exact version of <CODE>bzip2</CODE> (do <CODE>bzip2 -V</CODE>).  
-   Exact version of the compiler used.  
-   Flags passed to the compiler.
-</pre></td></tr></table>However, the most important single thing that will help me is
-the file that you were trying to compress or decompress at the
-time the problem happened.  Without that, my ability to do anything
-more than speculate about the cause, is limited.
-</P><P>
-
-Please remember that I connect to the Internet with a modem, so
-you should contact me before mailing me huge files.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC47"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC46"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC48"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 4.4 Did you get the right package? </H2>
-<!--docid::SEC47::-->
-<P>
-
-<CODE>bzip2</CODE> is a resource hog.  It soaks up large amounts of CPU cycles
-and memory.  Also, it gives very large latencies.  In the worst case, you
-can feed many megabytes of uncompressed data into the library before
-getting any compressed output, so this probably rules out applications
-requiring interactive behaviour.
-</P><P>
-
-These aren't faults of my implementation, I hope, but more
-an intrinsic property of the Burrows-Wheeler transform (unfortunately).  
-Maybe this isn't what you want.
-</P><P>
-
-If you want a compressor and/or library which is faster, uses less
-memory but gets pretty good compression, and has minimal latency,
-consider Jean-loup
-Gailly's and Mark Adler's work, <CODE>zlib-1.1.3</CODE> and
-<CODE>gzip-1.2.4</CODE>.  Look for them at
-</P><P>
-
-<CODE>http://www.zlib.org</CODE> and
-<CODE>http://www.gzip.org</CODE> respectively.
-</P><P>
-
-For something faster and lighter still, you might try Markus F X J
-Oberhumer's <CODE>LZO</CODE> real-time compression/decompression library, at
-<BR> <CODE>http://wildsau.idv.uni-linz.ac.at/mfx/lzo.html</CODE>.
-</P><P>
-
-If you want to use the <CODE>bzip2</CODE> algorithms to compress small blocks
-of data, 64k bytes or smaller, for example on an on-the-fly disk
-compressor, you'd be well advised not to use this library.  Instead,
-I've made a special library tuned for that kind of use.  It's part of
-<CODE>e2compr-0.40</CODE>, an on-the-fly disk compressor for the Linux
-<CODE>ext2</CODE> filesystem.  Look at
-<CODE>http://www.netspace.net.au/~reiter/e2compr</CODE>.
-</P><P>
-
-<HR SIZE="6">
-<A NAME="SEC48"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC47"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC49"> > </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 4.5 Testing </H2>
-<!--docid::SEC48::-->
-<P>
-
-A record of the tests I've done.
-</P><P>
-
-First, some data sets:
-<UL>
-<LI>B: a directory containing 6001 files, one for every length in the
-      range 0 to 6000 bytes.  The files contain random lowercase
-      letters.  18.7 megabytes.
-<LI>H: my home directory tree.  Documents, source code, mail files,
-      compressed data.  H contains B, and also a directory of 
-      files designed as boundary cases for the sorting; mostly very
-      repetitive, nasty files.  565 megabytes.
-<LI>A: directory tree holding various applications built from source:
-      <CODE>egcs</CODE>, <CODE>gcc-2.8.1</CODE>, KDE, GTK, Octave, etc.
-      2200 megabytes.
-</UL>
-The tests conducted are as follows.  Each test means compressing 
-(a copy of) each file in the data set, decompressing it and
-comparing it against the original.
-<P>
-
-First, a bunch of tests with block sizes and internal buffer
-sizes set very small, 
-to detect any problems with the
-blocking and buffering mechanisms.  
-This required modifying the source code so as to try to 
-break it.
-<OL>
-<LI>Data set H, with
-      buffer size of 1 byte, and block size of 23 bytes.
-<LI>Data set B, buffer sizes 1 byte, block size 1 byte.
-<LI>As (2) but small-mode decompression.
-<LI>As (2) with block size 2 bytes.
-<LI>As (2) with block size 3 bytes.
-<LI>As (2) with block size 4 bytes.
-<LI>As (2) with block size 5 bytes.
-<LI>As (2) with block size 6 bytes and small-mode decompression.
-<LI>H with buffer size of 1 byte, but normal block
-      size (up to 900000 bytes).
-</OL>
-Then some tests with unmodified source code.
-<OL>
-<LI>H, all settings normal.
-<LI>As (1), with small-mode decompress.
-<LI>H, compress with flag <CODE>-1</CODE>.
-<LI>H, compress with flag <CODE>-s</CODE>, decompress with flag <CODE>-s</CODE>.
-<LI>Forwards compatibility: H, <CODE>bzip2-0.1pl2</CODE> compressing,
-      <CODE>bzip2-0.9.5</CODE> decompressing, all settings normal.
-<LI>Backwards compatibility:  H, <CODE>bzip2-0.9.5</CODE> compressing,
-      <CODE>bzip2-0.1pl2</CODE> decompressing, all settings normal.
-<LI>Bigger tests: A, all settings normal.
-<LI>As (7), using the fallback (Sadakane-like) sorting algorithm.
-<LI>As (8), compress with flag <CODE>-1</CODE>, decompress with flag
-      <CODE>-s</CODE>.
-<LI>H, using the fallback sorting algorithm.
-<LI>Forwards compatibility: A, <CODE>bzip2-0.1pl2</CODE> compressing,
-      <CODE>bzip2-0.9.5</CODE> decompressing, all settings normal.
-<LI>Backwards compatibility:  A, <CODE>bzip2-0.9.5</CODE> compressing,
-      <CODE>bzip2-0.1pl2</CODE> decompressing, all settings normal.
-<LI>Misc test: about 400 megabytes of <CODE>.tar</CODE> files with
-      <CODE>bzip2</CODE> compiled with Checker (a memory access error
-       detector, like Purify).
-<LI>Misc tests to make sure it builds and runs ok on non-Linux/x86
-      platforms.
-</OL>
-These tests were conducted on a 225 MHz IDT WinChip machine, running
-Linux 2.0.36.  They represent nearly a week of continuous computation.
-All tests completed successfully.
-<P>
-
-<HR SIZE="6">
-<A NAME="SEC49"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_4.html#SEC48"> < </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ > ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top"> Up </A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H2> 4.6 Further reading </H2>
-<!--docid::SEC49::-->
-<CODE>bzip2</CODE> is not research work, in the sense that it doesn't present
-any new ideas.  Rather, it's an engineering exercise based on existing
-ideas.
-<P>
-
-Four documents describe essentially all the ideas behind <CODE>bzip2</CODE>:
-<TABLE><tr><td> </td><td class=example><pre>Michael Burrows and D. J. Wheeler:
-  "A block-sorting lossless data compression algorithm"
-   10th May 1994. 
-   Digital SRC Research Report 124.
-   ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz
-   If you have trouble finding it, try searching at the
-   New Zealand Digital Library, http://www.nzdl.org.
-
-Daniel S. Hirschberg and Debra A. LeLewer
-  "Efficient Decoding of Prefix Codes"
-   Communications of the ACM, April 1990, Vol 33, Number 4.
-   You might be able to get an electronic copy of this
-      from the ACM Digital Library.
-
-David J. Wheeler
-   Program bred3.c and accompanying document bred3.ps.
-   This contains the idea behind the multi-table Huffman
-   coding scheme.
-   ftp://ftp.cl.cam.ac.uk/users/djw3/
-
-Jon L. Bentley and Robert Sedgewick
-  "Fast Algorithms for Sorting and Searching Strings"
-   Available from Sedgewick's web page,
-   www.cs.princeton.edu/~rs
-</pre></td></tr></table>The following paper gives valuable additional insights into the
-algorithm, but is not immediately the basis of any code
-used in bzip2.
-<TABLE><tr><td> </td><td class=example><pre>Peter Fenwick:
-   Block Sorting Text Compression
-   Proceedings of the 19th Australasian Computer Science Conference,
-     Melbourne, Australia.  Jan 31 - Feb 2, 1996.
-   ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps
-</pre></td></tr></table>Kunihiko Sadakane's sorting algorithm, mentioned above,
-is available from:
-<TABLE><tr><td> </td><td class=example><pre>http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz
-</pre></td></tr></table>The Manber-Myers suffix array construction
-algorithm is described in a paper
-available from:
-<TABLE><tr><td> </td><td class=example><pre>http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps
-</pre></td></tr></table>Finally, the following paper documents some recent investigations
-I made into the performance of sorting algorithms:
-<TABLE><tr><td> </td><td class=example><pre>Julian Seward:
-   On the Performance of BWT Sorting Algorithms
-   Proceedings of the IEEE Data Compression Conference 2000
-     Snowbird, Utah.  28-30 March 2000.
-</pre></td></tr></table></P><P>
-
-<HR SIZE="6">
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">   <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<BR>  
-<FONT SIZE="-1">
-This document was generated
-by <I>Julian Seward</I> on <I>January, 5  2002</I>
-using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
-"><I>texi2html</I></A>
-
-</BODY>
-</HTML>
diff --git a/c++/src/util/compress/bzip2/manual_abt.html b/c++/src/util/compress/bzip2/manual_abt.html
deleted file mode 100644
index d7f5472..0000000
--- a/c++/src/util/compress/bzip2/manual_abt.html
+++ /dev/null
@@ -1,201 +0,0 @@
-<HTML>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<!-- Created on January, 5  2002 by texi2html 1.64 -->
-<!-- 
-Written by: Lionel Cons <Lionel.Cons at cern.ch> (original author)
-            Karl Berry  <karl at freefriends.org>
-            Olaf Bachmann <obachman at mathematik.uni-kl.de>
-            and many others.
-Maintained by: Olaf Bachmann <obachman at mathematik.uni-kl.de>
-Send bugs and suggestions to <texi2html at mathematik.uni-kl.de>
- 
--->
-<HEAD>
-<TITLE>Untitled Document: About this document</TITLE>
-
-<META NAME="description" CONTENT="Untitled Document: About this document">
-<META NAME="keywords" CONTENT="Untitled Document: About this document">
-<META NAME="resource-type" CONTENT="document">
-<META NAME="distribution" CONTENT="global">
-<META NAME="Generator" CONTENT="texi2html 1.64">
-
-</HEAD>
-
-<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
-
-<A NAME="SEC_About"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H1>About this document</H1>
-This document was generated by <I>Julian Seward</I> on <I>January, 5  2002</I>
-using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
-"><I>texi2html</I></A>
-<P></P>  
-The buttons in the navigation panels have the following meaning:
-<P></P>
-<table border = "1">
-<TR>
-<TH> Button </TH>
-<TH> Name </TH>
-<TH> Go to </TH>
-<TH> From 1.2.3 go to</TH>
-</TR>
-<TR>
-<TD ALIGN="CENTER">
- [ < ] </TD>
-<TD ALIGN="CENTER">
-Back
-</TD>
-<TD>
-previous section in reading order
-</TD>
-<TD>
-1.2.2
-</TD>
-</TR>
-<TR>
-<TD ALIGN="CENTER">
- [ > ] </TD>
-<TD ALIGN="CENTER">
-Forward
-</TD>
-<TD>
-next section in reading order
-</TD>
-<TD>
-1.2.4
-</TD>
-</TR>
-<TR>
-<TD ALIGN="CENTER">
- [ << ] </TD>
-<TD ALIGN="CENTER">
-FastBack
-</TD>
-<TD>
-previous or up-and-previous section 
-</TD>
-<TD>
-1.1
-</TD>
-</TR>
-<TR>
-<TD ALIGN="CENTER">
- [ Up ] </TD>
-<TD ALIGN="CENTER">
-Up
-</TD>
-<TD>
-up section
-</TD>
-<TD>
-1.2
-</TD>
-</TR>
-<TR>
-<TD ALIGN="CENTER">
- [ >> ] </TD>
-<TD ALIGN="CENTER">
-FastForward
-</TD>
-<TD>
-next or up-and-next section
-</TD>
-<TD>
-1.3
-</TD>
-</TR>
-<TR>
-<TD ALIGN="CENTER">
- [Top] </TD>
-<TD ALIGN="CENTER">
-Top
-</TD>
-<TD>
-cover (top) of document
-</TD>
-<TD>
-   
-</TD>
-</TR>
-<TR>
-<TD ALIGN="CENTER">
- [Contents] </TD>
-<TD ALIGN="CENTER">
-Contents
-</TD>
-<TD>
-table of contents
-</TD>
-<TD>
-   
-</TD>
-</TR>
-<TR>
-<TD ALIGN="CENTER">
- [Index] </TD>
-<TD ALIGN="CENTER">
-Index
-</TD>
-<TD>
-concept index
-</TD>
-<TD>
-   
-</TD>
-</TR>
-<TR>
-<TD ALIGN="CENTER">
- [ ? ] </TD>
-<TD ALIGN="CENTER">
-About
-</TD>
-<TD>
-this page
-</TD>
-<TD>
-   
-</TD>
-</TR>
-</TABLE>
-<P></P>
-where the <STRONG> Example </STRONG> assumes that the current position 
-is at <STRONG> Subsubsection One-Two-Three </STRONG> of a document of 
-the following structure:
-<UL>
-<LI> 1. Section One  </LI>
-<UL>
-<LI>1.1 Subsection One-One</LI>
-<UL>
-<LI> ... </LI>
-</UL>
-<LI>1.2 Subsection One-Two</LI>
-<UL>
-<LI>1.2.1 Subsubsection One-Two-One
-</LI><LI>1.2.2 Subsubsection One-Two-Two
-</LI><LI>1.2.3 Subsubsection One-Two-Three     <STRONG>
-<== Current Position </STRONG>
-</LI><LI>1.2.4 Subsubsection One-Two-Four
-</LI></UL>
-<LI>1.3 Subsection One-Three</LI>
-<UL>
-<LI> ... </LI>
-</UL>
-<LI>1.4 Subsection One-Four</LI>
-</UL>
-</UL>
-
-<HR SIZE=1>
-<BR>  
-<FONT SIZE="-1">
-This document was generated
-by <I>Julian Seward</I> on <I>January, 5  2002</I>
-using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
-"><I>texi2html</I></A>
-
-</BODY>
-</HTML>
diff --git a/c++/src/util/compress/bzip2/manual_ovr.html b/c++/src/util/compress/bzip2/manual_ovr.html
deleted file mode 100644
index 3b102b9..0000000
--- a/c++/src/util/compress/bzip2/manual_ovr.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<HTML>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<!-- Created on January, 5  2002 by texi2html 1.64 -->
-<!-- 
-Written by: Lionel Cons <Lionel.Cons at cern.ch> (original author)
-            Karl Berry  <karl at freefriends.org>
-            Olaf Bachmann <obachman at mathematik.uni-kl.de>
-            and many others.
-Maintained by: Olaf Bachmann <obachman at mathematik.uni-kl.de>
-Send bugs and suggestions to <texi2html at mathematik.uni-kl.de>
- 
--->
-<HEAD>
-<TITLE>Untitled Document: Short Table of Contents</TITLE>
-
-<META NAME="description" CONTENT="Untitled Document: Short Table of Contents">
-<META NAME="keywords" CONTENT="Untitled Document: Short Table of Contents">
-<META NAME="resource-type" CONTENT="document">
-<META NAME="distribution" CONTENT="global">
-<META NAME="Generator" CONTENT="texi2html 1.64">
-
-</HEAD>
-
-<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
-
-<A NAME="SEC_OVERVIEW"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H1>Short Table of Contents</H1>
-<BLOCKQUOTE>
-<A NAME="TOC1" HREF="manual_1.html#SEC1">1. Introduction</A>
-<BR>
-<A NAME="TOC2" HREF="manual_2.html#SEC2">2. How to use <CODE>bzip2</CODE></A>
-<BR>
-<A NAME="TOC12" HREF="manual_3.html#SEC12">3. Programming with <CODE>libbzip2</CODE></A>
-<BR>
-<A NAME="TOC43" HREF="manual_4.html#SEC43">4. Miscellanea</A>
-<BR>
-
-</BLOCKQUOTE>
-<HR SIZE=1>
-<BR>  
-<FONT SIZE="-1">
-This document was generated
-by <I>Julian Seward</I> on <I>January, 5  2002</I>
-using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
-"><I>texi2html</I></A>
-
-</BODY>
-</HTML>
diff --git a/c++/src/util/compress/bzip2/manual_toc.html b/c++/src/util/compress/bzip2/manual_toc.html
deleted file mode 100644
index bc08705..0000000
--- a/c++/src/util/compress/bzip2/manual_toc.html
+++ /dev/null
@@ -1,163 +0,0 @@
-<HTML>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<!-- Created on January, 5  2002 by texi2html 1.64 -->
-<!-- 
-Written by: Lionel Cons <Lionel.Cons at cern.ch> (original author)
-            Karl Berry  <karl at freefriends.org>
-            Olaf Bachmann <obachman at mathematik.uni-kl.de>
-            and many others.
-Maintained by: Olaf Bachmann <obachman at mathematik.uni-kl.de>
-Send bugs and suggestions to <texi2html at mathematik.uni-kl.de>
- 
--->
-<HEAD>
-<TITLE>Untitled Document: Table of Contents</TITLE>
-
-<META NAME="description" CONTENT="Untitled Document: Table of Contents">
-<META NAME="keywords" CONTENT="Untitled Document: Table of Contents">
-<META NAME="resource-type" CONTENT="document">
-<META NAME="distribution" CONTENT="global">
-<META NAME="Generator" CONTENT="texi2html 1.64">
-
-</HEAD>
-
-<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
-
-<A NAME="SEC_Contents"></A>
-<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
-<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual.html#SEC_Top">Top</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_toc.html#SEC_Contents">Contents</A>]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
-<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="manual_abt.html#SEC_About"> ? </A>]</TD>
-</TR></TABLE>
-<H1>Table of Contents</H1>
-<UL>
-<A NAME="TOC1" HREF="manual_1.html#SEC1">1. Introduction</A>
-<BR>
-<A NAME="TOC2" HREF="manual_2.html#SEC2">2. How to use <CODE>bzip2</CODE></A>
-<BR>
-<UL>
-<UL>
-<UL>
-<A NAME="TOC3" HREF="manual_2.html#SEC3">NAME</A>
-<BR>
-<A NAME="TOC4" HREF="manual_2.html#SEC4">SYNOPSIS</A>
-<BR>
-<A NAME="TOC5" HREF="manual_2.html#SEC5">DESCRIPTION</A>
-<BR>
-<A NAME="TOC6" HREF="manual_2.html#SEC6">OPTIONS</A>
-<BR>
-<A NAME="TOC7" HREF="manual_2.html#SEC7">MEMORY MANAGEMENT</A>
-<BR>
-<A NAME="TOC8" HREF="manual_2.html#SEC8">RECOVERING DATA FROM DAMAGED FILES</A>
-<BR>
-<A NAME="TOC9" HREF="manual_2.html#SEC9">PERFORMANCE NOTES</A>
-<BR>
-<A NAME="TOC10" HREF="manual_2.html#SEC10">CAVEATS</A>
-<BR>
-<A NAME="TOC11" HREF="manual_2.html#SEC11">AUTHOR</A>
-<BR>
-</UL>
-</UL>
-</UL>
-<A NAME="TOC12" HREF="manual_3.html#SEC12">3. Programming with <CODE>libbzip2</CODE></A>
-<BR>
-<UL>
-<A NAME="TOC13" HREF="manual_3.html#SEC13">3.1 Top-level structure</A>
-<BR>
-<UL>
-<A NAME="TOC14" HREF="manual_3.html#SEC14">3.1.1 Low-level summary</A>
-<BR>
-<A NAME="TOC15" HREF="manual_3.html#SEC15">3.1.2 High-level summary</A>
-<BR>
-<A NAME="TOC16" HREF="manual_3.html#SEC16">3.1.3 Utility functions summary</A>
-<BR>
-</UL>
-<A NAME="TOC17" HREF="manual_3.html#SEC17">3.2 Error handling</A>
-<BR>
-<A NAME="TOC18" HREF="manual_3.html#SEC18">3.3 Low-level interface</A>
-<BR>
-<UL>
-<A NAME="TOC19" HREF="manual_3.html#SEC19">3.3.1 <CODE>BZ2_bzCompressInit</CODE></A>
-<BR>
-<A NAME="TOC20" HREF="manual_3.html#SEC20">3.3.2 <CODE>BZ2_bzCompress</CODE></A>
-<BR>
-<A NAME="TOC21" HREF="manual_3.html#SEC21">3.3.3 <CODE>BZ2_bzCompressEnd</CODE></A>
-<BR>
-<A NAME="TOC22" HREF="manual_3.html#SEC22">3.3.4 <CODE>BZ2_bzDecompressInit</CODE></A>
-<BR>
-<A NAME="TOC23" HREF="manual_3.html#SEC23">3.3.5 <CODE>BZ2_bzDecompress</CODE></A>
-<BR>
-<A NAME="TOC24" HREF="manual_3.html#SEC24">3.3.6 <CODE>BZ2_bzDecompressEnd</CODE></A>
-<BR>
-</UL>
-<A NAME="TOC25" HREF="manual_3.html#SEC25">3.4 High-level interface</A>
-<BR>
-<UL>
-<A NAME="TOC26" HREF="manual_3.html#SEC26">3.4.1 <CODE>BZ2_bzReadOpen</CODE></A>
-<BR>
-<A NAME="TOC27" HREF="manual_3.html#SEC27">3.4.2 <CODE>BZ2_bzRead</CODE></A>
-<BR>
-<A NAME="TOC28" HREF="manual_3.html#SEC28">3.4.3 <CODE>BZ2_bzReadGetUnused</CODE></A>
-<BR>
-<A NAME="TOC29" HREF="manual_3.html#SEC29">3.4.4 <CODE>BZ2_bzReadClose</CODE></A>
-<BR>
-<A NAME="TOC30" HREF="manual_3.html#SEC30">3.4.5 <CODE>BZ2_bzWriteOpen</CODE></A>
-<BR>
-<A NAME="TOC31" HREF="manual_3.html#SEC31">3.4.6 <CODE>BZ2_bzWrite</CODE></A>
-<BR>
-<A NAME="TOC32" HREF="manual_3.html#SEC32">3.4.7 <CODE>BZ2_bzWriteClose</CODE></A>
-<BR>
-<A NAME="TOC33" HREF="manual_3.html#SEC33">3.4.8 Handling embedded compressed data streams</A>
-<BR>
-<A NAME="TOC34" HREF="manual_3.html#SEC34">3.4.9 Standard file-reading/writing code</A>
-<BR>
-</UL>
-<A NAME="TOC35" HREF="manual_3.html#SEC35">3.5 Utility functions</A>
-<BR>
-<UL>
-<A NAME="TOC36" HREF="manual_3.html#SEC36">3.5.1 <CODE>BZ2_bzBuffToBuffCompress</CODE></A>
-<BR>
-<A NAME="TOC37" HREF="manual_3.html#SEC37">3.5.2 <CODE>BZ2_bzBuffToBuffDecompress</CODE></A>
-<BR>
-</UL>
-<A NAME="TOC38" HREF="manual_3.html#SEC38">3.6 <CODE>zlib</CODE> compatibility functions</A>
-<BR>
-<A NAME="TOC39" HREF="manual_3.html#SEC39">3.7 Using the library in a <CODE>stdio</CODE>-free environment</A>
-<BR>
-<UL>
-<A NAME="TOC40" HREF="manual_3.html#SEC40">3.7.1 Getting rid of <CODE>stdio</CODE></A>
-<BR>
-<A NAME="TOC41" HREF="manual_3.html#SEC41">3.7.2 Critical error handling</A>
-<BR>
-</UL>
-<A NAME="TOC42" HREF="manual_3.html#SEC42">3.8 Making a Windows DLL</A>
-<BR>
-</UL>
-<A NAME="TOC43" HREF="manual_4.html#SEC43">4. Miscellanea</A>
-<BR>
-<UL>
-<A NAME="TOC44" HREF="manual_4.html#SEC44">4.1 Limitations of the compressed file format</A>
-<BR>
-<A NAME="TOC45" HREF="manual_4.html#SEC45">4.2 Portability issues</A>
-<BR>
-<A NAME="TOC46" HREF="manual_4.html#SEC46">4.3 Reporting bugs</A>
-<BR>
-<A NAME="TOC47" HREF="manual_4.html#SEC47">4.4 Did you get the right package?</A>
-<BR>
-<A NAME="TOC48" HREF="manual_4.html#SEC48">4.5 Testing</A>
-<BR>
-<A NAME="TOC49" HREF="manual_4.html#SEC49">4.6 Further reading</A>
-<BR>
-</UL>
-</UL>
-<HR SIZE=1>
-<BR>  
-<FONT SIZE="-1">
-This document was generated
-by <I>Julian Seward</I> on <I>January, 5  2002</I>
-using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
-"><I>texi2html</I></A>
-
-</BODY>
-</HTML>
diff --git a/c++/src/util/compress/bzip2/mk251.c b/c++/src/util/compress/bzip2/mk251.c
index 205778a..c9c36f6 100644
--- a/c++/src/util/compress/bzip2/mk251.c
+++ b/c++/src/util/compress/bzip2/mk251.c
@@ -5,6 +5,21 @@
    case, which is fixed in this version (1.0.2) and above.
 */
 
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
 #include <stdio.h>
 
 int main ()
diff --git a/c++/src/util/compress/bzip2/ncbi_bz2_compress.c b/c++/src/util/compress/bzip2/ncbi_bz2_compress.c
index cb7ab9f..caf7696 100644
--- a/c++/src/util/compress/bzip2/ncbi_bz2_compress.c
+++ b/c++/src/util/compress/bzip2/ncbi_bz2_compress.c
@@ -1,34 +1,672 @@
-/* $Id: ncbi_bz2_compress.c 99676 2007-03-05 20:41:55Z kazimird $
- * ===========================================================================
- *
- *                            PUBLIC DOMAIN NOTICE
- *               National Center for Biotechnology Information
- *
- *  This software/database is a "United States Government Work" under the
- *  terms of the United States Copyright Act.  It was written as part of
- *  the author's official duties as a United States Government employee and
- *  thus cannot be copyrighted.  This software/database is freely available
- *  to the public for use. The National Library of Medicine and the U.S.
- *  Government have not placed any restriction on its use or reproduction.
- *
- *  Although all reasonable efforts have been taken to ensure the accuracy
- *  and reliability of the software and data, the NLM and the U.S.
- *  Government do not and cannot warrant the performance or results that
- *  may be obtained by using this software or data. The NLM and the U.S.
- *  Government disclaim all warranties, express or implied, including
- *  warranties of performance, merchantability or fitness for any particular
- *  purpose.
- *
- *  Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- * Author:  Viatcheslav Gorelenkov
- *
- */
-// A workaround for problem with several "compress" source in different libs:
-// z, bz2 and xcompress has source file with name "compress",
-// and it's impossible to combine these libs to one shared dll.
-
-// This will produce different object file from "compress" source:
-#include "compress.c"
+
+/*-------------------------------------------------------------*/
+/*--- Compression machinery (not incl block sorting)        ---*/
+/*---                                            compress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+/* CHANGES
+    0.9.0    -- original version.
+    0.9.0a/b -- no changes in this file.
+    0.9.0c   -- changed setting of nGroups in sendMTFValues() 
+                so as to do a bit better on small files
+*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O                              ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+void BZ2_bsInitWrite ( EState* s )
+{
+   s->bsLive = 0;
+   s->bsBuff = 0;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsFinishWrite ( EState* s )
+{
+   while (s->bsLive > 0) {
+      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
+      s->numZ++;
+      s->bsBuff <<= 8;
+      s->bsLive -= 8;
+   }
+}
+
+
+/*---------------------------------------------------*/
+#define bsNEEDW(nz)                           \
+{                                             \
+   while (s->bsLive >= 8) {                   \
+      s->zbits[s->numZ]                       \
+         = (UChar)(s->bsBuff >> 24);          \
+      s->numZ++;                              \
+      s->bsBuff <<= 8;                        \
+      s->bsLive -= 8;                         \
+   }                                          \
+}
+
+
+/*---------------------------------------------------*/
+static
+__inline__
+void bsW ( EState* s, Int32 n, UInt32 v )
+{
+   bsNEEDW ( n );
+   s->bsBuff |= (v << (32 - s->bsLive - n));
+   s->bsLive += n;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUInt32 ( EState* s, UInt32 u )
+{
+   bsW ( s, 8, (u >> 24) & 0xffL );
+   bsW ( s, 8, (u >> 16) & 0xffL );
+   bsW ( s, 8, (u >>  8) & 0xffL );
+   bsW ( s, 8,  u        & 0xffL );
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUChar ( EState* s, UChar c )
+{
+   bsW( s, 8, (UInt32)c );
+}
+
+
+/*---------------------------------------------------*/
+/*--- The back end proper                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+static
+void makeMaps_e ( EState* s )
+{
+   Int32 i;
+   s->nInUse = 0;
+   for (i = 0; i < 256; i++)
+      if (s->inUse[i]) {
+         s->unseqToSeq[i] = s->nInUse;
+         s->nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+static
+void generateMTFValues ( EState* s )
+{
+   UChar   yy[256];
+   Int32   i, j;
+   Int32   zPend;
+   Int32   wr;
+   Int32   EOB;
+
+   /* 
+      After sorting (eg, here),
+         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
+         and
+         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] 
+         holds the original block data.
+
+      The first thing to do is generate the MTF values,
+      and put them in
+         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
+      Because there are strictly fewer or equal MTF values
+      than block values, ptr values in this area are overwritten
+      with MTF values only when they are no longer needed.
+
+      The final compressed bitstream is generated into the
+      area starting at
+         (UChar*) (&((UChar*)s->arr2)[s->nblock])
+
+      These storage aliases are set up in bzCompressInit(),
+      except for the last one, which is arranged in 
+      compressBlock().
+   */
+   UInt32* ptr   = s->ptr;
+   UChar* block  = s->block;
+   UInt16* mtfv  = s->mtfv;
+
+   makeMaps_e ( s );
+   EOB = s->nInUse+1;
+
+   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
+
+   wr = 0;
+   zPend = 0;
+   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
+
+   for (i = 0; i < s->nblock; i++) {
+      UChar ll_i;
+      AssertD ( wr <= i, "generateMTFValues(1)" );
+      j = ptr[i]-1; if (j < 0) j += s->nblock;
+      ll_i = s->unseqToSeq[block[j]];
+      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
+
+      if (yy[0] == ll_i) { 
+         zPend++;
+      } else {
+
+         if (zPend > 0) {
+            zPend--;
+            while (True) {
+               if (zPend & 1) {
+                  mtfv[wr] = BZ_RUNB; wr++; 
+                  s->mtfFreq[BZ_RUNB]++; 
+               } else {
+                  mtfv[wr] = BZ_RUNA; wr++; 
+                  s->mtfFreq[BZ_RUNA]++; 
+               }
+               if (zPend < 2) break;
+               zPend = (zPend - 2) / 2;
+            };
+            zPend = 0;
+         }
+         {
+            register UChar  rtmp;
+            register UChar* ryy_j;
+            register UChar  rll_i;
+            rtmp  = yy[1];
+            yy[1] = yy[0];
+            ryy_j = &(yy[1]);
+            rll_i = ll_i;
+            while ( rll_i != rtmp ) {
+               register UChar rtmp2;
+               ryy_j++;
+               rtmp2  = rtmp;
+               rtmp   = *ryy_j;
+               *ryy_j = rtmp2;
+            };
+            yy[0] = rtmp;
+            j = ryy_j - &(yy[0]);
+            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
+         }
+
+      }
+   }
+
+   if (zPend > 0) {
+      zPend--;
+      while (True) {
+         if (zPend & 1) {
+            mtfv[wr] = BZ_RUNB; wr++; 
+            s->mtfFreq[BZ_RUNB]++; 
+         } else {
+            mtfv[wr] = BZ_RUNA; wr++; 
+            s->mtfFreq[BZ_RUNA]++; 
+         }
+         if (zPend < 2) break;
+         zPend = (zPend - 2) / 2;
+      };
+      zPend = 0;
+   }
+
+   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
+
+   s->nMTF = wr;
+}
+
+
+/*---------------------------------------------------*/
+#define BZ_LESSER_ICOST  0
+#define BZ_GREATER_ICOST 15
+
+static
+void sendMTFValues ( EState* s )
+{
+   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
+   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
+   Int32 nGroups, nBytes;
+
+   /*--
+   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   is a global since the decoder also needs it.
+
+   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   are also globals only used in this proc.
+   Made global to keep stack frame size small.
+   --*/
+
+
+   UInt16 cost[BZ_N_GROUPS];
+   Int32  fave[BZ_N_GROUPS];
+
+   UInt16* mtfv = s->mtfv;
+
+   if (s->verbosity >= 3)
+      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
+                "%d+2 syms in use\n", 
+                s->nblock, s->nMTF, s->nInUse );
+
+   alphaSize = s->nInUse+2;
+   for (t = 0; t < BZ_N_GROUPS; t++)
+      for (v = 0; v < alphaSize; v++)
+         s->len[t][v] = BZ_GREATER_ICOST;
+
+   /*--- Decide how many coding tables to use ---*/
+   AssertH ( s->nMTF > 0, 3001 );
+   if (s->nMTF < 200)  nGroups = 2; else
+   if (s->nMTF < 600)  nGroups = 3; else
+   if (s->nMTF < 1200) nGroups = 4; else
+   if (s->nMTF < 2400) nGroups = 5; else
+                       nGroups = 6;
+
+   /*--- Generate an initial set of coding tables ---*/
+   { 
+      Int32 nPart, remF, tFreq, aFreq;
+
+      nPart = nGroups;
+      remF  = s->nMTF;
+      gs = 0;
+      while (nPart > 0) {
+         tFreq = remF / nPart;
+         ge = gs-1;
+         aFreq = 0;
+         while (aFreq < tFreq && ge < alphaSize-1) {
+            ge++;
+            aFreq += s->mtfFreq[ge];
+         }
+
+         if (ge > gs 
+             && nPart != nGroups && nPart != 1 
+             && ((nGroups-nPart) % 2 == 1)) {
+            aFreq -= s->mtfFreq[ge];
+            ge--;
+         }
+
+         if (s->verbosity >= 3)
+            VPrintf5( "      initial group %d, [%d .. %d], "
+                      "has %d syms (%4.1f%%)\n",
+                      nPart, gs, ge, aFreq, 
+                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
+ 
+         for (v = 0; v < alphaSize; v++)
+            if (v >= gs && v <= ge) 
+               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
+               s->len[nPart-1][v] = BZ_GREATER_ICOST;
+ 
+         nPart--;
+         gs = ge+1;
+         remF -= aFreq;
+      }
+   }
+
+   /*--- 
+      Iterate up to BZ_N_ITERS times to improve the tables.
+   ---*/
+   for (iter = 0; iter < BZ_N_ITERS; iter++) {
+
+      for (t = 0; t < nGroups; t++) fave[t] = 0;
+
+      for (t = 0; t < nGroups; t++)
+         for (v = 0; v < alphaSize; v++)
+            s->rfreq[t][v] = 0;
+
+      /*---
+        Set up an auxiliary length table which is used to fast-track
+	the common case (nGroups == 6). 
+      ---*/
+      if (nGroups == 6) {
+         for (v = 0; v < alphaSize; v++) {
+            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
+            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
+            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
+	 }
+      }
+
+      nSelectors = 0;
+      totc = 0;
+      gs = 0;
+      while (True) {
+
+         /*--- Set group start & end marks. --*/
+         if (gs >= s->nMTF) break;
+         ge = gs + BZ_G_SIZE - 1; 
+         if (ge >= s->nMTF) ge = s->nMTF-1;
+
+         /*-- 
+            Calculate the cost of this group as coded
+            by each of the coding tables.
+         --*/
+         for (t = 0; t < nGroups; t++) cost[t] = 0;
+
+         if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            register UInt32 cost01, cost23, cost45;
+            register UInt16 icv;
+            cost01 = cost23 = cost45 = 0;
+
+#           define BZ_ITER(nn)                \
+               icv = mtfv[gs+(nn)];           \
+               cost01 += s->len_pack[icv][0]; \
+               cost23 += s->len_pack[icv][1]; \
+               cost45 += s->len_pack[icv][2]; \
+
+            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
+            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
+            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
+            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
+            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
+            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
+            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
+            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
+            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
+            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
+
+#           undef BZ_ITER
+
+            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
+            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
+            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i <= ge; i++) { 
+               UInt16 icv = mtfv[i];
+               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
+            }
+         }
+ 
+         /*-- 
+            Find the coding table which is best for this group,
+            and record its identity in the selector table.
+         --*/
+         bc = 999999999; bt = -1;
+         for (t = 0; t < nGroups; t++)
+            if (cost[t] < bc) { bc = cost[t]; bt = t; };
+         totc += bc;
+         fave[bt]++;
+         s->selector[nSelectors] = bt;
+         nSelectors++;
+
+         /*-- 
+            Increment the symbol frequencies for the selected table.
+          --*/
+         if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+
+#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
+
+            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
+            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
+            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
+            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
+            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
+            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
+            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
+            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
+            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
+            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
+
+#           undef BZ_ITUR
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i <= ge; i++)
+               s->rfreq[bt][ mtfv[i] ]++;
+         }
+
+         gs = ge+1;
+      }
+      if (s->verbosity >= 3) {
+         VPrintf2 ( "      pass %d: size is %d, grp uses are ", 
+                   iter+1, totc/8 );
+         for (t = 0; t < nGroups; t++)
+            VPrintf1 ( "%d ", fave[t] );
+         VPrintf0 ( "\n" );
+      }
+
+      /*--
+        Recompute the tables based on the accumulated frequencies.
+      --*/
+      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See 
+         comment in huffman.c for details. */
+      for (t = 0; t < nGroups; t++)
+         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 
+                                 alphaSize, 17 /*20*/ );
+   }
+
+
+   AssertH( nGroups < 8, 3002 );
+   AssertH( nSelectors < 32768 &&
+            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
+            3003 );
+
+
+   /*--- Compute MTF values for the selectors. ---*/
+   {
+      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
+      for (i = 0; i < nGroups; i++) pos[i] = i;
+      for (i = 0; i < nSelectors; i++) {
+         ll_i = s->selector[i];
+         j = 0;
+         tmp = pos[j];
+         while ( ll_i != tmp ) {
+            j++;
+            tmp2 = tmp;
+            tmp = pos[j];
+            pos[j] = tmp2;
+         };
+         pos[0] = tmp;
+         s->selectorMtf[i] = j;
+      }
+   };
+
+   /*--- Assign actual codes for the tables. --*/
+   for (t = 0; t < nGroups; t++) {
+      minLen = 32;
+      maxLen = 0;
+      for (i = 0; i < alphaSize; i++) {
+         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+         if (s->len[t][i] < minLen) minLen = s->len[t][i];
+      }
+      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
+      AssertH ( !(minLen < 1),  3005 );
+      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 
+                          minLen, maxLen, alphaSize );
+   }
+
+   /*--- Transmit the mapping table. ---*/
+   { 
+      Bool inUse16[16];
+      for (i = 0; i < 16; i++) {
+          inUse16[i] = False;
+          for (j = 0; j < 16; j++)
+             if (s->inUse[i * 16 + j]) inUse16[i] = True;
+      }
+     
+      nBytes = s->numZ;
+      for (i = 0; i < 16; i++)
+         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
+
+      for (i = 0; i < 16; i++)
+         if (inUse16[i])
+            for (j = 0; j < 16; j++) {
+               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
+            }
+
+      if (s->verbosity >= 3) 
+         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
+   }
+
+   /*--- Now the selectors. ---*/
+   nBytes = s->numZ;
+   bsW ( s, 3, nGroups );
+   bsW ( s, 15, nSelectors );
+   for (i = 0; i < nSelectors; i++) { 
+      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
+      bsW(s,1,0);
+   }
+   if (s->verbosity >= 3)
+      VPrintf1( "selectors %d, ", s->numZ-nBytes );
+
+   /*--- Now the coding tables. ---*/
+   nBytes = s->numZ;
+
+   for (t = 0; t < nGroups; t++) {
+      Int32 curr = s->len[t][0];
+      bsW ( s, 5, curr );
+      for (i = 0; i < alphaSize; i++) {
+         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
+         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
+         bsW ( s, 1, 0 );
+      }
+   }
+
+   if (s->verbosity >= 3)
+      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
+
+   /*--- And finally, the block data proper ---*/
+   nBytes = s->numZ;
+   selCtr = 0;
+   gs = 0;
+   while (True) {
+      if (gs >= s->nMTF) break;
+      ge = gs + BZ_G_SIZE - 1; 
+      if (ge >= s->nMTF) ge = s->nMTF-1;
+      AssertH ( s->selector[selCtr] < nGroups, 3006 );
+
+      if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            UInt16 mtfv_i;
+            UChar* s_len_sel_selCtr 
+               = &(s->len[s->selector[selCtr]][0]);
+            Int32* s_code_sel_selCtr
+               = &(s->code[s->selector[selCtr]][0]);
+
+#           define BZ_ITAH(nn)                      \
+               mtfv_i = mtfv[gs+(nn)];              \
+               bsW ( s,                             \
+                     s_len_sel_selCtr[mtfv_i],      \
+                     s_code_sel_selCtr[mtfv_i] )
+
+            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
+            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
+            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
+            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
+            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
+            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
+            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
+            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
+            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
+            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
+
+#           undef BZ_ITAH
+
+      } else {
+	 /*--- slow version which correctly handles all situations ---*/
+         for (i = gs; i <= ge; i++) {
+            bsW ( s, 
+                  s->len  [s->selector[selCtr]] [mtfv[i]],
+                  s->code [s->selector[selCtr]] [mtfv[i]] );
+         }
+      }
+
+
+      gs = ge+1;
+      selCtr++;
+   }
+   AssertH( selCtr == nSelectors, 3007 );
+
+   if (s->verbosity >= 3)
+      VPrintf1( "codes %d\n", s->numZ-nBytes );
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_compressBlock ( EState* s, Bool is_last_block )
+{
+   if (s->nblock > 0) {
+
+      BZ_FINALISE_CRC ( s->blockCRC );
+      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
+      s->combinedCRC ^= s->blockCRC;
+      if (s->blockNo > 1) s->numZ = 0;
+
+      if (s->verbosity >= 2)
+         VPrintf4( "    block %d: crc = 0x%08x, "
+                   "combined CRC = 0x%08x, size = %d\n",
+                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
+
+      BZ2_blockSort ( s );
+   }
+
+   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
+
+   /*-- If this is the first block, create the stream header. --*/
+   if (s->blockNo == 1) {
+      BZ2_bsInitWrite ( s );
+      bsPutUChar ( s, BZ_HDR_B );
+      bsPutUChar ( s, BZ_HDR_Z );
+      bsPutUChar ( s, BZ_HDR_h );
+      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
+   }
+
+   if (s->nblock > 0) {
+
+      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
+      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
+      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
+
+      /*-- Now the block's CRC, so it is in a known place. --*/
+      bsPutUInt32 ( s, s->blockCRC );
+
+      /*-- 
+         Now a single bit indicating (non-)randomisation. 
+         As of version 0.9.5, we use a better sorting algorithm
+         which makes randomisation unnecessary.  So always set
+         the randomised bit to 'no'.  Of course, the decoder
+         still needs to be able to handle randomised blocks
+         so as to maintain backwards compatibility with
+         older versions of bzip2.
+      --*/
+      bsW(s,1,0);
+
+      bsW ( s, 24, s->origPtr );
+      generateMTFValues ( s );
+      sendMTFValues ( s );
+   }
+
+
+   /*-- If this is the last block, add the stream trailer. --*/
+   if (is_last_block) {
+
+      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
+      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
+      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
+      bsPutUInt32 ( s, s->combinedCRC );
+      if (s->verbosity >= 2)
+         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
+      bsFinishWrite ( s );
+   }
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        compress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/c++/src/util/compress/bzip2/randtable.c b/c++/src/util/compress/bzip2/randtable.c
index 5c922e9..6d62459 100644
--- a/c++/src/util/compress/bzip2/randtable.c
+++ b/c++/src/util/compress/bzip2/randtable.c
@@ -4,59 +4,19 @@
 /*---                                           randtable.c ---*/
 /*-------------------------------------------------------------*/
 
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
 
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
 
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
 
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward at acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
---*/
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
 
 
 #include "bzlib_private.h"
diff --git a/c++/src/util/compress/bzip2/spewG.c b/c++/src/util/compress/bzip2/spewG.c
index 7934e76..14a3649 100644
--- a/c++/src/util/compress/bzip2/spewG.c
+++ b/c++/src/util/compress/bzip2/spewG.c
@@ -9,6 +9,21 @@
    (but is otherwise harmless).
 */
 
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+	 ------------------------------------------------------------------ */
+
+
 #define _FILE_OFFSET_BITS 64
 
 #include <stdio.h>
diff --git a/c++/src/util/compress/bzip2/unzcrash.c b/c++/src/util/compress/bzip2/unzcrash.c
index f0f17fc..7041da5 100644
--- a/c++/src/util/compress/bzip2/unzcrash.c
+++ b/c++/src/util/compress/bzip2/unzcrash.c
@@ -8,11 +8,26 @@
    This should not cause any invalid memory accesses.  If it does, 
    I want to know about it!
 
-   p.s.  As you can see from the above description, the process is
+   PS.  As you can see from the above description, the process is
    incredibly slow.  A file of size eg 5KB will cause it to run for
    many hours.
 */
 
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward <jseward at bzip.org>
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
 #include <stdio.h>
 #include <assert.h>
 #include "bzlib.h"
diff --git a/c++/src/util/file_manifest.cpp b/c++/src/util/file_manifest.cpp
index 5438158..25f385d 100644
--- a/c++/src/util/file_manifest.cpp
+++ b/c++/src/util/file_manifest.cpp
@@ -1,4 +1,4 @@
-/*  $Id: file_manifest.cpp 494188 2016-03-04 12:23:34Z ivanov $
+/*  $Id: file_manifest.cpp 492854 2016-02-22 16:33:44Z elisovdn $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/util/format_guess.cpp b/c++/src/util/format_guess.cpp
index b35f941..43b4f5c 100644
--- a/c++/src/util/format_guess.cpp
+++ b/c++/src/util/format_guess.cpp
@@ -1,4 +1,4 @@
-/*  $Id: format_guess.cpp 497436 2016-04-06 17:56:51Z ivanov $
+/*  $Id: format_guess.cpp 518720 2016-11-07 18:16:47Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -167,6 +167,7 @@ int CFormatGuess::s_CheckOrder[] =
     eGvf,
     eGff3,
     eGtf,
+    eGffAugustus,
     eGff2,
     eGlimmer3,
     eAgp,
@@ -176,18 +177,19 @@ int CFormatGuess::s_CheckOrder[] =
     eBed,
     eBed15,
     eHgvs,
-    eAlignment,
     eDistanceMatrix,
     eFlatFileSequence,
     eFiveColFeatureTable,
     eSnpMarkers,
     eFasta,
     eTextASN,
+    eAlignment,    
     eTaxplot,
     ePhrapAce,
     eTable,
     eBinaryASN,
     eUCSCRegion,
+    eJSON
 };
 
 
@@ -229,7 +231,9 @@ const char* const CFormatGuess::sm_FormatNames[CFormatGuess::eFormat_max] =
     "SRA",
     "BAM",
     "VCF",
-    "UCSC Region"
+    "UCSC Region",
+    "GFF Augustus",
+    "JSON"
 };
 
 const char*
@@ -321,7 +325,7 @@ CFormatGuess::SequenceType(const char* str, unsigned length,
 
 
 //  ----------------------------------------------------------------------------
-CFormatGuess::EFormat CFormatGuess::Format(const string& path, EOnError onerror)
+CFormatGuess::EFormat CFormatGuess::Format(const string& path, EOnError /*onerror*/)
 {
     CNcbiIfstream input(path.c_str(), IOS_BASE::in | IOS_BASE::binary);
     return Format(input);
@@ -341,8 +345,9 @@ CFormatGuess::EFormat CFormatGuess::Format(CNcbiIstream& input, EOnError onerror
 
 //  ----------------------------------------------------------------------------
 CFormatGuess::CFormatGuess()
-    : m_Stream( * new CNcbiIfstream )
-    , m_bOwnsStream( true )
+    : m_Stream(* new CNcbiIfstream)
+    , m_bOwnsStream(true)
+    , m_iTestBufferSize(0)
 {
     Initialize();
 }
@@ -385,10 +390,18 @@ CFormatGuess::GuessFormat( EMode )
 CFormatGuess::EFormat
 CFormatGuess::GuessFormat(
     EOnError onerror )
+//  ----------------------------------------------------------------------------
 {
+    //sqd-4036:
+    // make sure we got something to work with
+    //
     if (!x_TestInput(m_Stream, onerror)) {
         return eUnknown;
     }
+    if (!EnsureTestBuffer()) {
+        return eUnknown;
+    }
+
     EMode mode = eQuick;
     size_t uFormatCount = ArraySize(s_CheckOrder);
 
@@ -505,6 +518,10 @@ bool CFormatGuess::x_TestFormat(EFormat format, EMode mode)
         return TestFormatVcf( mode );
     case eUCSCRegion:
         return false;
+    case eGffAugustus:
+        return TestFormatAugustus( mode );
+    case eJSON:
+        return TestFormatJson( mode );
     default:
         NCBI_THROW( CCoreException, eInvalidArg,
             "CFormatGuess::x_TestFormat(): Unsupported format ID (" +
@@ -537,6 +554,7 @@ CFormatGuess::Initialize()
 //  ----------------------------------------------------------------------------
 bool
 CFormatGuess::EnsureTestBuffer()
+//  ----------------------------------------------------------------------------
 {
     if ( m_pTestBuffer ) {
         return true;
@@ -553,9 +571,16 @@ CFormatGuess::EnsureTestBuffer()
     //   or Multiplier hits 1024 
     int Multiplier = 1;
     while(true) {
-        m_pTestBuffer = new char[ Multiplier * s_iTestBufferSize ];
-        m_Stream.read( m_pTestBuffer, Multiplier * s_iTestBufferSize );
+        m_iTestBufferSize = Multiplier * s_iTestBufferGranularity;
+        m_pTestBuffer = new char[ m_iTestBufferSize ];
+        m_Stream.read( m_pTestBuffer, m_iTestBufferSize );
         m_iTestDataSize = m_Stream.gcount();
+        if (m_iTestDataSize == 0) {
+            delete[] m_pTestBuffer;
+            m_pTestBuffer = 0;
+            m_iTestBufferSize = 0;
+            return false; //empty file
+        } 
         m_Stream.clear();  // in case we reached eof
         CStreamUtils::Stepback( m_Stream, m_pTestBuffer, m_iTestDataSize );
         
@@ -563,7 +588,7 @@ CFormatGuess::EnsureTestBuffer()
             Multiplier *= 2;
             delete [] m_pTestBuffer;
             m_pTestBuffer = NULL;
-            if (Multiplier >= 1024 || m_iTestDataSize < ((Multiplier/2) * s_iTestBufferSize) )  {
+            if (Multiplier >= 1024 || m_iTestDataSize < m_iTestBufferSize)  {
                 return false;
             }
             continue;
@@ -578,6 +603,7 @@ CFormatGuess::EnsureTestBuffer()
 //  ----------------------------------------------------------------------------
 bool
 CFormatGuess::EnsureStats()
+//  ----------------------------------------------------------------------------
 {
     if ( m_bStatsAreValid ) {
         return true;
@@ -585,10 +611,6 @@ CFormatGuess::EnsureStats()
     if ( ! EnsureTestBuffer() ) {
         return false;
     }
-    if ( m_iTestDataSize == 0 ) {
-        m_bStatsAreValid = true;
-        return true;
-    }
 
     CNcbiIstrstream TestBuffer(
         reinterpret_cast<const char*>( m_pTestBuffer ), m_iTestDataSize );
@@ -799,6 +821,44 @@ CFormatGuess::TestFormatGff3(
 
 //  -----------------------------------------------------------------------------
 bool
+CFormatGuess::TestFormatAugustus(
+    EMode /*not used*/)
+{
+    if ( ! EnsureTestBuffer() || ! EnsureSplitLines() ) {
+        return false;
+    }
+
+    unsigned int uGffLineCount = 0;
+    list<string>::iterator it = m_TestLines.begin();
+
+    for ( ;  it != m_TestLines.end();  ++it) {
+        //
+        //  Make sure to ignore any UCSC track and browser lines prior to the
+        //  start of data
+        //
+        if (!uGffLineCount && NStr::StartsWith(*it, "##gff-version 3")) {
+            return false;
+        }
+        if ( it->empty() || (*it)[0] == '#' ) {
+            continue;
+        }
+        if ( !uGffLineCount && NStr::StartsWith( *it, "browser " ) ) {
+            return false;
+        }
+        if ( !uGffLineCount && NStr::StartsWith( *it, "track " ) ) {
+            return false;
+        }
+        if ( !IsLineAugustus( *it ) ) {
+            return false;
+        }
+        ++uGffLineCount;
+    }
+    return (uGffLineCount != 0);
+}
+
+
+//  -----------------------------------------------------------------------------
+bool
 CFormatGuess::TestFormatGff2(
     EMode /* not used */ )
 {
@@ -1085,10 +1145,7 @@ CFormatGuess::TestFormatFiveColFeatureTable(
             continue;
         }
 
-        if (it->find(">Feature ") != 0) {
-            return false;
-        }
-        if (it->find_first_of(" \t", 9) != string::npos) {
+        if (it->find(">Feature ") != 0 && it->find(">Features ") != 0) {
             return false;
         }
         break;
@@ -1210,7 +1267,7 @@ CFormatGuess::TestFormatAlignment(
         if (toks.size() != ncols) {
             list<string>::const_iterator it = iter;
             ++it;
-            if (it != m_TestLines.end() || (m_iTestDataSize < s_iTestBufferSize) ) {
+            if (it != m_TestLines.end() || (m_iTestDataSize < m_iTestBufferSize) ) {
                 return false;
             }
         } else {
@@ -1697,10 +1754,10 @@ bool CFormatGuess::TestFormatBam(EMode mode)
             &&  m_pTestBuffer[12] == 'B'  &&  m_pTestBuffer[13] == 'C');
 }
 
+
 //  ----------------------------------------------------------------------------
 bool CFormatGuess::TestFormatVcf(
     EMode)
-//  ----------------------------------------------------------------------------
 {
     // Currently, only look for the header line identifying the VCF version.
     // Waive requirement this be the first line, but still expect it to by
@@ -1716,6 +1773,338 @@ bool CFormatGuess::TestFormatVcf(
     }
     return false;
 }
+//  ----------------------------------------------------------------------------
+
+
+//  ----------------------------------------------------------------------------
+void CFormatGuess::x_StripJsonStrings(string& testString) const
+{
+    list<size_t> limits;
+    x_FindJsonStringLimits(testString, limits);
+
+    // If no strings found
+    if ( limits.empty() ) {
+        return;
+    }
+
+    if (limits.size()%2 == 1) { 
+        // Perhaps testString ends on an open string 
+        // Tack on an additional set of quotes at the end
+        testString += "\"";
+        limits.push_back(testString.size()-1);       
+    }
+    // The length of the limits container is now even
+
+    // Iterate over string start and stop sites
+    // Strip strings and copy what remains to complement
+    string complement = "";
+
+    auto it = limits.begin();
+    size_t comp_interval_start = 0;
+    while (it != limits.end()) {
+        const size_t string_start = *it++;
+        if (string_start > comp_interval_start) {
+            const size_t comp_interval_length = string_start-comp_interval_start;
+            complement += testString.substr(comp_interval_start, comp_interval_length);
+        }
+
+        const size_t string_stop = *it++;
+        comp_interval_start = string_stop+1;
+    }
+
+    if (comp_interval_start < testString.size()) {
+        complement += testString.substr(comp_interval_start);
+    }
+
+    testString = complement;
+    return;
+}
+//  ----------------------------------------------------------------------------
+
+
+//  ----------------------------------------------------------------------------
+void CFormatGuess::x_FindJsonStringLimits(const string& input, list<size_t>& limits) const
+{
+    limits.clear();
+    const string& double_quotes = R"(")";
+
+    bool is_start = true;
+    size_t pos = NStr::Find(input, double_quotes);
+    // List all string start and stop positions
+    while ( pos != NPOS ) {
+        limits.push_back(pos);
+        if (is_start) {
+            pos = x_FindNextJsonStringStop(input, pos+1);
+        } else {
+            pos = NStr::Find(input, double_quotes, pos+1);
+        }
+        is_start = !is_start;
+    }
+}
+//  ----------------------------------------------------------------------------
+
+
+//  ----------------------------------------------------------------------------
+size_t s_GetPrecedingFslashCount(const string& input, const size_t pos)
+{
+    if (pos == 0 ||
+        pos >= input.size() ||
+        NStr::IsBlank(input) ) 
+    {
+        return 0;
+    }
+
+    int current_pos = pos-1;
+    size_t num_fslash = 0;
+    while  ( current_pos >= 0 && input[current_pos] == '\\' ) {
+        ++num_fslash;
+        --current_pos;
+    }
+    return num_fslash;
+}
+//  ----------------------------------------------------------------------------
+
+
+//  ----------------------------------------------------------------------------
+size_t CFormatGuess::x_FindNextJsonStringStop(const string& input, const size_t from_pos) const
+{
+    const string& double_quotes = R"(")";
+    size_t pos = NStr::Find(input, double_quotes, from_pos);
+
+    // Double quotes immediately preceded by an odd number of forward 
+    // slashes, for example, /", ///", are escaped
+    while (pos != NPOS) {
+        const size_t num_fslash = s_GetPrecedingFslashCount(input, pos);
+        // If the number of forward slashes is even,
+        // return the position of the double quotes
+        if (num_fslash%2 == 0) {
+            break;
+        }
+        pos = NStr::Find(input, double_quotes, pos+1);
+    }   
+    return pos;
+}
+//  ----------------------------------------------------------------------------
+
+
+//  ----------------------------------------------------------------------------
+bool CFormatGuess::x_CheckStripJsonNumbers(string& testString) const
+{
+    if (NStr::IsBlank(testString)) {
+        return true;
+    }
+
+    list<string> subStrings;
+    // Split on white space
+    NStr::Split(testString, " \r\t\n", subStrings, NStr::fSplit_MergeDelims);
+
+    for (auto it = subStrings.cbegin(); it != subStrings.cend(); ++it) {
+        const string subString = *it;
+
+        if (!x_IsNumber(subString)) { // The last substring might be a truncated number or keyword
+           ++it;
+           if (it == subStrings.cend()) {
+               testString = subString;
+               return true;
+           }
+           return false;
+        }
+    }
+
+    testString.clear();
+    return true;
+}
+//  ----------------------------------------------------------------------------
+
+
+// -----------------------------------------------------------------------------
+bool CFormatGuess::x_IsTruncatedJsonNumber(const string& testString) const
+{
+    // Truncation of a JSON number may result strings of the following type:
+    //  1.1e
+    //  1.1E
+    //  1.7E-
+    //  +
+    //  -
+    // NStr::StringToDouble cannot handle such truncations, but we can "fix"
+    // the truncation by appending zero ("0") to the truncated string
+
+    const string extendedString = testString + "0"; 
+
+    return x_IsNumber(extendedString);
+}
+// -----------------------------------------------------------------------------
+
+
+// -----------------------------------------------------------------------------
+bool CFormatGuess::x_IsNumber(const string& testString) const 
+{
+    try {
+        NStr::StringToDouble(testString);
+    } 
+    catch (...) {
+        return false;
+    }
+    return true;
+}
+// -----------------------------------------------------------------------------
+
+
+// -----------------------------------------------------------------------------
+bool CFormatGuess::x_IsTruncatedJsonKeyword(const string& testString) const
+{
+    const size_t stringSize = testString.size();
+    // nul, tru, fals
+    if (stringSize > 4) {
+        return false;
+    }
+
+    const string nullString("null");
+    const string trueString("true");
+    const string falseString("false");
+
+    if (testString == nullString.substr(0, stringSize) ||
+        testString == trueString.substr(0, stringSize) ||
+        testString == falseString.substr(0, stringSize)) {
+        return true;
+    }
+
+    return false;
+}
+// -----------------------------------------------------------------------------
+
+
+//  ----------------------------------------------------------------------------
+bool CFormatGuess::x_IsBlankOrNumbers(const string& testString) const 
+{
+    if (NStr::IsBlank(testString)) {
+        return true;
+    }
+
+    list<string> numStrings;
+    // Split on white space
+    NStr::Split(testString, " \r\t\n", numStrings, NStr::fSplit_MergeDelims);
+
+    for (auto numString : numStrings) {
+        if (!x_IsNumber(numString)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+//  ----------------------------------------------------------------------------
+
+
+//  ----------------------------------------------------------------------------
+bool CFormatGuess::x_CheckStripJsonPunctuation(string& testString) const 
+{
+    // Parentheses are prohibited
+    if (testString.find_first_of("()") != string::npos) {
+        return false;
+    }
+
+    const size_t punctuation_threshold = 4;
+
+    // Reject if the number of punctuation characters falls below some threshold value.
+    // In this case, the threshold is hardcoded to 4.
+    if (x_StripJsonPunctuation(testString) < punctuation_threshold) {
+        return false;
+    }
+
+    return true;
+}
+//  ----------------------------------------------------------------------------
+
+
+//  ----------------------------------------------------------------------------
+size_t CFormatGuess::x_StripJsonPunctuation(string& testString) const 
+{
+    size_t initial_len = testString.size();
+
+    NStr::ReplaceInPlace(testString, "{", "");
+    NStr::ReplaceInPlace(testString, "}", "");
+    NStr::ReplaceInPlace(testString, "[", "");
+    NStr::ReplaceInPlace(testString, "]", "");
+    NStr::ReplaceInPlace(testString, ":", "");
+    NStr::ReplaceInPlace(testString, ",", "");
+
+    return testString.size() - initial_len;
+}
+//  ----------------------------------------------------------------------------
+
+
+//  ----------------------------------------------------------------------------
+void CFormatGuess::x_StripJsonKeywords(string& testString) const 
+{
+    NStr::ReplaceInPlace(testString, "true", "");
+    NStr::ReplaceInPlace(testString, "false", "");
+    NStr::ReplaceInPlace(testString, "null", "");
+}
+//  ----------------------------------------------------------------------------
+
+
+//  ----------------------------------------------------------------------------
+bool CFormatGuess::x_CheckJsonStart(const string& testString) const 
+{
+    if (NStr::StartsWith(testString, "{")) {
+        // Next character must begin a string
+        const auto next_pos = testString.find_first_not_of("( \t\r\n",1); 
+        if (next_pos != NPOS && testString[next_pos] == '\"') {
+            return true;
+        }
+    } 
+    else
+    if (NStr::StartsWith(testString, "[")) {
+        return true;
+    }
+
+    return false;
+}
+//  ----------------------------------------------------------------------------
+
+
+//  ----------------------------------------------------------------------------
+bool CFormatGuess::TestFormatJson(
+        EMode)
+{
+
+    // Convert the test-buffer character array to a string
+    string testString(m_pTestBuffer, m_iTestDataSize);
+
+    if ( NStr::IsBlank(testString) ) {
+        return false;
+    }
+
+    NStr::TruncateSpacesInPlace(testString, NStr::eTrunc_Begin);
+
+    if (!x_CheckJsonStart(testString)) {
+        return false;
+    }
+
+    x_StripJsonStrings(testString);
+
+    if ( !x_CheckStripJsonPunctuation(testString) ) {
+        return false;
+    }
+
+    x_StripJsonKeywords(testString);
+
+    if (!x_CheckStripJsonNumbers(testString)) {
+        return false;
+    }
+
+    if ( NStr::IsBlank(testString) ) {
+        return true;
+    }
+
+    // What remains is either a truncated number
+    // or a truncated keyword
+    return x_IsTruncatedJsonNumber(testString) | 
+           x_IsTruncatedJsonKeyword(testString);
+}
+//  ----------------------------------------------------------------------------
+
 
 //  ----------------------------------------------------------------------------
 bool CFormatGuess::IsInputRepeatMaskerWithHeader()
@@ -2260,6 +2649,99 @@ bool CFormatGuess::IsLineGff3(
 
 
 //  ----------------------------------------------------------------------------
+bool CFormatGuess::IsLineAugustus(
+    const string& line )
+{
+    vector<string> tokens;
+    string remaining(line), head, tail;
+
+    //column 0: ID, string
+    if (!NStr::SplitInTwo(remaining, " \t", head, tail)) {
+        return false;
+    }
+    remaining = tail;
+
+    //column 1: method, most likely "AUGUSTUS" but don't want to rely on this
+    if (!NStr::SplitInTwo(remaining, " \t", head, tail)) {
+        return false;
+    }
+    remaining = tail;
+
+    //column 2: feature type, controlled vocabulary
+    if (!NStr::SplitInTwo(remaining, " \t", head, tail)) {
+        return false;
+    }
+    remaining = tail;
+    string featureType = head;
+
+    //column 3: start, integer
+    if (!NStr::SplitInTwo(remaining, " \t", head, tail)  ||  !s_IsTokenPosInt(head)) {
+        return false;
+    }
+    remaining = tail;
+
+    //column 4: stop, integer
+    if (!NStr::SplitInTwo(remaining, " \t", head, tail)  ||  !s_IsTokenPosInt(head)) {
+        return false;
+    }
+    remaining = tail;
+
+    //column 5: score, double
+    if (!NStr::SplitInTwo(remaining, " \t", head, tail)  ||  !s_IsTokenDouble(head)) {
+        return false;
+    }
+    remaining = tail;
+
+    //column 6: strand, one in "+-.?"
+    const string legalStrands{"+-.?"};
+    if (!NStr::SplitInTwo(remaining, " \t", head, tail)  ||  head.size() != 1  ||  
+            string::npos == legalStrands.find(head)) {
+        return false;
+    }
+    remaining = tail;
+
+    //column 7: phase, one in ".0123"
+    const string legalPhases{".0123"};
+    if (!NStr::SplitInTwo(remaining, " \t", head, tail)  ||  head.size() != 1  ||  
+            string::npos == legalPhases.find(head)) {
+        return false;
+    }
+    remaining = tail;
+
+    //everything else: attributes, format depends on featureType
+    if (remaining.empty()) {
+        return false;
+    }
+
+    if (featureType == "gene") {
+        if (NPOS != NStr::Find(remaining, ";")) {
+            return false;
+        }
+        if (NPOS != NStr::Find(remaining, " ")) {
+            return false;
+        }
+        return true;
+    }
+    if (featureType == "transcript") {
+        if (NPOS != NStr::Find(remaining, ";")) {
+            return false;
+        }
+        if (NPOS != NStr::Find(remaining, " ")) {
+            return false;
+        }
+        return true;
+    }
+    if (NPOS == NStr::Find(remaining, "transcript_id")) {
+        return false;
+    }
+    if (NPOS == NStr::Find(remaining, "gene_id")) {
+        return false;
+    }
+    return true;
+}
+
+
+//  ----------------------------------------------------------------------------
 bool CFormatGuess::IsLineGff2(
     const string& line )
 {
@@ -2399,6 +2881,7 @@ CFormatGuess::IsAsnComment(
 }
 
 //  ----------------------------------------------------------------------------
+
 bool
 CFormatGuess::EnsureSplitLines()
 //  ----------------------------------------------------------------------------
@@ -2437,12 +2920,17 @@ CFormatGuess::EnsureSplitLines()
     else if ( string::npos != data.find("\r") ) {
         NStr::Split(data, "\r", m_TestLines, NStr::fSplit_Tokenize);
     }
-    else {
-        //single truncated line
+    else if ( m_iTestDataSize == m_iTestBufferSize) {
+        //most likely single truncated line
         return false;
     }
+    else {
+        //test buffer contains the entire file
+        m_TestLines.push_back(data);
+    }
 
-    if ( m_iTestDataSize == s_iTestBufferSize   &&  m_TestLines.size() > 1 ) {
+    if ( m_iTestDataSize == m_iTestBufferSize   &&  m_TestLines.size() > 1 ) {
+        //multiple lines, last likely truncated
         m_TestLines.pop_back();
     }
     return !m_TestLines.empty();
diff --git a/c++/src/util/retry_ctx.cpp b/c++/src/util/retry_ctx.cpp
index bb70b52..f715bc1 100644
--- a/c++/src/util/retry_ctx.cpp
+++ b/c++/src/util/retry_ctx.cpp
@@ -1,4 +1,4 @@
-/*  $Id: retry_ctx.cpp 499300 2016-04-25 15:23:35Z ivanov $
+/*  $Id: retry_ctx.cpp 498886 2016-04-20 13:48:22Z grichenk $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/util/scheduler.cpp b/c++/src/util/scheduler.cpp
index ca6dac5..92809fe 100644
--- a/c++/src/util/scheduler.cpp
+++ b/c++/src/util/scheduler.cpp
@@ -1,4 +1,4 @@
-/*  $Id: scheduler.cpp 489095 2016-01-08 13:02:41Z ivanov $
+/*  $Id: scheduler.cpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -76,15 +76,15 @@ public:
 
 
     /// Check if this event matches given series id
-    bool IsMatch(TScheduler_SeriesID id) const
+    bool IsMatch(TScheduler_SeriesID match_id) const
     {
-        return this->id == id;
+        return this->id == match_id;
     }
 
     /// Check if this event matches given task
-    bool IsMatch(IScheduler_Task* task) const
+    bool IsMatch(IScheduler_Task* match_task) const
     {
-        return &*this->task == task;
+        return &*this->task == match_task;
     }
 
     /// Dummy function to support code templates and avoid duplication of code
diff --git a/c++/src/util/sequtil/sequtil_convert_imp.cpp b/c++/src/util/sequtil/sequtil_convert_imp.cpp
index 9e637c6..000eda8 100644
--- a/c++/src/util/sequtil/sequtil_convert_imp.cpp
+++ b/c++/src/util/sequtil/sequtil_convert_imp.cpp
@@ -1,4 +1,4 @@
-/*  $Id: sequtil_convert_imp.cpp 495186 2016-03-15 16:38:09Z ivanov $
+/*  $Id: sequtil_convert_imp.cpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -1177,13 +1177,13 @@ SIZE_TYPE CSeqConvert_imp::CPacker::Pack(const char* src, TSeqPos length)
             ++i; // merge when possible
         }
 
-        TSeqPos length  = m_Boundaries[i + 1] - start;
-        char *  segment = m_Target.NewSegment(coding, length);
+        TSeqPos len = m_Boundaries[i + 1] - start;
+        char* segment = m_Target.NewSegment(coding, len);
         if (coding == CSeqUtil::e_not_set) { // gap
             _ASSERT(m_GapsOK);
-            result += length;
+            result += len;
         } else {
-            result += CSeqConvert::Convert(src, m_SrcCoding, start, length,
+            result += CSeqConvert::Convert(src, m_SrcCoding, start, len,
                                            segment, coding);
         }
     }
diff --git a/c++/src/util/sequtil/sequtil_convert_imp.hpp b/c++/src/util/sequtil/sequtil_convert_imp.hpp
index 8e3da15..940c15c 100644
--- a/c++/src/util/sequtil/sequtil_convert_imp.hpp
+++ b/c++/src/util/sequtil/sequtil_convert_imp.hpp
@@ -1,7 +1,7 @@
 #ifndef UTIL_SEQUTIL___SEQUTIL_CONVERT_IMP__HPP
 #define UTIL_SEQUTIL___SEQUTIL_CONVERT_IMP__HPP
 
-/*  $Id: sequtil_convert_imp.hpp 495186 2016-03-15 16:38:09Z ivanov $
+/*  $Id: sequtil_convert_imp.hpp 495056 2016-03-14 16:14:57Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/util/strbuffer.cpp b/c++/src/util/strbuffer.cpp
index 9003e9d..26f9b9d 100644
--- a/c++/src/util/strbuffer.cpp
+++ b/c++/src/util/strbuffer.cpp
@@ -1,4 +1,4 @@
-/*  $Id: strbuffer.cpp 489095 2016-01-08 13:02:41Z ivanov $
+/*  $Id: strbuffer.cpp 511367 2016-08-22 12:15:50Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
@@ -792,7 +792,14 @@ struct STemporarilyClearStreamState
         }
     ~STemporarilyClearStreamState()
         {
-            m_Stream.setstate(m_State);
+            try {
+                m_Stream.setstate(m_State);
+            }
+            catch ( ios_base::failure& /*ignored*/ ) {
+                // stream may throw exception of type failure if instructed so
+                // the exception should've been already thrown
+                // we only restore the stream state
+            }
         }
 
     ios& m_Stream;
diff --git a/c++/src/util/stream_source.cpp b/c++/src/util/stream_source.cpp
index 5aa2547..1fd4f79 100644
--- a/c++/src/util/stream_source.cpp
+++ b/c++/src/util/stream_source.cpp
@@ -1,4 +1,4 @@
-/*  $Id: stream_source.cpp 497775 2016-04-11 11:26:07Z mozese2 $
+/*  $Id: stream_source.cpp 497774 2016-04-11 11:24:26Z mozese2 $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
diff --git a/c++/src/util/table_printer.cpp b/c++/src/util/table_printer.cpp
index 455634e..7112f23 100644
--- a/c++/src/util/table_printer.cpp
+++ b/c++/src/util/table_printer.cpp
@@ -1,4 +1,4 @@
-/*  $Id: table_printer.cpp 489095 2016-01-08 13:02:41Z ivanov $
+/*  $Id: table_printer.cpp 500279 2016-05-03 17:12:04Z ivanov $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -53,10 +53,10 @@ void CTablePrinter::SColInfoVec::AddCol(
 CTablePrinter::CTablePrinter(
     const SColInfoVec & vecColInfo, 
     ostream & ostrm,
-    const string & m_sColumnSeparator)
+    const string & sColumnSeparator)
     : m_eState(eState_Initial), 
       m_vecColInfo(vecColInfo), m_ostrm(ostrm), m_iNextCol(0),
-      m_sColumnSeparator(m_sColumnSeparator)
+      m_sColumnSeparator(sColumnSeparator)
 {
     // if any column width is less than the length of the name of the column,
     // expand it
diff --git a/c++/src/util/tables/raw_scoremat.c b/c++/src/util/tables/raw_scoremat.c
index 493abbe..9dad83a 100644
--- a/c++/src/util/tables/raw_scoremat.c
+++ b/c++/src/util/tables/raw_scoremat.c
@@ -1,4 +1,4 @@
-/*  $Id: raw_scoremat.c 489095 2016-01-08 13:02:41Z ivanov $
+/*  $Id: raw_scoremat.c 503968 2016-06-09 18:13:53Z ucko $
  * ===========================================================================
  *
  *                            PUBLIC DOMAIN NOTICE
@@ -87,7 +87,12 @@ void NCBISM_Unpack(const SNCBIPackedScoreMatrix* psm,
     sym = psm->symbols;
     dim = (int)strlen(sym);
     /* fill with default */
-    memset(&fsm->s, psm->defscore, NCBI_FSM_DIM * NCBI_FSM_DIM);
+    for (i = 0;  i < NCBI_FSM_DIM;  ++i) {
+        fsm->s[0][i] = psm->defscore;
+    }
+    for (i = 1;  i < NCBI_FSM_DIM;  ++i) {
+        memcpy(fsm->s[i], fsm->s[0], NCBI_FSM_DIM * sizeof(fsm->s[0][0]));
+    }
     for (i = 0;  i < dim;  ++i) {
         aa1 = sym[i];
         /* get core (NCBIeaa x NCBIeaa) */
diff --git a/c++/src/util/thread_pool.cpp b/c++/src/util/thread_pool.cpp
index 90d7102..61e42c7 100644
--- a/c++/src/util/thread_pool.cpp
+++ b/c++/src/util/thread_pool.cpp
@@ -1,4 +1,4 @@
-/*  $Id: thread_pool.cpp 497872 2016-04-11 18:27:29Z ivanov $
+/*  $Id: thread_pool.cpp 497641 2016-04-08 15:17:34Z ucko $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/ncbi-blast+.git



More information about the debian-med-commit mailing list